知识点:UPX + 移位密码 + XOR
查壳
32bit;UPX壳,upx -d直接脱。
查看主函数。
第一处输入Str1然后做一个比较。这里进去。
有个小技巧,这里传入的参数是Str字符串,但是原本IDA自动识别出来的类型是int a1
,所以直接看就是很多(BYTE *)类型转换,可以直接对a1按Y键修改,修改成char *a1
;这样就特别容易看了,其他题目同理。
这里是一些移位处理(类似于凯撒密码)
写一个简单的脚本:
str = 'z8layn_b91_nb9ha1}'
str = list(str)
for i in range(len(str)):
if '0' <= str[i] <= '9':
str[i] = chr((ord(str[i]) - ord('0') - 8) % 10 + ord('0'))
elif 'A' <= str[i] <= 'Z' or 'a' <= str[i] <= 'z':
if 'a' <= str[i] <= 'z':
str[i] = chr((ord(str[i]) - ord('a') - 20) % 26 + ord('a'))
else:
str[i] = chr((ord(str[i]) - ord('A') - 20) % 26 + ord('A'))
print(''.join(str))
# f0rget_h13_th1ng3}
验证:
正确,也就得到了后半部分flag。
前面看起来像是RC4加密,结合题目一开始也以为是RC4,实际上并没有发现key。直接看到异或操作。之后下面还有一次TEA和前面进行过的encode。尝试之后,发现下面俩个加密实际都不重要。下个断点。
输入1111122222为flag,动态调试。
这里发现key就只是0xDE而已。
根据程序后面可以知道,flag片段里面的flag就是密文,拿密文和key异或可以得到前半段flag。
str = 'z8layn_b91_nb9ha1}'
str = list(str)
flag2 = ''
for i in range(len(str)):
if '0' <= str[i] <= '9':
str[i] = chr((ord(str[i]) - ord('0') - 8) % 10 + ord('0'))
flag2 += str[i]
elif 'A' <= str[i] <= 'Z' or 'a' <= str[i] <= 'z':
if 'a' <= str[i] <= 'z':
str[i] = chr((ord(str[i]) - ord('a') - 20) % 26 + ord('a'))
flag2 += str[i]
else:
str[i] = chr((ord(str[i]) - ord('A') - 20) % 26 + ord('A'))
flag2 += str[i]
else:
flag2 += str[i]
f = open(r'C:\\Users\\Sciurdae\\Downloads\\魔鬼凯撒的RC4茶室_1940d04e8d88c973aff655f10d7d6ba3\\flag片段\\flag', 'rb')
flag_encode = f.read()
flag1 = ''
for x in flag_encode:
flag1 += chr(x ^ 0xde)
print(flag1 + flag2)
d()
flag1 = ''
for x in flag_encode:
flag1 += chr(x ^ 0xde)
print(flag1 + flag2)