首页
社区
课程
招聘
KCTF 2024 第十题 试探 WriteUp
发表于: 2024-9-6 01:40 3208

KCTF 2024 第十题 试探 WriteUp

2024-9-6 01:40
3208

使用ida打开程序查看main函数, 发现存在字符串加密:

xor_140001FC0函数中有较为繁复的处理参数1的长度模3剩余部分的代码逻辑:

大致猜想xor_140001FC0函数其逻辑为将参数3当作3字节的key,令参数1与其循环异或;
实验可验证:

之后继续分析main函数逻辑:

之后看到stdstr_error_toolong_140001280的函数内容是std::_Xlength_error("string too long")
可以判断接下来一段涉及到new与两次memcpy的代码为内联的std::string的处理函数
memcpy的src与dst判断逻辑为构造内容是"kctf" + inputstring
之后的部分为

查找了NtAddBootEntry函数地址加上0x12并在之后的函数中跳转到该处:

打开ntdll.dll查看, NtAddBootEntry实际解析到的是ZwAddBootEntry其代码为

程序中使用的为ZwAddBootEntry+0x12syscall_140002533函数实际上是对syscall的包装.
分析出syscall_init_140002510syscall_140002533的功能后再分析较为复杂的find_syscall_num_140002160
因该函数主要对全局变量syscall_num_1400075A8赋值并会在之后作为系统调用号传递, 其功能就可以判断出来是在查找系统调用号
通过动态调试查看syscallnum_140006000可检索到该处系统调用为NtAllocateVirtualMemory
之后

向申请的内存中填入"kctf"+input的内容, 再在其后从loc_140006050复制0xED3字节,并保存offsetof_6050
再之后为:

启动了两个线程; main函数之后的内容就只剩free一些内存就结束了, 所以之后分析这两个线程
先看print_thread_140001530:

等待buffer_1400075C0的内容变化然后从中解密3字节内容并输出, 错误时输出的no!就是从这来的
再看thread2_1400012C0

分别调用了TpAllocWait TpSetWaitNtWaitForSingleObject;
搜索TpAllocWait函数找到了文章creating-an-opsec-safe-loader-for-red-team-operations与随文章开源的TpAllocInject
其代码为

过程与之前分析的大致相同;
所以可以认为thread2_1400012C0的功能为执行buffer_1400075C0 + offsetof_6050_1400075AC处的代码
buffer_1400075C0 + offsetof_6050_1400075AC是从loc_140006050处复制来的
所以转至loc_140006050开始分析
一开始有一个特技call

因为140006058inc eax为无效指令, 所以此处可以patch为call 0x14000605A
之后的循环是从0x14000607B0x14000607B+0xEA7中出现的所有0x2a改为0
写idapython脚本为

再观察之后的代码:

稍微跟一会跳转, 发现似乎只存在cmp jnz jz jbe jmp跳转混淆, 写idapython去除脚本为

之后f5分析函数sub_14000607B, 第一段为:

这些具体是哪些函数可以通过windbg调试指令bp findfunc_by_hash_14000660F "r rcx;bp @$ra \"u rax\";g"查看得到;
之后为:

可看出verify_14000671B为具体验证输入的函数.
首先看准备过程与第一段过程

上面的代码首先准备了两个3x3数组, 分别为:

之后在循环中将输入作为横纵坐标交换array_013526478中0与坐标处的数字
第二段过程与最后比较为(过程大概看一下,重点看最后比较)

第二段过程没有用到输入内容, 所以动调获得与input_len_div2_1比较的v82为6;
猜测第二段过程为动态规划算法找出从013526478交换到123456780所需的最少步数.
最后比较的是输入步数为6,及经输入调整后的array_013526478array_1_8相同
对着array_013526478走一下, 类似解谜游戏常见的移动拼图:

得到输入应为011110202122

