--- global_structures.h~ Fri Sep 10 18:58:50 1999 +++ global_structures.h Fri Sep 10 19:09:43 1999 @@ -169,6 +169,7 @@ int xmasscan; int fragscan; int synscan; + int ackscan; int maimonscan; int finscan; int udpscan; @@ -180,7 +181,7 @@ }; typedef port *portlist; -typedef enum { SYN_SCAN, FIN_SCAN, XMAS_SCAN, UDP_SCAN, CONNECT_SCAN, NULL_SCAN, RPC_SCAN, MAIMON_SCAN } stype; +typedef enum { SYN_SCAN, FIN_SCAN, XMAS_SCAN, UDP_SCAN, CONNECT_SCAN, NULL_SCAN, ACK_SCAN, RPC_SCAN, MAIMON_SCAN } stype; #endif /*GLOBAL_STRUCTURES_H */ --- nmap.c~ Fri Sep 10 18:47:27 1999 +++ nmap.c Fri Sep 10 19:09:44 1999 @@ -253,6 +253,7 @@ case 'P': o.pingscan = 1; break; case 'R': o.rpcscan = 1; break; case 'S': o.synscan = 1; break; + case 'A': o.ackscan = 1; break; case 'T': o.connectscan = 1; break; case 'U': fprintf(o.nmap_stdout, "WARNING: -sU is now UDP scan -- for TCP FIN scan use -sF\n"); @@ -283,7 +284,7 @@ /* Now we check the option sanity */ /* Insure that at least one scantype is selected */ -if (!o.connectscan && !o.udpscan && !o.synscan && !o.finscan && !o.maimonscan && !o.nullscan && !o.xmasscan && !o.bouncescan && !o.pingscan) { +if (!o.connectscan && !o.udpscan && !o.synscan && !o.ackscan && !o.finscan && !o.maimonscan && !o.nullscan && !o.xmasscan && !o.bouncescan && !o.pingscan) { o.connectscan++; if (o.verbose) error("No tcp,udp, or ICMP scantype specified, assuming vanilla tcp connect() scan. Use -sP if you really don't want to portscan (and just want to see what hosts are up)."); } @@ -299,7 +300,7 @@ if (fastscan && ports) { fatal("You can specify fast scan (-F) or explicitly select individual ports (-p), but not both"); } else if (fastscan) { - ports = getfastports(o.synscan|o.connectscan|o.fragscan|o.finscan|o.maimonscan|o.bouncescan|o.nullscan|o.xmasscan,o.udpscan); + ports = getfastports(o.ackscan|o.synscan|o.connectscan|o.fragscan|o.finscan|o.maimonscan|o.bouncescan|o.nullscan|o.xmasscan,o.udpscan); } if (o.pingscan && ports) { @@ -311,7 +312,7 @@ } if (!ports) { - ports = getdefaultports(o.synscan|o.connectscan|o.fragscan|o.finscan| + ports = getdefaultports(o.ackscan|o.synscan|o.connectscan|o.fragscan|o.finscan| o.maimonscan|o.bouncescan|o.nullscan|o.xmasscan, o.udpscan); } @@ -320,7 +321,7 @@ if (!o.tcp_probe_port) o.tcp_probe_port = 80; -if (o.pingscan && (o.connectscan || o.udpscan || o.synscan || o.finscan || o.maimonscan || o.nullscan || o.xmasscan || o.bouncescan)) { +if (o.pingscan && (o.connectscan || o.udpscan || o.ackscan || o.synscan || o.finscan || o.maimonscan || o.nullscan || o.xmasscan || o.bouncescan)) { fatal("Ping scan is not valid with any other scan types (the other ones all include a ping scan"); } @@ -332,7 +333,7 @@ o.pingtype = PINGTYPE_TCP; } - if (o.finscan || o.synscan || o.maimonscan || o.nullscan || o.xmasscan + if (o.finscan || o.ackscan || o.synscan || o.maimonscan || o.nullscan || o.xmasscan || o.udpscan ) { fatal("You requested a scan type which requires r00t privileges, and you do not have them.\n"); } @@ -353,8 +354,8 @@ if (o.bouncescan && o.pingtype != PINGTYPE_NONE) fprintf(o.nmap_stdout, "Hint: if your bounce scan target hosts aren't reachable from here, remember to use -P0 so we don't try and ping them prior to the scan\n"); -if (o.connectscan + o.synscan + o.finscan + o.maimonscan + o.xmasscan + o.nullscan > 1) { - fatal("You specified more than one type of TCP scan. Please choose only one of -sT, -sS, -sF, -sM, -sX, and -sN"); +if (o.connectscan + o.ackscan + o.synscan + o.finscan + o.maimonscan + o.xmasscan + o.nullscan > 1) { + fatal("You specified more than one type of TCP scan. Please choose only one of -sT, -sS, -sF, -sM, -sX, -sA, and -sN"); } if (o.numdecoys > 0 && (o.bouncescan || o.connectscan)) { @@ -362,9 +363,9 @@ } if (o.fragscan && (o.connectscan || - (o.udpscan && (o.synscan + o.finscan + o.maimonscan + + (o.udpscan && (o.ackscan + o.synscan + o.finscan + o.maimonscan + o.xmasscan + o.nullscan == 0)))) - fatal("Fragmentation scan can only be used with SYN, FIN, Maimon, XMAS, or NULL scan types"); + fatal("Fragmentation scan can only be used with SYN, FIN, Maimon, XMAS, ACK, or NULL scan types"); if (o.identscan && !o.connectscan) { error("Identscan only works with connect scan (-sT) ... ignoring option"); @@ -533,7 +534,7 @@ if (currenths->flags & HOST_UP /* && !currenths->wierd_responses*/ && !o.pingscan) { - if (currenths->flags & HOST_UP && !currenths->source_ip.s_addr && ( o.synscan || o.finscan || o.maimonscan || o.udpscan || o.nullscan || o.xmasscan)) { + if (currenths->flags & HOST_UP && !currenths->source_ip.s_addr && ( o.ackscan || o.synscan || o.finscan || o.maimonscan || o.udpscan || o.nullscan || o.xmasscan)) { if (gethostname(myname, MAXHOSTNAMELEN) || !(target = gethostbyname(myname))) fatal("Cannot get hostname! Try using -S or -e \n"); @@ -545,7 +546,7 @@ } /* Figure out what link-layer device (interface) to use (ie eth0, ppp0, etc) */ - if (!*currenths->device && currenths->flags & HOST_UP && (o.nullscan || o.xmasscan || o.udpscan || o.finscan || o.maimonscan || o.synscan || o.osscan) && (ipaddr2devname( currenths->device, ¤ths->source_ip) != 0)) + if (!*currenths->device && currenths->flags & HOST_UP && (o.nullscan || o.xmasscan || o.udpscan || o.finscan || o.maimonscan || o.synscan || o.osscan || o.ackscan) && (ipaddr2devname( currenths->device, ¤ths->source_ip) != 0)) fatal("Could not figure out what device to send the packet out on! You might possibly want to try -S (but this is probably a bigger problem). If you are trying to sp00f the source of a SYN/FIN scan with -S , then you must use -e eth0 (or other devicename) to tell us what interface to use.\n"); /* Set up the decoy */ o.decoys[o.decoyturn] = currenths->source_ip; @@ -554,6 +555,7 @@ if (o.synscan) pos_scan(currenths, ports, SYN_SCAN); + if (o.ackscan) pos_scan(currenths, ports, ACK_SCAN); if (o.connectscan) pos_scan(currenths, ports, CONNECT_SCAN); if (o.finscan) super_scan(currenths, ports, FIN_SCAN); @@ -1993,7 +1995,7 @@ FD_ZERO(&csi.fds_write); FD_ZERO(&csi.fds_except); - if (scantype == SYN_SCAN || scantype == RPC_SCAN) + if (scantype == SYN_SCAN || scantype == RPC_SCAN || scantype == ACK_SCAN) ss.max_width = 150; else ss.max_width = o.max_sockets; @@ -2025,7 +2027,7 @@ } /* Init our raw socket */ - if (scantype == SYN_SCAN) { + if ((scantype == SYN_SCAN) || (scantype == ACK_SCAN)) { if ((rawsd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0 ) pfatal("socket troubles in super_scan"); /* We do not wan't to unblock the socket since we want to wait @@ -2075,7 +2077,10 @@ fatal("Error compiling our pcap filter: %s\n", pcap_geterr(pd)); if (pcap_setfilter(pd, &fcode) < 0 ) fatal("Failed to set the pcap filter: %s\n", pcap_geterr(pd)); - scanflags = TH_SYN; + if (scantype == SYN_SCAN) + scanflags = TH_SYN; + else + scanflags = TH_ACK; } else if (scantype == CONNECT_SCAN) { rawsd = -1; /* Init our sock */ @@ -2107,7 +2112,9 @@ fprintf(o.nmap_stdout, "Initiating SYN half-open stealth scan against %s (%s)\n", target->name, inet_ntoa(target->host)); else if (scantype == CONNECT_SCAN) fprintf(o.nmap_stdout, "Initiating TCP connect() scan against %s (%s)\n",target->name, inet_ntoa(target->host)); - else { + else if (scantype == ACK_SCAN) + fprintf(o.nmap_stdout, "Initiating ACK scan against %s (%s)\n",target->name, inet_ntoa(target->host)); + else { fprintf(o.nmap_stdout, "Initiating RPC scan against %s (%s)\n",target->name, inet_ntoa(target->host)); } } @@ -2181,7 +2188,7 @@ scan[current->next].prev = current - scan; } } - if (scantype == SYN_SCAN || scantype == RPC_SCAN) + if (scantype == SYN_SCAN || scantype == RPC_SCAN || scantype == ACK_SCAN) ss.numqueries_outstanding--; else { /* close the appropriate sd for each try */ @@ -2202,7 +2209,7 @@ current->trynum++; gettimeofday(¤t->sent[current->trynum], NULL); now = current->sent[current->trynum]; - if (scantype == SYN_SCAN) { + if ((scantype == SYN_SCAN) || (scantype == ACK_SCAN)) { for(decoy=0; decoy < o.numdecoys; decoy++) { if (o.fragscan) send_small_fragz(rawsd, &o.decoys[decoy], &target->host, sequences[current->trynum],o.magic_port + tries * 3 + current->trynum, current->portno, scanflags); @@ -2292,7 +2299,7 @@ /* if (!testinglist) testinglist = current; */ ss.numqueries_outstanding++; gettimeofday(¤t->sent[0], NULL); - if (scantype == SYN_SCAN) { + if ((scantype == SYN_SCAN) || (scantype == ACK_SCAN)) { for(decoy=0; decoy < o.numdecoys; decoy++) { if (o.fragscan) send_small_fragz(rawsd, &o.decoys[decoy], &target->host, sequences[current->trynum], o.magic_port + tries * 3, current->portno, scanflags); @@ -2349,8 +2356,8 @@ /* Now that we have sent the packets we wait for responses */ ss.alreadydecreasedqueries = 0; - if (scantype == SYN_SCAN) - get_syn_results(target, scan, &ss, &pil, portlookup, pd, sequences); + if ((scantype == SYN_SCAN) || (scantype == ACK_SCAN)) + get_syn_results(target, scan, &ss, &pil, portlookup, pd, sequences, scantype); else if (scantype == RPC_SCAN) { /* We only bother worrying about responses if we haven't reached a conclusion yet */ @@ -2435,7 +2442,7 @@ } if (o.verbose) - fprintf(o.nmap_stdout, "The %s scan took %ld seconds to scan %d ports.\n", (scantype == SYN_SCAN)? "SYN" : (scantype == CONNECT_SCAN)? "TCP connect" : "RPC", (long) time(NULL) - starttime, o.numports); + fprintf(o.nmap_stdout, "The %s scan took %ld seconds to scan %d ports.\n", (scantype == ACK_SCAN) ? "ACK" : (scantype == SYN_SCAN)? "SYN" : (scantype == CONNECT_SCAN)? "TCP connect" : "RPC", (long) time(NULL) - starttime, o.numports); free(scan); if (rawsd >= 0) @@ -2857,7 +2864,7 @@ void get_syn_results(struct hoststruct *target, struct portinfo *scan, struct scanstats *ss, struct portinfolist *pil, - int *portlookup, pcap_t *pd, unsigned long *sequences) { + int *portlookup, pcap_t *pd, unsigned long *sequences, stype scantype) { struct ip *ip; int bytes; @@ -2916,12 +2923,21 @@ error("Received SYN packet implying trynum %d from port %hi even though that port is only on trynum %d (could be from an earlier round)", trynum, newport, current->trynum); trynum = -1; } - if ((tcp->th_flags & (TH_SYN|TH_ACK)) == (TH_SYN|TH_ACK)) { - newstate = PORT_OPEN; - } - else if (tcp->th_flags & TH_RST) { - newstate = PORT_CLOSED; + if (scantype == SYN_SCAN) { + if ((tcp->th_flags & (TH_SYN|TH_ACK)) == (TH_SYN|TH_ACK)) { + newstate = PORT_OPEN; + } + else if (tcp->th_flags & TH_RST) { + newstate = PORT_CLOSED; } + } + if (scantype == ACK_SCAN) { + if (tcp->th_win) { + newstate = PORT_OPEN; + } else { + newstate = PORT_CLOSED; + } + } } else if (ip->ip_p == IPPROTO_ICMP) { icmp = (struct icmp *) ((char *)ip + sizeof(struct ip)); ip2 = (struct ip *) (((char *) ip) + 4 * ip->ip_hl + 8); @@ -2990,8 +3006,8 @@ fatal("Deletion of port %d failed\n", ports[i]); } } - if (o.connectscan || o.nullscan || o.xmasscan || o.synscan || - o.maimonscan || o.finscan || o.bouncescan) { + if (o.connectscan || o.nullscan || o.xmasscan || o.synscan || + o.ackscan || o.maimonscan || o.finscan || o.bouncescan) { current = lookupport(*pl, ports[i], IPPROTO_TCP); if (!current) addport(pl, ports[i], IPPROTO_TCP, NULL, PORT_UNFIREWALLED); --- nmap.h~ Fri Sep 10 19:02:15 1999 +++ nmap.h Fri Sep 10 19:09:45 1999 @@ -258,7 +258,7 @@ struct portinfolist *pil, struct connectsockinfo *csi); void get_syn_results(struct hoststruct *target, struct portinfo *scan, struct scanstats *ss, struct portinfolist *pil, - int *portlookup, pcap_t *pd, unsigned long *sequences); + int *portlookup, pcap_t *pd, unsigned long *sequences, stype scantype); int get_connect_results(struct hoststruct *target, struct portinfo *scan, struct scanstats *ss, struct portinfolist *pil, int *portlookup, unsigned long *sequences,