HexBrain

curl · Report #3480712

Telnet Suboption Buffer Pointer Underflow in lib/telnet.c leads to Out-of-Bounds Read

Informativestatus
lowseverity
16upvotes
29 Dec 2025disclosed

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

  1. Malicious telnet server sends suboption data to fill the 512-byte buffer (SUBBUFSIZE)
  2. Server sends IAC followed by another byte while buffer is full
  3. CURL_SB_ACCUM macro does nothing (buffer full check passes)
  4. subpointer -= 2 executes unconditionally, causing pointer underflow
  5. CURL_SB_TERM sets subend = subpointer (now pointing before buffer start)
  6. suboption() is called with corrupted pointer
  7. CURL_SB_LEN macro calculates negative/wrapped length
  8. printsub() 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

  1. Save the attached PoC script as curl_telnet_poc.py

  2. Run the malicious telnet server:

python3 curl_telnet_poc.py -p 2323
  1. In another terminal, connect with curl in verbose mode:
curl -v telnet://127.0.0.1:2323
  1. Observe the verbose output for:

    • Anomalous suboption data in the output
    • Potential non-printable characters indicating memory leak
    • Possible crash (depending on memory layout)
  2. 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


## 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

This report was disclosed publicly on HackerOne and belongs to its author and the program. See the original