XYCTF2025 re wp

WARMUP

附件可以直接用记事本打开,里面就是很多的运算,运算即可

点击查看代码
calculations = []  #运算式
result = ''.join(chr(c) for c in calculations)
print(result)

但是有些结果为负数的要忽略

最后我没有还原完,但是大致能够将看懂

点击查看代码
MsgBox "Dear CTFER. Have fun in XYCTF 2025!"
flag = InputBox("Enter the FLAG:", "XYCTF")
wefbuwiue = "90df4407ee093d309098d85a42be57a2979f1e51463a31e8d15e2fac4e84ea0df622a55c4ddfb535ef3e51e8b2528b826d5347e165912e99118333151273cc3fa8b2b3b413cf2bdb1e8c9c52865efc095a8dd89b3b3cfbb200bbadbf4a6cd4"
qwfe = "rc4key"

' RC4
Function RunRC(sMessage, strKey)
    Dim kLen, i, j, temp, pos, outHex
    Dim s(255), k(255)

    i = 0 : j = 0 : outHex = ""
    For pos = 1 To Len(sMessage)
        i = (i + 1) Mod 256
        j = (j + s(i)) Mod 256
        temp = s(i)
        s(i) = s(j)
        s(j) = tempmp, pos, outHex
    D



If LCase(RunRC(flag, qwfe)) = LCase(wefbuwiue) Then
    MsgBox "Congratulations! Correct FLAG!"
Else
    MsgBox "Wrong flag."
End If

就是一个rc4

最后根据比赛描述可以得出flag

XYCTF{5f9f46c147645dd1e2c8044325d4f93c}

Dragon

第一次拿一血😉

看到文件后缀是bc,然后就浏览器搜索.bc文件逆向,找到博客

https://www.cnblogs.com/ren-ctfnote/p/14948764.html

用clang重编译

clang安装:https://zhuanlan.zhihu.com/p/663843824

clang Dragon.bc -o Dragon

有这个warning也不用管,在文件目录下已经生成了Dragon文件

看到常数,是crc64

cmp处提取crc64

爆破

点击查看代码
#include <stdio.h>
#include <stdint.h>

int64_t CRC64(const uint8_t *data, uint64_t length) {
    int64_t crc = -1;
    for (int i = 0; i < length; i++) {
        crc ^= (int64_t)data[i] << 56;
        for (int j = 0; j < 8; j++) {
            if (crc < 0)
                crc = (crc *2) ^ 0x42F0E1EBA9EA3693ULL;
            else
                crc <<= 1;
        }
    }
    return ~crc;
}

int main() {
    int64_t enc[] = {
        0xDC63E34E419F7B47, 0x031EF8D4E7B2BFC6, 0x12D62FBC625FD89E, 0x83E8B6E1CC5755E8,
        0xFC7BB1EB2AB665CC, 0x9382CA1B2A62D96B, 0xB1FFF8A07673C387, 0x0DA81627388E05E1,
        0x9EF1E61AE8D0AAB7, 0x92783FD2E7F26145, 0x63C97CA1F56FE60B, 0x9BD3A8B043B73AAB
    };
    for (int i = 0; i < 12; i++) {
        for (int j = 0x2020; j <= 0x7E7E; j++) {//可见字符
            uint8_t data[2];
            data[0] = (uint8_t) j;//低字节
            data[1] = (j>>8)&0xff;//高字节
            if (CRC64(data, 2) == enc[i]) {
                printf("%c%c", data[0], data[1]);
                break;
            }
        }
    }
    return 0;
}


flag:flag{LLVM_1s_Fun_Ri9h7?}

后来看ollvm的时候又学习到了

LLVM的pass是用来优化分析的, pass编写都是针对IR指令的
中间层代码(IR)主要有两种表现形式:

  1. 人类可阅读的文本形式,对应后缀为 .ll
    clang -S -emit-llvm fileName.c -o fileName.ll
  2. 方便机器处理的二进制文本,对应后缀为 .bc

moon

python逆向的重要点:同一个环境!!!

题目的环境是py31

pyd逆向

点击查看代码
import moon
print(dir(moon))
print('--------')
help(moon)
print('--------')
help(moon.check_flag)

查看moon的基本信息 (运行脚本出现more要回车)

