
对程序分析后得到上图,总体思路:输入key后对将key放入v7中对v7进行tea加密后和给后的v7[0]和v7[1]比较如果成功则进入smc对rc4的代码进行修复,在rc4代码中找到密文后进行解密。
对于tea加密密钥v8和v7[1]已给出,解密即可
def fun(a1,a2):
v6 = a1[0]
v5 = a1[1]
v4=(0-(0x61C88647<<5))&0xffffffff
for x in range(32):
v5 -= (a2[3] + (v6 >> 5)) ^ (v4 + v6) ^ (a2[2] + 16 * v6)
v5 &= 0xffffffff
v6 -= (a2[1] + (v5 >> 5)) ^ (v4 + v5) ^ (a2[0] + 16 * v5)
v6 &= 0xffffffff
v4 += 0x61C88647
return hex(v6),hex(v5)
k=[0x12,0x34,0x56,0x78]
v=[0x60FCDEF7,0x236DBEC]
print(fun(v,k))
得到key值为3

接着对程序进行动态调试输入3后在rc4函数下断点一直按f7直到跳出设置eip指令后得到
v16[0] = 15;
v16[1] = -108;
v16[2] = -82;
v16[3] = -14;
v16[4] = -64;
v16[5] = 87;
v16[6] = -62;
v16[7] = -32;
v16[8] = -102;
v16[9] = 69;
v16[10] = 55;
v16[11] = 80;
v16[12] = -11;
v16[13] = -96;
v16[14] = 94;
v16[15] = -53;
v16[16] = 44;
v16[17] = 22;
v16[18] = 40;
v16[19] = 41;
v16[20] = -2;
v16[21] = -1;
v16[22] = 51;
v16[23] = 70;
v16[24] = 14;
v16[25] = 87;
v16[26] = -126;
v16[27] = 34;
v16[28] = 82;
v16[29] = 38;
v16[30] = 43;
v16[31] = 110;
v16[32] = -28;
v16[33] = -126;
v16[34] = 36;
j_memset(v15, 0, 0x100u);
v14 = j_strlen(Str);
strcpy(v13, "you_are_master");
v12[531] = 0;
v5 = 0;
for ( i = 0; i < 256; ++i )
{
v12[i + 264] = i;
v12[i] = v13[i % j_strlen(v13)];
}
for ( j = 0; j < 256; ++j )
{
v5 = (v12[j] + v5 + v12[j + 264]) % 256;
v10 = v12[j + 264];
v12[j + 264] = v12[v5 + 264];
v12[v5 + 264] = v10;
}
v6 = 0;
v9 = 0;
for ( k = 0; k < v14; ++k )
{
v9 = (v9 + 1) % 256;
v6 = (v6 + v12[v9 + 264]) % 256;
v11 = v12[v9 + 264];
v12[v9 + 264] = v12[v6 + 264];
v12[v6 + 264] = v11;
v15[k] = v12[(v12[v6 + 264] + v12[v9 + 264]) % 256 + 264] ^ Str[k];
}
v3 = j_strlen(Str) == 35;
for ( m = 0; m < j_strlen(v16); ++m )
{
if ( v16[m] != v15[m] )
{
v3 = 0;
break;
给出了加密后密文且密钥已给出为you_are_master尝试解密
# RC4加密
def rc4(key, ciphertext):
sbox = list(range(256))
j = 0
for i in range(256):
j = (j + sbox[i] + key[i % len(key)]) % 256
sbox[i], sbox[j] = sbox[j], sbox[i]
i = 0
j = 0
keystream = []
for _ in range(len(ciphertext)):
i = (i + 1) % 256
j = (j + sbox[i]) % 256
sbox[i], sbox[j] = sbox[j], sbox[i]
k = sbox[(sbox[i] + sbox[j]) % 256]
keystream.append(k)
plaintext = []
for i in range(len(ciphertext)):
m = ciphertext[i] ^ keystream[i]
plaintext.append(m)
print(plaintext)
return ''.join([chr(p) for p in plaintext])
v16 = [15, 148, 174, 242, 192, 87, 194,
224, 154, 69, 55, 80, 245, 160, 94,
203, 44, 22, 40, 41, 254, 255, 51, 70, 14,
87, 130, 34, 82, 38, 43, 110, 228, 130, 36]
key = b"you_are_master"
plaintext = rc4(key, v16)
a=[72, 68, 67, 84, 70, 123, 121, 48, 117, 95, 97, 114, 51, 95, 114, 99, 52, 95, 116, 51, 97, 95, 115, 109, 99, 95, 109, 52, 115, 116, 101, 114, 33, 33, 125]
for x in a:
print(chr(x),end="")

在smc部分我们跟进代码,发现他将我们输入的密钥作为参数传进

在sub_411046函数中我们可以看到

上述代码是在遍历寻找.hdctf段,如果找到就进行sub_411221函数,看一下.hdctf段正是我们的rc4函数


smc代码,对.hdctf段异或我们所输入的key,可以尝试手动smc

#include <idc.idc>
static xor_setp2(){
auto addr = 0x0041D00C;
auto i = 0;
for(i=0;addr+i<0x0041D491;i++)
{
PatchByte(addr+i,Byte(addr+i)^0x3);
}
}
static main()
{
xor_setp2();
}
Comments NOTHING