[羊城杯2023RE]WP

Reverse

CSGO

Go逆向静态不好看,考虑动调
在main_init有IsDebuggerPresent反调试,nop掉
img
img
看一眼findcrypt插件,识别到base64
img
看看main_main
img
main__Cfunc_enc_abi0是加密
runtime_memequal是最后的check,base64完是60位说明flag为44位
在81行下断
一直跟踪mian_Cfunc_enc_abi0,发现最后是指向fkReverse
img
下断,动调拿到base64表LMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ABCDEFGHIJK
img
然后继续F9来到main_main函数的check处
img
unk_6A9091是密文cPQebAcRp+n+ZeP+YePEWfP7bej4YefCYd/7cuP7WfcPb/URYeMRbesObi/=
img
DASCTF{73913519-A0A6-5575-0F10-DDCBF50FA8CA}

vm_wo

我擦,苹果
image.png
静态手撸吧

int __cdecl main(int argc, const char **argv, const char **envp)
{
  __int64 i; // x8
  char __s[16]; // [xsp+10h] [xbp-E0h] BYREF
  __int128 v6; // [xsp+20h] [xbp-D0h]
  __int128 v7; // [xsp+30h] [xbp-C0h]
  __int128 v8; // [xsp+40h] [xbp-B0h]
  __int128 v9; // [xsp+50h] [xbp-A0h]
  __int128 v10; // [xsp+60h] [xbp-90h]
  __int128 v11; // [xsp+70h] [xbp-80h]
  __int128 v12; // [xsp+80h] [xbp-70h]
  __int128 v13; // [xsp+90h] [xbp-60h]
  __int128 v14; // [xsp+A0h] [xbp-50h]
  __int128 v15; // [xsp+B0h] [xbp-40h]
  __int128 v16; // [xsp+C0h] [xbp-30h]
  __int64 v17; // [xsp+D0h] [xbp-20h]

  if ( ptrace(0, 0, (caddr_t)1, 0) == -1 )
    goto LABEL_8;
  v17 = 0LL;
  v15 = 0u;
  v16 = 0u;
  v13 = 0u;
  v14 = 0u;
  v11 = 0u;
  v12 = 0u;
  v9 = 0u;
  v10 = 0u;
  v7 = 0u;
  v8 = 0u;
  *(_OWORD *)__s = 0u;
  v6 = 0u;
  printf("please input your flag:");
  scanf("%s", __s);
  if ( strlen(__s) != 29 )
LABEL_8:
    exit(0);
  myoperate(__s, 29);
  for ( i = 0LL; i != 29; ++i )
  {
    if ( __s[i] != byte_100003F47[i] )
    {
      printf("error!");
      goto LABEL_8;
    }
  }
  printf("ok you get the flag");
  return 0;
}

提取到密文:

unsigned char ida_chars[] =
{
  0xDF, 0xD5, 0xF1, 0xD1, 0xFF, 0xDB, 0xA1, 0xA5, 0x89, 0xBD, 
  0xE9, 0x95, 0xB3, 0x9D, 0xE9, 0xB3, 0x85, 0x99, 0x87, 0xBF, 
  0xE9, 0xB1, 0x89, 0xE9, 0x91, 0x89, 0x89, 0x8F, 0xAD
};

指令好像写死了

