[ACTF新生赛2020]usualCrypt
有两个文件,其中.开头的是mac平台的程序,这里我们只要分析windows平台的就好
熟悉的查壳加ida分析
没有壳就直接拖进IDA吧,看见了main函数,f5反编译
分析一下main函数
关键点在于sub_401080函数,双击该函数粗略一看是一个常规的base编码算法,但其实有些改动
sub_401000()将byte_40E0AA数组和byte_40E0A0数组的第6到15位元素作替换,双击任意一个数组可以发现其实byte_40E0AA是byte_40E0A0数组中从第11位元素开始截取的一部分
返回值是sub_401030函数,双击查看该函数
可以分析出这是一个字母大小写转换的算法
再回到main函数,接下来是判断v5是否和byte_40E0E4相等,若不相等则报错,相等则继续向下执行
有了上边的分析基础,接下来就可以根据byte_40E0E4这个切入点逆推出flag。
双击byte_40E0E4可以看到byte的元素(需要注意的是7Ah也是这个数组的一部分,选中这一部分元素按a将其转换为一个整体)
转换后如下
接着根据上边的分析步骤,我们可以知道加密过程是
- 改变编码表
- 根据改变后的编码表对原数据进行类base64编码
- 对得到的数据大小写转换
我们可以反向推导写出解密脚本:
#导入base64模块用于将base64编码的数据转换为原始值
import base64
#key即是上边的byte_40E0E4
key = 'zMXHz3TIgnxLxJhFAdtZn2fFk3lYCrtPC2l9'
#对key进行大小写转换,这样就得到了编码后的值
key = key.swapcase()
#table是按base64编码表排列的字符串
table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
dict = {}
flag = ''
#初始化一个键和值相等且根据按照table排列顺序的字典
for i in range(len(table)):
dict[table[i]] = table[i]
#根据sub_401000函数的算法,构建一个原始与修改过的base64编码表的映射
for i in range(6,15):
dict[table[i]], dict[table[i + 10]] = dict[table[i + 10]], dict[table[i]]
#将key映射后的值传给flag
for i in range(len(key)):
flag += dict[key[i]]
#利用base64模块中的b64decode方法将flag(base64编码)转换为对应的原数据
flag = base64.b64decode(flag.encode()).decode()
#打印flag
print(flag)
得到flag{bAse64_h2s_a_Surprise}