v57[0] = 0LL;
size = 0LL;
v59 = 15LL;
stdstr_140001CA0((__int64)v57, 0x16uLL, v3, "Ummdrm%dfqdz%xgps(ndq?", v44, v46); // Please enter your key:
v4 = v57;
if ( v59 >= 0x10 )
v4 = (void **)v57[0];
v5 = (const char *)xor_140001FC0((__int64)v4, size, (const __m128i *)&byte_1400043BC);
v57[0] = 0LL;
size = 0LL;
v59 = 15LL;
stdstr_140001CA0((__int64)v57, 0x16uLL, v3, "Ummdrm%dfqdz%xgps(ndq?", v44, v46); // Please enter your key:
v4 = v57;
if ( v59 >= 0x10 )
v4 = (void **)v57[0];
v5 = (const char *)xor_140001FC0((__int64)v4, size, (const __m128i *)&byte_1400043BC);
__int64 __fastcall xor_140001FC0(__int64 str1, int size, const __m128i *key) {
  size_1 = size;
  divide_3 = size / 3;
  if ( divide_3 > 0 )
  {
    v6 = str1 + 2;
    v7 = (unsigned int)divide_3;
    do
    {
      *(_BYTE *)(v6 - 2) ^= key->m128i_i8[0];
      v6 += 3LL;
      *(_WORD *)(v6 - 4) ^= *(unsigned __int16 *)((char *)key->m128i_u16 + 1);
      --v7;
    }
    while ( v7 );
  }
  v8 = 3 * divide_3;
  if ( 3 * divide_3 == (_DWORD)size_1 )
    return str1;
  mod3 = size_1 - v8;
  v10 = v8;
  if ( v8 < (int)size_1
    && mod3 >= 0x40
    && (v8 + str1 > (unsigned __int64)key->m128i_u64 + (int)size_1 - 1 - v8
     || str1 + (int)size_1 - 1 < (unsigned __int64)key) )
  {
    v11 = key + 2;
    v12 = (int)size_1 - (int)mod3 % 64;
    v13 = v8 - (_QWORD)key + str1;
    v14 = v8 - (_QWORD)key - 32LL;
    do
    {
      v15 = _mm_loadu_si128((const __m128i *)((char *)v11 + v13 - 32));
      v8 += 64;
      v16 = _mm_loadu_si128(v11 - 2);
      v11 += 4;
      *(const __m128i *)((char *)&v11[-6] + v13) = _mm_xor_si128(v16, v15);
      *(const __m128i *)((char *)&v11[-5] + v13) = _mm_xor_si128(
                                                     _mm_loadu_si128(v11 - 5),
                                                     _mm_loadu_si128((const __m128i *)((char *)v11 + v13 - 80)));
      *(const __m128i *)((char *)&v11[-4] + v13) = _mm_xor_si128(
                                                     _mm_loadu_si128(v11 - 4),
                                                     _mm_loadu_si128((const __m128i *)((char *)v11 + v13 - 64)));
      *(const __m128i *)((char *)&v11[-3] + v13) = _mm_xor_si128(
                                                     _mm_loadu_si128(v11 - 3),
                                                     _mm_loadu_si128((const __m128i *)((char *)v11 + v13 - 48)));
    }
    while ( (__int64)v11->m128i_i64 + v14 < v12 );
  }
  if ( v8 < size_1 )
  {
    v17 = (_BYTE *)(v8 + str1);
    v18 = &key->m128i_i8[-v10 - str1];
    v19 = size_1 - v8;
    do
    {
      *v17 ^= v17[(_QWORD)v18];
      ++v17;
      --v19;
    }
    while ( v19 );
  }
  return str1;
}
__int64 __fastcall xor_140001FC0(__int64 str1, int size, const __m128i *key) {
  size_1 = size;
  divide_3 = size / 3;
  if ( divide_3 > 0 )
  {
    v6 = str1 + 2;
    v7 = (unsigned int)divide_3;
    do
    {
      *(_BYTE *)(v6 - 2) ^= key->m128i_i8[0];
      v6 += 3LL;
      *(_WORD *)(v6 - 4) ^= *(unsigned __int16 *)((char *)key->m128i_u16 + 1);
      --v7;
    }
    while ( v7 );
  }
  v8 = 3 * divide_3;
  if ( 3 * divide_3 == (_DWORD)size_1 )
    return str1;
  mod3 = size_1 - v8;
  v10 = v8;
  if ( v8 < (int)size_1
    && mod3 >= 0x40
    && (v8 + str1 > (unsigned __int64)key->m128i_u64 + (int)size_1 - 1 - v8
     || str1 + (int)size_1 - 1 < (unsigned __int64)key) )
  {
    v11 = key + 2;
    v12 = (int)size_1 - (int)mod3 % 64;
    v13 = v8 - (_QWORD)key + str1;
    v14 = v8 - (_QWORD)key - 32LL;
    do
    {
      v15 = _mm_loadu_si128((const __m128i *)((char *)v11 + v13 - 32));
      v8 += 64;
      v16 = _mm_loadu_si128(v11 - 2);
      v11 += 4;
      *(const __m128i *)((char *)&v11[-6] + v13) = _mm_xor_si128(v16, v15);
      *(const __m128i *)((char *)&v11[-5] + v13) = _mm_xor_si128(
                                                     _mm_loadu_si128(v11 - 5),
                                                     _mm_loadu_si128((const __m128i *)((char *)v11 + v13 - 80)));
      *(const __m128i *)((char *)&v11[-4] + v13) = _mm_xor_si128(
                                                     _mm_loadu_si128(v11 - 4),
                                                     _mm_loadu_si128((const __m128i *)((char *)v11 + v13 - 64)));
      *(const __m128i *)((char *)&v11[-3] + v13) = _mm_xor_si128(
                                                     _mm_loadu_si128(v11 - 3),
                                                     _mm_loadu_si128((const __m128i *)((char *)v11 + v13 - 48)));
    }
    while ( (__int64)v11->m128i_i64 + v14 < v12 );
  }
  if ( v8 < size_1 )
  {
    v17 = (_BYTE *)(v8 + str1);
    v18 = &key->m128i_i8[-v10 - str1];
    v19 = size_1 - v8;
    do
    {
      *v17 ^= v17[(_QWORD)v18];
      ++v17;
      --v19;
    }
    while ( v19 );
  }
  return str1;
}
def xor(a, b):
    if(len(a) < len(b)):
        a, b = b, a
     
    blen = len(b)
    ret = r''
    for i in range(len(a)):
        ret += chr(a[i] ^ b[i%blen])
    return bytes(ret, 'latin1')
 
def dec(s):
    return xor(s, '\x05\x01\x08') # byte_1400043BC 内容
 
print(dec("Ummdrm%dfqdz%xgps(ndq?")) # 输出为 b'Please enter your key:'
def xor(a, b):
    if(len(a) < len(b)):
        a, b = b, a
     
    blen = len(b)
    ret = r''
    for i in range(len(a)):
        ret += chr(a[i] ^ b[i%blen])
    return bytes(ret, 'latin1')
 
def dec(s):
    return xor(s, '\x05\x01\x08') # byte_1400043BC 内容
 
print(dec("Ummdrm%dfqdz%xgps(ndq?")) # 输出为 b'Please enter your key:'
v5 = (const char *)xor_140001FC0((__int64)v4, size, (const __m128i *)&byte_1400043BC);
  printf_140001020(v5); // Please enter your key:
  v6 = Src;
  if ( v52 >= 0x10 )
    v6 = (void **)Src[0];
  scanf_140001080("%s", v6);
  v62 = 15LL;
  v61 = 4LL;
  v60 = (void *)'c|bn'; // dec(b'nb|c') is kctf
  v7 = xor_140001FC0((__int64)&v60, 4, (const __m128i *)&byte_1400043BC);
  v10 = (const void *)v7;
  v11 = -1LL;
  do
    ++v11;
  while ( *(_BYTE *)(v7 + v11) );
  v12 = Size;
  if ( 0x7FFFFFFFFFFFFFFFLL - Size < v11 )