__int64 __fastcall myoperate(char *a1, int a2)
{
  __int64 v2; // x20
  _QWORD v5[2]; // [xsp+8h] [xbp-98h] BYREF
  _QWORD v6[2]; // [xsp+18h] [xbp-88h] BYREF
  _QWORD v7[2]; // [xsp+28h] [xbp-78h] BYREF
  _QWORD v8[2]; // [xsp+38h] [xbp-68h] BYREF

  LODWORD(v2) = a2;
  dword_100008003 = -1091715345;
  if ( ptrace(0, 0, (caddr_t)1, 0) == -1 )
    exit(0);
  if ( (int)v2 >= 1 )
  {
    v2 = (unsigned int)v2;
    do
    {
      v8[0] = 0x20D01011903001ALL;
      *(_QWORD *)((char *)v8 + 7) = 0x300010201180702LL;
      BYTE2(v8[0]) = *a1;
      interpretBytecode((char *)v8, 15);
      v7[0] = 0x20D02011903001ALL;
      *(_QWORD *)((char *)v7 + 7) = 0x400010201180602LL;
      BYTE2(v7[0]) = vm_body;
      interpretBytecode((char *)v7, 15);
      v6[0] = 0x20D03011903001ALL;
      *(_QWORD *)((char *)v6 + 7) = 0x500010201180502LL;
      BYTE2(v6[0]) = vm_body;
      interpretBytecode((char *)v6, 15);
      v5[0] = 0x20D04011903001ALL;
      *(_QWORD *)((char *)v5 + 7) = 0x600010201180402LL;
      BYTE2(v5[0]) = vm_body;
      interpretBytecode((char *)v5, 15);
      *a1++ = ((unsigned __int8)vm_body >> 5) | (8 * vm_body);
      --v2;
    }
    while ( v2 );
  }
  return 0LL;
}

手撸,发现加密很对称,写出解密脚本(异或和位移)

enc = [
    0xDF, 0xD5, 0xF1, 0xD1, 0xFF, 0xDB, 0xA1, 0xA5, 0x89, 0xBD, 0xE9, 0x95, 0xB3, 0x9D, 0xE9, 0xB3, 0x85, 0x99,
    0x87, 0xBF, 0xE9, 0xB1, 0x89, 0xE9, 0x91, 0x89, 0x89, 0x8F, 0xAD, 0x57]
flag = ''
for tmp in enc:
    tmp = ((tmp >> 3) | (tmp << 5)) & 0xff
    tmp ^= 0xBE
    tmp = ((tmp >> 4) | (tmp << 4)) & 0xff
    tmp ^= 0xED
    tmp = ((tmp >> 5) | (tmp << 3)) & 0xff
    tmp ^= 0xBE
    tmp = ((tmp >> 6) | (tmp << 2)) & 0xff
    tmp ^= 0xEF
    tmp = ((tmp >> 7) | (tmp << 1)) & 0xff
    # print(tmp)
    flag += chr(tmp)
print(flag)
# DASCTF{you_are_right_so_cool}

Ez加密器

通过------\nGetFlag!\n------定位到sub_7FF798C240E0
分析如下

