COMMAND
inetd
SYSTEMS AFFECTED
Linux 1.2.x, 2.0.x
PROBLEM
'moOd' has found that inetd on (*atleast*) Debian distribution of
LiNUX crashes when port 13 (daytime) / port 37 (time) is
"half-open scanned".. This seems to be problem with Linux 1.2.x,
2.0.x.
The problem caused by an implementation of Linux kernel - accept()
returns socket after getting first SYN (for example, BSD returns
socket only after 3-way handshake). If your program uses
getpeername() or getsockname() right after the accept(), it will
detect the situation when socket is not valid (because connection
was cancelled by RST), but in any other case it has big chances to
die due SIGPIPE. So well-written programs aren't affected.
This bug can also affect early sendmail versions (can't remember
exact version, something around 8.7.*). This bug affects ssh,
but ssh does fork() right after accept(), so only child dies.
Half-open scanning means that you:
1) send SYN
2) if reply is SYN|ACK, send RST = port is listening
3) if reply is RST = port is not listening
Most of the new portscanner include this type of scanning method
(scantcp 1.32, sirc, etc.). For code check Phrack 49-07, the
`Vengeance` module:
ftp://www.phrack.com/pub/phrack/phrack49.zip
Aleph One gave following comment. The problem is two fold.
First, inetd is dying because it receives a SIGPIPE when it tries
to write to the socket returned by accept since it does not
install a signal handler for it. To fix install a signal handler
for SIGPIPE. He belives the latest version of NetKit already does
this. Now you may be wondering why does a write to the socket
returned by accept() generates a SIGPIPE. This bring us to the
second issue. It seems that at least under Linux 2.0.X accept will
return a socket in the received queue if it is not in the
SYN_SENT or SYN_RECV state, even when it has not gone through the
ESTABLISHED state. By doing a stealth scan on the port the socket
goes from the SYN_RECV state to the CLOSED state. When you try to
read from such a socket you get a SIGPIPE. The sematics of Linux's
accept seems to be non-standard.
This sounds a lot like the antiquated SYN, RST DoS problem older
Linux inetds were vulnerable to. Send a SYN to an internal
service, and immediately follow it up with a RST packet. inetd
would become unstable and die after the next connection.
SOLUTION
Quick & dirty workaround would be to comment out daytime & time
services from /etc/inetd.conf and restart inetd. However as it
seems to be problem with older kernel and older version of NetKit,
appropriate upgrade will do it.
The workaround for inetd - put it in "fork() after accept()" mode
(some option in command line). Another workaround - put your
router in "ip established" mode (router will pass session only
after connection will be established)