点击查看代码
['SEED', 'TARGET_HEX', '__builtins__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '__test__', 'check_flag', 'random', 'xor_crypt']
--------
Help on module moon:                                                                                                                                            

NAME
    moon

FUNCTIONS
    check_flag(input_str)
        返回验证结果的元组:(是否通过, 错误类型)

    xor_crypt(seed_value, data_bytes)
                                                                                                                                                                
DATA                                                                                                                                                            
    SEED = 1131796                                                                                                                                              
    TARGET_HEX = '426b87abd0ceaa3c58761bbb0172606dd8ab064491a2a76af9a93e1a...                                                                                   
    __test__ = {}                                                                                                                                               
                                                                                                                                                                
FILE                                                                                                                                                            
    e:\comp\xyctf2025\moon\moon.pyd                                                                                                                             
                                                                                                                                                                

--------
Help on cython_function_or_method in module moon:                                                                                                               

check_flag(input_str)
    返回验证结果的元组:(是否通过, 错误类型)


发现seed和不完全的hex

ida查看pyd就能看到,还能看到xor

PyLong_FromLong对数值处理的函数

逻辑也就差不多了

点击查看代码
import random

seed=0x114514
random.seed(seed)
for i in range(0,35):
    print(random.randint(0,255),end=',')
#36,7,230,204,171,172,223,72,7,15,43,206,94,30,80,93,179,152,98,27,228,210,248,42,141,246,74,114,214,48,197,13,73,204,138
a=[36,7,230,204,171,172,223,72,7,15,43,206,94,30,80,93,179,152,98,27,228,210,248,42,141,246,74,114,214,48,197,13,73,204,138]
b="426b87abd0ceaa3c58761bbb0172606dd8ab064491a2a76af9a93e1ae56fa84206a2f7"
c=bytes.fromhex(b)
for i,j in zip(a,c):
    print(chr(i^j),end="")
#flag{but_y0u_l00k3d_up_@t_th3_mOOn}

Lake

对照官方wp和 https://www.cnblogs.com/Q7h2q9/p/18817669 这位师傅的博客做出来的

动态调试找到主函数

从start函数开始

F7步进

F7步进

进入主函数

这里的异或是对字符的加密

opcode格式

操作名 操作下标,操作值

所以以每三个为一组

enc1 就是这种操作符进行加密,但是实际上只有加、减和异或

enc2 是移位操作

点击查看代码
#include <stdio.h>
#include <ctype.h>
#include <stdint.h>
#include<stdlib.h>
int main(){
//	int a[]={0x4A,0xAB,0x9B,0x1B,0x61,0xB1,0xF3,0x32,0xD1,0x8B,0x73,0xEB,0xE9,0x73,0x6B,0x22,0x81,0x83,0x23,0x31,0xCB,0x1B,0x22,0xFB,0x25,0xC2,0x81,0x81,0x73,0x22,0xFA,0x3,0x9C,0x4B,0x5B,0x49,0x97,0x87,0xDB,0x51};
//	int b[48];
//	for(int i=0;i<40;i+=4){
//		b[i] = ((a[i+2] & 0x07) << 5) | ((a[i+3] >> 3) & 0x1f );
//		b[i+1] = ((a[i] >> 3) & 0x1f) | ((a[i+3] & 0x07) << 5);
//		b[i+2] = ((a[i] & 0x07) << 5) | ((a[i+1] >> 3) & 0x1f);
//		b[i+3] = ((a[i+1] & 0x07) << 5) | ((a[i+2] >> 3) & 0x1f);
//printf("%d,%d,%d,%d,",b[i]%256,b[i+1]%256,b[i+2]%256,b[i+3]%256);
//	}
int a[]={99,105,85,115,102,76,54,62,125,122,49,110,100,93,46,109,102,48,48,100,95,121,99,100,48,36,184,80,64,110,100,95,105,51,137,107,106,50,240,251};
int b[]={0x2,0x2,0xc,0x1,0x1a,0x55,0x1,0x23,0xc,0x2,0xe,0x9,0x1,0x1b,0x6,0x8,0x6,0x5,0x8,0x1,0x5,0x2,0x1b,0xe,0x2,0x19,0x3,0x2,0x1a,0x4,0x8,0x4,0x8,0x1,0x3,0xc,0x2,0xc,0xa,0x1,0x25,0x2,0x1,0x20,0x2,0x1,0x9,0xc,0x8,0x1a,0x5,0x2,0x4,0xd,0x8,0x8,0xf,0x2,0xa,0xe,0x1,0x10,0x7,0x1,0xc,0x7,0x8,0x22,0x8,0x8,0x15,0xa,0x1,0x27,0x7e,0x2,0x7,0x2,0x8,0xf,0x3,0x8,0xa,0xa,0x1,0x22,0xb,0x2,0x12,0x8,0x2,0x19,0x9,0x8,0xe,0x6,0x8,0x0,0x5,0x1,0xa,0x8,0x8,0x1b,0x7,0x8,0xd,0x6,0x8,0xd,0x4,0x8,0x17,0xc,0x8,0x22,0xe,0x2,0x12,0x34,0x1,0x26,0x77};
//for(int i=0;i<123;i+=3){
//	int opcode = b[i];
//	int index = b[i+1];
//	int value = b[i+2];
//	switch(opcode){
//		case 1:printf("a[%d] -= %d;\n",index,value);break;
//		case 2:printf("a[%d] += %d;\n",index,value);break;
//		case 3:printf("a[%d] *= %d;\n",index,value);break;
//		case 4:printf("a[%d] /= %d;\n",index,value);break;
//		case 5:printf("a[%d] %= %d;\n",index,value);break;
//		case 6:printf("a[%d] &= %d;\n",index,value);break;
//		case 7:printf("a[%d] |= %d;\n",index,value);break;
//		case 8:printf("a[%d] ^= %d;\n",index,value);break;
//	}
//}
a[2] += 12;
a[26] -= 85;
a[35] -= 12;
a[14] += 9;
a[27] -= 6;
a[6] ^= 5;
a[1] ^= 5;
a[27] += 14;
a[25] += 3;
a[26] += 4;
a[4] ^= 8;
a[3] -= 12;
a[12] += 10;
a[37] -= 2;
a[32] -= 2;
a[9] -= 12;
a[26] ^= 5;
a[4] += 13;
a[8] ^= 15;
a[10] += 14;
a[16] -= 7;
a[12] -= 7;
a[34] ^= 8;
a[21] ^= 10;
a[39] -= 126;
a[7] += 2;
a[15] ^= 3;
a[10] ^= 10;
a[34] -= 11;
a[18] += 8;
a[25] += 9;
a[14] ^= 6;
a[0] ^= 5;
a[10] -= 8;
a[27] ^= 7;
a[13] ^= 6;
a[13] ^= 4;
a[23] ^= 12;
a[34] ^= 14;
a[18] += 52;
a[38] -= 119;
for(int i=0;i<40;i++){
	printf("%c",a[i]);
}
//int m[]={0x2,0x0,0x2,0x0,0xC,0x0,0x1,0x0,0x1A,0x0,0x55,0x0,0x1,0x0,0x23,0x0,0xC,0x0,0x2,0x0,0xE,0x0,0x9,0x0,0x1,0x0,0x1B,0x0,0x6,0x0,0x8,0x0,0x6,0x0,0x5,0x0,0x8,0x0,0x1,0x0,0x5,0x0,0x2,0x0,0x1B,0x0,0xE,0x0,0x2,0x0,0x19,0x0,0x3,0x0,0x2,0x0,0x1A,0x0,0x4,0x0,0x8,0x0,0x4,0x0,0x8,0x0,0x1,0x0,0x3,0x0,0xC,0x0,0x2,0x0,0xC,0x0,0xA,0x0,0x1,0x0,0x25,0x0,0x2,0x0,0x1,0x0,0x20,0x0,0x2,0x0,0x1,0x0,0x9,0x0,0xC,0x0,0x8,0x0,0x1A,0x0,0x5,0x0,0x2,0x0,0x4,0x0,0xD,0x0,0x8,0x0,0x8,0x0,0xF,0x0,0x2,0x0,0xA,0x0,0xE,0x0,0x1,0x0,0x10,0x0,0x7,0x0,0x1,0x0,0xC,0x0,0x7,0x0,0x8,0x0,0x22,0x0,0x8,0x0,0x8,0x0,0x15,0x0,0xA,0x0,0x1,0x0,0x27,0x0,0x7E,0x0,0x2,0x0,0x7,0x0,0x2,0x0,0x8,0x0,0xF,0x0,0x3,0x0,0x8,0x0,0xA,0x0,0xA,0x0,0x1,0x0,0x22,0x0,0xB,0x0,0x2,0x0,0x12,0x0,0x8,0x0,0x2,0x0,0x19,0x0,0x9,0x0,0x8,0x0,0xE,0x0,0x6,0x0,0x8,0x0,0x0,0x0,0x5,0x0,0x1,0x0,0xA,0x0,0x8,0x0,0x8,0x0,0x1B,0x0,0x7,0x0,0x8,0x0,0xD,0x0,0x6,0x0,0x8,0x0,0xD,0x0,0x4,0x0,0x8,0x0,0x17,0x0,0xC,0x0,0x8,0x0,0x22,0x0,0xE,0x0,0x2,0x0,0x12,0x0,0x34,0x0,0x1,0x0,0x26,0x0,0x77};
//for(int i=0;i<246;i+=2){
//	printf("0x%x,",m[i]); 
//}
}
//flag{L3@rn-ng_1n_0ld_sch00b_@nd_g3x_j0y}
posted @ 2025-04-17 17:20  zzz222666  阅读(32)  评论(0)    收藏  举报