Buuoj-reverse-ACTF新生赛2020_usualCrypt
1. 分析文件类型,是否加壳
将文件扔进exeinfope中查看,发现是无壳的32位可执行程序
2. 使用IDA对文件进行分析
- 此处的main函数代码较为简单,其逻辑为接收输入,用
sub_401080
函数对其进行处理,处理后的结果若与byte_40E0E4
处字符串相同,则该输出即为flag。所以我们的重点应该放在sub_401080
函数上。
- 分析
sub_401080
函数的逻辑
从上面两幅图的分析中可以得到,函数sub_401080
的作用就是进行base64编码,只是它还将原本的编码表做了一个简单的处理。所以根据以上分析,我们可以写出解码代码。
解题
# 大小写转化
def convert_little_big(s):
ans = ''
for c in s:
if c >= 'a' and c <= 'z':
ans += chr(ord(c) - ord('a') + ord('A'))
elif c >= 'A' and c <= 'Z':
ans += chr(ord(c) - ord('A') + ord('a'))
else:
ans += c
return ans
# 处理base编码表
def shift(s):
idx = 6
s = list(s)
for idx in range(6, 15):
s[idx], s[idx + 10] = s[idx + 10], s[idx]
return ''.join(s)
'''
base64解码
因为编码后无 '='
所以可以知道原字符串的长度必然是3的倍数
所以我们这里不需要去处理余数的情况
'''
def solve(s, base):
flag = [0] * (len(s) * 3 // 4)
idx = 0
for i in range(0, len(s), 4):
a, b, c, d = base.index(s[i]), base.index(s[i+1]), base.index(s[i+2]), base.index(s[i+3])
flag[idx] = (a << 2) | ((b >> 4) & 0x3)
flag[idx + 1] = ((b & 0xf) << 4) | ((c >> 2) & 0xf)
flag[idx + 2] = ((c & 0x3) << 6) | (d & 0x3f)
idx += 3
print(flag)
print(''.join(chr(c) for c in flag))
if __name__ == '__main__':
base = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
base = shift(base)
print(base)
res = 'zMXHz3TIgnxLxJhFAdtZn2fFk3lYCrtPC2l9'
res = convert_little_big(res)
print(len(res))
solve(res, base)
flag{bAse64_h2s_a_Surprise}