LABEL_74:
    stdstr_error_toolong_140001280();
  v13 = Src;
  if ( v52 >= 0x10 )
    v13 = (void **)Src[0];
v5 = (const char *)xor_140001FC0((__int64)v4, size, (const __m128i *)&byte_1400043BC);
  printf_140001020(v5); // Please enter your key:
  v6 = Src;
  if ( v52 >= 0x10 )
    v6 = (void **)Src[0];
  scanf_140001080("%s", v6);
  v62 = 15LL;
  v61 = 4LL;
  v60 = (void *)'c|bn'; // dec(b'nb|c') is kctf
  v7 = xor_140001FC0((__int64)&v60, 4, (const __m128i *)&byte_1400043BC);
  v10 = (const void *)v7;
  v11 = -1LL;
  do
    ++v11;
  while ( *(_BYTE *)(v7 + v11) );
  v12 = Size;
  if ( 0x7FFFFFFFFFFFFFFFLL - Size < v11 )
LABEL_74:
    stdstr_error_toolong_140001280();
  v13 = Src;
  if ( v52 >= 0x10 )
    v13 = (void **)Src[0];
string_size = v12 + v11;
v66 = v15;
memcpy(string, kctf, v11);
memcpy(&string[v11], input, v12);
string[v14] = 0;
v56 = 15LL;
v55 = 9LL;
strcpy((char *)v54, "kulim&amd");
ntdll = (const CHAR *)xor_140001FC0((__int64)v54, 9, (const __m128i *)&byte_1400043BC);// ntdll.dll
hntdll = GetModuleHandleA(ntdll);
v49 = 15LL;
v48 = 14LL;
strcpy((char *)Block, "KuIaeJjn|@o|wx");
v23 = (const CHAR *)xor_140001FC0((__int64)Block, 14, (const __m128i *)&byte_1400043BC);// NtAddBootEntry
syscall_1400075B8 = (__int64)GetProcAddress(hntdll, v23) + 0x12;
event_1400075B0 = (__int64)CreateEventA(0LL, 0, 1, 0LL);
input_size_1 = string_size;
size_1 = string_size + 0xED4;
find_syscall_num_140002160((__int64)hntdll, v25, (__int64)aQimjgbgDpasrJe);
syscall_init_140002510(syscall_num_1400075A8, (__int64 (*)(void))syscall_1400075B8);
LODWORD(InitFlag) = 4096;
syscall_140002533(-1LL, (__int64)&buffer_1400075C0, 0LL, (__int64)&size_1, InitFlag);// NtAllocateVirtualMemory
string_size = v12 + v11;
v66 = v15;
memcpy(string, kctf, v11);
memcpy(&string[v11], input, v12);
string[v14] = 0;
v56 = 15LL;
v55 = 9LL;
strcpy((char *)v54, "kulim&amd");
ntdll = (const CHAR *)xor_140001FC0((__int64)v54, 9, (const __m128i *)&byte_1400043BC);// ntdll.dll
hntdll = GetModuleHandleA(ntdll);
v49 = 15LL;
v48 = 14LL;
strcpy((char *)Block, "KuIaeJjn|@o|wx");
v23 = (const CHAR *)xor_140001FC0((__int64)Block, 14, (const __m128i *)&byte_1400043BC);// NtAddBootEntry
syscall_1400075B8 = (__int64)GetProcAddress(hntdll, v23) + 0x12;
event_1400075B0 = (__int64)CreateEventA(0LL, 0, 1, 0LL);
input_size_1 = string_size;
size_1 = string_size + 0xED4;
find_syscall_num_140002160((__int64)hntdll, v25, (__int64)aQimjgbgDpasrJe);
syscall_init_140002510(syscall_num_1400075A8, (__int64 (*)(void))syscall_1400075B8);
LODWORD(InitFlag) = 4096;
syscall_140002533(-1LL, (__int64)&buffer_1400075C0, 0LL, (__int64)&size_1, InitFlag);// NtAllocateVirtualMemory
void __fastcall syscall_init_140002510(int a1, __int64 a2)
{
  syscallnum_140006000 = a1;
  syscall_140006004 = a2;
}
void __fastcall syscall_init_140002510(int a1, __int64 a2)
{
  syscallnum_140006000 = a1;
  syscall_140006004 = a2;
}
.text:0000000140002533 ; __int64 syscall_140002533(__int64, __int64, __int64, __int64, __int64)
.text:0000000140002533 syscall_140002533 proc near             ; CODE XREF: thread2_1400012C0+170↑p
.text:0000000140002533                                         ; main+32E↑p
.text:0000000140002533                 mov     r10, rcx
.text:0000000140002536                 mov     eax, cs:syscallnum_140006000
.text:000000014000253C                 jmp     cs:syscall_140006004
.text:0000000140002533 ; __int64 syscall_140002533(__int64, __int64, __int64, __int64, __int64)
.text:0000000140002533 syscall_140002533 proc near             ; CODE XREF: thread2_1400012C0+170↑p
.text:0000000140002533                                         ; main+32E↑p
.text:0000000140002533                 mov     r10, rcx
.text:0000000140002536                 mov     eax, cs:syscallnum_140006000
.text:000000014000253C                 jmp     cs:syscall_140006004
.text:0000000180092300                 public ZwAddBootEntry
.text:0000000180092300 ZwAddBootEntry  proc near
.text:0000000180092300                 mov     r10, rcx        ; NtAddBootEntry
.text:0000000180092303                 mov     eax, 6Ah ; 'j'
.text:0000000180092308                 test    byte ptr ds:7FFE0308h, 1
.text:0000000180092310                 jnz     short loc_180092315
.text:0000000180092312                 syscall                 ; Low latency system call
.text:0000000180092314                 retn
.text:0000000180092315 ; ---------------------------------------------------------------------------
.text:0000000180092315
.text:0000000180092315 loc_180092315:                          ; CODE XREF: ZwAddBootEntry+10↑j
.text:0000000180092315                 int     2Eh             ; DOS 2+ internal - EXECUTE COMMAND
.text:0000000180092315                                         ; DS:SI -> counted CR-terminated command string
.text:0000000180092317                 retn
.text:0000000180092317 ZwAddBootEntry  endp
.text:0000000180092300                 public ZwAddBootEntry
.text:0000000180092300 ZwAddBootEntry  proc near
.text:0000000180092300                 mov     r10, rcx        ; NtAddBootEntry
.text:0000000180092303                 mov     eax, 6Ah ; 'j'
.text:0000000180092308                 test    byte ptr ds:7FFE0308h, 1
.text:0000000180092310                 jnz     short loc_180092315
.text:0000000180092312                 syscall                 ; Low latency system call
.text:0000000180092314                 retn
.text:0000000180092315 ; ---------------------------------------------------------------------------
.text:0000000180092315
.text:0000000180092315 loc_180092315:                          ; CODE XREF: ZwAddBootEntry+10↑j
.text:0000000180092315                 int     2Eh             ; DOS 2+ internal - EXECUTE COMMAND
.text:0000000180092315                                         ; DS:SI -> counted CR-terminated command string
.text:0000000180092317                 retn
.text:0000000180092317 ZwAddBootEntry  endp
string_cstr = string_1;
v24 = v63;
v25 = v63 >= 0x10;
v26 = (char *)string_1[0];
if ( v63 >= 0x10 )
  string_cstr = (void **)string_1[0];
