2021GFCTF部分RE_WP
2021GFCTF RE_WP
wordy
去除花指令
1 | addr =0X556AE377FD56 |
BabyReverse
IDA打开,去除所有的花指令
直接看下面对flag如何加密的,进入sub_412E10
, 发现是SM4加密
而传入的第二个参数是key,即byte_4409c0
是key,回到main函数再往上看,发现前面有一个对byte_4409c0
类似RC4加密的操作,
对 byte_4409C0
进行交叉引用
于是下断点调试来获取key,发现不行,猜测前面是反调试,从main函数头部下断点调试
最终定位到这个函数
采用的是self_mapping技术实现反调试,本质是创建secion的时候设置SEC_NO_CHANGE,映射后不能改变
关于这个技术,可以参考下这位大佬的笔记 https://jev0n.com/2021/09/23/Self-Remapping.html
我们直接将call sub_411CE0
的地方nop掉,手动的把byte_4409c0
的地方加1
1 | a = [ 0x07, 0xB8, 0x0D, 0x24, 0xB1, 0x0C, 0x2D, 0xC7, 0x28, 0x2D, |
运行起来
得到key为 GF?->GirlFriend?
提取密文
1 | 0D 40 3B 87 A5 66 DA 74 92 7F BB E1 B8 CD EB BC 59 45 1B C0 38 99 AA 22 AA 3F 9D 21 07 4E 81 1F |
2e69df5961f20aee0897cf1905156344
, 最终得到flag为 GFCTF{2e69df5961f20aee0897cf1905156344}
re_EasyRE_0x00
IDA打开分析,最关键的是sub_100016A0
函数
经过分析,发现sub_10001180
是解密login.key文件,生成的数据放到V13里面
然后下面这个地方是将V13处的数据与生成的一些数据进行对比,猜测是机器码的验证
这是V13处的数据
1 | 11 55 66 55 0D 50 51 0C FF 01 80 12 CE A9 08 75 73 65 72 32 33 33 33 |
最后8个字符是user2333
将对比的数据也提取出来, 然后结合题目,用户名用admin6677登录,长度是9,整理得
1 | 11 55 66 55 98 FA 9B 59 6F F6 14 8F E9 DA 09 61 64 6D 69 6E 36 36 37 37 |
我们写脚本,每次运行到对比数据的时候就把v13的数据给他替换掉
1 | data = [0x11, 0x55, 0x66, 0x55, 0x98, 0xFA, 0x9B, 0x59, 0x6F, 0xF6, 0x14, 0x8F, 0xE9, 0xDA, 0x09, 0x61, 0x64, 0x6D, 0x69, 0x6E, 0x36, 0x36, 0x37, 0x37] |
然后绕过机器码验证,往下走,来到sub_10001610
处
可以发现,这个地方肯定是与服务器通信了,我们直接运行,直接Wireshark抓包
提取数据
1 | ---> 11 55 66 55 1a 27 00 00 00 00 |
重新调试,接着刚才的位置往下分析,看到了RC4的初始化及加密
猜测是刚开始,服务器端返回RC4的key,然后后面全部使用RC4加密方式进行加密
根据sub_10001350
这个函数可以猜测出数据包的格式, 拿上面服务器返回的key举例子
1 | 11 55 66 55 //标志 |
写脚本验证RC4加密
1 | from Crypto.Cipher import ARC4 as rc4cipher |
结合login.key,发现当命令为1的时候,向服务器发送的是login.key的数据,然后服务器返回信息
所以现在需要构造 真正的login.key(11 55 66 55 98 FA 9B 59 6F F6 14 8F E9 DA 09 61 64 6D 69 6E 36 36 37 37)
加密后的数据
sub_10001180
是解密函数,进去分析,发现是RSA的PKCS#1加密
根据这个结构找到e和n
提取出来
1 | e: 65537 |
利用rsatool.py生成private.pem
1 | python rsatool.py -e 65537 -p 322922590106035145437937724697895880569 -q 304171468404401467258708275665013611777 -o private.pem |
利用在线解密网站测试 https://the-x.cn/cryptography/Rsa.aspx
发现解密成功,将构造好的数据进行加密,
对于PKCS#1的填充方式可以参考下面2篇文章
然后写程序与服务器交互,发现服务器返回命令为2的验证码问题
Question(Send result in uint32_t format, 1 second!): 9540808 * 32 + 509 * 859 = ?
然后利用eval计算数值,构造,返回给服务器,即可得到flag,完整的exp如下
1 | import socket |
得到flag为 GFCTF{e8e9071b7a70770bec1f6415c4ed4c1d}