[dreamhack] small counter

Monitor In Secure☃️·2024년 4월 3일

wargame_rev

목록 보기
5/11

[ida에서 디컴파일한 결과]

int __fastcall main(int argc, const char **argv, const char **envp)
{
  __int64 src[10]; // [rsp+0h] [rbp-F0h] BYREF
  char dest[72]; // [rsp+A0h] [rbp-50h] BYREF
  unsigned int i; // [rsp+ECh] [rbp-4h]

  puts("---Counter---");
  for ( i = 10; (int)i > 0; --i )
  {
    printf("%d\n", i);
    if ( i == 3 )
    {
      strcpy((char *)src, "IM{508889j32j87j9jg54650840428hjhi2ii08h74ihj538h543j7g6k5jk8jih22f}");
      memcpy(dest, src, 0x45uLL);
    }
  }
  puts("---END---");
  return 0;
}

memcpy(복사할 구조체 주소, 원본 구조체 주소, 크기) : 정해진 길이만큼 복사. 주로 이진 데이터는 이 함수를 이용하여 처리
strcpy(char str1, const char str2) : str2의 내용을 sr1에 문자열 복사 (\0 만나면 여기까지 복사되고 종료)

-> 10부터 1까지 카운터를 세는데, 만약 i가 3일 경우 strcpy 함수가 사용되면서 위에 있는 지정 문자열을 src 변수에 이를 저장하고, memcpy 함수가 사용되면서 0x45uLL만큼 구조체를 복사한다.


그래프로 확인해보니,

조건에 따라 성공거나 '---END---'가 출력되면서 끝나는 로직이라는 걸 볼 수 있다.

따라서 여기서 중요한 부분은 바로

cmp [rbp+var_4], 5
jnz short loc_15FE

이다.

jnz(Not Zero Jump) : 비교값이 0이 아닌 경우 A로 이동. 비교값이 0인 경우 점프하지 않고 다음 코드 실행

-> [rbp+var_4]가 5이면 flag_gen을 호출한다.

[flag_gen함수 디컴파일 결과]