p_buffer = (_BYTE *)buffer_1400075C0;
v28 = input_size_1;
if ( input_size_1 )
{
  do
  {
    *p_buffer++ = *(_BYTE *)string_cstr;
    string_cstr = (void **)((char *)string_cstr + 1);
    --v28;
  }
  while ( v28 );
  p_buffer = (_BYTE *)buffer_1400075C0;
}
p_buffer_1 = &p_buffer[input_size_1 + 1];
tmp_p = &loc_140006050;
v31 = 0xED3LL;
do
{
  *p_buffer_1++ = *tmp_p++;
  --v31;
}
while ( v31 );
offsetof_6050_1400075AC = input_size_1 + 1;
string_cstr = string_1;
v24 = v63;
v25 = v63 >= 0x10;
v26 = (char *)string_1[0];
if ( v63 >= 0x10 )
  string_cstr = (void **)string_1[0];
p_buffer = (_BYTE *)buffer_1400075C0;
v28 = input_size_1;
if ( input_size_1 )
{
  do
  {
    *p_buffer++ = *(_BYTE *)string_cstr;
    string_cstr = (void **)((char *)string_cstr + 1);
    --v28;
  }
  while ( v28 );
  p_buffer = (_BYTE *)buffer_1400075C0;
}
p_buffer_1 = &p_buffer[input_size_1 + 1];
tmp_p = &loc_140006050;
v31 = 0xED3LL;
do
{
  *p_buffer_1++ = *tmp_p++;
  --v31;
}
while ( v31 );
offsetof_6050_1400075AC = input_size_1 + 1;
v32 = (int (**)())operator new(8uLL);
 *v32 = print_thread_140001530;
 v64._Hnd = v32;
 if ( !beginthreadex(0LL, 0, (_beginthreadex_proc_type)call_arg1_140001F90, v32, 0, &v66) )
   goto LABEL_73;
 v33 = (void (**)())operator new(8uLL);
 *v33 = thread2_1400012C0;
 v64._Hnd = v33;
 *(_QWORD *)v50 = beginthreadex(0LL, 0, (_beginthreadex_proc_type)call_arg1_140001F90, v33, 0, &v50[2]);
v32 = (int (**)())operator new(8uLL);
 *v32 = print_thread_140001530;
 v64._Hnd = v32;
 if ( !beginthreadex(0LL, 0, (_beginthreadex_proc_type)call_arg1_140001F90, v32, 0, &v66) )
   goto LABEL_73;
 v33 = (void (**)())operator new(8uLL);
 *v33 = thread2_1400012C0;
 v64._Hnd = v33;
 *(_QWORD *)v50 = beginthreadex(0LL, 0, (_beginthreadex_proc_type)call_arg1_140001F90, v33, 0, &v50[2]);
