<2023强网杯>复现
reverse
ezre(2023-12-19)
来自http://mtw.so/5ECr2q
父子进程(fork函数) 参考文献http://mtw.so/5xMbp5 http://mtw.so/6gTs9O
简言之,fork()函数执行后会复制一遍代码,开启一个新的进程(子进程),父子进程执行顺序不确定,且二者共享存储空间,二者的变量发生改变不影响另一进程。文章中还涉及返回值,pid,pcb,以及缓冲区刷新等,在此不多赘述。
虽然目前没看到哪里是父子进程,继续往下看“d810”,看不懂哈哈,我们换篇文章(来源:https://mp.weixin.qq.com/s/ksGjGGeYjvWpgmRA5xyBpg)
好好好,看样子是个插件,装!!!哇去,感觉这个插件,好吊。
参考:https://zhuanlan.zhihu.com/p/598019392?utm_id=0
使用后观察主函数,发现依旧看不懂,看了gyc的题解后才发现,可以查出来sm4加密,用findcrypt3试了一下,发现查不到,问了wm才知道需要用signsrh插件,启动,跳转,发现byte_6130是sm4的sbox表,那么sub_1260函数应该就是sm4的tao运算,也没怎么做过sm4的题目,发现这个加密了,猜测一下应该就是解一下,开始寻找密文与密钥,发现在sub_3058函数中
这里是我的一个疑惑点,这是小端序,感觉总是区分不出那个是小端序,哪个不是,害。
总结一下应该就是主函数给了一个假check,看题解说啥init_arry中调用了fork(),说实话,真没看明白,害,慢慢学吧。
最后附上gyc的代码(py是真的不会,赛博厨子又要先把小端序处理了,感觉也挺麻烦,还是学习代码吧)
import struct
from sm4 import SM4Key
e\_arr = \[0x7C88631647197506, 0x4A0D7D3FFF55668B, 0xDEC2E93F384ED2F5, 0x3C1FB1746F7F7CDB\]
key = \[0xEFCDAB8967452301, 0xEFCDAB8967452301\]
e = struct.pack('<4Q', e\_arr\[0\], e\_arr\[1\], e\_arr\[2\], e\_arr\[3\])
key = struct.pack('<2Q', key\[0\], key\[1\])
d = SM4Key(key).decrypt(e)
# cipher.set\_key(key, mode=SM4\_DECRYPT)
# d = cipher.crypt\_cbc(e)
print(d)
#flag{h3kk0\_w0rld\_sur3\_3n0ugh}
分析一下代码
强网先锋
babyre
tls反调试:(参考文献:http://mtw.so/5ECQzY http://mtw.so/61RrQw)
啊这,我也看不懂这个文章,什么线程,变量啥啥的。
Thread Local Storage(TLS),是Windows为解决一个进程中多个线程同时访问全局变量而提供的机制。TLS可以简单地由操作系统代为完成整个互斥过程,也可以由用户自己编写控制信号量的函数。当进程中的线程访问预先制定的内存空间时,操作系统会调用系统默认的或用户自定义的信号量函数,保证数据的完整性与正确性。
通俗点应该就是解决多线程同时访问全局变量是,害怕冲突互斥发生错误的一种机制,这样应该就可以理解为什么ida里面直接查看密钥与密文的数据不是正确的数据这件事了。(只是我的猜测哈,也可能就是在程序运行时他们的值被更改了。)
判别方法(1)动调一下,发现报错"something go wrong",回去搜一下这个字符串,之后跳转到该对应位置,找到显示此字符串的函数,按x查看一下哪些函数调用了这个函数,
判别方法(2)看export位置,里面除了主函数,还有什么函数可以结束程序
去除反调试方法:分析该函数,可以看到beingdebug啥啥的,判断beingdebug==一个值,就代表判断你是否在调试,后面调用的函数应该就是显示"something go wrong"的函数,tab转到汇编位置,patch一下,把jz改jnz或者把jnz改成jz。
需要注意的是patch后要运用到程序上需要在按图操作
在babyre程序中除了xtea加密外,还有两个函数对flag进行了处理,一开始不是很能理解,为什么不需要逆向这几个函数,后来问了🌳才知道,函数1是把4个char型的flag转换成int型的来方便对其xtea加密,还有可能会逆序一下,这个挺关键的。
至于函数2则是反过来,把转换后的int型改成4个char型,这个也可能逆序,两个函数是否逆序不同的话,解密后的结果可能是倒过来的,应该挺好发现的。
之后就是xtea的解密了
进到这个函数中,一眼xtea魔改
附上解密脚本
#include <stdio.h>
int main(){
int i,j;
unsigned int cryber\[32\] = {
0x9523F2E0, 0x8ED8C293, 0x8668C393, 0xDDF250BC, 0x510E4499, 0x8C60BD44, 0x34DCABF2, 0xC10FD260
};
unsigned long long v3;
unsigned char key\[4\] = {
0x62, 0x6F, 0x6D, 0x62
};
for (int k = 0; k < 4; ++k) {
v3 = 0x90508D47 - 4 \* 33 \* 0x77BF7F99;
for (i = 0; i < 4; ++i) {
for (j = 0; j < 33; ++j) {
v3 += 0x77BF7F99;
cryber\[2 \* k + 1\] -= (((32 \* cryber\[2 \* k\]) ^ (cryber\[2 \* k\] >> 4)) + cryber\[2 \* k\]) ^(v3 + key\[(v3 >> 11) & 3\]);
cryber\[2 \* k\] -= (((32 \* cryber\[2 \* k + 1\]) ^ (cryber\[2 \* k + 1\] >> 4)) + cryber\[2 \* k + 1\]) ^(v3 + key\[v3 & 3\]) ^ v3;
}
}
}
printf("%s",cryber);
}