2023年春秋杯网络安全联赛冬季赛file_encryptor
0x00 分析
此题比较综合,涉及到了TLS回调函数反调试、SEH异常处理、花指令
总的来说很是有意思
0x01 解
无壳,上IDA直接爆红
反调肯定有的,应该还有异常处理
tab看一下,发现有try...except...
结构
这就涉及到“异常”这个东西了
关于异常可以看这个:windows-SEH详解
关于SEH在IDA中的表现可以看这个:C++异常处理
这个处理的方法还算简单,就是将整个try
包裹的结构nop掉之后改掉jcc的跳转位置,使其强制跳转就行
不过在此之前,先看看TLSCallback函数吧
关于TLS回调函数:TLS回调函数的学习
TLS回调函数是指,每当创建/终止线程时会自动调用执行的函数(创建进程的主线程时也会自动调用回调函数,且回调函数的执行顺序是先于EP代码的执行,所以TLS回调函数的这个特性通常被用于反调试技术)由于是创建和终止线程时都会调用,所以在程序从打开到结束这个TLS回调函数会被执行两次。
在本题中,这个TlsCallback函数是反调试之一
整个流程大概是这样的:
检测是否有调试器的存在,如果有则exit,否则执行一个异常,然后交由except进行处理
由此处理方法是:
让其直接跳转到except位置,执行except的内容
此时可以发现TLSCallback函数内执行了一些操作(幸好没有整个nop掉)
接下来再去处理main函数
这边的try里的内容对反编译有影响,索性全nop了
之后往下看有个爆红的call
在这行U,然后发现有个E8的花:逆向分析基础 — 花指令实现及清除
直接nop掉e8然后C就行
这下反编译比较正常了
继续检查main函数,发现下面调用的loc_401320里面有爆红
同样的去花方法
这下能被解析成函数了
再检查发现没有别的地方有问题了
可以apply patch了
之后就慢慢分析了
用了很多资源相关的函数
这边试着dump资源下来
看v10被拿去做运算了,在dword_100541C处下断点,然后跟进去v10看看资源
发现有个MZ,直接dump下来
丢进CFF Explorer看看
看来跟加密有关
去看看输出表
很多crypt的函数
看看在程序里面怎么调用这些函数的
尝试单步调试
发现在这里sub_1001320处会退出,跟进发现这里有个exit(0)
调试到这会发现这个
JNZ指令的含义是“Jump if Not Zero”,即当结果不为0时转移。如果执行操作的寄存器或操作数的结果不为0,则控制权转移到指定的标签位置。 JZ指令的含义是“Jump if Zero”,即当结果为0时转移。如果执行操作的寄存器或操作数的结果为0,则控制权转移到指定的标签位置。
这里为了让他不跳转,需要将jz
改为jnz
(动调时改标志位就行)
继续动调,发现在这里又退出了
反编译发现是因为找不到文件
通过查看ppszPath
发现路径是桌面
也就是说要在桌面里新建一个documet文件夹然后放文件进去才能加密
那就patch一下上面的jz
然后新建一个文件夹试试
里面再顺便创建一个1.txt
存个输入
之后发现会跑到这个函数里面
跟进去发现有两个变量off_A55414
和off_A55418
点进去可以发现是两个函数:rsaenh_CPGenKey
和rsaenh_CPAcquireContext
这下应该是快要见到加密部分了
先执行sub_A51640
会发现文件内容并没有改变
猜测这是一个初始化的东西
而执行下面的sub_A513E0
会发现文件内容被加密,说明加密函数就是这个sub_A513E0
进去会发现在v6
那一行有一个0xB
,恰好对应上面的CryptEncrypt
函数
由此猜测sub_A51BB0
是用于调用dll输出表中对应Name Ordinal
值的函数
那么尝试将0xB
改为0x5
(对应CryptDecrypt
)
再次执行程序
就会发现flag被解密了
1 | flag{7sa963fa-91a6-4371-bl7b-225102y789a0} |