int print_thread_140001530()
{
  __int64 v0; // rcx
  char i; // al
  const __m128i *v2; // r8
  const char *v3; // rax
 
  v0 = buffer_1400075C0;
  for ( i = *(_BYTE *)buffer_1400075C0; *(_BYTE *)buffer_1400075C0 == 'k'; i = *(_BYTE *)buffer_1400075C0 )
  {
    Sleep(0xAu);
    v0 = buffer_1400075C0;
  }
  v2 = (const __m128i *)&unk_1400043F8;         // \x06\x04\x01
  if ( i != 'i' )
    v2 = (const __m128i *)&unk_1400043FC;       // \x03\x05\x08
  v3 = (const char *)xor_140001FC0(v0, 3, v2);
  return printf_140001020(v3);
}
int print_thread_140001530()
{
  __int64 v0; // rcx
  char i; // al
  const __m128i *v2; // r8
  const char *v3; // rax
 
  v0 = buffer_1400075C0;
  for ( i = *(_BYTE *)buffer_1400075C0; *(_BYTE *)buffer_1400075C0 == 'k'; i = *(_BYTE *)buffer_1400075C0 )
  {
    Sleep(0xAu);
    v0 = buffer_1400075C0;
  }
  v2 = (const __m128i *)&unk_1400043F8;         // \x06\x04\x01
  if ( i != 'i' )
    v2 = (const __m128i *)&unk_1400043FC;       // \x03\x05\x08
  v3 = (const char *)xor_140001FC0(v0, 3, v2);
  return printf_140001020(v3);
}
v11 = 0LL;
v19 = 15LL;
v18[2] = 9LL;
strcpy((char *)v18, "kulim&amd");             // ntdll.dll
v0 = (const CHAR *)xor_140001FC0((__int64)v18, 9, (const __m128i *)&byte_1400043BC);
hntdll = GetModuleHandleA(v0);
v14 = 15LL;
v13 = 11LL;
strcpy((char *)v12, "QqIimgfVilu");           // TpAllocWait
v2 = (const CHAR *)xor_140001FC0((__int64)v12, 11, (const __m128i *)&byte_1400043BC);
TpAllocWait = GetProcAddress(hntdll, v2);
((void (__fastcall *)(__int64 *, __int64, _QWORD, _QWORD))TpAllocWait)(
  &v11,
  buffer_1400075C0 + (unsigned int)offsetof_6050_1400075AC,
  0LL,
  0LL);
v17 = 15LL;
v16 = 9LL;
strcpy((char *)Block, "Qq[`u_dh|");           // TpSetWait
v4 = (const CHAR *)xor_140001FC0((__int64)Block, 9, (const __m128i *)&byte_1400043BC);
TpSetWait = GetProcAddress(hntdll, v4);
((void (__fastcall *)(__int64, __int64, _QWORD))TpSetWait)(v11, event_1400075B0, 0LL);
find_syscall_num_140002160(hntdll, v6, "Or_`o|GizRoffjmNdbde|");
syscall_init_140002510((unsigned int)syscall_num_1400075A8, syscall_1400075B8);
syscall_140002533(event_1400075B0, 0LL, 0LL, v7, v11, v12[0]);// NtWaitForSingleObject
v11 = 0LL;
v19 = 15LL;
v18[2] = 9LL;
strcpy((char *)v18, "kulim&amd");             // ntdll.dll
v0 = (const CHAR *)xor_140001FC0((__int64)v18, 9, (const __m128i *)&byte_1400043BC);
hntdll = GetModuleHandleA(v0);
v14 = 15LL;
v13 = 11LL;
strcpy((char *)v12, "QqIimgfVilu");           // TpAllocWait
v2 = (const CHAR *)xor_140001FC0((__int64)v12, 11, (const __m128i *)&byte_1400043BC);
TpAllocWait = GetProcAddress(hntdll, v2);
((void (__fastcall *)(__int64 *, __int64, _QWORD, _QWORD))TpAllocWait)(
  &v11,
  buffer_1400075C0 + (unsigned int)offsetof_6050_1400075AC,
  0LL,
  0LL);
