Systems implementing the TCP/IP protocol typically include the netstat utility, which can be used, among other things, to list opened sockets.
The netstat command of Windows systems is known to be buggy:
The second bug can lead to suprising netstat outputs on Windows NT 4.0 systems. One particularly odd result is that TCP port 135 (used by the rpcss service, as explained later) is displayed twice in netstat outputs:
C:\WINNT>netstat -anp tcp | find ":135 " TCP 0.0.0.0:135 0.0.0.0:0 LISTENING TCP 0.0.0.0:135 0.0.0.0:0 LISTENING UDP 0.0.0.0:135 *:*
This is because the rpcss service opens both ports 135/tcp and 135/udp. But, with the bug aforementionned, 135/tcp is displayed a second time. This explains why 135/tcp appears twice.
Another serious bug exists in all versions of Windows NT systems before Windows Server 2003 and Windows XP SP2: for each outgoing TCP connection established from a Windows system, the local source port is displayed as LISTENING [7].
In the following example, a TCP connection was established to port 22 of a remote server. The TCP/IP driver allocated port 1367 as source port for the connection. In the netstat output, the port appears in the LISTENING state:
C:\WINDOWS>netstat -anp tcp | find ":1367" TCP 0.0.0.0:1367 0.0.0.0:0 LISTENING TCP 192.70.106.142:1367 192.70.106.76:22 ESTABLISHED
However, this port is not really in the LISTENING state, i.e, it is not possible to establish a new TCP connection on port 1367. Using hping [8] to send a TCP segment with the SYN flag set, a TCP segment with the RST-ACK flags set is returned:
jbm@garbarek ~> sudo hping -S -c 1 192.70.106.142 -p 1367 HPING 192.70.106.142 (ep1 192.70.106.142): S set, 40 headers + 0 data bytes len=46 ip=192.70.106.142 flags=RA seq=0 ttl=127 id=47511 win=0 rtt=3.7 ms --- 192.70.106.142 hping statistic --- 1 packets tramitted, 1 packets received, 0% packet loss round-trip min/avg/max = 3.7/3.7/3.7 ms
It turns out that this bug comes from an incorrect mapping between TDI objects and TCP sockets.
The Winsock API (implementation of BSD sockets API on Windows systems) is implemented on TCP/IP using the Afd driver, which uses the TDI (Transport Driver Interface) API to communicate with the TCP/IP driver.
To implement an outgoing TCP connection, the Afd driver creates two TDI objets:
Using a simple TCP client (nc.exe, [9]) to establish a TCP connection to port 22 of a remote server:
C:\WINNT>nc -z 192.168.1.254 22the implementation at the TDI level can be monitored, using the TDIMon tool [10]:
1 8246D3F0 IRP_MJ_CREATE TCP:0.0.0.0:0 SUCCESS Address Open 2 8246D3F0 TDI_SET_EVENT_HANDLER TCP:0.0.0.0:1038 SUCCESS Error Event 3 8246D3F0 TDI_SET_EVENT_HANDLER TCP:0.0.0.0:1038 SUCCESS Disconnect Event 4 8246D3F0 TDI_SET_EVENT_HANDLER TCP:0.0.0.0:1038 SUCCESS Receive Event 5 8246D3F0 TDI_SET_EVENT_HANDLER TCP:0.0.0.0:1038 SUCCESS Expedited Receive Event 6 8246D3F0 TDI_SET_EVENT_HANDLER TCP:0.0.0.0:1038 SUCCESS Chained Receive Event 7 8246D3F0 TDI_QUERY_INFORMATION TCP:0.0.0.0:1038 SUCCESS Query Address 8 824C1AE0 IRP_MJ_CREATE TCP:Connection obj SUCCESS Context:0x822CF9B8 9 824C1AE0 TDI_ASSOCIATE_ADDRES TCP:Connection obj SUCCESS TCP:0.0.0.0:1038 10 824C1AE0 TDI_CONNECT TCP:0.0.0.0:1038 192.168.1.254:22 SUCCESSThe output can be interpreted as follow: