Rev/Write-up

HTB - debugme.exe

zooonique 2021. 1. 13. 20:01
반응형
```c
// positive sp value has been detected, the output may be wrong!
char mainCRTStartup_0()
{
  int v0; // eax
  unsigned __int64 v1; // rax
  int v2; // ebx
  unsigned __int64 v3; // rax
  int (__cdecl *v4)(int, const char **, const char **); // eax

  LOBYTE(v0) = NtCurrentPeb()->BeingDebugged;
  if ( !(_BYTE)v0 )
  {
    LOBYTE(v0) = NtCurrentPeb()->UnicodeCaseTableData;
    if ( !(_BYTE)v0 )
    {
      v1 = __rdtsc();
      v2 = v1;
      v3 = __rdtsc();
      v0 = v3 - v2;
      if ( v0 <= 1000 )
      {
        v4 = main;
        do
        {
          *(_BYTE *)v4 ^= 0x5Cu;
          v4 = (int (__cdecl *)(int, const char **, const char **))((char *)v4 + 1);
        }
        while ( (int)v4 <= (int)sub_401791 );
        mingw_app_type = 0;
        __security_init_cookie();
        LOBYTE(v0) = __tmainCRTStartup();
      }
    }
  }
  return v0;
}
```

 

BeingDebugged와 UnicodeCaseTableData 부분이 안티디버깅함수이므로 이부분에 들어가면 안된다.

 

일단 BeingDebugged에 bp를 걸고, ctrl+n으로 main을 xor하는 부분으로 eip를 컨트롤한다.

 

그 후, xor된 main부분으로 가서 55라는 OPCODE부터 subroutine까지 드래그한후,

Analyze selected area를 처리를 해준다. xor된 main이 어셈블리의 형태로 재해석되고,

그 이후에 함수의 push ebp부분에서 P단축어를 이용해 패킹해주면 main함수를 디컴파일할수있다.

 

int __cdecl main(int argc, const char **argv, const char **envp)
{
  unsigned __int64 v3; // rax
  int v4; // ebx
  unsigned __int64 v5; // rax
  int result; // eax
  _BYTE *v7; // esi
  _BYTE *v8; // edi
  int v9; // ecx
  _DWORD v10[10]; // [esp-28h] [ebp-28h] BYREF

  if ( NtCurrentPeb()->BeingDebugged )
    return printf("Looks like your doing something naughty. Stop it!!!\n");
  if ( LOBYTE(NtCurrentPeb()->UnicodeCaseTableData) )
    return printf("Looks like your doing something naughty. Stop it!!!\n");
  v3 = __rdtsc();
  v4 = v3;
  v5 = __rdtsc();
  if ( (int)v5 - v4 > 1000 )
    return printf("Looks like your doing something naughty. Stop it!!!\n");
  printf("I heard you like bugs so I put bugs in your debugger so you can have bugs while you debug!!!\n");
  printf("Seriously though try and find the flag, you will find it in your debugger!!!\n");
  v10[9] = 0x6A253E2D;
  v10[8] = 0x14191431;
  v10[7] = 0x20282239;
  v10[6] = 0x3F14192E;
  v10[5] = 0xC0C3E29;
  v10[4] = 0x780F147A;
  v10[3] = 0x3F250A14;
  v10[2] = 0x2C252227;
  v10[1] = 0x277B391F;
  v7 = v10;
  v8 = v10;
  v9 = 36;
  result = 0;
  v10[0] = 0;
  do
  {
    LOBYTE(result) = *v7++;
    result ^= 0x4Bu;
    *v8++ = result;
    --v9;
  }
  while ( v9 );
  return result;
}

 

메인함수는 위와같은데, v10에 어떤 문자열들을 넣고 이를 통해 연산작업을 거친다.

 

앞선과정과 동일하게 안티디버깅을 우회할 수 있게 EIP를 컨트롤한다.

 

v10에 문자열을 넣어주는 부분부터 xor하는 부분까지!

 

여기서 내가 실수한 부분은 eip를 컨트롤하는과정에서

 

어셈블리어 코드상으로 컨트롤하는게 더 정확하게 컨트롤을 할 수있다.

 

난 수도코드상에서만 컨트롤하다보니...자꾸 이상한 짓을 했다.

그러고 나면 v8에 플래그가 있다.

 

Tr0ling_Ant1_d3buGGeR_trickz_R_fun!

반응형