curl · Report #3480712
Telnet Suboption Buffer Pointer Underflow in lib/telnet.c leads to Out-of-Bounds Read
How it was found
Summary
A buffer pointer underflow vulnerability exists in curl's telnet protocol handler (lib/telnet.c). When processing telnet suboptions in the CURL_TS_SE state, the code unconditionally decrements the suboption buffer pointer by 2 (subpointer -= 2), even when the CURL_SB_ACCUM macro skips writing due to a full buffer. This leads to an out-of-bounds read when suboption() and printsub() are subsequently called.
Affected Version
- All curl versions with telnet support containing this code pattern
- Tested on latest curl source from GitHub (master branch)
- File:
lib/telnet.c - Vulnerable lines: 1210 and 1226
Technical Analysis
Vulnerable Code Pattern
In lib/telnet.c, the CURL_SB_ACCUM macro (lines 69-73) conditionally writes to the buffer:
#define CURL_SB_ACCUM(x, c) \
do { \
if(x->subpointer < (x->subbuffer + sizeof(x->subbuffer))) \
*x->subpointer++ = (c); \
} while(0)
However, in the CURL_TS_SE state handling (lines 1207-1211 and 1223-1227), the pointer decrement is unconditional:
Path 1 (line 1207-1211):
CURL_SB_ACCUM(tn, CURL_IAC);
CURL_SB_ACCUM(tn, c);
tn->subpointer -= 2; // UNCONDITIONAL - causes underflow when buffer is full
CURL_SB_TERM(tn);
Path 2 (line 1223-1227):
CURL_SB_ACCUM(tn, CURL_IAC);
CURL_SB_ACCUM(tn, CURL_SE);
tn->subpointer -= 2; // UNCONDITIONAL - causes underflow when buffer is full
CURL_SB_TERM(tn);
Exploitation Flow
- Malicious telnet server sends suboption data to fill the 512-byte buffer (
SUBBUFSIZE) - Server sends
IACfollowed by another byte while buffer is full CURL_SB_ACCUMmacro does nothing (buffer full check passes)subpointer -= 2executes unconditionally, causing pointer underflowCURL_SB_TERMsetssubend = subpointer(now pointing before buffer start)suboption()is called with corrupted pointerCURL_SB_LENmacro calculates negative/wrapped lengthprintsub()reads out-of-bounds memory in verbose mode
Memory Layout (struct TELNET)
struct TELNET {
// ... other fields ...
struct dynbuf out; // Contains heap pointers
unsigned char subbuffer[512]; // The suboption buffer
unsigned char *subpointer; // Points into subbuffer
unsigned char *subend; // End marker
// ...
};
When subpointer underflows, it points to the dynbuf out structure, which contains heap pointers that may be leaked.
Steps To Reproduce
-
Save the attached PoC script as
curl_telnet_poc.py -
Run the malicious telnet server:
python3 curl_telnet_poc.py -p 2323
- In another terminal, connect with curl in verbose mode:
curl -v telnet://127.0.0.1:2323
-
Observe the verbose output for:
- Anomalous suboption data in the output
- Potential non-printable characters indicating memory leak
- Possible crash (depending on memory layout)
-
For better observation, build curl with AddressSanitizer:
./configure CFLAGS="-fsanitize=address -g"
make
./src/curl -v telnet://127.0.0.1:2323
ASan should report an out-of-bounds read.
Supporting Material/References
- Attached:
curl_telnet_poc.py- Python PoC server script - Source file: https://github.com/curl/curl/blob/master/lib/telnet.c
- Vulnerable lines: 1210, 1226
- Related macros: lines 63-76 (CURL_SB_CLEAR, CURL_SB_TERM, CURL_SB_ACCUM, CURL_SB_GET, CURL_SB_LEN)
## Impact
## Impact
### Security Impact
1. **Information Disclosure (Low-Medium)**: When curl is run in verbose mode (`-v`), the `printsub()` function may read and display memory contents from before the suboption buffer. This could potentially leak:
- Heap pointers (useful for ASLR bypass in chained exploits)
- Contents of the `dynbuf out` structure
- Other sensitive data in adjacent memory
2. **Denial of Service (Low)**: Depending on memory layout and access patterns, the out-of-bounds read could cause a crash.
### Attack Scenario
An attacker controlling a malicious telnet server could:
1. Wait for a victim to connect using `curl -v telnet://malicious-server`
2. Send crafted telnet suboption data to trigger the vulnerability
3. Potentially observe leaked memory contents in error messages or logs
4. Use leaked heap pointers to aid in exploiting other vulnerabilities
### Limitations
- Requires victim to connect to attacker-controlled telnet server
- Most impactful in verbose mode (`-v` flag)
- Telnet protocol is deprecated and rarely used
- No direct code execution capability