-
-
[原创]2022DASCTF MAY letsgo2 re
-
发表于: 2022-6-4 19:15 7018
-
Dasctf 5月 letsgo2
分析:
打开解压包发现letsgo2 和 server两个go程序,运行letsgo2随便输入返回wrong; 打开server没反应,查看netstat -aonb
发现启动了tcp:3333端口。猜测估计需要交互式破解:(。
分析letsgo2程序:
ida拖进来,ida7.6定位“wrong”字符串,发现在main_main函数内,但是main_main用F5解析代码不全,分析了下某处指令跳转(自己找找:嘿嘿)有问题nop掉,最终看到代码逻辑:
1、一共需要输入42个字节,同时它内部会产生的4字节随机数(姑且认为是4个字节的时间int)
2、对输入每个字节进行rol移位,3个一组 (此过程在server接收数据也会这样处理下)
3、把2结果作为输入,依次异或time[i%4];(此过程在server接收数据也会这样处理下)
4、建立tcp:3333链接,发送随机数+加密的数据(write 2次)
分析server:
1、接受letsgo2发送过来的加密数据
2、依次异或发送的time[i%4];
3、对2对输入每个字节进行rol移位,3个一组
4、对3的输出结果,每3个字节一组再次做一次异或运算(这个地方需要点小坑:代码开了个goroutine计算xor,主进程等待每次计算结果)。
5、对4数据进行加密,最后比较内置数据和加密后的数据是否一致。
注意过程2和3完全与letsgo2的程序相反,可以认为是接收数据后解密,经进坑出坑分析:过程2和letsgo2都是异或同一组数字(随机数),所以我们只要拿到3的结果,就拿到flag。开干:
用x64dbg,在aes解密函数处下断点获取密钥和iv(插曲,iv没看见,然后用解密工具尝试发现iv是全0):
找到key
找到目标密文:
解密得到过程4的输出:
拿到了4的输出,开始还原4的输入。查看代码比较简单直接无脑写xor脚本即可(见代码):
搞定4的输入,开始还原过程3的输入。因为letsgo2程序每个字节做了一次rol,server这里每个字节又做了一次rol,无其它操作,依据此我们可以代码还原,实现破解过程3.(见代码)
按照我们分析,破解3后即可停止破解,3的输出结果即是flag。
部分wp代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | import binascii # 动态调试分析key和内置密文 c = binascii.unhexlify( "c541959c1889f4b4ad6db8358ccd956969a5ddded3804119e8eae6d0520b55c119c6d1dfa9e9a4ca0d52" ) def ROL(i,index): tmp = bin (i)[ 2 :].rjust( 8 , "0" ) for _ in range (index): tmp = tmp[ 1 :] + tmp[ 0 ] return int (tmp, 2 ) #go routine 里面那个解密 def dexor(x, y, z): c = z ^ y a = x ^ c b = y ^ a return a, b, c # 破解过程4 i = 0 list = [] while i < 42 : p = dexor(c[i], c[i + 1 ], c[i + 2 ]) i = i + 3 list .append(p[ 0 ]) list .append(p[ 1 ]) list .append(p[ 2 ]) for x in list : h = hex (x)[ 2 :] if len (h) ! = 2 : h = '0' + h print (h, end = "") print ("") i = 0 #破解过程3 while i < 42 : print ( chr (ROL( list [i], 6 )), end = "") print ( chr (ROL( list [i + 1 ], 2 )), end = "") print ( chr (ROL( list [i + 2 ], 2 )), end = "") i = i + 3 |
总结
1 2 3 4 5 6 7 8 9 10 | letsgo2 - >[c1 = 加密(明文,rol运算)] - >[c2 = 加密(随机数r,c1)] = = = = = tcp send(c2,r) = = = = = server - >[c1 = 解密(r, c2)] - > [x1 = 加密(c1, rol)] - > [x2 = 加密(x1,xor)] - > [x3 = 加密(x2,aes)] - > x3与内置的加密值比较(返回T或F) |
binary地址见附件。
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!