v17 = 15LL;
v16 = 9LL;
strcpy((char *)Block, "Qq[`u_dh|");           // TpSetWait
v4 = (const CHAR *)xor_140001FC0((__int64)Block, 9, (const __m128i *)&byte_1400043BC);
TpSetWait = GetProcAddress(hntdll, v4);
((void (__fastcall *)(__int64, __int64, _QWORD))TpSetWait)(v11, event_1400075B0, 0LL);
find_syscall_num_140002160(hntdll, v6, "Or_`o|GizRoffjmNdbde|");
syscall_init_140002510((unsigned int)syscall_num_1400075A8, syscall_1400075B8);
syscall_140002533(event_1400075B0, 0LL, 0LL, v7, v11, v12[0]);// NtWaitForSingleObject
// from https://github.com/nettitude/Tartarus-TpAllocInject
int main()
{
    auto hNtdll = GetModuleHandleA("ntdll.dll");
    DWORD SyscallId = 0;
    LPVOID spoofJump = ((char*)GetProcAddress(hNtdll, "NtAddBootEntry")) + 18; //Fetching the Syscall instruction address
    HANDLE c = CreateEventA(NULL, FALSE, TRUE, NULL);
 
    LPVOID currentVmBase = NULL;
    SIZE_T szWmResv = sizeof(buf);
    //Resolving ZwAllocateVirtualMemory
    GetSyscallId(hNtdll, &SyscallId, (PCHAR)"ZwAllocateVirtualMemory");
    setup(SyscallId, spoofJump);
    NTSTATUS status = executioner((HANDLE)-1,&currentVmBase, NULL,&szWmResv,MEM_COMMIT,PAGE_READWRITE);
    //Allocating space in memory for shellcode
 
    CopyMemoryEx(currentVmBase, buf, szWmResv);
    //Avoiding hooks with custom copying on current process
 
    //Resolving NtProtectVirtualMemory
    DWORD oldProt;
    GetSyscallId(hNtdll, &SyscallId, (PCHAR)"NtProtectVirtualMemory");
    setup(SyscallId, spoofJump);
    status = executioner((HANDLE)-1,&currentVmBase, &szWmResv,PAGE_EXECUTE_READ,&oldProt);
 
    //Resolving TpAllocWait
    HANDLE hThread = NULL;
    pTpAllocWait TpAllocWait = (pTpAllocWait)GetProcAddress(hNtdll, "TpAllocWait");
    status = TpAllocWait((TP_WAIT**)&hThread, (PTP_WAIT_CALLBACK)currentVmBase, NULL, NULL);
 
    //Resolving TpSetWait
    pTpSetWait TpSetWait = (pTpSetWait)GetProcAddress(hNtdll, "TpSetWait");
    TpSetWait((TP_WAIT*)hThread, c, NULL);
 
    //Resolving NtWaitForSingleObject
    GetSyscallId(hNtdll, &SyscallId, (PCHAR)"NtWaitForSingleObject");
    setup(SyscallId, spoofJump);
    status = executioner(c, 0, NULL);
}
// from https://github.com/nettitude/Tartarus-TpAllocInject
int main()
{
    auto hNtdll = GetModuleHandleA("ntdll.dll");
    DWORD SyscallId = 0;
    LPVOID spoofJump = ((char*)GetProcAddress(hNtdll, "NtAddBootEntry")) + 18; //Fetching the Syscall instruction address
    HANDLE c = CreateEventA(NULL, FALSE, TRUE, NULL);
 
    LPVOID currentVmBase = NULL;
    SIZE_T szWmResv = sizeof(buf);
    //Resolving ZwAllocateVirtualMemory
    GetSyscallId(hNtdll, &SyscallId, (PCHAR)"ZwAllocateVirtualMemory");
    setup(SyscallId, spoofJump);
    NTSTATUS status = executioner((HANDLE)-1,&currentVmBase, NULL,&szWmResv,MEM_COMMIT,PAGE_READWRITE);
    //Allocating space in memory for shellcode
 
    CopyMemoryEx(currentVmBase, buf, szWmResv);
    //Avoiding hooks with custom copying on current process
 
    //Resolving NtProtectVirtualMemory
    DWORD oldProt;
    GetSyscallId(hNtdll, &SyscallId, (PCHAR)"NtProtectVirtualMemory");
    setup(SyscallId, spoofJump);
    status = executioner((HANDLE)-1,&currentVmBase, &szWmResv,PAGE_EXECUTE_READ,&oldProt);
 
    //Resolving TpAllocWait
    HANDLE hThread = NULL;
    pTpAllocWait TpAllocWait = (pTpAllocWait)GetProcAddress(hNtdll, "TpAllocWait");
    status = TpAllocWait((TP_WAIT**)&hThread, (PTP_WAIT_CALLBACK)currentVmBase, NULL, NULL);
 
    //Resolving TpSetWait
    pTpSetWait TpSetWait = (pTpSetWait)GetProcAddress(hNtdll, "TpSetWait");
    TpSetWait((TP_WAIT*)hThread, c, NULL);
 
    //Resolving NtWaitForSingleObject
    GetSyscallId(hNtdll, &SyscallId, (PCHAR)"NtWaitForSingleObject");
    setup(SyscallId, spoofJump);
    status = executioner(c, 0, NULL);
}
.data:0000000140006050 loc_140006050:                          ; DATA XREF: main+381↑o
.data:0000000140006050                 push    rdi
.data:0000000140006051                 push    rax
.data:0000000140006052                 push    rcx
.data:0000000140006053                 push    rsi
.data:0000000140006054
.data:0000000140006054 loc_140006054:                          ; CODE XREF: .data:loc_140006054↑p
.data:0000000140006054                 call    near ptr loc_140006054+4
.data:0000000140006059                 rcr     byte ptr [rdi-47h], 0A6h
.data:000000014000605D                 sgdt    fword ptr [rcx]
.data:0000000140006050 loc_140006050:                          ; DATA XREF: main+381↑o
.data:0000000140006050                 push    rdi
.data:0000000140006051                 push    rax
.data:0000000140006052                 push    rcx
.data:0000000140006053                 push    rsi
.data:0000000140006054
.data:0000000140006054 loc_140006054:                          ; CODE XREF: .data:loc_140006054↑p
.data:0000000140006054                 call    near ptr loc_140006054+4
.data:0000000140006059                 rcr     byte ptr [rdi-47h], 0A6h
.data:000000014000605D                 sgdt    fword ptr [rcx]
.data:0000000140006050 loc_140006050:                          ; DATA XREF: main+381↑o
.data:0000000140006050                 push    rdi
.data:0000000140006051                 push    rax
.data:0000000140006052                 push    rcx
.data:0000000140006053                 push    rsi
.data:0000000140006053 ; ---------------------------------------------------------------------------
.data:0000000140006054                 db 0E8h
.data:0000000140006055                 db 0FFh
.data:0000000140006056                 db 0FFh
.data:0000000140006057                 db 0FFh
.data:0000000140006058 ; ---------------------------------------------------------------------------
.data:0000000140006058                 inc     eax
.data:000000014000605A                 pop     rdi
.data:000000014000605B                 mov     ecx, 1010FA6h
.data:0000000140006060                 xor     ecx, 1010101h  ; 0xEA7
.data:0000000140006066                 add     rdi, 22h ; '"' ; 0x14000607B
.data:000000014000606A                 xor     esi, esi
.data:000000014000606C                 cld
.data:000000014000606D
.data:000000014000606D loc_14000606D:                          ; CODE XREF: .data:0000000140006075↓j
.data:000000014000606D                 mov     al, [rdi]
.data:000000014000606F                 cmp     al, 2Ah ; '*'
.data:0000000140006071                 cmovz   eax, esi
.data:0000000140006074                 stosb
.data:0000000140006075                 loop    loc_14000606D
.data:0000000140006077                 pop     rdi
.data:0000000140006078                 pop     rax
.data:0000000140006079                 pop     rcx
.data:000000014000607A                 pop     rsi
.data:0000000140006050 loc_140006050:                          ; DATA XREF: main+381↑o
.data:0000000140006050                 push    rdi
.data:0000000140006051                 push    rax
.data:0000000140006052                 push    rcx
.data:0000000140006053                 push    rsi
.data:0000000140006053 ; ---------------------------------------------------------------------------
.data:0000000140006054                 db 0E8h
.data:0000000140006055                 db 0FFh
.data:0000000140006056                 db 0FFh
.data:0000000140006057                 db 0FFh
.data:0000000140006058 ; ---------------------------------------------------------------------------
.data:0000000140006058                 inc     eax
.data:000000014000605A                 pop     rdi
.data:000000014000605B                 mov     ecx, 1010FA6h
.data:0000000140006060                 xor     ecx, 1010101h  ; 0xEA7
.data:0000000140006066                 add     rdi, 22h ; '"' ; 0x14000607B
.data:000000014000606A                 xor     esi, esi
.data:000000014000606C                 cld
.data:000000014000606D
.data:000000014000606D loc_14000606D:                          ; CODE XREF: .data:0000000140006075↓j
.data:000000014000606D                 mov     al, [rdi]
.data:000000014000606F                 cmp     al, 2Ah ; '*'
.data:0000000140006071                 cmovz   eax, esi
.data:0000000140006074                 stosb
.data:0000000140006075                 loop    loc_14000606D
.data:0000000140006077                 pop     rdi
.data:0000000140006078                 pop     rax
.data:0000000140006079                 pop     rcx
.data:000000014000607A                 pop     rsi
import idaapi
def patch_2a():
    pos = 0x14000607B
    size = 0xEA7
    for i in range(0xEA7):
        c = idaapi.get_byte(pos)
        if c == 0x2a:
            idaapi.patch_byte(pos, 0)
        pos += 1
