Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2026-3805-curl-SMB-UAF — CVE-2026-3805: Use-After-Free in curl SMB connection reuse - heap info disclosure | Kitploit
Tools/GitHubGitHub/rat5ak/cve-2026-3805-curl-smb-uaf
Memory ForensicsVulnerability AnalysisExploitationBinary AnalysisPapers & ResearchLearning & Education
GitHubrat5ak/cve-2026-3805-curl-smb-uaf

CVE-2026-3805-curl-SMB-UAF

CVE-2026-3805: Use-After-Free in curl SMB connection reuse - heap info disclosure

View Repository
122 months agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2026-3805: Use-After-Free in curl SMB Connection Reuse

I found a use-after-free vulnerability in libcurl's SMB protocol handler. When a second SMB transfer reuses an existing connection to the same server, the file path for the new request (req->path) is a dangling pointer to freed heap memory. This memory is read via strlen() and copied into an outgoing SMB packet, leaking heap contents to the server or crashing.

One-line fix: make req->path own its own copy instead of borrowing from the needle's smbc->share.

CVECVE-2026-3805
Bug classUse-After-Free (CWE-416)
Root causereq->path points into needle's smbc->share, freed on connection reuse
Introduced777c5209df (2025-04-30) - curl 8.13.0
Fixede090be9f73a7a71459ef678c - curl 8.19.0 (Mar 11, 2026)
Affectedcurl 8.13.0 through 8.18.0
ImpactHeap information disclosure to server, crash
Severity7.5 - HIGH - CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

TL;DR

smb_setup_connection() runs on a temporary "needle" connection used for cache lookup. It sets req->path to point inside smbc->share (heap memory owned by the needle). When the connection cache finds a reusable connection, the needle is destroyed - freeing smbc->share - but req->path survives on the easy handle, now dangling.

When smb_send_open() builds the SMB OPEN request, it calls strlen(req->path) and copies the result into the outgoing packet. Whatever data is in that freed heap region goes to the server. If the attacker controls the server (SSRF, or user connecting to malicious SMB), they receive the leaked heap contents as the "filename" in the SMB NT_CREATE_ANDX request.


Background: curl Connection Reuse

libcurl aggressively reuses connections for performance. When you make multiple requests to the same host, curl checks if an existing connection can be reused rather than establishing a new one. The mechanism works like this:

  1. Create a temporary "needle" connection with the new request's parameters
  2. Search the connection cache for a matching connection
  3. If found: reuse the existing connection, destroy the needle
  4. If not found: the needle becomes the actual connection

The SMB protocol handler stores state in two places:

  • smbc (connection state) on the connection's meta_hash
  • req (request state) on the easy handle's meta

The bug: req->path is set to point inside smbc->share during needle setup. When the needle is destroyed on reuse, smbc->share is freed, but req->path still points there.

The Bug

In smb_parse_url_path(), the code parses the SMB URL path and splits it into share name and file path:

root@kitploit:~
// lib/smb.c, smb_parse_url_path() line 431:
smbc->share = curlx_strdup((*path == '/' || *path == '\\') ? path + 1 : path);
// ...
*slash++ = 0;
req->path = slash;   // <--- points into smbc->share on the NEEDLE

For URL smb://server/share1/file1.txt, this creates:

  • smbc->share = "share1\0file1.txt" (heap allocated, owned by needle)
  • req->path = pointer to "file1.txt" (inside smbc->share)

When connection reuse triggers:

root@kitploit:~
// lib/url.c, url_find_or_create_conn() line 3619:
out:
  if(needle)
    Curl_conn_free(data, needle);  // Destroys needle -> frees smbc->share

Curl_conn_free() calls Curl_hash_destroy(&conn->meta_hash) which invokes smb_conn_dtor(), freeing smbc->share. But req->path (on the easy handle, which survives) still points into the now-freed memory.

When the SMB request proceeds:

root@kitploit:~
// lib/smb.c, smb_send_open() line 750-769:
const size_t byte_count = strlen(req->path) + 1;    // UAF READ
// ...
curlx_strcopy(msg.bytes, sizeof(msg.bytes), req->path, byte_count - 1);  // UAF READ

Impact

Information Disclosure

The freed heap memory may have been reallocated and contain sensitive data. strlen(req->path) scans forward until it hits a null byte, and curlx_strcopy() copies that content into the SMB packet sent to the server.