__int64 sub_1400140E0()
{
  char *v0; // r8
  char *v1; // rcx
  char *v2; // r9
  char v3; // si
  unsigned __int8 v4; // di
  int v5; // eax
  int v6; // edx
  int v7; // edi
  int v8; // eax
  int v9; // edi
  int v10; // ebp
  int v11; // edi
  int v12; // er12
  int v13; // edi
  char v14; // di
  int v15; // eax
  int v16; // edx
  int v18; // esi
  int v19; // eax
  int v20; // esi
  int v21; // edi
  int v22; // esi
  int v23; // ebp
  int v24; // esi
  char *enc; // [rsp+20h] [rbp-D8h] BYREF
  __int64 v26; // [rsp+28h] [rbp-D0h]
  char code_base64[8]; // [rsp+38h] [rbp-C0h] BYREF
  char enc_hex[184]; // [rsp+40h] [rbp-B8h] BYREF

  sub_140003D87();
  get_input((__int64)code, (__int64)input);
  base64_enc(code, 6i64, code_base64);
  DES(&enc, code_base64, input, 40i64);
  v0 = enc;
  if ( (int)v26 <= 0 )
  {
    v2 = enc_hex;
  }
  else
  {
    v1 = enc_hex;
    v2 = &enc_hex[2 * (int)v26];
    do
    {
      v3 = *v0;
      v4 = (unsigned __int8)*v0 >> 4;
      v5 = v4;
      if ( v4 <= 9u )
      {
        LOBYTE(v6) = v4 ^ 0x30;
        if ( !v4 )
          LOBYTE(v6) = 48;
      }
      else
      {
        v6 = 65;
        do
        {
          v7 = v6 & v5;
          v6 ^= v5;
          v5 = 2 * v7;
        }
        while ( 2 * v7 );
        v8 = -11;
        v9 = 1;
        do
        {
          v10 = v9;
          v11 = v8 & v9;
          v12 = v8;
          v8 ^= v10;
          v9 = 2 * v11;
        }
        while ( v9 );
        if ( v10 != v12 )
        {
          do
          {
            v13 = v6 & v8;
            v6 ^= v8;
            v8 = 2 * v13;
          }
          while ( 2 * v13 );
        }
      }
      *v1 = v6;
      v1 += 2;
      v14 = v3 & 0xF;
      v15 = v3 & 0xF;
      if ( (v3 & 0xFu) > 9 )
      {
        v16 = 65;
        do
        {
          v18 = v16 & v15;
          v16 ^= v15;
          v15 = 2 * v18;
        }
        while ( 2 * v18 );
        v19 = -11;
        v20 = 1;
        do
        {
          v21 = v20;
          v22 = v19 & v20;
          v23 = v19;
          v19 ^= v21;
          v20 = 2 * v22;
        }
        while ( v20 );
        if ( v21 != v23 )
        {
          do
          {
            v24 = v16;
            v16 ^= v19;
            v19 = 2 * (v19 & v24);
          }
          while ( v19 );
        }
      }
      else
      {
        LOBYTE(v16) = v14 ^ 0x30;
        if ( !v14 )
          LOBYTE(v16) = 48;
      }
      *(v1 - 1) = v16;
      ++v0;
    }
    while ( v1 != v2 );
  }
  *v2 = 0;
  if ( !strcmp(Big_Numbers1_1400150A0, enc_hex) )
    print("------\nGetFlag!\n------");
  system("pause");
  return 0i64;
}

可以知道程序先获取长度为6位的密钥和长度为40的flag,然后用自定义表base64编码密钥,接着DES加密
最后和Big_Numbers1_7FF798C250A0进行check
get_intput函数里有长度和格式检验
img
base64_enc那个函数里可以找到base64表
img
DES加密Findcrypt没识别出来,但是Signsrch识别出来了DES标志
img
在DES函数里的sub_140001A20函数里看到对Big_Numbers1_1400150A0的异或操作,可以在脚本中手动异或一下,这里选择动调直接拿到
img
image.png
据此可以通过爆破得到6位数字密钥key,然后用变表base64编码过的key去解Big_Numbers1_7FF798C250A0

from Crypto.Cipher import DES
import binascii
import itertools
import base64
def custom_base64_encode(data):
    custom_chars = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ+/'
    # 创建标准Base64字符集和自定义字符集的映射表
    base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
    char_map = str.maketrans(base64_chars, custom_chars)
    # 使用标准Base64编码
    encoded_data = base64.b64encode(data.encode()).decode()
    # 替换为自定义字符
    encoded_data = encoded_data.translate(char_map)
    return encoded_data

def generate_sequential_key():
    digits = '0123456789'
    for key_tuple in itertools.product(digits, repeat=6):
        yield ''.join(key_tuple)

def des_decrypt(ciphertext, key):
    # 将密钥转换为8字节
    key = key.encode('utf-8')[:8]
    # 将16进制字符串转换为字节
    ciphertext = binascii.unhexlify(ciphertext)
    # 创建DES加密器
    cipher = DES.new(key, DES.MODE_ECB)
    # 解密数据
    plaintext = cipher.decrypt(ciphertext)
    return plaintext
# 要解密的数据和密钥        
encrypted_data = "0723105D5C12217DCDC3601F5ECB54DA9CCEC2279F1684A13A0D716D17217F4C9EA85FF1A42795731CA3C55D3A4D7BEA"
for psw in generate_sequential_key():
    key = custom_base64_encode(psw)
    #DES解密
    decrypted_data = des_decrypt(encrypted_data, key)
    if b'DASCTF' in decrypted_data:
        print(f"Found key:{psw}\nIt's base64_encode:{key}\nDecrypted Data:{decrypted_data.decode()}")
        encryption_key = key
        break
    pass