patch_2a()
import idaapi
def patch_2a():
    pos = 0x14000607B
    size = 0xEA7
    for i in range(0xEA7):
        c = idaapi.get_byte(pos)
        if c == 0x2a:
            idaapi.patch_byte(pos, 0)
        pos += 1
patch_2a()
.data:000000014000607B loc_14000607B:                          ; CODE XREF: .data:0000000140006097↓j
.data:000000014000607B                 push    rbx
.data:000000014000607D                 push    rsi
.data:000000014000607E                 push    rdi
.data:000000014000607F                 push    r12
.data:0000000140006081                 push    r13
.data:0000000140006083                 push    r14
.data:0000000140006085                 push    r15
.data:0000000140006087                 sub     rsp, 2C0h
.data:000000014000608E                 cmp     esi, 0FFFFFFF5h
.data:0000000140006091                 jnz     short loc_1400060A0
.data:0000000140006093                 jz      short loc_14000609D
.data:0000000140006095                 jbe     short near ptr loc_1400060A0+4
.data:0000000140006097                 jmp     short loc_14000607B
.data:0000000140006097 ; ---------------------------------------------------------------------------
.data:0000000140006099                 db 0FDh
.data:000000014000609A ; ---------------------------------------------------------------------------
.data:000000014000609A
.data:000000014000609A loc_14000609A:                          ; CODE XREF: .data:00000001400060B6↓j
.data:000000014000609A                 jmp     short loc_1400060BB
.data:000000014000609A ; ---------------------------------------------------------------------------
.data:000000014000609C                 db  3Eh ; >
.data:000000014000609D ; ---------------------------------------------------------------------------
.data:000000014000609D
.data:000000014000609D loc_14000609D:                          ; CODE XREF: .data:0000000140006093↑j
.data:000000014000609D                 sbb     al, 0EBh
.data:000000014000609D ; ---------------------------------------------------------------------------
.data:000000014000609F                 db 0EBh
.data:00000001400060A0 ; ---------------------------------------------------------------------------
.data:00000001400060A0
.data:00000001400060A0 loc_1400060A0:                          ; CODE XREF: .data:0000000140006091↑j
.data:00000001400060A0                                         ; .data:0000000140006095↑j
.data:00000001400060A0                 mov     ecx, 0F88DDF46h
.data:00000001400060A5                 call    near ptr unk_14000660F
.data:00000001400060AA                 mov     rbx, rax
.data:00000001400060AD                 cmp     edx, 0FFFFFFF5h
.data:00000001400060B0                 jnz     short near ptr loc_1400060BE+1
.data:00000001400060B2                 jz      short loc_1400060B9
.data:000000014000607B loc_14000607B:                          ; CODE XREF: .data:0000000140006097↓j
.data:000000014000607B                 push    rbx
.data:000000014000607D                 push    rsi
.data:000000014000607E                 push    rdi
.data:000000014000607F                 push    r12
.data:0000000140006081                 push    r13
.data:0000000140006083                 push    r14
.data:0000000140006085                 push    r15
.data:0000000140006087                 sub     rsp, 2C0h
.data:000000014000608E                 cmp     esi, 0FFFFFFF5h
.data:0000000140006091                 jnz     short loc_1400060A0
.data:0000000140006093                 jz      short loc_14000609D
.data:0000000140006095                 jbe     short near ptr loc_1400060A0+4
.data:0000000140006097                 jmp     short loc_14000607B
.data:0000000140006097 ; ---------------------------------------------------------------------------
.data:0000000140006099                 db 0FDh
.data:000000014000609A ; ---------------------------------------------------------------------------
.data:000000014000609A
.data:000000014000609A loc_14000609A:                          ; CODE XREF: .data:00000001400060B6↓j
.data:000000014000609A                 jmp     short loc_1400060BB
.data:000000014000609A ; ---------------------------------------------------------------------------
.data:000000014000609C                 db  3Eh ; >
.data:000000014000609D ; ---------------------------------------------------------------------------
.data:000000014000609D
.data:000000014000609D loc_14000609D:                          ; CODE XREF: .data:0000000140006093↑j
.data:000000014000609D                 sbb     al, 0EBh
.data:000000014000609D ; ---------------------------------------------------------------------------
.data:000000014000609F                 db 0EBh
.data:00000001400060A0 ; ---------------------------------------------------------------------------
.data:00000001400060A0
.data:00000001400060A0 loc_1400060A0:                          ; CODE XREF: .data:0000000140006091↑j
.data:00000001400060A0                                         ; .data:0000000140006095↑j
.data:00000001400060A0                 mov     ecx, 0F88DDF46h
.data:00000001400060A5                 call    near ptr unk_14000660F
.data:00000001400060AA                 mov     rbx, rax
.data:00000001400060AD                 cmp     edx, 0FFFFFFF5h
.data:00000001400060B0                 jnz     short near ptr loc_1400060BE+1
.data:00000001400060B2                 jz      short loc_1400060B9
import idaapi
import keystone
ks = keystone.Ks(keystone.KS_ARCH_X86, keystone.KS_MODE_LITTLE_ENDIAN | keystone.KS_MODE_64)
 
