0x00
好久没做题了,IDA都还是6.8的版本,重装了Python环境连IDA Python都没有。协会也有自己的CTF比赛了,RE题目整体都比较简单,是面向萌新的,我做题过程基本上都很偷懒,很多都是调试的时候硬扒下来的。
0x01 Cr0ssFun
拖进IDA,F5看反汇编,逻辑很简单,输入字符串,然后check函数判断
看check函数,发现直接return iven_is_handsome()
后面都是一层一层的套娃,把这些提取出来放到文本,正则替换一下,放入Python运行即可,如果套娃层数多的话可以写IDA Python提取
wctf2020{cpp_@nd_r3verse_@re_fun}
0x02 level1
output.txt里面有一些数字,程序逻辑很简单,逆过来就好了
1 | a=[0,198,232,816,200,1536,300,6144,984,51200, |
wctf2020{d9-dE6-20c}
0x03 level2
用upx加壳了
直接用upx shell脱壳
wctf2020{Just_upx_-d}
0x04 level3
这题是修改了base64编码表
进行修改的函数
1 | import base64 |
wctf2020{Base64_is_the_start_of_reverse}
0x05 level4
提示有个二叉树的数据结构
type1是后序遍历
type2是中序遍历
显然flag就是求先序遍历了,直接用网上的代码
1 |
|
wctf2020{This_IS_A_7reE}
0x06 funnyre
先运行一下,发现啥都没提示就结束了,先看下start函数,传了init和main的地址
先看init,F5一下,
可以看到里面有个do while循环,看下off_602E08
可以知道当v5为0时调用sub_401E90,V5为1时调用sub_4004C0,这里盲猜v4 = 2,动态调试一下,先在init开头下断点
把要调试的main放入linux下,linux_serverx64也放进去,先用chmod 766 给两个赋予权限,运行linux_serverx64
选择Remote Linux debugger,填上被调试文件的路径和目录,还有Linux的ip地址,参数暂时不填
一路f8到调用函数的地方,可以看到v4确实为2
在call的地方f7进去,在sub_401E90逛了一圈,发现它对put函数的地址操作了一番,好像没找到有用的地方。出来sub_401E90后第二次f7进去就是进sub_4004C0,里面有很多对byte的异或操作
通过动调看下byte异或后变成了啥。在retn的地方下个断点,按f9到这个地方
再去看下byte_603048,按R键把hex转成char,可以看到 you get flag!
init对成功后提示的字符串进行了初始化,继续看main函数,有很多个比较,R转换后发现是flag{},‘}’在第37位,所以flag长度为37,中间的部分长度为32
后面是对中间32位每一位都进行xor或者add的操作,中间穿插着花指令,没办法反编译,但是其余正常的指令比较简单,影响不大
搜一下byte prt [rdx + rax +5],有特别多的结果
继续动调,修改下调试参数,填flag{1*32}试下
在最后一个操作结束后下个断点,把其他断点先删除
在断点处停下在寄存器RDX处右键,跳转过去看下heap
可以看到原本的 '1' 经过一系列操作变成了0xd9,其实就是 '1' -> 0xd9 的映射
同时在停下来的地方,可以看到有一个_memcmp,比较中间32位,将unk_4025c0里面这段提取出来
现在的思路就比较清晰了,获取字符[a-zA-Z0-9]映射,然后把unk_4025c0逆映射回来,这里为了偷懒,直接用动调获取
把变化后的字节提取出来
1 | unk_4025c0=[0xD9,0x2C,0x27,0xD6,0xD8,0x2A,0xDA,0x2D, |
flag{1dc20f6e3d497d15cef47d9a66d6f1af}