SBCTF2024
Last updated on February 5, 2024 am
SBCTF2024 Reverse wp
Week1
babymath
z3一把梭
1 | |
simple
简单的字节码阅读,是个经典的TEA算法加密,不过需要注意的是这里的运算都是有符号的
1 | |
1 | |
babysmc
ESP定律脱壳,然后简单SMC,下断点在函数处,然后使用p让IDA重新分析为函数
1 | |
babyhash
题目先要求输入6个key,并要求为小写字符
然后与字符串12345进行拼接操作
然后进行一系列操作,每个函数都有很多个调用,直接从最后面的比较看起
跟入sub_7FF618207E04,然后一直跟入到sub_7FF6182175F0
其中函数sub_7FF6182061FD最终只是调用memcmp函数进行比较,因此这里就是输入的key和正确的key进行比较的地方,查看比较的两个参数
a1 是输入的密文 6d6eaa76a827ebae246617c27107c8dd
a3 是真正的密文 f27d71f53ae17679fb352baa5ea326db
这两个看起来很像是hash后的值,结合题目信息,用一些md5进行尝试计算
发现真正用来md5的是12345aaaaaa67890,也就是输入的六位key会和12345以及67890进行拼接,那么直接进行爆破得到真正的key
1 | |
在得到key后继续往后审计
关键只有两处,sub_7FF618208C4B这个函数对输入进行加密,72行处的if语句对输入进行判断
查看加密函数,发现就是普通的RC4加密,密钥则是12345maikei67890
直接解密即可
babydecode
题目用到两个反调试手段
第一个是在函数sub_401F7B中调用Ptrace函数进行反调试,许多调试器的功能都是基于ptrace这一个强大的系统调用实现,但是一个进程在同一时间只能被另外一个进程调试,那么这个程序就可以调用ptrace函数来调试自己,如果失败,说明有进程在调试自己。这一个教程是十分清晰的解释了这个函数使用。
- ptrace PTRACE_ATTACH可以附加到目标进程上,对其进行调试。
- 反调试的方式
跟踪自己:因为,一个进程在同一时间只能被一个进程跟踪。如果进程在启动时,就调用ptrace PTRACE_TRACEME跟踪了自己。那么这个进程将无法被其他进程附加
将两个if条件patch一下就可以绕过
还有一处反调试是使用sys_alram这一函数,通过字符串查找很容易到相关地方。
这里绕过方式也很多,可以修改时间,或者直接nop掉函数。
完成patch后就可以正常调试。
整体加密流程也很简单,先是正常TEA算法加密,然后进行一个BASE64的变表处理,然后用所得Base64加密后在一个新表里面找索引,最终的索引为密文
现在中间变量都可以通过调试正常正确拿到
得到Base加密
1 | |
得到TEA加密
最终解密
1 | |
Week2
start_main
程序逻辑很简单,输入36位的flag然后经过一个变表的base64解码,然后再经过一个RC4解密,通过调试可以拿到变表RSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ABCDEFGHIJKLMNOPQ和RC4密钥lFaUmVp=,其中用变表可以解RC4密钥为SBCTF

不过奇怪的是并没有看到密文比较的地方,先运行看看

是有错误的输出提示的,但是直接搜这个字符串却搜不到,看来是做了一点加密。不过这也告诉我们一个东西,即在main函数运行完后还有函数在运行,这实际上就是fini_array了。
简单说main函数并不是第一个运行的函数,第一个运行的函数应该是start,然后调用_libc_start_main,_libc_start_main再调用main函数,并且在main函数开始前运行init_array里面的函数,main函数结束后运行fini_array里面的函数。

因此只需转过去看看fini_array有函数即可,在IDA中按shift+F7即可打开段窗口,在里面就有fini_array地址


发现一个函数sub_55934E697E47,跟过去看看

这就是很明显的比较流程了,这里俩函数就是解密失败成功字符串的。至此整题的流程就清楚了,当然init_array也有一个函数,那个函数就是起到一个变表的作用。除了这种方式找之外,也可以直接搜索输入的引用,同样能够找到这个地方

最后的base解码就是猜测了,因为输入的字符会进行一个解码,那么猜测输入的字符串也应该是经过base加密的。
ez_ptrace
程序逻辑也很简单

函数sub_124D写了一个文件son,然后子进程使用调用excel执行这个文件,父进程收到消息然后发出信号,父子进程函数也很简单。
父进程:

子进程:

