TCP Idle Scan (-sI
)
Note | |
---|---|
Volunteers have translated this section into Spanish and Portuguese (Brazil) |
In 1998, security researcherAntirez(who also wrote thehping2tool used in parts of this book) posted to the Bugtraq mailinglist an ingenious new port scanning technique. Idle scan, as it hasbecome known, allows for completely blind port scanning. Attackerscan actually scan a target without sending a single packet to thetarget from their own IP address! Instead, a clever side-channelattack allows for the scan to be bounced off a dumb“zombie host”.Intrusion detection system (IDS) reports will finger theinnocent zombie as the attacker. Besides being extraordinarilystealthy, this scan type permits discovery of IP-based trustrelationshipsbetween machines.
While idle scanning is more complex than any of the techniquesdiscussed so far, you don't need to be a TCP/IP expert to understandit. It can be put together from these basic facts:
One way to determine whether a TCP port is open is to send a SYN (session establishment) packet to the port. The target machine will respond with a SYN/ACK (session request acknowledgment) packet if the port is open, and RST (reset) if the port is closed. This is the basis of the previously discussed SYN scan.
A machine that receives an unsolicited SYN/ACK packet will respond with a RST. An unsolicited RST will be ignored.
Every IP packet on the Internet has a fragment identification number (IP ID). Since many operating systems simply increment this number for each packet they send, probing for the IPID can tell an attacker how many packets have been sent since the last probe.
By combining these traits, it is possible to scan a targetnetwork while forging your identity so that it looks like an innocentzombie machine did the scanning.
Idle Scan Step by Step
Fundamentally, an idle scan consists of three steps that arerepeated for each port:
Probe the zombie's IP ID and record it.
Forge a SYN packetfrom the zombie and send it to the desired porton the target. Depending on the port state, the target's reaction may or may not cause the zombie's IP ID to be incremented.
Probe the zombie's IP ID again. The target port state is thendetermined by comparing this new IP ID with the one recorded in step1.
After this process, the zombie's IP ID should have increased byeither one or two. An increase of one indicates that the zombie hasn'tsent out any packets, except for its reply to the attacker'sprobe. This lack of sent packets means that the port is not open (thetarget must have sent the zombie either a RST packet, which wasignored, or nothing at all). An increase of two indicates that the zombie sentout a packet between the two probes. This extra packet usually meansthat the port is open (the target presumably sent the zombie a SYN/ACKpacket in response to the forged SYN, which induced a RST packet fromthe zombie). Increases larger than two usually signify a bad zombiehost. It might not have predictable IP ID numbers, or might beengaged in communication unrelated to the idle scan.
Even though what happens with a closed port is slightlydifferent from what happens with a filtered port, the attackermeasures the same result in both cases, namely, an IPID increaseof1. Therefore it is not possible for the idle scan to distinguishbetween closed and filtered ports. When Nmap records an IPIDincrease of1 it marks the portclosed|filtered
.
For those wanting more detail, the following three diagrams showexactly what happens in the three cases of an open, closed, and filteredport. The actors in each are:
the attacker, the zombie, andthe target.
Figure5.6.Idle scan of an open port
Figure5.7.Idle scan of a closed port
Figure5.8.Idle scan of a filtered port
Idle scan is the ultimate stealth scan. Nmap offersdecoyscanning (-D
)to help users shield their identity, butthat (unlike idle scan) still requires an attacker to send somepackets to the target from his real IP address in order to get scanresults back. One upshot of idle scan is that intrusion detection systems willgenerally send alerts claiming that the zombie machine has launched ascan against them. So it can be used to frame some other party for ascan. Keep this possibility in mind when reading alerts from yourIDS.
A unique advantage of idle scan is that it can be used to defeatcertain packet filtering firewalls androuters.IP source address filteringis a common (though weak) security mechanism for limitingmachines that may connect to a sensitive host or network. For example,a company database server might only allow connections from the publicweb server that accesses it. Or a home user might only allow SSH(interactive login) connections from his work machines.
A more disturbing scenario occurs when some company bigwigdemands that network administrators open a firewall hole so he canaccess internal network resources from his home IP address. This canhappen when executives are unwilling or unable to use secure VPNalternatives.
Idle scanning can sometimes be used to map out these trustrelationships.The key factor is that idle scan results list open portsfrom the zombie host's perspective. A normal scan against theaforementioned database server might show no ports open, butperforming an idle scan while using the web server's IP as the zombiecould expose the trust relationship by showing the database-relatedservice ports as open.
Mapping out these trust relationships can be very useful toattackers for prioritizing targets. The web server discussed above mayseem mundane to an attacker until she notices its special databaseaccess.
A disadvantage to idle scanning is that it takes far longer thanmost other scan types. Despite the optimized algorithms described inthe section called “Idle Scan Implementation Algorithms”, A 15-second SYNscan could take 15 minutes or more as an idle scan. Another issue isthat you must be able to spoof packets as if they are coming from thezombie and have them reach the target machine. Many ISPs(particularly dialup and residential broadband providers) nowimplement egress filtering to prevent this sort of packetspoofing.Higher end providers (such as colocation and T1 services) are much lesslikely to do this. If this filtering is in effect, Nmap will print aquick error message for every zombie you try. If changing ISPs is notan option, you might try using another IP on the same ISP network.Sometimes the filtering only blocks spoofing of IP addresses that areoutside the range used by customers. Anotherchallenge with idle scan is that you must find a working zombie host,as described in the next section.
Finding a Working Idle Scan Zombie Host
The first step in executing an IP ID idle scan is to find anappropriate zombie. It needs to assign IP ID packets incrementally ona global (rather than per-host it communicates with) basis. It should be idle(hence the scan name), as extraneous traffic will bump up its IP IDsequence, confusing the scan logic. The lower the latency between theattacker and the zombie, and between the zombie and the target, thefaster the scan will proceed.
When an idle scan is attempted, Nmap tests the proposedzombie and reports any problems with it. If one doesn't work, tryanother. Enough Internet hosts are vulnerable that zombie candidatesaren't hard to find. Since the hosts need to be idle, choosing awell-known host such as www.yahoo.com or google.com will almost neverwork.
A common approach is to simply execute a Nmap ping scan of somenetwork. You could use Nmap's random IP selection mode(-iR
),but that is likely to result in far awayzombies with substantial latency. Choosing a network near your sourceaddress, or near the target, produces better results. You cantry an idle scan using each available host from the ping scan resultsuntil you find one that works. As usual, it is best to ask permissionbefore using someone's machines for unexpected purposes such as idlescanning.
We didn't just choose a printer icon to represent a zombie inour illustrations to be funny—simple network devices often makegreat zombies because they are commonly both underused (idle) and builtwith simple network stacks which are vulnerable to IP ID trafficdetection.
Performing a port scan and OS identification(-O
)on the zombie candidate network rather than justa ping scan helps in selecting a good zombie. As long as verbose mode(-v
)is enabled, OS detection will usually determinethe IP ID sequence generation method and print a line such as“IP ID Sequence Generation: Incremental”.If the type isgiven as Incremental
or Brokenlittle-endian incremental
, the machine is a good zombiecandidate. That is still no guarantee that it will work, as Solarisand some other systems create a new IP ID sequence for each host theycommunicate with. The host could also be too busy. OS detection andthe open port list can also help in identifying systems that arelikely to be idle.
Another approach to identifying zombie candidates is the run theipidseqNSE script against a host. This script probes a host to classify itsIP ID generation method, then prints the IP ID classification muchlike the OS detection does. Like most NSE scripts, ipidseq.nse
can be run against many hosts in parallel, making it another good choicewhen scanning entire networks looking for suitable hosts.
While identifying a suitable zombie takes some initial work, you cankeep re-using the good ones.
Executing an Idle Scan
Once a suitable zombie has been found, performing a scan iseasy. Simply specify the zombie hostname to the -sI
option and Nmap does the rest. Example5.19 shows an example ofEreetscanning the Recording Industry Association of America by bouncing anidle scan off an Adobe machine named Kiosk.
Example5.19.An idle scan against the RIAA
# nmap -Pn -p- -sI kiosk.adobe.com www.riaa.com
Starting Nmap ( https://nmap.org )Idlescan using zombie kiosk.adobe.com (192.150.13.111:80); Class: IncrementalNmap scan report for 208.225.90.120(The 65522 ports scanned but not shown below are in state: closed)Port State Service21/tcp open ftp25/tcp open smtp80/tcp open http111/tcp open sunrpc135/tcp open loc-srv443/tcp open https1027/tcp open IIS1030/tcp open iad12306/tcp open unknown5631/tcp open pcanywheredata7937/tcp open unknown7938/tcp open unknown36890/tcp open unknownNmap done: 1 IP address (1 host up) scanned in 2594.47 seconds
From the scan above, we learn that the RIAA is not very securityconscious (note the open PC Anywhere, portmapper, and Legato nsrexecports). Since they apparently have no firewall, it is unlikely thatthey have an IDS. But if they do, it will show kiosk.adobe.com as thescan culprit. The -Pn
option prevents Nmap fromsending an initial ping packet to the RIAA machine. That would havedisclosed Ereet's true address. The scan took a long time because-p-
was specified to scan all 65K ports. Don't tryto use kiosk for your scans, as it has already been removed.
By default, Nmap forges probes to the target from the sourceport 80 of the zombie. You can choose a different port by appending acolon and port number to the zombie name (e.g. -sIkiosk.adobe.com:113
). The chosen port must not be filteredfrom the attacker or the target. A SYN scan of the zombie should showthe port in the open
orclosed
state.
Idle Scan Implementation Algorithms
While the section called “Idle Scan Step by Step” describesidle scan at the fundamental level, the Nmap implementation is farmore complex. Key differences areparallelismfor quick execution and redundancy to reduce false positives.
Parallelizing idle scan is trickier than with other scantechniques due to indirect method of deducing port states. If Nmapsends probes to many ports on the target and then checks the new IP IDvalue of the zombie, the number of IP ID increments will expose howmany target ports are open, but not which ones. This isn't actually a major problem,as the vast majority of ports in a large scan will beclosed|filtered
.Sinceonly open ports cause the IP ID value to increment, Nmap will see nointervening increments and can mark the whole group of ports asclosed|filtered
. Nmap can scan groups of up to 100 ports in parallel. If Nmapprobes a group then finds that the zombie IP ID has increased<N>
times, there must be<N>
open ports among that group. Nmap then findsthe open ports with a binary search. It splits the group into two andseparately sends probes to each. If a subgroup shows zero open ports,that group's ports are all marked closed|filtered
. If asubgroup shows one or more open ports, it is divided again and theprocess continues until those ports are identified. While thistechnique adds complexity, it can reduce scan times by an order of magnitude over scanning just one port at a time.
Reliability is another major idle scanning concern. If thezombie host sends packets to any unrelated machines during the scan,its IP ID increments. This causes Nmap to think it has foundan open port. Fortunately, parallel scanning helps here too. If Nmapscans 100 ports in a group and the IP ID increase signals two openports, Nmap splits the group into two fifty-port subgroups. When Nmapdoes an IP ID scan on both subgroups, the total zombie IP ID increasebetter be two again! Otherwise, Nmap will detect the inconsistencyand rescan the groups. It also modifies group size and scan timingbased on the detected reliability rate of the zombie. If Nmap detectstoo many inconsistent results, it will quit and ask the user toprovide a better zombie.
Sometimes a packet trace is the best way to understand complexalgorithms and techniques such as these. Once again, the Nmap--packet-trace
makes these trivial to produce whendesired. The remainder of this section provides anannotated packet trace of an actual seven port idle scan. TheIP addresses have been changed to Attacker
,Zombie
, and Target
and some irrelevantaspects of the trace lines (such as TCP window size) have been removedfor clarity.
Attacker# nmap -sI Zombie -Pn -p20-25,110 -r --packet-trace -v Target
Starting Nmap ( https://nmap.org )
-Pn
is necessary for stealth, otherwise ping packets would be sent tothe target from Attacker's real address. Version scanning would alsoexpose the true address, and so -sV
isnot specified. The -r
option (turns off port randomization)is only used to make this example easier to follow.
Nmap firsts tests Zombie's IP ID sequence generation by sending sixSYN/ACK packets to it and analyzing the responses. This helps Nmapimmediately weed out bad zombies. It is also necessary because somesystems (usually Microsoft Windows machines, though not all Windowsboxes do this) increment the IP ID by 256 for each packet sent ratherthan by one. This happens on little-endian machines when they don'tconvert the IP ID to network byte order (big-endian). Nmap uses theseinitial probes to detect and work around this problem.
SENT (0.0060s) TCP Attacker:51824 > Zombie:80 SA id=35996SENT (0.0900s) TCP Attacker:51825 > Zombie:80 SA id=25914SENT (0.1800s) TCP Attacker:51826 > Zombie:80 SA id=39591RCVD (0.1550s) TCP Zombie:80 > Attacker:51824 R id=15669SENT (0.2700s) TCP Attacker:51827 > Zombie:80 SA id=43604RCVD (0.2380s) TCP Zombie:80 > Attacker:51825 R id=15670SENT (0.3600s) TCP Attacker:51828 > Zombie:80 SA id=34186RCVD (0.3280s) TCP Zombie:80 > Attacker:51826 R id=15671SENT (0.4510s) TCP Attacker:51829 > Zombie:80 SA id=27949RCVD (0.4190s) TCP Zombie:80 > Attacker:51827 R id=15672RCVD (0.5090s) TCP Zombie:80 > Attacker:51828 R id=15673RCVD (0.5990s) TCP Zombie:80 > Attacker:51829 R id=15674Idlescan using zombie Zombie (Zombie:80); Class: Incremental
Thistest demonstrates that the zombie is working fine. Every IP ID was anincrease of one over the previous one. So the system appears to beidle and vulnerable to IP ID traffic detection. These promisingresults are still subject to the next test, in which Nmap spoofs fourpackets to Zombie as if they are coming from Target. Then it probesthe zombie to ensure that the IP ID increased. If it hasn't, then itis likely that either the attacker's ISP is blocking the spoofedpackets or the zombie uses a separate IP ID sequence counter for eachhost it communicates with. Both are common occurrences, so Nmapalways performs this test. The last-known Zombie IP ID was 15674, asshown above.
SENT (0.5990s) TCP Target:51823 > Zombie:80 SA id=1390SENT (0.6510s) TCP Target:51823 > Zombie:80 SA id=24025SENT (0.7110s) TCP Target:51823 > Zombie:80 SA id=15046SENT (0.7710s) TCP Target:51823 > Zombie:80 SA id=48658SENT (1.0800s) TCP Attacker:51987 > Zombie:80 SA id=27659RCVD (1.2290s) TCP Zombie:80 > Attacker:51987 R id=15679
The four spoofed packets coupled with the probe from Attacker causedthe Zombie to increase its IP ID from 15674 to 15679. Perfect! Nowthe real scanning begins. Remember that 15679 is the latest ZombieIP ID.
Initiating Idlescan against TargetSENT (1.2290s) TCP Zombie:80 > Target:20 S id=13200SENT (1.2290s) TCP Zombie:80 > Target:21 S id=3737SENT (1.2290s) TCP Zombie:80 > Target:22 S id=65290SENT (1.2290s) TCP Zombie:80 > Target:23 S id=10516SENT (1.4610s) TCP Attacker:52050 > Zombie:80 SA id=33202RCVD (1.6090s) TCP Zombie:80 > Attacker:52050 R id=15680
Nmap probes ports 20-23. Then it probes Zombie and finds that the newIP ID is 15680, only one higher than the previous value of 15679.There were no IP ID increments in between those two known packets,meaning ports 20-23 are probably closed|filtered
.It is also possible that a SYN/ACK from a Target port has simply notarrived yet. In that case, Zombie has not responded with a RST andthus its IP ID has not incremented. To ensure accuracy, Nmap will trythese ports again later.
SENT (1.8510s) TCP Attacker:51986 > Zombie:80 SA id=49278RCVD (1.9990s) TCP Zombie:80 > Attacker:51986 R id=15681
Nmap probes again because four tenths of a second has gone bysince the last probe it sent. The Zombie (if not truly idle) couldhave communicated with other hosts during this period, which wouldcause inaccuracies later if not detected here. Fortunately, that hasnot happened: the next IP ID is 15681 as expected.
SENT (2.0000s) TCP Zombie:80 > Target:24 S id=23928SENT (2.0000s) TCP Zombie:80 > Target:25 S id=50425SENT (2.0000s) TCP Zombie:80 > Target:110 S id=14207SENT (2.2300s) TCP Attacker:52026 > Zombie:80 SA id=26941RCVD (2.3800s) TCP Zombie:80 > Attacker:52026 R id=15684
Nmap probes ports 24, 25, and 110 then queries the Zombie IP ID. Ithas jumped from 15681 to 15684. It skipped 15682 and 15683, meaningthat two of those three ports are likely open. Nmap cannot tell whichtwo are open, and it could also be a false positive. So Nmap drillsdown deeper, dividing the scan into subgroups.
SENT (2.6210s) TCP Attacker:51867 > Zombie:80 SA id=18869RCVD (2.7690s) TCP Zombie:80 > Attacker:51867 R id=15685SENT (2.7690s) TCP Zombie:80 > Target:24 S id=30023SENT (2.7690s) TCP Zombie:80 > Target:25 S id=47253SENT (3.0000s) TCP Attacker:51979 > Zombie:80 SA id=12077RCVD (3.1480s) TCP Zombie:80 > Attacker:51979 R id=15687
The first subgroup is ports 24 and 25. The IP ID jumps from 15685 to15687, meaning that one of these two ports is most likely open. Nmaptries the divide and conquer approach again, probing each portseparately.
SENT (3.3910s) TCP Attacker:51826 > Zombie:80 SA id=32515RCVD (3.5390s) TCP Zombie:80 > Attacker:51826 R id=15688SENT (3.5390s) TCP Zombie:80 > Target:24 S id=47868SENT (3.7710s) TCP Attacker:52012 > Zombie:80 SA id=14042RCVD (3.9190s) TCP Zombie:80 > Attacker:52012 R id=15689
A port 24 probe shows no jump in the IP ID. So that port is not open.From the results so far, Nmap has tentatively determined:
Ports 20-23 are
closed|filtered
Two of the ports 24, 25, and 110 are
open
One of the ports 24 and 25 are
open
Port 24 is
closed|filtered
Stare at this puzzle long enough and you'll find only one solution:ports 25 and 110 are open while the other five areclosed|filtered
. Using this logic, Nmap couldcease scanning and print results now. It used to do so, but thatproduced too many false positive open ports when the Zombie wasn'ttruly idle. So Nmap continues scanning to verify its results:
SENT (4.1600s) TCP Attacker:51858 > Zombie:80 SA id=6225RCVD (4.3080s) TCP Zombie:80 > Attacker:51858 R id=15690SENT (4.3080s) TCP Zombie:80 > Target:25 S id=35713SENT (4.5410s) TCP Attacker:51856 > Zombie:80 SA id=28118RCVD (4.6890s) TCP Zombie:80 > Attacker:51856 R id=15692Discovered open port 25/tcp on TargetSENT (4.6900s) TCP Zombie:80 > Target:110 S id=9943SENT (4.9210s) TCP Attacker:51836 > Zombie:80 SA id=62254RCVD (5.0690s) TCP Zombie:80 > Attacker:51836 R id=15694Discovered open port 110/tcp on Target
Probes of ports 25 and 110 show that they are open
, as we deduced previously.
SENT (5.0690s) TCP Zombie:80 > Target:20 S id=8168SENT (5.0690s) TCP Zombie:80 > Target:21 S id=36717SENT (5.0690s) TCP Zombie:80 > Target:22 S id=4063SENT (5.0690s) TCP Zombie:80 > Target:23 S id=54771SENT (5.3200s) TCP Attacker:51962 > Zombie:80 SA id=38763RCVD (5.4690s) TCP Zombie:80 > Attacker:51962 R id=15695SENT (5.7910s) TCP Attacker:51887 > Zombie:80 SA id=61034RCVD (5.9390s) TCP Zombie:80 > Attacker:51887 R id=15696
Just to be sure, Nmap tries ports 20-23 again. A Zombie IP IDquery shows no sequence jump. On the off chance that a SYN/ACK fromTarget to Zombie came in late, Nmap tries another IP ID query. Thisagain shows no open ports. Nmap is now sufficiently confident withits results to print them.
The Idlescan took 5 seconds to scan 7 ports.Nmap scan report for TargetPORT STATE SERVICE20/tcp closed|filtered ftp-data21/tcp closed|filtered ftp22/tcp closed|filtered ssh23/tcp closed|filtered telnet24/tcp closed|filtered priv-mail25/tcp open smtp110/tcp open pop3Nmap finished: 1 IP address (1 host up) scanned in 5.949 seconds
For complete details on the Nmap idle scan implementation, readidle_scan.cc
from the Nmap source codedistribution.
While port scanning is a clever abuse of predictable IP IDsequences, they can be exploited for many other purposes as well.Examples are peppered throughout this book, particularly in Chapter10, Detecting and Subverting Firewalls and Intrusion Detection Systems.