Attack scenario: SSRF where the attacker controls the SMB server. The victim application makes two SMB requests to the attacker's server. The second request leaks heap contents as the "filename" in the SMB OPEN request.

Denial of Service

If the freed memory has been returned to the OS (unmapped), strlen() triggers a SIGSEGV/access violation.

Secondary Bug: Wrong Share

Even without the UAF, SMB connection reuse is semantically broken. smb_send_tree_connect() uses smbc->share from the reused connection (the old share), not the new request's share. The TREE_CONNECT goes to the wrong share entirely.


Reproduction

Via curl CLI

root@kitploit:~
# Two SMB URLs to the same server, different shares/files:
curl smb://192.168.1.100/share1/file1.txt -o /dev/null \
     smb://192.168.1.100/share2/file2.txt -o /dev/null

Via libcurl (multi-handle)

root@kitploit:~
CURLM *multi = curl_multi_init();

CURL *e1 = curl_easy_init();
curl_easy_setopt(e1, CURLOPT_URL, "smb://server/share1/file1");
curl_multi_add_handle(multi, e1);

CURL *e2 = curl_easy_init();
curl_easy_setopt(e2, CURLOPT_URL, "smb://server/share2/file2");
curl_multi_add_handle(multi, e2);

// When e2 runs after e1 completes and reuses the connection: UAF

With AddressSanitizer

Build curl with -fsanitize=address and run the above:

root@kitploit:~
==PID==ERROR: AddressSanitizer: heap-use-after-free on address 0x...
READ of size 1 at 0x... thread T0
    #0 strlen
    #1 smb_send_open lib/smb.c:750
    #2 smb_request_state lib/smb.c:1163
    ...

freed by thread T0 here:
    #0 free
    #1 smb_conn_dtor lib/smb.c:388
    #2 Curl_hash_destroy
    #3 Curl_conn_free lib/url.c:557

See poc/REPRODUCE_UAF.sh for the full reproduction script.


The Fix

The fundamental issue is that req->path borrows a pointer into memory owned by the needle's smbc. The fix makes req->path own its own copy:

root@kitploit:~
--- a/lib/smb.c
+++ b/lib/smb.c
@@ -378,7 +378,7 @@ static void smb_easy_dtor(void *key, size_t klen, void *entry)
   (void)key;
   (void)klen;
+  curlx_free(req->path);
   curlx_free(req);
 }

@@ -428,7 +428,10 @@ static CURLcode smb_parse_url_path(struct Curl_easy *data,
   /* Parse the path for the file path converting any forward slashes into
      backslashes */
   *slash++ = 0;
-  req->path = slash;
+  req->path = curlx_strdup(slash);
+  if(!req->path) {
+    Curl_safefree(smbc->share);
+    return CURLE_OUT_OF_MEMORY;
+  }

Stefan Eissing implemented the official fix in e090be9f73a7a71459ef678c.


Developer Awareness

The developers were partially aware of the dangling pointer risk. This comment exists in smb_easy_dtor():

root@kitploit:~
/* `req->path` points to somewhere in `struct smb_conn` which is
 * kept at the connection meta. If the connection is destroyed first,
 * req->path points to free'd memory. */

But this only considers the scenario where the connection is destroyed before the easy handle. It missed the needle destruction during connection reuse scenario, which is the actual trigger.


Timeline

DateEvent

Affected Configuration

  • SMB must be enabled: !defined(CURL_DISABLE_SMB)
  • NTLM core must be available: defined(USE_CURL_NTLM_CORE)
  • sizeof(curl_off_t) > 4 (64-bit off_t, standard on most platforms)

SMB is enabled by default in curl builds that have NTLM support.


Resources

  • Fix commit: e090be9f73a7a71459ef678c
  • Official advisory: curl.se/docs/CVE-2026-3805.html
  • HackerOne report: #3591944
  • Introducing commit: 777c5209df

CVE-2026-3805 - Fixed in curl 8.19.0. Affected: 8.13.0 through 8.18.0.

Daniel Wade - GitHub - [email protected]

Download Tool
2025-04-30777c5209df refactors SMB to use meta hash, introducing the bug
2026-03-07I find the bug during security audit
2026-03-08Reported to curl via HackerOne (#3591944)
2026-03-08curl contacts distros@openwall
2026-03-11curl 8.19.0 released with fix, CVE-2026-3805 published