具体流程如下
- sub_124d 写文件
- fork一个子进程
- 父进程执行
wait函数等待子进程信号- 子进程执行
ptrace()函数,参数为PTRACE_TRACEME,表示希望得到调试,然后调用execl函数,将刚刚的写好的son文件进行运行,并替换当前的进程,这个操作回向父进程发送信号- 父进程收到信号,使用
ptrace函数修改子进程内存中的一个值,然后向子进程发送继续运行信号- 父进程等待子进程退出
所以这里面的关键就是找到这个son文件,有挺多方法可以得到这个son文件。
第一个思路是既然父进程中写了文件,但是程序运行起来却看不到这个文件,说明调用了文件删除函数,这个函数需要一个文件路径的参数,那么把文件名字改一下,让文件删除函数无法删除即可

比如修改写文件的名字,或者找一下子进程里面的字符串,也比较好找。

第二个思路就是对程序下断点,先不让子进程运行excel函数,或者在父进程发送继续运行处下断点。
第三个思路就是手动提取,这里简单用个idapython脚本即可
1 | |
总之现在得到了son文件,打开看看

函数流程也很简单,输入32位flag,然后sub_6000131对输入进行4位一组的合并,变成一个32位的整型,然后丢进sub_600011ED进行加密

这个加密算法的逆运算也很好搓,但这个时候还有一个地方需要注意,父进程调用了ptrace函数修改了一个值,我们需要找到这个地方,修改地址是dword_4c64

而dword_4c64是6000404c,这个是RVA,还需要转换为FOA,即文件偏移,这里应该就是404c

在子文件中找到这个地方,发现是把密钥最后一个给改了

1 | |
happydebug
用了很多IsDebugpresent来进行反调试,逐一patch掉,其中还有一个TLS函数,TLS会先于main函数运行

然后在主函数下断点调试,发现断不下来,而且会有错误输出,那么就肯定还有反调试手段。继续找,发现第二个TLS函数

发现这里的逻辑与主函数基本相同,不过对一些字符串进行了加密,防止直接搜索,看来这里才是真正程序逻辑的地方,通过搜索字符串找的函数是虚假的,即使通过手撕也无法解出flag。
加密很简单,前面的for循环都是对密钥做处理,与输入无关直接跳到sub_7FF79c22112c,这个函数就是个简单的TEA加密
1 | |
Week3
babymath
pyinstaller打包,解包然后pycdc反编译
1 | |
简单迷宫题
1 | |
八色三月七
题目逻辑倒很简单,不过挺烦这个中文编码的(这题中文编码是 GB21312)

输入字符串然后进行Base编码,再输出编码后结果

容易找到码表是这个东西,转化为中文就是一二三四五六七八

编码过程跟base64差不多,同样按照3个字节24bit为一个加密组,然后在24位里面再分6bit一组,由于码表只有8个汉字,于是6bit再分高3个bit和低3个bit来进行索引。这里面D4C2是月的中文编码,没有起到什么作用,解密直接丢掉就好。所以一个组输入24bit会被加密成8个汉字,每3个bit对应一个汉字
1 | |
中文也差不多

so many flowers
如题目所言,确实有很多花指令,不再简单局限于jz jnz了,需要稍微分析下
main函数第一处花指令,先push了eax的值然后清零eax,那么这个jz跳转就一定会实现,前面push后面也应该会有相应的pop

patch后如下,那么这两个push和pop也一起patch掉

这一组花指令最终是这样

main函数第二组花指令在下面不远处,这里是用了call $+5,即跳到当前指令下一条指令执行。这里需要对call和retn熟悉,call指令在会把下一条指令地址压栈,然后jmp去相应地址执行,

简单分析下就知道这三条指令没有任何用处,全部nop掉即可
main函数最后一处花指令在下面的jmp处,也很明显,patch掉

最后main函数反汇编如下

显然sub_411203比较关键,不断跟进去

与前面的花指令差不多,不过稍微绕了一点点,简单分析下。先把eax压栈,然后给eax赋值为4,再eax = eax * eax,然后与0x100比较,然后返回,这时会返回去mul eax处,再eax = eax * eax现在下面那条jz指令就会执行,因此patch如下

反汇编如下

发现就是个把输入4字节一组转为32位整形的操作,加密应该还在后面,接着往下看
不断跟入sub_41126c

一进去就有明显的爆红,因此查看下sub_4113d9

继续跟,关健在这三条汇编,这实际上就是把返回地址给+1了

patch如下,会多出一个字节,按c让IDA重新识别为代码,然后按p分析为函数即可

简单的XXTEA而已

1 | |