_BYTE *__fastcall flag_gen(const char *a1, __int64 a2, int a3)
{
  size_t v3; // rbx
  _BYTE *result; // rax
  char v6[64]; // [rsp+20h] [rbp-A0h]
  char v7[32]; // [rsp+60h] [rbp-60h] BYREF
  char v8[35]; // [rsp+80h] [rbp-40h] BYREF
  char v9; // [rsp+A3h] [rbp-1Dh]
  int j; // [rsp+A4h] [rbp-1Ch]
  int i; // [rsp+A8h] [rbp-18h]
  int v12; // [rsp+ACh] [rbp-14h]

  strcpy(v8, "abcdefghijklmnopqrstuvwxyz");
  strcpy(v7, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
  for ( i = 0; i <= 25; ++i )
  {
    v6[(a3 + i) % 26 + 32] = v8[i];
    v6[(a3 + i) % 26] = v7[i];
  }
  v6[i + 32] = 0;
  v6[i] = 0;
  for ( j = 0; ; ++j )
  {
    v3 = j;
    if ( v3 >= strlen(a1) )
      break;
    v9 = a1[j];
    if ( ((*__ctype_b_loc())[v9] & 0x200) != 0 )
    {
      *(_BYTE *)(a2 + j) = v6[v9 - 65];
    }
    else if ( ((*__ctype_b_loc())[v9] & 0x100) != 0 )
    {
      *(_BYTE *)(a2 + j) = v6[v9 - 65];
    }
    else if ( ((*__ctype_b_loc())[v9] & 0x800) != 0 )
    {
      v12 = (a3 + 3) * v9 % 9;
      if ( v12 <= 7 || v12 > 9 )
        v12 += 50;
      else
        v12 += 40;
      *(_BYTE *)(j + a2) = v12;
    }
    else
    {
      *(_BYTE *)(a2 + j) = v9;
    }
  }
  result = (_BYTE *)(a2 + strlen(a1));
  *result = 0;
  return result;
}

... 뭔가 잘하면 여기서 해결할 수 있을 것 같지만, 크게 감이 안오니 gdb로 살펴봐야겠다..

   0x0000000000001494 <+0>:	endbr64 
   0x0000000000001498 <+4>:	push   rbp
   0x0000000000001499 <+5>:	mov    rbp,rsp
   0x000000000000149c <+8>:	sub    rsp,0xf0
   0x00000000000014a3 <+15>:	mov    DWORD PTR [rbp-0x4],0x0
   0x00000000000014aa <+22>:	lea    rax,[rip+0xb53]        # 0x2004
   0x00000000000014b1 <+29>:	mov    rdi,rax
   0x00000000000014b4 <+32>:	call   0x1090 <puts@plt>
   0x00000000000014b9 <+37>:	mov    DWORD PTR [rbp-0x4],0xa
   0x00000000000014c0 <+44>:	jmp    0x15a0 <main+268>
   0x00000000000014c5 <+49>:	mov    eax,DWORD PTR [rbp-0x4]
   0x00000000000014c8 <+52>:	mov    esi,eax
   0x00000000000014ca <+54>:	lea    rax,[rip+0xb41]        # 0x2012
   0x00000000000014d1 <+61>:	mov    rdi,rax
   0x00000000000014d4 <+64>:	mov    eax,0x0
   0x00000000000014d9 <+69>:	call   0x10b0 <printf@plt>
   0x00000000000014de <+74>:	cmp    DWORD PTR [rbp-0x4],0x3
   0x00000000000014e2 <+78>:	jne    0x159c <main+264>
   0x00000000000014e8 <+84>:	movabs rax,0x38383830357b4d49
   0x00000000000014f2 <+94>:	movabs rdx,0x6a37386a32336a39
   0x00000000000014fc <+104>:	mov    QWORD PTR [rbp-0xf0],rax
   0x0000000000001503 <+111>:	mov    QWORD PTR [rbp-0xe8],rdx
   0x000000000000150a <+118>:	movabs rax,0x3035363435676a39
   0x0000000000001514 <+128>:	movabs rdx,0x6a68383234303438
   0x000000000000151e <+138>:	mov    QWORD PTR [rbp-0xe0],rax
   0x0000000000001525 <+145>:	mov    QWORD PTR [rbp-0xd8],rdx
   0x000000000000152c <+152>:	movabs rax,0x6838306969326968
   0x0000000000001536 <+162>:	movabs rdx,0x3833356a68693437
   0x0000000000001540 <+172>:	mov    QWORD PTR [rbp-0xd0],rax
   0x0000000000001547 <+179>:	mov    QWORD PTR [rbp-0xc8],rdx
   0x000000000000154e <+186>:	movabs rax,0x3667376a33343568
   0x0000000000001558 <+196>:	movabs rdx,0x68696a386b6a356b
   0x0000000000001562 <+206>:	mov    QWORD PTR [rbp-0xc0],rax
   0x0000000000001569 <+213>:	mov    QWORD PTR [rbp-0xb8],rdx
   0x0000000000001570 <+220>:	mov    DWORD PTR [rbp-0xb0],0x7d663232
   0x000000000000157a <+230>:	mov    BYTE PTR [rbp-0xac],0x0
   0x0000000000001581 <+237>:	lea    rcx,[rbp-0xf0]
   0x0000000000001588 <+244>:	lea    rax,[rbp-0x50]
   0x000000000000158c <+248>:	mov    edx,0x45
   0x0000000000001591 <+253>:	mov    rsi,rcx
   0x0000000000001594 <+256>:	mov    rdi,rax
   0x0000000000001597 <+259>:	call   0x10c0 <memcpy@plt>
   0x000000000000159c <+264>:	sub    DWORD PTR [rbp-0x4],0x1
   0x00000000000015a0 <+268>:	cmp    DWORD PTR [rbp-0x4],0x0
   0x00000000000015a4 <+272>:	jg     0x14c5 <main+49>
   0x00000000000015aa <+278>:	cmp    DWORD PTR [rbp-0x4],0x5
   0x00000000000015ae <+282>:	jne    0x15fe <main+362>
   0x00000000000015b0 <+284>:	lea    rax,[rip+0xa5f]        # 0x2016
   0x00000000000015b7 <+291>:	mov    rdi,rax
   0x00000000000015ba <+294>:	call   0x1090 <puts@plt>
   0x00000000000015bf <+299>:	mov    eax,DWORD PTR [rbp-0x4]
   0x00000000000015c2 <+302>:	mov    DWORD PTR [rbp-0x8],eax
   0x00000000000015c5 <+305>:	mov    edx,DWORD PTR [rbp-0x8]
   0x00000000000015c8 <+308>:	lea    rcx,[rbp-0xa0]
   0x00000000000015cf <+315>:	lea    rax,[rbp-0x50]
   0x00000000000015d3 <+319>:	mov    rsi,rcx
   0x00000000000015d6 <+322>:	mov    rdi,rax
   0x00000000000015d9 <+325>:	call   0x11c9 <flag_gen>
   0x00000000000015de <+330>:	lea    rax,[rbp-0xa0]
   0x00000000000015e5 <+337>:	mov    rsi,rax
   0x00000000000015e8 <+340>:	lea    rax,[rip+0xa2d]        # 0x201c
   0x00000000000015ef <+347>:	mov    rdi,rax
   0x00000000000015f2 <+350>:	mov    eax,0x0
   0x00000000000015f7 <+355>:	call   0x10b0 <printf@plt>
   0x00000000000015fc <+360>:	jmp    0x160d <main+377>
   0x00000000000015fe <+362>:	lea    rax,[rip+0xa1c]        # 0x2021
   0x0000000000001605 <+369>:	mov    rdi,rax
   0x0000000000001608 <+372>:	call   0x1090 <puts@plt>
   0x000000000000160d <+377>:	mov    eax,0x0
   0x0000000000001612 <+382>:	leave  
   0x0000000000001613 <+383>:	ret    
End of assembler dump.

ida에서 발견했던 것이 gdb에 있는지 확인한 후에 해당 주소에 브레이크를 걸어줘야 한다.

break 후 실행(r)

실행하면 내가 break를 걸어둔 위치까지 실행이 된 상태로 멈춰있는 것을 확인해볼 수 있다. 여기서 jnz의 조건을 맞춰주어 flag 값을 알아내야하기 때문에 [rbp-4]의 주소값을 확인한 후 주소값에 조건에 맞는 값을 삽입한 후 실행하면 된다.


플래그값이 나왔다.

0개의 댓글