ipwn

[CODEGATE 2018] BaskinRobins31 본문

CTF's/CODEGATE

[CODEGATE 2018] BaskinRobins31

ipwn 2018. 3. 2. 23:50

이번에 작성할 Writeup은 코게 2018에 나온 BaskinRobins31이다.


그냥 되게 간단히 풀리는 문제였다.



64bit이며, NX가 걸려있다.


int __cdecl main(int argc, const char **argv, const char **envp)
{
  unsigned int v3; // eax
  unsigned int v5; // [rsp+8h] [rbp-8h]
  _BOOL4 v6; // [rsp+Ch] [rbp-4h]
 
  setvbuf(stdout, 0LL, 2, 0LL);
  setvbuf(stdin, 0LL, 2, 0LL);
  v3 = time(0LL);
  srand(v3);
  v5 = 31;
  v6 = 0;
  puts("### This game is similar to the BaskinRobins31 game. ###");
  puts("### The one that take the last match win ###");
  printf("There are %u number(s)\n", 31LL);
  while ( (signed int)v5 > )
  {
    if ( v6 )
    {
      my_turn(&v5);
      v6 = 0;
    }
    else
    {
      v6 = (unsigned __int64)your_turn(&v5) != 0;
    }
    printf("remaining number(s) : %i \n", v5);
  }
  if ( v6 )
  {
    puts("Wow! You win!");
    puts("Hint is : ROP");
  }
  else
  {
    puts("You lose!");
  }
  return 0;
}



일단 BaskinRobins31이름 그대로이다 바로 게임을 시작한다.

취약점은 your_turn함수에서 터졌다.


signed __int64 __fastcall your_turn(_DWORD *a1)
{
  signed __int64 result; // rax
  char s; // [rsp+10h] [rbp-B0h]
  size_t n; // [rsp+B0h] [rbp-10h]
  int v4; // [rsp+BCh] [rbp-4h]
 
  v4 = 0;
  memset(&s, 0, 0x96uLL);
  puts("How many numbers do you want to take ? (1-3)");
  n = read(0&s, 0x190uLL);
  write(1&s, n);
  putchar(10);
  v4 = strtoul(&s, 0LL, 10);
  if ( (unsigned int)check_decision((unsigned int)(char)v4, 0LL) )
  {
    *a1 -= v4;
    result = 1LL;
  }
  else
  {
    puts("Don't break the rules...:( ");
    result = 0LL;
  }
  return result;
}



s로부터 ebp까지의 거리는 0xb0인데 입력은 0x190만큼 터진다.

공간도 낭낭한게 바로 익스가 가능할 것 같다.


일단 elf에 system함수가 없으므로, 시나리오는 read함수로 bss에 /bin/sh를 적고, write로 read함수의 주소를 leak해주고 그 leak된 read함수의 주소값을 이용해 read함수를 사용해 read함수의 got에 system함수의 주소를 덮어씌워 줄 것이다.


그러기 위해서는 일단 gadget을 구해야하는데, 32bit rop와는 다르게, 64bit rop는 register을 이용해서 rop를 진행한다.


먼저 사용할 인자 갯수만큼의 필요한 register들을 pop해주고 값을 넣어준 뒤에 함수를실행시키면 인자로 값이 들어간다.

단 인자가 6개를 넘어가는 경우에는 스택을 사용한다고 한다.


일단 gadget을 구해보겠다.


read함수와 write함수만 사용할 것이니 register를 3개 pop해주는 pop pop pop ret gadget을 구하면 될 것이다.



가젯을 구했다.


이제 system함수의 offset을 구하면 exploit할 수 있을 것 같다.

사실 처음엔 pwntools rop기능 이용해서 푸려고했는데 32bit rop형식으로 값을 채워넣어주길래 그냥 rop기능 안쓰고 풀었다.



offset을 구했다. 이제 exploit해보겠다.


successful!


성공적으로 exploit했다.


flag{The Korean name of "Puss in boots" is "My mom is an alien"}





당연한 얘기지만 local server에서도 쉘이 잘 따진다

'CTF's > CODEGATE' 카테고리의 다른 글

[CODEGATE 2018] betting  (0) 2018.05.17
[CODEGATE 2016] bugbug  (0) 2018.03.26
[CODEGATE 2014] nuclear  (0) 2018.02.02
[CODEGATE 2017] babyMISC  (0) 2018.01.31
[CODEGATE 2014] angry_doraemon  (0) 2018.01.30
Comments