NPING NEW ECHO MODE PROPOSAL June 2010 Luis MartinGarcia (luis.mgarc@gmail.com) TABLE OF CONTENTS 0x01. Introduction 0x02. Input 0x03. Output 0x04. Results 0x05. Protocol == 0x01: INTRODUCTION == Troubleshooting routing and firewall issues is a common task nowadays. The scenario is generally that some network traffic should be flowing but isn't. The causes of problem can range from routing issues to network firewall to host-based firewalls to all sorts of other strange things. It is usually the "middle box" problem that is the hardest to find. Suppose there is some host with a TCP service listening that you can't connect to for an unknown reason. If a Nmap -sS scan doesn't show the port as open there are a multitude of possible problems. Maybe the SYN packet never made it because of some firewall in the middle. Maybe the SYN did make it but the SYN+ACK got dropped on it's way back to you. Maybe the TTL expired in transit but the ICMP message got blocked by another firewall before making it back to you. Maybe the SYN made it but some intermediate host forged a reset packet to snipe the connection before the SYN+ACK made it back to you. When things like the above are going on, it is often the case that one has to turn to Wireshark/tcpdump on one station and Nping on the other. However, this is usually difficult to coordinate, specially when the person at the remote host does not even know what an IP address is. To solve this problem, Nping will have a new mode, called "Echo mode" that will give it the power of a combination like hping + tcpdump. This echo mode turns Nping into a client/server application. One station runs Nping in server mode and the other in client mode. The way it works is: the Nping client performs an initial handshake with the server over some standard port (creating a side-channel). Then it notifies the server what packets are about to be sent. The server sets up a liberal BPF filter that captures those packets, and starts listening. When the server receives a packet it encapsulates it into a packet of our own protocol, the Nping Echo Protocol (NEP), and sends it back to the client. This would be essentially like running tcpdump on the remote machine and having it report back the packets you sent to it with Nping. By having the side-channel to talk to the server, things like NAT would become immediately apparent because you'd see your source IP (and sometimes port) change. Things like "packet shapers" that change TCP window sizes transparently between hosts would turn up. It would be easy to tell if the traffic is being dropped in transit and never gets to the box. It would also be easy to tell if the traffic does make it to the box but the reply never makes it back to you. In general, it would be like sending a postal package to someone and having them email you a photo of the package when they get it. If you think your packages are being abused by the parcel service then having someone on the other end to send information back is a great way to uncover what is going on. == 0x02: INPUT == From a user's perpective, this new mode would be set up from the command line. Here's a possible interface: SERVER Users may start the server, using the default parameters, running: nping --echo-server Obvioulsy it would be possible to override defaults running something like: nping --echo-server --echo-port 9999 -vvv --passphrase "Squemmish Ossifrage" CLIENT Users would need to supply "--echo-client" and a list of packets to send. There would be a new command line parameter, "-P", whose argument should be the list of options that define the packet. This options would be the same ones used for the Nping normal operation mode. For example, the next command tells nping to connect to the echo server at echo.insecure.org, and send two TCP-SYN packets and one ICMP echo reply to the echo server. nping --echo-client --passphrase "Squemmish Ossifrage" -P"{--tcp --flags psh,ack --win 0 -c2 }" -P"{--icmp --icmp-type echo-reply --icmp-seq 3}" echo.insecure.org == 0x03: OUTPUT == About the output, there are a few different possibilities. We still need to decide which is the best approach: 1. Nping could do something similar to its regular mode, where it prints sent and received packets line by line, only that this time, there are no received packets but "captured" packets, received from the side channel. The output could be something like this: 1.1 Default level of detail: SENT (0.0570s) TCP 192.168.1.99:9134 > 212.16.233.4:80 S ttl=64 id=42427 iplen=40 seq=3817491960 win=1480 CAPT (1.0218s) TCP 29.23.11.23:9134 > 212.16.233.4:80 S ttl=53 id=42427 iplen=40 seq=3817491960 win=1480 1.2 Medium level of detail: SENT (0.0570s) TCP [192.168.1.99:9134 > 212.16.233.4:80 S seq=811845341 win=1480 csum=0x3B31] IP [ttl=64 id=16518 proto=6 csum=0x3c48 iplen=40 ] CAPT (1.0873s) TCP [29.23.11.23:9134 > 212.16.233.4:80 S seq=811845341 win=1480 csum=0x3B31] IP [ttl=51 id=16518 proto=6 csum=0x3c48 iplen=40 ] 1.3 High level of detail: SENT (0.0560s) TCP [192.168.1.99:9134 > 212.16.233.4:80 S seq=1441305493 ack=0 off=5 res=0 win=1480 csum=0xE4FB urp=0] IP [ver=4 ihl=5 tos=0x00 iplen=40 id=2461 foff=0 ttl=64 proto=6 csum=0x7331] CAPT (0.0560s) TCP [29.23.11.23:9134 > 212.16.233.4:80 S seq=1441305493 ack=0 off=5 res=0 win=1480 csum=0xE4FB urp=0] IP [ver=4 ihl=5 tos=0x00 iplen=40 id=2461 foff=0 ttl=52 proto=6 csum=0x7331] 2. Alternatively, Nping could only display, for captured packets, the fields that changed in transit. This would look like this: SENT (0.0560s) TCP [192.168.1.99:9134 > 212.16.233.4:80 S seq=1441305493 ack=0 off=5 res=0 win=1480 csum=0xE4FB urp=0] IP [ver=4 ihl=5 tos=0x00 iplen=40 id=2461 foff=0 ttl=64 proto=6 csum=0x7331] CAPT (0.0560s) TCP [29.23.11.23:9134 > ] IP [ttl=52 csum=0x7301] 3. Nping could print sent and captured packets, side by side, using RFC-like format. The following diagram illustrates this: (note that only IP header is shown in this example but trannsport layer headers would also be printed in a real execution): 0 1 2 3 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | V=4 | HL=5 | TOS=0 | TLEN=20 | | V=4 | HL=5 | TOS=0 | TLEN=20 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ID=65535 | |D| | OFF=0 | | ID=65535 | |D| | OFF=0 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | TTL=128 | NP=8 | CSUM=3AF2 | | TTL=113 | NP=8 | CSUM=F9EA | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | SRC=192.168.1.99 | | SRC=129.23.11.23 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | DST=212.16.233.4 | | DST=212.16.233.4 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ SENT PACKET CAPTURED PACKET Probably, fields that have changed should be marked somehow so it's easier to spot them. For example, values that have changed in transit may be enclosed in something like "*" or "#" (e.g: ##SRC=129.23.11.23##) While some people may like this kind of output, it may be problematic for some others, as it does not fit in an 80char-wide terminal. It may be possible to compact the output, but it may not be possible to display all fields properly. Here's an example: 0 1 2 3 0 1 2 3 01234567890123456789012345678901 01234567890123456789012345678901 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |v4 | 5 | TOS=0 | TLEN=20 | |v4 | 5 | TOS=0 | TLEN=20 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ID=65535 | D | OFF=0 | | ID=65535 | D | OFF=0 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |TTL=128| NP=8 | CSUM=3AF2 | |TTL=113| NP=8 | CSUM=3AF2 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | SRC=192.168.1.99 | | SRC=129.23.11.23 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | SRC=212.16.233.4 | | SRC=212.16.233.4 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ SENT PACKET CAPTURED PACKET == 0x04: RESULTS == Apart from displaying the packet that was sent and the one that was captured, Nping could, if possible, give hints about what may have happened in transit. For example, if the original source address does not match the source address of the received packet, Nping could inform that with high probability there is a NAT device close to the client. Nping could detect things like variation of TCP window size and warn about possible proxies, etc. Suggestions on this kind of output are welcome. == 0x05: PROTOCOL == The side channel will be run over a custom application layer protocol called NEP, Nping Echo Protocol. The protocol itself is described in a separate RFC-like document, but here is a basic flow diagram that describes a typical client/server interaction. C S | | | TCP Handshake | Establish regular TCP |------------------------->| connection |<-------------------------| |------------------------->| | | | | | | Check that both | | understand each other | NEP Handshake and Auth | and authenticate the |<------------------------>| client |<------------------------>| |<------------------------>| | | | | | | Client tells the server | PacketType={IP/TCP/Syn} | which kind of packet is |------------------------->| going so send | | S | | | /* Server starts */ | | | /* capturing packets*/ | ServerReadyToGo | | /* here. */ Server indicates its |<-------------------------| | sniffing engine is | | | readty to capture the | C | | packet | | | | | | | | | | | | | | | | Client sends the pkt | | IP/TCP/Syn Packet | | via raw sockets | |---------------------------->| | | | | /* Server receives */ | | | /* the packet */ | Echo of the packet |....| Server echoes the |<-------------------------| packet via the NEP | | session they have. | . | | . | | . | | More raw pkt/echo | | exchanges | | . | | . | | . | | | | | | Terminate Session | Client indicates that |------------------------->| is going to stop | | sending packets | | | | | ACK Terminate Session | Server confirms |<-------------------------| | | | | | TCP Connection Close | TCP connection closed |<------------------------>| | |