# Found key:151490
# It's base64_encode:mtuNndAM
# Decrypted Data: DASCTF{f771b96b71514bb6bc20f3275fa9404e}

Blast

ida Findcrypt插件看到MD5和好多个哈希值
image.png
image.png
定位到MD5加密函数,查看引用有两个
image.png
一个在main函数一个在sub_402370,发现main函数和sub_402370差不多且在main函数中调用了sub_402370
所以直接盲猜两次哈希MD5(MD5(data))

enc = [
  '14d89c38cd0fb23a14be2798d449c182','a94837b18f8f43f29448b40a6e7386ba','af85d512594fc84a5c65ec9970956ea5','af85d512594fc84a5c65ec9970956ea5','10e21da237a4a1491e769df6f4c3b419','a705e8280082f93f07e3486636f3827a','297e7ca127d2eef674c119331fe30dff','b5d2099e49bdb07b8176dff5e23b3c14','83be264eb452fcf0a1c322f2c7cbf987','a94837b18f8f43f29448b40a6e7386ba','71b0438bf46aa26928c7f5a371d619e1','a705e8280082f93f07e3486636f3827a','ac49073a7165f41c57eb2c1806a7092e','a94837b18f8f43f29448b40a6e7386ba','af85d512594fc84a5c65ec9970956ea5','ed108f6919ebadc8e809f8b86ef40b05','10e21da237a4a1491e769df6f4c3b419','3cfd436919bc3107d68b912ee647f341','a705e8280082f93f07e3486636f3827a','65c162f7c43612ba1bdf4d0f2912bbc0','10e21da237a4a1491e769df6f4c3b419','a705e8280082f93f07e3486636f3827a','3cfd436919bc3107d68b912ee647f341','557460d317ae874c924e9be336a83cbe','a705e8280082f93f07e3486636f3827a','9203d8a26e241e63e4b35b3527440998','10e21da237a4a1491e769df6f4c3b419','f91b2663febba8a884487f7de5e1d249','a705e8280082f93f07e3486636f3827a','d7afde3e7059cd0a0fe09eec4b0008cd','488c428cd4a8d916deee7c1613c8b2fd','39abe4bca904bca5a11121955a2996bf','a705e8280082f93f07e3486636f3827a','3cfd436919bc3107d68b912ee647f341','39abe4bca904bca5a11121955a2996bf','4e44f1ac85cd60e3caa56bfd4afb675e','45cf8ddfae1d78741d8f1c622689e4af','3cfd436919bc3107d68b912ee647f341','39abe4bca904bca5a11121955a2996bf','4e44f1ac85cd60e3caa56bfd4afb675e','37327bb06c83cb29cefde1963ea588aa','a705e8280082f93f07e3486636f3827a','23e65a679105b85c5dc7034fded4fb5f','10e21da237a4a1491e769df6f4c3b419','71b0438bf46aa26928c7f5a371d619e1','af85d512594fc84a5c65ec9970956ea5','39abe4bca904bca5a11121955a2996bf']
import hashlib
import itertools

# 生成所有ASCII可见字符
characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 !"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'
combinations = itertools.product(characters, repeat=1)
# 创建一个字典以存储已知哈希值和对应的原始字符
hashes_dict = {hash_val: None for hash_val in enc}
# 遍历所有组合,计算哈希值并与已知的哈希值进行比较
for combo in combinations:
    plaintext = ''.join(combo)
    hash1 = hashlib.md5(plaintext.encode()).hexdigest()
    hash2 = hashlib.md5(hash1.encode()).hexdigest()
    if hash2 in enc:
        hashes_dict[hash2] = plaintext
flag = ''
for i in enc:
  flag += hashes_dict[i]
  print(f"Original Text for Hash '{i}': {hashes_dict[i]}")
