网谷杯安全极客大赛2025-NewRC4のWP

debu8ger Lv3

题目描述

题目名称

NewRC4

题目难度

★★

题目分值

475

前置知识

1、查壳以及UPX脱壳

2、RC4加密算法

考察知识点

1、UPX魔改壳

2、RC4加密算法+魔改

解题工具

1、Exeinfo

2、010Editor

3、IDA

4、python3

解题步骤

第一步:题目信息

使用Exeinfo查看程序基本信息,发现了UPX压缩壳

syc_1

第二步 :解题过程

1、使用UPX尝试脱壳,发现报错

syc_2

于是拖到010里面查看详细信息,看到原本应该是“UPX”的地方变成了VMP,把所有的VMP改为UPX

syc_3

保存后再次尝试脱壳,成功脱壳

syc_4

2、进IDA里查看,点进main函数

 v3 = 256LL;
Buf1[0] = -1099083345;
Buf1[1] = 2129584582;
Buf1[2] = 1339278712;
Buf1[3] = -1197737055;
Buf1[4] = 632459247;
Buf1[5] = -1426643507;
Buf1[6] = -314991759;
Buf1[7] = -1937737471;
Buf1[8] = -1369194212;
Buf1[9] = -269001761;
v15 = 10008;
memset(v18, 0, sizeof(v18));
sub_7FF7883F1380("%s");
v4 = 0;
v5 = 0;
v6 = 0LL;
do
{
byte_7FF7883F5770[v6] = v5;
v7 = v5;
++v6;
v8 = v5++ / 0x14u;
Buf2[v6 - 1] = aNbgvzyhebfgcv8[v7 - 20 * v8];
}
while ( v5 < 256 );
v9 = 0LL;
do
{
v10 = byte_7FF7883F5770[v9];
v4 = (v10 + v4 + (unsigned __int8)Buf2[v9]) % 256;
byte_7FF7883F5770[v9++] = byte_7FF7883F5770[v4];
byte_7FF7883F5770[v4] = v10;
--v3;
}
while ( v3 );
sub_7FF7883F1000(v18, Buf2);
v11 = memcmp(Buf1, Buf2, 0x2AuLL);
v12 = "OK,Right\n";
if ( v11 )
v12 = "Error\n";
sub_7FF7883F1320(v12);
return 0;
}

通过v4 = (v10 + v4 + (unsigned __int8)Buf2[v9]) % 256;等相关特征分析是RC4加密算法,但是静态分析看不出sbox和key,于是尝试动态调试

在以下地方下断点,跑动调

syc_7

在程序执行时随便输入字符串,进入断点,分别点击aNbgvzyhebfgcv8byte_7FF7883F5770,得到最终的key

syc_5

sbox

syc_6

3、根据得到的sbox和key,以及main函数的加密逻辑编写exp

key_table = [
0x14, 0x18, 0x3D, 0x0C, 0x00, 0x03, 0x32, 0x1F, 0x18, 0x3C,
0x3D, 0x19, 0x2C, 0x42, 0x1B, 0x0F, 0x23, 0x15, 0x0B, 0x1F
]

key_stream_256 = [key_table[i % len(key_table)] for i in range(256)]

S = list(range(256))
j = 0
for i in range(256):
j = (S[i] + j + key_stream_256[i]) & 0xFF
S[i], S[j] = S[j], S[i]

def rc4_prga(state, n):
S = state[:]
i = 0
j = 0
out = []
for _ in range(n):
i = (i + 1) & 0xFF
j = (j + S[i]) & 0xFF
S[i], S[j] = S[j], S[i]
out.append(S[(S[i] + S[j]) & 0xFF])
return out


keystream = rc4_prga(S, 42)

buf1_ints = [
0xBE7D51AF, 0x7EEEE1C6, 0x4FD3C578, 0xB89BFBA1, 0x25B28FEF,
0xAAF725CD, 0xED399B71, 0x8C807901, 0xAE63C11C, 0xEFF75BDF
]

cipher_bytes = []
for value in buf1_ints:
cipher_bytes += [(value >> (8 * k)) & 0xFF for k in range(4)]

v15 = 10008
cipher_bytes += [v15 & 0xFF, (v15 >> 8) & 0xFF]
assert len(cipher_bytes) == 42
plain_bytes = bytes(((c - 113) & 0xFF) ^ k for c, k in zip(cipher_bytes, keystream))

print("Plain (hex):", plain_bytes.hex())
try:
print("Plain (ascii):", plain_bytes.decode('ascii'))
except UnicodeDecodeError:
print("Plain (ascii, replace):", plain_bytes.decode('ascii', errors='replace'))

Flag

flag{590CF439-E304-4E27-BE45-49CC7B02B3F3}

评论
目录
网谷杯安全极客大赛2025-NewRC4のWP