2024网鼎杯RE初赛[wp]
REVERSE1
这个题当时是最后两个小时有思路(多亏了咱们的王杰gg),虽然最后没做出来,最后知道了sm4加密,也知道了密钥,结果没找到密文(其实找到了,一串16进制数据,本来以为是要转换成ascii字符,结果16进制本身就是密文...还是做的题不够多...)
先是jadx反编译打开之后,开始找程序入口点,即MainActivity,然后找onclick事件,然后一直找一直到找到check检查函数,但是里面只有几行,有个cma

然后修改文件后缀名zip解压,lib文件找到一个有重叠名字的so文件easystd\lib\arm64-v8a
ida64位打开之后函数挺少,一个一个看,然后在sub_75C函数最后找到一个类似最后验证的功能

点开byte_C14数组之后有一大串字符串(其实这去掉0x,提取出来就是密文,但当时可能脑袋宕机了,一直觉得还要再处理一下,然后一直找处理函数)

然后点开sub_904函数,其实当时是看不懂的,但是有ai助我,大致分析了一下应该是sm4加密(可能是与bswap32这个函数有关)

然后开始找密钥


这个的意思就是将原本aA1122357753221数组的后八位改成Z0099864,但是要注意的是这里是小端存储,所以要倒着填充后八位,所以实际密钥就是A11223574689900Z,刚好16位,128bit
然后直接用密钥对那一串16进制解密就行(就败在最后一步了,桑心~)

REVERSE2
ida64位打开
根据题目提示得知是对flag四段加密,ida反编译有四个return 1,应该就是四段加密

这一段就是对flag前八位加密,就是很简单的直接密文除2就行,直接上脚本
点击查看代码
# 已知的 s2 数组值
s2 = [112, -62, 108, -54, ord('n'), ord('p'), ord('p'), ord('l')]
s2 = [(x + 256) if x < 0 else x for x in s2] # 将负值转换为无符号字节
# 解密出 flag 的前 8 个字符
dest_part1 = ''.join([chr(x // 2) for x in s2])
print("解密的 flag 前 8 个字符:", dest_part1)
#8a6e7886

这一段也简单,就是简单的异或,v22和v11异或即可
点击查看代码
#已知的 v11 和 v22 值
v11 = [57, 91, 23, 16, 127, 13, 71, 6]
v22 = "XorrLord"
# 解密出 flag 的第 8-15 个字符
dest_part2 = ''.join([chr(v11[i] ^ ord(v22[i])) for i in range(8)])
print("解密的 flag 第 8-15 个字符:", dest_part2)
##a4eb3b5b

这个就是base64换表(前面短一个C,需要补一下),然后在线网站解密即可

然后base64解码

第四段:

第四段就是AES_set_encrypt_key函数使用AesMasterAesMast生成一个密钥,然后AES_encrypt函数在根据密钥去加密,最后将加密后的内容hex_to_string处理后与v4数组匹配,所以其实v8其实并没有上面用,就是单纯的充当了一个明文的存在,所以写脚本逆向即可
点击查看代码
from Crypto.Cipher import AES
# 定义密钥,添加 '\0' 使其长度为 16 字节
key = b'AesMasterAesMast'
# 定义密文 v4,转换为无符号字节
ciphertext = bytes([
(-89 + 256) % 256, 32, 21, (-1 + 256) % 256,
(-51 + 256) % 256, (-12 + 256) % 256, 80, (-34 + 256) % 256,
120, (-66 + 256) % 256, (-89 + 256) % 256, (-108 + 256) % 256,
127, (-65 + 256) % 256, (-84 + 256) % 256, (-59 + 256) % 256
])
# 创建 AES 解密器
cipher = AES.new(key, AES.MODE_ECB)
# 解密得到明文 v8
plaintext = cipher.decrypt(ciphertext)
# 检查后 8 个字节是否全为数值 8
if plaintext[8:] == bytes([8]*8):
# 提取前 8 个字节,即为 v18
v18 = plaintext[:8]
print("解密成功,得到的明文 v18 为:", v18)
print("v18 的十六进制表示:", v18.hex())
print("v18 的字符串形式:", v18.decode('utf-8'))
else:
print("解密失败,明文格式不符合预期。")
#06d28a04
组合起来就是flag
wdflag{8a6e7886a4eb3b5b52e93a4506d28a04}

浙公网安备 33010602011771号