print(flag)
'''
Original Text for Hash '14d89c38cd0fb23a14be2798d449c182': H
Original Text for Hash 'a94837b18f8f43f29448b40a6e7386ba': e
Original Text for Hash 'af85d512594fc84a5c65ec9970956ea5': l
Original Text for Hash 'af85d512594fc84a5c65ec9970956ea5': l
Original Text for Hash '10e21da237a4a1491e769df6f4c3b419': o
Original Text for Hash 'a705e8280082f93f07e3486636f3827a': _
Original Text for Hash '297e7ca127d2eef674c119331fe30dff': C
Original Text for Hash 'b5d2099e49bdb07b8176dff5e23b3c14': t
Original Text for Hash '83be264eb452fcf0a1c322f2c7cbf987': f
Original Text for Hash 'a94837b18f8f43f29448b40a6e7386ba': e
Original Text for Hash '71b0438bf46aa26928c7f5a371d619e1': r
Original Text for Hash 'a705e8280082f93f07e3486636f3827a': _
Original Text for Hash 'ac49073a7165f41c57eb2c1806a7092e': V
Original Text for Hash 'a94837b18f8f43f29448b40a6e7386ba': e
Original Text for Hash 'af85d512594fc84a5c65ec9970956ea5': l
Original Text for Hash 'ed108f6919ebadc8e809f8b86ef40b05': c
Original Text for Hash '10e21da237a4a1491e769df6f4c3b419': o
Original Text for Hash '3cfd436919bc3107d68b912ee647f341': m
Original Text for Hash 'a705e8280082f93f07e3486636f3827a': _
Original Text for Hash '65c162f7c43612ba1bdf4d0f2912bbc0': T
Original Text for Hash '10e21da237a4a1491e769df6f4c3b419': o
Original Text for Hash 'a705e8280082f93f07e3486636f3827a': _
Original Text for Hash '3cfd436919bc3107d68b912ee647f341': m
Original Text for Hash '557460d317ae874c924e9be336a83cbe': y
Original Text for Hash 'a705e8280082f93f07e3486636f3827a': _
Original Text for Hash '9203d8a26e241e63e4b35b3527440998': M
Original Text for Hash '10e21da237a4a1491e769df6f4c3b419': o
Original Text for Hash 'f91b2663febba8a884487f7de5e1d249': v
Original Text for Hash 'a705e8280082f93f07e3486636f3827a': _
Original Text for Hash 'd7afde3e7059cd0a0fe09eec4b0008cd': a
Original Text for Hash '488c428cd4a8d916deee7c1613c8b2fd': n
Original Text for Hash '39abe4bca904bca5a11121955a2996bf': d
Original Text for Hash 'a705e8280082f93f07e3486636f3827a': _
Original Text for Hash '3cfd436919bc3107d68b912ee647f341': m
Original Text for Hash '39abe4bca904bca5a11121955a2996bf': d
Original Text for Hash '4e44f1ac85cd60e3caa56bfd4afb675e': 5
Original Text for Hash '45cf8ddfae1d78741d8f1c622689e4af': (
Original Text for Hash '3cfd436919bc3107d68b912ee647f341': m
Original Text for Hash '39abe4bca904bca5a11121955a2996bf': d
Original Text for Hash '4e44f1ac85cd60e3caa56bfd4afb675e': 5
Original Text for Hash '37327bb06c83cb29cefde1963ea588aa': )
Original Text for Hash 'a705e8280082f93f07e3486636f3827a': _
Original Text for Hash '23e65a679105b85c5dc7034fded4fb5f': w
Original Text for Hash '10e21da237a4a1491e769df6f4c3b419': o
Original Text for Hash '71b0438bf46aa26928c7f5a371d619e1': r
Original Text for Hash 'af85d512594fc84a5c65ec9970956ea5': l
Original Text for Hash '39abe4bca904bca5a11121955a2996bf': d
Hello_Ctfer_Velcom_To_my_Mov_and_md5(md5)_world
'''
posted @ 2023-09-09 16:30  Tree_24  阅读(169)  评论(0编辑  收藏  举报