James Hoi's Blog

CUMTCTF 2021

Word count: 1.2kReading time: 5 min
2021/01/28 Share

re1re1.rar

扔进Exeinfo PE,64位ELF文件,无壳
image.png
ida分析找到主函数,sub_950函数应该是进行了某种加密,然后再和v9比较
image.png
进入sub_950函数,网上查了一轮发现是进行了base58编码
image.png
python base58解码即出flag

1
2
3
4
import base58

enflag = "34avux4BwXYJzh1nHK1oG5xTKeBSCERZs4xC"
print(base58.b58decode(enflag))# CUMTCTF{8Ase5B_1s_Ea5y~~~}

re2re2.rar

扔进Exeinfo PE,32位exe,Aspack壳
image.png
尝试用网上的脱壳机不行决定手动脱壳,用od打开
image.png
跟着网上的ESP定律脱壳视频学,F8一下再右键ESP寄存器选择 HW_break[ESP],然后再F9,取消断点
image.png
再F8几下进入壳内的exe函数,然后就找到了程序真正的OEP
image.png
选择 插件->OllyDump,自动选择了当前EIP作为OEP,啥都不用选直接按脱壳,保存为dump.exe
image.png
用IDA进行分析,题目给了提示说要动调(实际上直接静态看也能看出来)
image.png
双击进入验证函数再双击进入unk_403020,shift+E提取数据
image.png
进入加密函数sub_4026A0,直接分析if判断或者动调一下就知道只会执行else语句
image.png
a1为0x12345678和flag的异或,所以a1%a2=a1。写脚本即出flag

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

enflag = [
0x1A,0x0C,0x14,0x0D,0x1A,0x0D,0x1F,0x22,0x11,0x38,
0x2F,0x3C,0x06,0x3F,0x2C,0x17,0x06,0x1F,0x69,0x0B,
0x06,0x11,0x69,0x35,0x30,0x3D,0x38,0x20,0x78,0x78,
0x78,0x24
]

v9 = 0x12345678
v10 = 0x87654321
v11 = 0x22222222

def encode(flag):
# return [hex((v10^(v9^ord(f))%v11)&0xFF) for f in flag]
return [hex((v10^(v9^ord(f)))&0xFF) for f in flag]

def decode(enflag):
return "".join([chr(e^(v10&0xFF)^(v9&0xFF)) for e in enflag])

print(decode(enflag))# CUMTCTF{Have_fuN_F0R_H0liday!!!}

re4re4.rar

这题让我好好学了一下pyc的逆向还有pyc的字节码混淆
参考:通过字节码混淆来保护Python代码
python逆向学习-pyc文件的反混淆(python2)
这题和第二篇文章一样(图片并非题目文件)

找到pyc文件中的两个 71 03 00 71 00 06 64 FF 并删掉,然后将第一个73后面的32改为22,因为删掉了16个字节。
用uncompyle6 转为python源码,得到下面的代码(有修改),爆破得到flag

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
print('plz input flag:')
flag = input('')
b = [237, 255, 243, 225, 238, 248, 246, 107, 37, 95, 7, 30, 36, 229, 79, 45, 20, 76, 30, 248, 231, 227, 75, 243, 62, 238, 19, 77, 29, 227, 2, 224, 110]

def change(a):
x = ord(a)
if 96 < x <= 122:
x = x - 97
return x
if 65 < x <= 90:
x = x - 65 ^ 255
return x
return x

def encode(flag,i):
key = 'QuanTum'
if 96 < ord(key[(i % 7)]) <= 122:
m = change(key[(i % 7)])
n = change(flag)
return m ^ n
else:
m = change(chr(ord(key[(i % 7)]) + 32))
n = change(flag)
return m ^ n

def brute(i):
for j in range(65,123):
if encode(chr(j),i) == b[i]: print(chr(j),end="")

for k in range(len(b)):
brute(k)
# CUMTCTF_knW_uAnTUM_MChAnIcS

REgameREgame.zip

扔进Exeinfo PE,64位ELF文件,无壳,中间有加花,去花后F5得到下面的伪代码
image.png
进入验证函数sub_40092D,这里删除了真正的答案,因为限制了答案需要nc得到
image.png
再进入sub_400967函数,发现将每两个输入将字串对应转成数值,然后10v8+v9是把两个数转为两位数,且下一次输入的个位十位对应和上一次输入的必须至少有一个相同
image.png
其中byte_602180长这样(我转换了一下)
image.png
scanf(sub_400967)和到sub_4008D6函数中间的代码做了一些操作,但实际上就是把含有scanf函数的return转为字串放进 转换函数里
image.pngimage.png
转换函数将”CFUMT”字符串的一些组合作为”abcdefghijklmnopqrstuvwxyz!.?
“的索引
image.png
总的流程就是(看下面的脚本)
输入key1索引-> 转换为”CFUMT”的组合->转换为”abcdefghijklmnopqrstuvwxyz!.?*”的索引->验证最后的字串为”johnnysilverhand”->成功
实际上可以完全写脚本解出来,我最后选择手搓

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
43
44
import re

key1 = "AZTUYPFQAZUIVZVCRAAIDAZMVIACZDHZHZHVIHAIHDMFUTUTDIMUCMZFTHDHVDVBDHVMACZFUTBDCRBDFABBCDRIRICBTDFIVDBR"
key2 = "johnnysilverhand"
key3 = "CUMTF"
dict1 = "abcdefghijklmnopqrstuvwxyz!.?*"
dict2 = ["CFUMT","CFUTM","CTFMU","CTFUM","CTMFU","FCMTU","FCMUT","FCUTM","FMCTU","FTMUC","FTUCM","FTUMC","FUCMT","FUTCM","FUTMC","MCFTU","MUCFT","MUCTF","MUTCF","TUCFM","TUCMF","TUFMC","TUMCF","TUMFC","UCFMT","UCMFT","UCMTF","UCTFM","UTMCF","UTMFC"]
dict3 = {}
enflag1 = [dict2[dict1.index(c)] for c in key2]

for c in key3:
it = re.finditer(c,key1)
dict3[c] = [match.start() for match in it]

print(enflag1)
print(dict3)

# ['FTMUC', 'FUTMC', 'FCUTM', 'FUTCM', 'FUTCM',
# 'UCFMT', 'MUTCF', 'FMCTU', 'FTUMC', 'TUFMC',
# 'CTMFU', 'MUCTF', 'FCUTM', 'CFUMT', 'FUTCM', 'CTFUM']
# {'C': [15, 27, 52, 69, 76, 84, 90],
# 'U': [3, 10, 44, 46, 51, 72],
# 'M': [23, 42, 50, 53, 67],
# 'T': [2, 45, 47, 56, 73, 92],
# 'F': [6, 43, 55, 71, 80, 94]}

# 0602424484 j
# 0603732327 o
# 0676465650 h
# 0646565253 n
# 0646565253 n
# 1015555056 y
# 5051565255 s
# 8050909272 i
# 0656464252 l
# 0203435352 v
# 9092424303 e
# 5010154555 r
# 0676465650 h
# 9080105056 a
# 0646565250 n
# 9092944442 d
# input=0602424484060373232706764656500646565253064656525310155550565051565255805090927206564642520203435352909242430350101545550676465650908010505606465652509092944442

输入input进题目的nc里,即可得flag
image.png

CATALOG
  1. 1. re1re1.rar
  2. 2. re2re2.rar
  3. 3. re4re4.rar
  4. 4. REgameREgame.zip