2023NepCTF九龙拉棺
0x00 题目分析
8线程+1进程+反调试+多重加密+SMC
难度:easy
……
0x01 解
照例,查壳(Not packed)
没壳就拖进IDA直接到main函数看

多个线程+长度限制
还有看到个提权:https://www.jianshu.com/p/232fbd1a3cfb
感觉挺麻烦的
接下来看看每个线程都执行了什么函数
StartAddress函数

这个函数里面有个CreateProcessA,创建了一个进程,估计有一部分的操作是在创建的子进程里面进行的
sub_402460

下面有这个

这个byte_404210有点怪,里面是空的
sub_402630

这里面有个sub_401120

base64
结合这个base64和上面那个函数的1.37+1,可以知道上面那个函数应该是base58
参考:https://blog.csdn.net/weixin_34258782/article/details/88830132
sub_4020B0

看不太懂,但是应该是什么算法,下面有很多操作

结合WP,这应该是一个反调试(
反调试动态读取.text(第一个段)并通过累加的方式,不断读取对比的方式,来实现反调试。如果程序一开始就存在断点,则该反调试无效,若在调试中突然增加int3断点,则该程序直接退出
sub_401700

这些应该就是密文了,往下滑滑可以看到老朋友TEA

但是这个和原版不太一样,是XTEA
sub_4023A0

里面的这个sub_4012B0是这样的

看来是个base32的操作
sub_401E60

看不太懂,但是这个byte_406018有一大堆乱码,合理怀疑是被加密的什么东西

sub_4018F0

结合WP,这应该就是
上动调,会发现一下断点或者下了断点运行后程序会自动退出
看来有反调试,先干一下
刚刚那些进程里面的函数基本都有调用这个sub_4015E0
进这个函数看看

Dr7,看来这个是反调试了
参考:http://www.jybase.net/ruanjianpojie/20111221725.html
ExitProcess这个地方nop掉应该就行了

别忘了还要处理sub_4020B0

搞完之后就可以正常下断点调试了
看了一下官方WP发现有一个子线程是进行判断的,如果判断不对会直接退出程序
行吧,那就只能从上面的加密下手了
结合CreateProcessA和byte_406018的长度可以知道

这里应该是用了SMC
参考:https://segmentfault.com/a/1190000043519957
所以这串代码就要解密了
现在有两个方法进行解密
第一种是直接dump这段byte然后根据算法解密
第二种是直接动调然后在内存中找
第一种要注意解密顺序
可以根据各函数开头的while(dword_409804)来看,同时也要结合dword_409804来判断下一个执行的解密函数
以sub_401E60为例

这个算法是RC4,key是”MessageBoxA”(很有迷惑性)
它是第一个进行的解密,因为它的while (dword_409804 != 1)
它的下一个解密流程是dword_409804为3的函数

其他函数同理,顺序应该是
RC4 → Base32 → Base58 → Base64
解出结果是这样的

第二种方法就是直接动调然后在内存里找到解密后的代码
在CreateProcessA处下断点


之后在主线程中的WaitForMultipleObjects后会断下来

然后找到CreateProcessA下面的SetThreadContext


上图注意内存窗口的地址和ECX的值
然后就可以dump出来分析了
直接上IDA吧

函数很少,有用的就那么两个
主要是sub_2B2

往下滑滑,老朋友XTEA了

这里有点坑,数组长度要看v11,是4*i=64=0x40
看看这个函数的交叉引用

看来这个函数操作之后是用了MapViewOfFile传递给主函数的
然后就可以写脚本了
XTEA的抄抄大哥的
| 1 | 
 | 
python转换自己写写了(
| 1 | c1 = bytes.fromhex("4E65704354467B633963646E77646933697534316D3070763378376B6C6C7A7538706471366D74396E326E776A6470366B617438656E743464686E3572313538") | 
