【安洵杯 2023】ezr3
收获
- UPX 壳存在特征码,特征码被修改会导致 UPX 脱壳失败
思路
用 IDA 打开,发现不对劲:
函数很少,而且 start()
函数中参数爆红,应该是有壳
用 DIE 打开:(exeinfo pe 无法检测)
发现 UPX 壳,但是 UPX 脱壳失败,提示没有 UPX 壳:
用 010Editor 打开:
发现 UPX 的特征码被改为 HCK,并且还有 Android 字样,根据架构 AARCH64 这应该是一个 Android 程序
在 IDA 中同样可以看到:
在 010Editor 中将 HCK 全部替换为 UPX,并保存文件:
不过由于是 UPX 4.02,我的版本不够,更新后脱壳成功:
UPX v4.0.2 下载地址:Release v4.0.2 · upx/upx (github.com)
再次用 IDA 打开,恢复正常:
定位到主函数:
一开始会先运行 v()
函数:
有一些异或操作,不过逻辑看不大懂,只能看个大概
int8x16_t
是一个数据类型,通常用于表示包含 16 个 8 位整数的向量。它是一种矢量类型,可以在特定的硬件架构(如 SIMD 指令集)中进行并行计算,以提高程序的性能
这里的 v3
做什么用的暂时不清楚,不过可以看到代码 v4 = &auth + v1
对 auth
做了处理
跟进 auth
:
按照形式,使用 IDA 提取 auth
:
auth = [0x0003BC69, 0x000D3FA0, 0x0003A94A, 0x00044AFF, 0x00045254, 0x0000CDD1, 0x00001815, 0x00003B08, 0x00070868,
0x000C6560, 0x00065662, 0x000855C8, 0x0000DCF6, 0x00004CE6, 0x0014EEC2, 0x0002CFD6, 0x00032766, 0x0014F6BA,
0x00025E69, 0x0006A9A3, 0x00121EBD, 0x0005991C, 0x00050016, 0x00004A3D, 0x00097485, 0x0008D0A0, 0x0003B916,
0x00054C58, 0x00096F94, 0x00010334, 0x000DAD22, 0x0004B234, 0x0002FE96, 0x000F33CC, 0x0012C1E8, 0x00148F9E]
主要经过的处理:
v1 = 0LL;
v2 = &off_B6D0;
do
{
v4 = &auth + v1;
v1 += 24LL;
v6 = *(v4 + 4) ^ v2[12];
v7 = *(v4 + 5) ^ v2[24];
v2 += 2;
*(v4 + 4) = v6;
*(v4 + 5) = v7;
}
while ( v1 != 144 );
根据 v1
可知总共循环了 6 次,对应的逆向脚本:
v2 = 0
for i in range(0, len(auth), 6):
for j in range(6):
auth[i + j] ^= mere[v2 + j * 12]
v2 += 2
其中 mere
的数据如下:
mere = [0x00000D21, 0x00000000, 0x0000009D, 0x00000000, 0x0000094B, 0x00000000, 0x000003C9, 0x00000000, 0x00000C3F,
0x00000000, 0x000017E9, 0x00000000, 0x0000130E, 0x00000000, 0x00000088, 0x00000000, 0x00000486, 0x00000000,
0x0000202F, 0x00000000, 0x00002230, 0x00000000, 0x000024B4, 0x00000000, 0x000008B1, 0x00000000, 0x00000A9F,
0x00000000, 0x00001AD2, 0x00000000, 0x000023EB, 0x00000000, 0x00000C7E, 0x00000000, 0x0000042B, 0x00000000,
0x000005BF, 0x00000000, 0x0000113C, 0x00000000, 0x00000449, 0x00000000, 0x00001751, 0x00000000, 0x00000ACE,
0x00000000, 0x00001894, 0x00000000, 0x0000208A, 0x00000000, 0x00000E82, 0x00000000, 0x000006BD, 0x00000000,
0x00000CEE, 0x00000000, 0x00002386, 0x00000000, 0x000013D4, 0x00000000, 0x00000111, 0x00000000, 0x00000D1C,
0x00000000, 0x0000238E, 0x00000000, 0x00001759, 0x00000000, 0x0000012B, 0x00000000, 0x0000214D, 0x00000000,
0x00000040]
发现后面还有一个 p()
函数:
进行了一次对数据前四位和后四位的转换,然后进行异或,最后进行验证
写出逆向脚本:
v2 = 0
for i in range(0, len(auth), 6):
for j in range(6):
flag.append(auth[i + j] // mere[(v2 + j * 6) * 2])
v2 += 1
for i in range(len(flag)):
flag[len(flag) - 1 - i] ^= flag[i]
flag[len(flag) - 1 - i] = (flag[len(flag) - 1 - i] >> 4 | flag[len(flag) - 1- i] << 4) & 0xff
脚本
auth = [0x0003BC69, 0x000D3FA0, 0x0003A94A, 0x00044AFF, 0x00045254, 0x0000CDD1, 0x00001815, 0x00003B08, 0x00070868,
0x000C6560, 0x00065662, 0x000855C8, 0x0000DCF6, 0x00004CE6, 0x0014EEC2, 0x0002CFD6, 0x00032766, 0x0014F6BA,
0x00025E69, 0x0006A9A3, 0x00121EBD, 0x0005991C, 0x00050016, 0x00004A3D, 0x00097485, 0x0008D0A0, 0x0003B916,
0x00054C58, 0x00096F94, 0x00010334, 0x000DAD22, 0x0004B234, 0x0002FE96, 0x000F33CC, 0x0012C1E8, 0x00148F9E]
mere = [0x00000D21, 0x00000000, 0x0000009D, 0x00000000, 0x0000094B, 0x00000000, 0x000003C9, 0x00000000, 0x00000C3F,
0x00000000, 0x000017E9, 0x00000000, 0x0000130E, 0x00000000, 0x00000088, 0x00000000, 0x00000486, 0x00000000,
0x0000202F, 0x00000000, 0x00002230, 0x00000000, 0x000024B4, 0x00000000, 0x000008B1, 0x00000000, 0x00000A9F,
0x00000000, 0x00001AD2, 0x00000000, 0x000023EB, 0x00000000, 0x00000C7E, 0x00000000, 0x0000042B, 0x00000000,
0x000005BF, 0x00000000, 0x0000113C, 0x00000000, 0x00000449, 0x00000000, 0x00001751, 0x00000000, 0x00000ACE,
0x00000000, 0x00001894, 0x00000000, 0x0000208A, 0x00000000, 0x00000E82, 0x00000000, 0x000006BD, 0x00000000,
0x00000CEE, 0x00000000, 0x00002386, 0x00000000, 0x000013D4, 0x00000000, 0x00000111, 0x00000000, 0x00000D1C,
0x00000000, 0x0000238E, 0x00000000, 0x00001759, 0x00000000, 0x0000012B, 0x00000000, 0x0000214D, 0x00000000,
0x00000040]
v2 = 0
flag = []
for i in range(0, len(auth), 6):
for j in range(6):
auth[i + j] ^= mere[v2 + j * 12]
v2 += 2
v2 = 0
for i in range(0, len(auth), 6):
for j in range(6):
flag.append(auth[i + j] // mere[(v2 + j * 6) * 2])
v2 += 1
for i in range(len(flag)):
flag[len(flag) - 1 - i] ^= flag[i]
flag[len(flag) - 1 - i] = (flag[len(flag) - 1 - i] >> 4 | flag[len(flag) - 1 - i] << 4) & 0xff
print(bytes(flag))
结果
SYC{1_w4Nn4_buy_4_c4R_G1V3_M3_50w_$}
评论