idle_scan.cc
来自「Ubuntu packages of security software。 相」· CC 代码 · 共 1,063 行 · 第 1/3 页
CC
1,063 行
/*************************************************************************** * idle_scan.cc -- Includes the function specific to "Idle Scan" support * * (-sI). This is an extraordinarily cool scan type that can allow for * * completely blind scanning (eg no packets sent to the target from your * * own IP address) and can also be used to penetrate firewalls and scope * * out router ACLs. This is one of the "advanced" scans meant for * * experienced Nmap users. * * * ***********************IMPORTANT NMAP LICENSE TERMS************************ * * * The Nmap Security Scanner is (C) 1996-2008 Insecure.Com LLC. Nmap is * * also a registered trademark of Insecure.Com LLC. This program is free * * software; you may redistribute and/or modify it under the terms of the * * GNU General Public License as published by the Free Software * * Foundation; Version 2 with the clarifications and exceptions described * * below. This guarantees your right to use, modify, and redistribute * * this software under certain conditions. If you wish to embed Nmap * * technology into proprietary software, we sell alternative licenses * * (contact sales@insecure.com). Dozens of software vendors already * * license Nmap technology such as host discovery, port scanning, OS * * detection, and version detection. * * * * Note that the GPL places important restrictions on "derived works", yet * * it does not provide a detailed definition of that term. To avoid * * misunderstandings, we consider an application to constitute a * * "derivative work" for the purpose of this license if it does any of the * * following: * * o Integrates source code from Nmap * * o Reads or includes Nmap copyrighted data files, such as * * nmap-os-fingerprints or nmap-service-probes. * * o Executes Nmap and parses the results (as opposed to typical shell or * * execution-menu apps, which simply display raw Nmap output and so are * * not derivative works.) * * o Integrates/includes/aggregates Nmap into a proprietary executable * * installer, such as those produced by InstallShield. * * o Links to a library or executes a program that does any of the above * * * * The term "Nmap" should be taken to also include any portions or derived * * works of Nmap. This list is not exclusive, but is just meant to * * clarify our interpretation of derived works with some common examples. * * These restrictions only apply when you actually redistribute Nmap. For * * example, nothing stops you from writing and selling a proprietary * * front-end to Nmap. Just distribute it by itself, and point people to * * http://insecure.org/nmap/ to download Nmap. * * * * We don't consider these to be added restrictions on top of the GPL, but * * just a clarification of how we interpret "derived works" as it applies * * to our GPL-licensed Nmap product. This is similar to the way Linus * * Torvalds has announced his interpretation of how "derived works" * * applies to Linux kernel modules. Our interpretation refers only to * * Nmap - we don't speak for any other GPL products. * * * * If you have any questions about the GPL licensing restrictions on using * * Nmap in non-GPL works, we would be happy to help. As mentioned above, * * we also offer alternative license to integrate Nmap into proprietary * * applications and appliances. These contracts have been sold to dozens * * of software vendors, and generally include a perpetual license as well * * as providing for priority support and updates as well as helping to * * fund the continued development of Nmap technology. Please email * * sales@insecure.com for further information. * * * * As a special exception to the GPL terms, Insecure.Com LLC grants * * permission to link the code of this program with any version of the * * OpenSSL library which is distributed under a license identical to that * * listed in the included Copying.OpenSSL file, and distribute linked * * combinations including the two. You must obey the GNU GPL in all * * respects for all of the code used other than OpenSSL. If you modify * * this file, you may extend this exception to your version of the file, * * but you are not obligated to do so. * * * * If you received these files with a written license agreement or * * contract stating terms other than the terms above, then that * * alternative license agreement takes precedence over these comments. * * * * Source is provided to this software because we believe users have a * * right to know exactly what a program is going to do before they run it. * * This also allows you to audit the software for security holes (none * * have been found so far). * * * * Source code also allows you to port Nmap to new platforms, fix bugs, * * and add new features. You are highly encouraged to send your changes * * to fyodor@insecure.org for possible incorporation into the main * * distribution. By sending these changes to Fyodor or one the * * Insecure.Org development mailing lists, it is assumed that you are * * offering Fyodor and Insecure.Com LLC the unlimited, non-exclusive right * * to reuse, modify, and relicense the code. Nmap will always be * * available Open Source, but this is important because the inability to * * relicense code has caused devastating problems for other Free Software * * projects (such as KDE and NASM). We also occasionally relicense the * * code to third parties as discussed above. If you wish to specify * * special license conditions of your contributions, just say so when you * * send them. * * * * This program is distributed in the hope that it will be useful, but * * WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * * General Public License for more details at * * http://www.gnu.org/copyleft/gpl.html , or in the COPYING file included * * with Nmap. * * * ***************************************************************************//* $Id: idle_scan.cc 6633 2007-12-22 06:32:03Z fyodor $ */#include "idle_scan.h"#include "timing.h"#include "osscan2.h"#include "nmap.h"#include "NmapOps.h"#include "services.h"#include "Target.h"#include "utils.h"#include <stdio.h>/* For unknown reasons, MS VC++ is warning about lines like: proxy->senddelay *= 0.95; This is the brute-force way to fix that. */ #ifdef _MSC_VER#pragma warning(disable: 4244)#endifextern NmapOps o;struct idle_proxy_info { Target host; /* contains name, IP, source IP, timing info, etc. */ int seqclass; /* IP ID sequence class (IPID_SEQ_* defined in nmap.h) */ u16 latestid; /* The most recent IP ID we have received from the proxy */ u16 probe_port; /* The port we use for probing IP ID infoz */ u16 max_groupsz; /* We won't test groups larger than this ... */ u16 min_groupsz; /* We won't allow the group size to fall below this level. Affected by --min_parallelism */ double current_groupsz; /* Current group size being used ... depends on conditions ... won't be higher than max_groupsz */ int senddelay; /* Delay between sending pr0be SYN packets to target (in microseconds) */ int max_senddelay; /* Maximum time we are allowed to wait between sending pr0bes (when we send a bunch in a row. In microseconds. */ pcap_t *pd; /* A Pcap descriptor which (starting in initialize_idleproxy) listens for TCP packets from the probe_port of the proxy box */ int rawsd; /* Socket descriptor for sending probe packets to the proxy */ struct eth_nfo eth; // For when we want to send probes via raw IP instead. struct eth_nfo *ethptr; // points to eth if filled out, otherwise NULL};/* Sends an IP ID probe to the proxy machine and returns the IP ID. This function handles retransmissions, and returns -1 if it fails. Proxy timing is adjusted, but proxy->latestid is NOT ADJUSTED -- you'll have to do that yourself. Probes_sent is set to the number of probe packets sent during execution */static int ipid_proxy_probe(struct idle_proxy_info *proxy, int *probes_sent, int *probes_rcvd) { struct timeval tv_end; int tries = 0; int trynum; int sent=0, rcvd=0; int maxtries = 3; /* The maximum number of tries before we give up */ struct timeval tv_sent[3], rcvdtime; int ipid = -1; int to_usec; unsigned int bytes; int timedout = 0; int base_port; struct ip *ip; struct tcp_hdr *tcp; static u32 seq_base = 0; static u32 ack = 0; static int packet_send_count = 0; /* Total # of probes sent by this program -- to ensure that our sequence # always changes */ if (o.magic_port_set) base_port = o.magic_port; else base_port = o.magic_port + get_random_u8(); if (seq_base == 0) seq_base = get_random_u32(); if (!ack) ack = get_random_u32(); do { timedout = 0; gettimeofday(&tv_sent[tries], NULL); /* Time to send the pr0be!*/ send_tcp_raw(proxy->rawsd, proxy->ethptr, proxy->host.v4sourceip(), proxy->host.v4hostip(), o.ttl, false, o.ipoptions, o.ipoptionslen, base_port + tries, proxy->probe_port, seq_base + (packet_send_count++ * 500) + 1, ack, 0, TH_SYN|TH_ACK, 0, 0, (u8 *) "\x02\x04\x05\xb4", 4, NULL, 0); sent++; tries++; /* Now it is time to wait for the response ... */ to_usec = proxy->host.to.timeout; gettimeofday(&tv_end, NULL); while((ipid == -1 || sent > rcvd) && to_usec > 0) { to_usec = proxy->host.to.timeout - TIMEVAL_SUBTRACT(tv_end, tv_sent[tries-1]); if (to_usec < 0) to_usec = 0; // Final no-block poll ip = (struct ip *) readip_pcap(proxy->pd, &bytes, to_usec, &rcvdtime, NULL); gettimeofday(&tv_end, NULL); if (ip) { if (bytes < ( 4 * ip->ip_hl) + 14U) continue; if (ip->ip_p == IPPROTO_TCP) { tcp = ((struct tcp_hdr *) (((char *) ip) + 4 * ip->ip_hl)); if (ntohs(tcp->th_dport) < base_port || ntohs(tcp->th_dport) - base_port >= tries || ntohs(tcp->th_sport) != proxy->probe_port || ((tcp->th_flags & TH_RST) == 0)) { if (ntohs(tcp->th_dport) > o.magic_port && ntohs(tcp->th_dport) < (o.magic_port + 260)) { if (o.debugging) { error("Received IP ID zombie probe response which probably came from an earlier prober instance ... increasing rttvar from %d to %d", proxy->host.to.rttvar, (int) (proxy->host.to.rttvar * 1.2)); } proxy->host.to.rttvar = (int) (proxy->host.to.rttvar * 1.2); rcvd++; } else if (o.debugging > 1) { error("Received unexpected response packet from %s during IP ID zombie probing:", inet_ntoa(ip->ip_src)); readtcppacket( (unsigned char *) ip,ntohs(ip->ip_len)); } continue; } trynum = ntohs(tcp->th_dport) - base_port; rcvd++; ipid = ntohs(ip->ip_id); adjust_timeouts2(&(tv_sent[trynum]), &rcvdtime, &(proxy->host.to)); } } } } while(ipid == -1 && tries < maxtries); if (probes_sent) *probes_sent = sent; if (probes_rcvd) *probes_rcvd = rcvd; return ipid;}/* Returns the number of increments between an early IP ID and a later one, assuming the given IP ID Sequencing class. Returns -1 if the distance cannot be determined */static int ipid_distance(int seqclass , u16 startid, u16 endid) { if (seqclass == IPID_SEQ_INCR) return endid - startid; if (seqclass == IPID_SEQ_BROKEN_INCR) { /* Convert to network byte order */ startid = htons(startid); endid = htons(endid); return endid - startid; } return -1;}static void initialize_proxy_struct(struct idle_proxy_info *proxy) { proxy->seqclass = proxy->latestid = proxy->probe_port = 0; proxy->max_groupsz = proxy->min_groupsz = 0; proxy->current_groupsz = 0; proxy->senddelay = 0; proxy->max_senddelay = 0; proxy->pd = NULL; proxy->rawsd = -1; proxy->ethptr = NULL;}/* takes a proxy name/IP, resolves it if neccessary, tests it for IP ID suitability, and fills out an idle_proxy_info structure. If the proxy is determined to be unsuitable, the function whines and exits the program */#define NUM_IPID_PROBES 6static void initialize_idleproxy(struct idle_proxy_info *proxy, char *proxyName, const struct in_addr *first_target) { int probes_sent = 0, probes_returned = 0; int hardtimeout = 9000000; /* Generally don't wait more than 9 secs total */ unsigned int bytes, to_usec; int timedout = 0; char *p, *q; char *endptr = NULL; int seq_response_num; int newipid; int i; char filter[512]; /* Libpcap filter string */ char name[MAXHOSTNAMELEN + 1]; struct sockaddr_storage ss; size_t sslen; u32 sequence_base; u32 ack = 0; struct timeval probe_send_times[NUM_IPID_PROBES], tmptv, rcvdtime; u16 lastipid = 0; struct ip *ip; struct tcp_hdr *tcp; int distance; int ipids[NUM_IPID_PROBES]; u8 probe_returned[NUM_IPID_PROBES]; struct route_nfo rnfo; assert(proxy); assert(proxyName); ack = get_random_u32(); for(i=0; i < NUM_IPID_PROBES; i++) probe_returned[i] = 0; initialize_proxy_struct(proxy); initialize_timeout_info(&proxy->host.to); proxy->max_groupsz = (o.max_parallelism)? o.max_parallelism : 100; proxy->min_groupsz = (o.min_parallelism)? o.min_parallelism : 4; proxy->max_senddelay = 100000; Strncpy(name, proxyName, sizeof(name)); q = strchr(name, ':'); if (q) { *q++ = '\0'; proxy->probe_port = strtoul(q, &endptr, 10); if (*q==0 || !endptr || *endptr != '\0' || !proxy->probe_port) { fatal("Invalid port number given in IP ID zombie specification: %s", proxyName); } } else { if (o.num_ping_synprobes > 0) { proxy->probe_port = o.ping_synprobes[0]; } else if (o.num_ping_ackprobes > 0) { proxy->probe_port = o.ping_ackprobes[0]; } else { u16 *ports; int count; getpts_simple(DEFAULT_TCP_PROBE_PORT_SPEC, SCAN_TCP_PORT, &ports, &count); assert(count > 0); proxy->probe_port = ports[0]; free(ports); } } proxy->host.setHostName(name); if (resolve(name, &ss, &sslen, o.pf()) == 0) { fatal("Could not resolve idle scan zombie host: %s", name); } proxy->host.setTargetSockAddr(&ss, sslen); /* Lets figure out the appropriate source address to use when sending
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?