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就行,直接上脚本
点击查看代码
1 2 3 4 5 6 7 # 已知的 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异或即可
点击查看代码
1 2 3 4 5 6 7 8 #已知的 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其实并没有上面用,就是单纯的充当了一个明文的存在,所以写脚本逆向即可
点击查看代码
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 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}