29 October, 2006

Hacker's friend: nmap, part two

Advanced scanning


Ping scan, List scan


Ping scan is used to scan large number of IP addresses for computers alive. As I mentioned in part one, by default every scan is preceded by a ping scan to see if the host is online.

$ nmap -sP 10.0.0.2

Starting Nmap 4.01 ( http://www.insecure.org/nmap/ ) at 2006-10-26 19:38 CEST
Host 10.0.0.2 appears to be up.
Nmap finished: 1 IP address (1 host up) scanned in 0.283 seconds


Ok, the scanned host is up, but this is not really interesting. Here's another scan.

$ nmap -sP 10.0.0.0/24

Starting Nmap 4.01 ( http://www.insecure.org/nmap/ ) at 2006-10-26 19:38 CEST
Host 10.0.0.2 appears to be up.
Host 10.0.0.138 appears to be up.
Nmap finished: 256 IP addresses (2 hosts up) scanned in 2.552 seconds


A little explanation about the address I specified in this scan: it features a /24 suffix, which denotes that it's not a single IP address but a range, it's called CIDR notation.
IP addresses are 32 bit numbers, usually presented as four 8 bit (0-255) numbers separated by dots for human consumption, this is called the dotted decimal notation. In the CIDR notation, the appended number after the slash is the number of significant bits in the address, these bits make up the prefix of the group: they are the same for every single address in the group. In my scan, it's 24, so there are 24 bits in the prefix, and 8 bits of the address are variable. This makes 10.0.0 the prefix, and leaves the last number variable, giving 256 possible addresses, from 10.0.0.0 to 10.0.0.255. If I scanned for 10.0.0.16/28, that would be only 2^4 = 16 hosts, ranging from 10.0.0.16 to 10.0.0.31. (16 is 00010000 in binary, the last 4 bits are variable, to it can range from 00010000 to 00011111.)
The list scan (-sL) is just the right tool to practice CIDR notation, as it does nothing but enumerates all the addresses in the given range.

A more straightforward way to supply IP ranges to nmap is like the port ranges: 10.0.0.0/24 is the same as 10.0.0.0-255.

FIN (-sF), Xmas tree (-sX) and Null (-sN) scans


In the previous part, I explained how SYN scan might just evade detection by not opening connections. However SYN scans are already looked for, so here are some more variation on the same, with more chance of being undetected and somewhat less chance of success.
When an endpoint decide to close it's TCP connection, it sends a packet with the FIN and ACK signals. The other end responds by sending an ACK+FIN packet, which is acknowledged with an ACK packet from the initiator, and at this moment the connection is fully closed. But what happens when a FIN packet is sent without an established connection? In this case, a packet with RST (reset) should sent back if the port is closed. Which makes sending FIN packets just the right tool to determine whether a port is closed or not. Well, almost, as Windows machines ignore these FIN packets, and never response to them.
Xmas tree and Null scans are quite similar in concept to FIN scan. Xmas tree scan has the URG (urgent) and PUSH flags also set along with the FIN, which make the flag bits alternating just like the lights on a Christmas tree, while Null scan has no flags set at all. Both of them supposed to get RST response in case a closed port is hit, and none of them get any response from a Windows box, just like FIN scans.
These scans used to be more stealth than a SYN scan, but nowadays IDSs do look out for them. For example every Null packet should raise suspicion as having no flags should not occur in normal traffic. This and the behavior of Windows systems make these less useful as port scanning techniques, and makes them more of a tool for OS fingerprinting, which will be taken care of in the next part of the series. These scans cannot make a difference between open and filtered ports, so the possible states reported by nmap are open|filtered and closed.

ACK scan (-sA) and Window scan (-sW)


These scans are used to learn about the firewalls ruleset. ACK scan sends ACK packets without anything to be acknowledged, so they should get RST replies from both open and closed ports. If there is no reply, it means the port is filtered. Otherwise it's reported as unfiltered.
Window scan takes this one step further, by examining the RST packet. Some systems has a behavior of setting TCP window size of it to zero in case a close port is hit and to non-zero for open ports. Actually this is quite rare, so just like FIN/Xmas/Null scans, it's more of a fingerprinting tool than a port scanning.


Staying under the radar


Every scan previously described might leave records in firewall/IDS logs along with our IP address, which is sometimes not desirable. But nmap offers quite a bunch of tricks to help evading detection.

Timing


There are lots of traffic on the Internet, and every host is hit by some random packets occasionally. IDSs can't log all of them, because it were just as useless as not logging anything: interesting events would be masked by the million lines of normal network noise. So instead of logging everything, they look for suspicious events, which look like intentional probing. If a thousand SYN packet arrives from a single host within a second, aimed at different ports, that looks quite like a SYN scan so it worth a line saying something like “[28-10-2006 20:11] Possible SYN scan from IP”. But if only one arrives from a host for minutes, that's quite normal. Tedious way to scan thousands of ports, but very hard to detect.
By default nmap sends many packets a second in parallel to achieve decent scan speed. But it also offers many options to change this. The most basic is the -Tn which sets a timing profile where n ranges from 0 to 5 (from slowest to fastest: Paranoid, Sneaky, Polite, Normal, Aggressive, Insane). -T1 might be slow enough, with 15 second waits between the probes, which gives 240 probes in an hour, while -T0 waits 5 minutes between each probe, and neither allows parallel scanning.

Decoys


In the previous section, I said that having too much noise compared to the useful records in IDS logs can be just as bad as having no records at all. Our IP address might appear in the log files, but if it's accompanied with dozens of other decoy IP addresses at the same, we will remain unidentified. We can accomplish this by sending the scanning packets with spoofed addresses along with the ones having our address. The list of addresses to be spoofed is supplied after the -D argument. Before blindly supplying random addresses, you might want to check if they are up, because if all entries in the IDS logs are down but one, it might be easy to figure out the culprit. Also, some ISPs filter out packets with spoofed addresses, so this may not work for you.

Fragmentation


Networking devices have an upper limit for transmission size, which is called MTU. If a packet exceeds this, it needs to be split into smaller chunks, this is called fragmentation. The receiving network stack notices that a packet is fragmented, waits till every piece arrives, then assemblies it to proceed. Generally MTU sizes ranges from hundreds of bytes to thousands, with a most common size of 1400-1500 bytes. What happens if we send packets using an MTU as small as 8 bytes? The TCP header is at least 20 bytes long, so it's fragmented into at least 3 pieces. These pieces alone do not contain enough information to determine their nature, and they might even arrive in the wrong order, so it makes hard to detect the probes. Also, having small fragments is quite ordinary: even normal internet traffic can generate small fragments for the trailing part of a packet.
Fragment size can also be set to an arbitrary multiple of 8 with the --mtu flag.

Idle scan


This one is truly ingenious. We will need a zombie host that fulfills some criteria. 1. It must be up. 2. It must have sequential IP id numbers. Sequential IPID means the sequence number in the IP header increases by 1 with each IP packet sent out. 3. It must not have network traffic during the scan. Nmap might handle zombies with occasional traffic, but the ideal zombie would have no traffic.
The scan works like this: 1. We probe the zombie for it's current IPID, which is N. Then we send a SYN packet to the target machine, but with the address spoofed to look like it's from the zombie. If the port is open, the target replies to the zombie with a SYN+ACK packet. As the zombie has no idea what that packet should mean (it didn't initiate connection), replies with a RST packet. If the port is closed or filtered, nothing happens. Now, we probe the zombie again to determine it's actual IPID. If it's N+2 it means the zombie sent out a packet since our last probe: as the zombie is supposedly idle, it must be RST reply, which means the port on the target is open. If the IPID is N+1, nothing happened since our last probe, so the port must be closed.
This scan is really stealthy, because we don't send a single packet to the target containing our own IP address. However, we need to be able to send out spoofed addresses, which might be filtered by our ISP. Also this scan is slower and less reliable: if the zombie has some other traffic, but not significant enough to be caught by nmap, this may result in closed ports reported being open.