obf_start = 0x14000607B
obf_end = 0x140006050+0xED3
 
insn_bytes, size = ks.asm('call 0x14000605A', 0x140006054)
idaapi.patch_bytes(0x140006054, bytes(insn_bytes)+b'\x90')
 
def patch_2a():
    pos = 0x14000607B
    size = 0xEA7
    for i in range(0xEA7):
        c = idaapi.get_byte(pos)
        if c == 0x2a:
            idaapi.patch_byte(pos, 0)
        pos += 1
patch_2a()
 
def is_cond_jmp(insn: idaapi.insn_t):
    return insn.itype >= idaapi.NN_ja and insn.itype <= idaapi.NN_jz
 
def get_target(insn: idaapi.insn_t):
    if insn.Op1.type == idaapi.o_near or insn.Op1.type == idaapi.o_far:
        return insn.Op1.addr
    print("get_target error at", hex(insn.ea))
    raise Exception("get_target error at " + hex(insn.ea))
 
def do_deobf():
    visited_blocks = []
    blocks = []
    visited_blocks.append(obf_start)
    blocks.append(obf_start)
    cur_insn = idaapi.insn_t()
    t_insn = idaapi.insn_t()
    while len(blocks) > 0:
        cur_ea = blocks.pop()
        while 1:
            idaapi.auto_make_code(cur_ea)
            insn_size = idaapi.decode_insn(cur_insn, cur_ea)
            if insn_size == 0:
                raise Exception('error decoding inst at', hex(cur_ea))
             
            if cur_insn.itype == idaapi.NN_jmp:
                jmp_target = get_target(cur_insn)
                if jmp_target not in visited_blocks:
                    visited_blocks.append(jmp_target)
                    blocks.append(jmp_target)
                break
             
            # jnz label
            # jz..
            # ...
            # label
            #  |
            #  v
            # jmp label
            # nop...
            # label
            if cur_insn.itype == idaapi.NN_jnz:
                idaapi.decode_insn(t_insn, cur_insn.ea+cur_insn.size)
                if t_insn.itype == idaapi.NN_jz:
                    assert(cur_insn.Op1.type == idaapi.o_near)
                    jmp_target = cur_insn.Op1.addr
                    insn_bytes, _ = ks.asm('jmp ' + str(jmp_target-cur_insn.ea))
                    size = jmp_target - cur_insn.ea - len(insn_bytes)
                    insn_bytes = bytes(insn_bytes)+b'\x90'*size
                    idaapi.patch_bytes(cur_insn.ea, insn_bytes)
                    if jmp_target not in visited_blocks:
                        visited_blocks.append(jmp_target)
                        blocks.append(jmp_target)
                    break
             
            if is_cond_jmp(cur_insn):
                jmp_target = get_target(cur_insn)
                if jmp_target not in visited_blocks:
                    visited_blocks.append(jmp_target)
                    blocks.append(jmp_target)
            elif cur_insn.itype == idaapi.NN_call and cur_insn.Op1.type == idaapi.o_near:
                call_target = get_target(cur_insn)
                if call_target not in visited_blocks:
                    visited_blocks.append(call_target)
                    blocks.append(call_target)
             
            if cur_insn.itype == idaapi.NN_retn:
                break
            if cur_insn.ea > obf_end:
                break
            cur_ea += insn_size
    idaapi.del_items(obf_start, nbytes=obf_end-obf_start)
    idaapi.auto_make_proc(obf_start)
    print('fin')
 
do_deobf()
import idaapi
import keystone
ks = keystone.Ks(keystone.KS_ARCH_X86, keystone.KS_MODE_LITTLE_ENDIAN | keystone.KS_MODE_64)
 
obf_start = 0x14000607B
obf_end = 0x140006050+0xED3
 
insn_bytes, size = ks.asm('call 0x14000605A', 0x140006054)
idaapi.patch_bytes(0x140006054, bytes(insn_bytes)+b'\x90')
 
def patch_2a():
    pos = 0x14000607B
    size = 0xEA7
    for i in range(0xEA7):
        c = idaapi.get_byte(pos)
        if c == 0x2a:
            idaapi.patch_byte(pos, 0)
        pos += 1
patch_2a()
 
def is_cond_jmp(insn: idaapi.insn_t):
    return insn.itype >= idaapi.NN_ja and insn.itype <= idaapi.NN_jz
 
def get_target(insn: idaapi.insn_t):
    if insn.Op1.type == idaapi.o_near or insn.Op1.type == idaapi.o_far:
        return insn.Op1.addr
    print("get_target error at", hex(insn.ea))
    raise Exception("get_target error at " + hex(insn.ea))
 
def do_deobf():
    visited_blocks = []
    blocks = []
    visited_blocks.append(obf_start)
    blocks.append(obf_start)
    cur_insn = idaapi.insn_t()
    t_insn = idaapi.insn_t()
    while len(blocks) > 0:
        cur_ea = blocks.pop()
        while 1:
            idaapi.auto_make_code(cur_ea)
            insn_size = idaapi.decode_insn(cur_insn, cur_ea)
            if insn_size == 0:

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2024-9-6 02:20 被tacesrever编辑 ,原因:
收藏
免费 1
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//