rctf2019-babyre1

介绍

rctf2019的一道逆向题,终于可以写点不是pwn的东西了。(pwn做不出来)

分析程序

  1. 读入flag([0-9a-f]),并转换为hex.
  2. 经过一个转换操作,输入8字节,输出6字节
  3. 转换操作中有一个加密函数,这个函数中有tea加密的特征值,且这个函数的第二个参数可以控制加密或解密,且输入8字节,输出8字节。
  4. 分析程序可知,加密操作后,要求最后一字节为02。
  5. 转换操作输出的结果为,加密操作后的前6字节。
  6. 转换后的值进行crc16_CCITT验证,结果为0x69E2
  7. 再将结果异或0x17,并输出

解答方法

  1. 由于我们知道最后输出结果应该为Bingo!,所以我们可以确定转换后的结果。55 7e 79 70 78 36
  2. 再放入转换操作中,我们就可以知道加密操作过后的值的前6字节,和最后一个字节,只有第七个字节未知。55 7e 79 70 78 36 xx 02
  3. patch文件,将加密操作改为解密操作,爆破第七个字节,可以得到256个结果。
  4. 根据提示的md5,可以得到最后的结果

脚本

脚本使用gdb的dump功能,将255个结果写入到文件中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!/usr/bin/env python2
# -*- coding: utf-8 -*-

from pwn import *

for x in range(256):

p = process('./babyre_pat')

p.recvuntil("flag you can got 'Bingo!' :")

gdb.attach(p,'b * $rebase(0x1211)\nc\ndump memory ~/d/1/%02x.txt $rdi $rdi+8\nc\nquit' % x)

p.sendline('557e79707836%02x02' % x)

p.interactive()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import hashlib

for x in range(256):

f = open('%02x.txt' % x,'r')
flag = ''
for x in f.read():
flag += hex(ord(x))[2:].zfill(2)
flag = 'rctf{' + flag + '}'

ret = hashlib.md5(flag.encode('utf8')).hexdigest()
if ret == '5f8243a662cf71bf31d2b2602638dc1d':
print(flag)

f.close()

后记

分析的时候出现了一些错误,这里不是tea加密,而是它的改进xxtea加密。所以我们就不需要patch文件,再用gdb dump出来了。而是直接用python调用xxtea解密即可。

1
2
import xxtea
xxtea.decrypt(text, key,padding=False)