Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LwIP is vulnerable to CVE-2004-0230 #14

Closed
tabascoeye opened this issue Sep 9, 2014 · 1 comment
Closed

LwIP is vulnerable to CVE-2004-0230 #14

tabascoeye opened this issue Sep 9, 2014 · 1 comment

Comments

@tabascoeye
Copy link
Owner

The TCP processing accepts RST packets which roughly fall into the ACK window instead of only accepting an RST packet if the seqno. is an exact match.

This is not a too big issue because an attacker would still have to guess around before hitting into the window, but it is still not too nice.

Some big players like most Linux distros still did not fix this issue because it is mainly bad for long lasting connections (e.g.BGP routes).

Still, fixing this in LwIP shouldn't be complicated (see the FreeBSD solution) and feasable

@tabascoeye
Copy link
Owner Author

Suggested simple fix (also the way FreeBSD fixed it):

If an RST is sent out of sequence, only answer with an ACK and wait for a re-send with the correct seq.no.
That way, the attacker would have to guess the absolute correct seq.no. instead of only hitting inside the receive window.

Change in tcp_inc.c in function tcp_process():

  /* Process incoming RST segments. */
  if (flags & TCP_RST) {
    /* First, determine if the reset is acceptable. */
    if (ackno == pcb->snd_nxt) {
      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: Connection RESET\n"));
      LWIP_ASSERT("tcp_input: pcb->state != CLOSED", pcb->state != CLOSED);
      recv_flags |= TF_RESET;
      pcb->flags &= ~TF_ACK_DELAY;
      return ERR_RST;
    } else {
      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n",
       seqno, pcb->rcv_nxt));
      LWIP_DEBUGF(TCP_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n",
       seqno, pcb->rcv_nxt));
      tcp_ack_now(pcb); //only send an ACK and wait for correct seqno. on RST packet ==> protection against RST spoofing (SVE-2004-0230)
      return ERR_OK;
    }
  }

tabascoeye added a commit that referenced this issue Oct 16, 2014
this relates to the fix for #14.
I forgot to change the sequence number, the ACK will have.
When the ACK is sent, the seq. no needs to be fitting to the first RST the peer sent, so that the nes RST will then hopefully fit THAT sequence no. exactly.
Before this, hte result was a RST<->ACK ping-pong because the peer kept re-sending and the seq no. kept not matching endlessly.
tabascoeye added a commit that referenced this issue Nov 19, 2014
This (again) relates to #14
Last two fixes, I used the wrong if statement (ackno == pcb->snd_nxt) which is only relevant for the SYN_SENT special case, not the normal ESTABLISHED state.
In that case, the seqno has to match the expected one.
If not, an ACK is sent (unmodified not like the last change)

This creates the correct and expected behavior in my lab setup and still fixes the vulnerability that CVE-2004-0230 describes
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant