Description
================================================================================
DESCRIPTION:
================================================================================
## Summary:
I discovered a heap buffer over-read vulnerability in libcurl's SMB protocol
implementation. A malicious SMB server can send a specially crafted READ_ANDX
response that causes curl to read and output up to 28KB of uninitialized heap
memory per request. This results in information disclosure to the attacker.
The vulnerability exists in lib/smb.c within the smb_request_state() function,
specifically in the SMB_DOWNLOAD state handler at lines 1110-1137.
No AI was used to discover this vulnerability. AI was used only to assist
with report formatting.
## Technical Analysis:
**Vulnerable Code (lib/smb.c lines 1116-1128):**
```c
case SMB_DOWNLOAD:
if(h->status || smbc->got < sizeof(struct smb_header) + 15) {
req->result = CURLE_RECV_ERROR;
next_state = SMB_CLOSE;
break;
}
// [1] Values read directly from attacker-controlled server response
len = Curl_read16_le(((const unsigned char *)msg) +
sizeof(struct smb_header) + 11);
off = Curl_read16_le(((const unsigned char *)msg) +
sizeof(struct smb_header) + 13);
if(len > 0) {
// [2] Bounds check validates against smbc->got (total received bytes)
if(off + sizeof(unsigned int) + len > smbc->got) {
failf(data, "Invalid input packet");
result = CURLE_RECV_ERROR;
}
else
// [3] Out-of-bounds read occurs here - reads heap memory
result = Curl_client_write(data, CLIENTWRITE_BODY,
(char *)msg + off + sizeof(unsigned int),
len);
```
**Root Cause:**
1. The attacker controls the NetBIOS header length field, allowing them to
claim a large message size (e.g., 0x7100 bytes)
2. The attacker pads the response with null bytes to make smbc->got match
the claimed size
3. The attacker sets data_offset and data_length to read from any position
within the receive buffer
4. The bounds check at [2] passes because off + 4 + len <= smbc->got
5. curl reads len bytes from msg + off + 4, which includes uninitialized
heap memory beyond the actual SMB response data
**Result:** curl outputs ~28KB when the server only sent 256 bytes of
legitimate data. The extra ~28KB is leaked heap memory.
## Affected version:
```
$ curl -V
curl 8.15.0 (x86_64-pc-linux-gnu) libcurl/8.15.0 OpenSSL/3.5.4 zlib/1.3.1
brotli/1.1.0 zstd/1.5.7 libidn2/2.3.8 libpsl/0.21.2 libssh2/1.11.1
nghttp2/1.64.0 nghttp3/1.12.0 librtmp/2.3 OpenLDAP/2.6.10
Release-Date: 2025-07-16
Protocols: dict file ftp ftps gopher gophers http https imap imaps ipfs
ipns ldap ldaps mqtt pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps
telnet tftp ws wss
Features: alt-svc AsynchDNS brotli GSS-API HSTS HTTP2 HTTP3 HTTPS-proxy
IDN IPv6 Kerberos Largefile libz NTLM PSL SPNEGO SSL threadsafe TLS-SRP
UnixSockets zstd
Platform: Linux x86_64 (Kali GNU/Linux Rolling)
```
All curl versions with SMB support enabled (USE_CURL_NTLM_CORE defined)
are likely affected.
## Steps To Reproduce:
1. Extract the attached PoC files to a directory
2. Run the automated exploit script:
```
chmod +x run_exploit.sh
./run_exploit.sh
```
3. Or manually:
Terminal 1 - Start malicious server:
```
python3 smb_exploit_server.py 4455
```
Terminal 2 - Connect with curl:
```
curl -u anyuser:anypass -o leaked.bin smb://127.0.0.1:4455/share/file.txt
```
Terminal 2 - Verify the leak:
```
ls -la leaked.bin
# Shows: 28672 bytes (server only sent 256)
xxd leaked.bin | head -20
# First 256 bytes are 'A' (0x41), rest is heap memory
```
4. Expected output:
```
$ ls -la leaked.bin
-rw-rw-r-- 1 user user 28672 Dec 18 13:00 leaked.bin
$ xxd leaked.bin | head -20
00000000: 4141 4141 4141 4141 4141 4141 4141 4141 AAAAAAAAAAAAAAAA
00000010: 4141 4141 4141 4141 4141 4141 4141 4141 AAAAAAAAAAAAAAAA
... (256 bytes of 'A')
00000100: 0000 0000 0000 0000 0000 0000 0000 0000 ................
... (heap memory - 28416 bytes leaked)
```
## Supporting Material/References:
* smb_exploit_server.py - Malicious SMB server (Python 3)
* run_exploit.sh - Automated PoC runner script
* Vulnerable code: https://github.com/curl/curl/blob/master/lib/smb.c#L1110-L1137
* Buffer allocation: https://github.com/curl/curl/blob/master/lib/smb.c#L505
## Impact
================================================================================
IMPACT:
================================================================================
**Severity: Medium (CVSS 6.5)**
**CWE-125: Out-of-bounds Read**
A remote attacker operating a malicious SMB server can exploit this
vulnerability to achieve:
**1. Heap Memory Disclosure**
The attacker can exfiltrate up to 28KB of heap memory from the curl client
process per SMB READ request. This memory may contain:
- Authentication credentials from previous HTTP/FTP requests
- Session tokens and API keys
- Private data from other network operations
- Memory layout information useful for further exploitation
**2. Attack Vectors**
- Phishing: Send victim a link to smb://attacker-server/share/file.txt
- Typosquatting: Register domains similar to legitimate SMB servers
- Man-in-the-Middle: Intercept SMB connections and inject malicious responses
- Compromised Infrastructure: Attacker compromises an internal SMB server
**3. Exploitation Requirements**
- Victim must connect to attacker-controlled SMB server
- curl must be compiled with SMB support (common in Linux distributions)
- No authentication required - server accepts any credentials
- No user interaction beyond clicking a link
- Attack is silent - victim receives no error messages
**4. Proof of Exploitation**
The attached PoC demonstrates:
- Server sends 256 bytes of legitimate data
- curl receives and outputs 28,672 bytes
- 28,416 bytes of heap memory are leaked
**Recommended Fix:**
Validate that data_offset points within the actual SMB READ_ANDX response
structure, not just within the total received bytes. The offset should be
checked against the expected message layout and byte_count field.
DESCRIPTION:
================================================================================
## Summary:
I discovered a heap buffer over-read vulnerability in libcurl's SMB protocol
implementation. A malicious SMB server can send a specially crafted READ_ANDX
response that causes curl to read and output up to 28KB of uninitialized heap
memory per request. This results in information disclosure to the attacker.
The vulnerability exists in lib/smb.c within the smb_request_state() function,
specifically in the SMB_DOWNLOAD state handler at lines 1110-1137.
No AI was used to discover this vulnerability. AI was used only to assist
with report formatting.
## Technical Analysis:
**Vulnerable Code (lib/smb.c lines 1116-1128):**
```c
case SMB_DOWNLOAD:
if(h->status || smbc->got < sizeof(struct smb_header) + 15) {
req->result = CURLE_RECV_ERROR;
next_state = SMB_CLOSE;
break;
}
// [1] Values read directly from attacker-controlled server response
len = Curl_read16_le(((const unsigned char *)msg) +
sizeof(struct smb_header) + 11);
off = Curl_read16_le(((const unsigned char *)msg) +
sizeof(struct smb_header) + 13);
if(len > 0) {
// [2] Bounds check validates against smbc->got (total received bytes)
if(off + sizeof(unsigned int) + len > smbc->got) {
failf(data, "Invalid input packet");
result = CURLE_RECV_ERROR;
}
else
// [3] Out-of-bounds read occurs here - reads heap memory
result = Curl_client_write(data, CLIENTWRITE_BODY,
(char *)msg + off + sizeof(unsigned int),
len);
```
**Root Cause:**
1. The attacker controls the NetBIOS header length field, allowing them to
claim a large message size (e.g., 0x7100 bytes)
2. The attacker pads the response with null bytes to make smbc->got match
the claimed size
3. The attacker sets data_offset and data_length to read from any position
within the receive buffer
4. The bounds check at [2] passes because off + 4 + len <= smbc->got
5. curl reads len bytes from msg + off + 4, which includes uninitialized
heap memory beyond the actual SMB response data
**Result:** curl outputs ~28KB when the server only sent 256 bytes of
legitimate data. The extra ~28KB is leaked heap memory.
## Affected version:
```
$ curl -V
curl 8.15.0 (x86_64-pc-linux-gnu) libcurl/8.15.0 OpenSSL/3.5.4 zlib/1.3.1
brotli/1.1.0 zstd/1.5.7 libidn2/2.3.8 libpsl/0.21.2 libssh2/1.11.1
nghttp2/1.64.0 nghttp3/1.12.0 librtmp/2.3 OpenLDAP/2.6.10
Release-Date: 2025-07-16
Protocols: dict file ftp ftps gopher gophers http https imap imaps ipfs
ipns ldap ldaps mqtt pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps
telnet tftp ws wss
Features: alt-svc AsynchDNS brotli GSS-API HSTS HTTP2 HTTP3 HTTPS-proxy
IDN IPv6 Kerberos Largefile libz NTLM PSL SPNEGO SSL threadsafe TLS-SRP
UnixSockets zstd
Platform: Linux x86_64 (Kali GNU/Linux Rolling)
```
All curl versions with SMB support enabled (USE_CURL_NTLM_CORE defined)
are likely affected.
## Steps To Reproduce:
1. Extract the attached PoC files to a directory
2. Run the automated exploit script:
```
chmod +x run_exploit.sh
./run_exploit.sh
```
3. Or manually:
Terminal 1 - Start malicious server:
```
python3 smb_exploit_server.py 4455
```
Terminal 2 - Connect with curl:
```
curl -u anyuser:anypass -o leaked.bin smb://127.0.0.1:4455/share/file.txt
```
Terminal 2 - Verify the leak:
```
ls -la leaked.bin
# Shows: 28672 bytes (server only sent 256)
xxd leaked.bin | head -20
# First 256 bytes are 'A' (0x41), rest is heap memory
```
4. Expected output:
```
$ ls -la leaked.bin
-rw-rw-r-- 1 user user 28672 Dec 18 13:00 leaked.bin
$ xxd leaked.bin | head -20
00000000: 4141 4141 4141 4141 4141 4141 4141 4141 AAAAAAAAAAAAAAAA
00000010: 4141 4141 4141 4141 4141 4141 4141 4141 AAAAAAAAAAAAAAAA
... (256 bytes of 'A')
00000100: 0000 0000 0000 0000 0000 0000 0000 0000 ................
... (heap memory - 28416 bytes leaked)
```
## Supporting Material/References:
* smb_exploit_server.py - Malicious SMB server (Python 3)
* run_exploit.sh - Automated PoC runner script
* Vulnerable code: https://github.com/curl/curl/blob/master/lib/smb.c#L1110-L1137
* Buffer allocation: https://github.com/curl/curl/blob/master/lib/smb.c#L505
## Impact
================================================================================
IMPACT:
================================================================================
**Severity: Medium (CVSS 6.5)**
**CWE-125: Out-of-bounds Read**
A remote attacker operating a malicious SMB server can exploit this
vulnerability to achieve:
**1. Heap Memory Disclosure**
The attacker can exfiltrate up to 28KB of heap memory from the curl client
process per SMB READ request. This memory may contain:
- Authentication credentials from previous HTTP/FTP requests
- Session tokens and API keys
- Private data from other network operations
- Memory layout information useful for further exploitation
**2. Attack Vectors**
- Phishing: Send victim a link to smb://attacker-server/share/file.txt
- Typosquatting: Register domains similar to legitimate SMB servers
- Man-in-the-Middle: Intercept SMB connections and inject malicious responses
- Compromised Infrastructure: Attacker compromises an internal SMB server
**3. Exploitation Requirements**
- Victim must connect to attacker-controlled SMB server
- curl must be compiled with SMB support (common in Linux distributions)
- No authentication required - server accepts any credentials
- No user interaction beyond clicking a link
- Attack is silent - victim receives no error messages
**4. Proof of Exploitation**
The attached PoC demonstrates:
- Server sends 256 bytes of legitimate data
- curl receives and outputs 28,672 bytes
- 28,416 bytes of heap memory are leaked
**Recommended Fix:**
Validate that data_offset points within the actual SMB READ_ANDX response
structure, not just within the total received bytes. The offset should be
checked against the expected message layout and byte_count field.
Basic Information
ID
H1:3470095
Published
Dec 18, 2025 at 11:38
Modified
Dec 20, 2025 at 15:57