2023D^3CTF
D^3CTF
有一段时间没摸RE了,最近几天打了铁三决赛和d3ctf作为复建赛。铁三决赛不好评价,CTF赛题质量堪忧,并且数据赛赛中会出标准答案(家人们xxx!),最后几分钟从2掉到4,第一次体验到奖金不够路费XD,能抢返程的车票只能说智行泰库辣。d3ctf体验还是蛮不错的,告别了"llvm加一堆"或是大量堆积某一技术的赛题,从做题角度感觉题目比较精致优雅,🙁Hell的后半段大数运算不好玩。
五月已至,退役ddl,希望还能有机会打qwb和ciscn。
RE
d3sky
TLS_CALLBACK函数中存在反调试和异常处理,正常执行会触发除0异常来修改key为YunZh1JunAlkaid。
main函数主要逻辑是3字节解密opcode,之后通过与非运算,通过与非实现取反、取自身、异或等其他逻辑运算。
输入逐字节读入,可在记录长度处下断之后调试观察对输入的处理,程序主要通过异或操作实现逻辑方程,所以直接对字节码进行处理获取方程,之后用z3求解,并且程序约束最后一个字符为~。
提取方程
1 |
|
线性求解
1 |
|
d3recover
ver2版本的pyd没有去符号,并且base64密文可直接解密,推测没有换表,之后用bindiff恢复ver1的符号。
找到可以的check函数,整理主要逻辑如下
1 |
|
对可疑base64串解密,并对上述操作求逆即可getflag。
1 |
|
d3rc4
init_array和fini_array中都添加了处理函数,前者负责解密秘钥和相关数据,后者为真正的flagcheck逻辑。main函数中为假逻辑,创建了全局管道,并且对输入进行了rc4加密,sbox为全局变量。
在fini_array注册的函数中,父程序fork出自程序并通过管道进行通信来对输入进一步加密,考虑到理清进程通信非常的耗时和复杂,所以通过patch程序来进行求解。可知对输入的加密离不开秘钥流keystream,并且秘钥流由单独的函数生成,而在对输入的加密中不会被干扰,所以对输入加密的部分可以随便patch。
程序中存在write函数,所以直接将加密的部分patch为write(1,keystream,len);即可将秘钥流输出到标准输出,之后只需将每次的秘钥流倒叙解密密文,之后再rc4解密即可getflag。
1 |
|
d3syscall
注册了init函数,解密出elf文件并释放到/tmp/my_module,之后通过读/proc/kallsyms获取sys_call_table,并通过syscall 313注册该模块出,传入sys_call_table的地址。
main函数通过系统调用分组对输入进行处理,一组处理16字节,而在注册的module中对系统调用进行了hook实现了一个小型的vm。
上述命名并不准确,可见其hook了程序中使用的系统调用,并且模拟了栈,使用了寄存器,并且0x150中实现了左移、异或、加减乘等运算,后续逆向只需解析系统调用,分析其逻辑即可。
1 |
|
d3Hell
64call32实现smc解密,后续则存在反调试和check patch来控制参数的生成。
1 |
|
对dll打patch即可,过掉反调和check patch,结果如下。
调试即可获取解密的字符串,其会更新d3.exe程序中的变量,正确值为0x86928e90099b26cedf3f1f2af783e1。在d3.exe中通过sleep和一些返回恒值的递归函数来耗时,但影响并不算大,最耗时的在sub_401E64及其上层函数,调试可知其通过 (x*x +120) mod m生成数据d,并通过gcd(d,m)来分解m为素因数。
sub_401799是gcd , sub_4040C0是mod等。
1 |
|
所以直接分解698740305822331500978964939673142241,得到两个素因子,后续为将两个素因子的值拼起来即为flag。
d3Tetris
Android游戏题,主要逻辑在GameViewModel类,通过重载的toString函数可知相关变量对应的具体内容。根据题目提供的附件中流量包,可知向192.168.43.57:1234发送了流量包,搜索ip定位关键代码。
其要求分数达到一定值才会发包,所以修改smail代码让其一直发包,并且包的内容与oO0OooOo0oO()和ooooOOOOO00000()函数相关,为libnative导出的函数,并将两者的内容拼接。
1 |
|
两个函数均不需要参数所以字符串为内部生成,尝试调试,个人调试过程中在ooooOOOOO00000很容易断下,在oO0OooOo0oO容易崩溃,不过能在首部断下即可修改pc到其他地址(不过这个过程仍不太顺利,pc会跳变回去,可能是一直发包存在线程处理不当的问题)。
调试可知(图未存XD)ooooOOOOO00000函数返回一个16直接的字符串,充当后续aes加密的iv,而oO0OooOo0oO负责加密,为魔改AES_256_CBC和RC4,AES和rc4的key或iv可以调试获取。
加密内容36字节,zer0填充后AES加密了48字节,RC4加密32字节后返回,所以实际上是丢了4字节,也是后来群通知flag补上 “65bd”。
AES256魔改了S盒和加密流程,但具体的处理函数没有变动,伪代码如下。
1 |
|
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!