[HDCTF 2023]enc

最后更新于 2024-07-15 871 字 预计阅读时间: 4 分钟


对程序分析后得到上图,总体思路:输入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();
}
此作者没有提供个人介绍。
最后更新于 2024-07-15