mirror of
https://github.com/nmap/nmap.git
synced 2025-12-06 04:31:29 +00:00
IPv6 idle scan patch by Mathias Morbitzer.
http://seclists.org/nmap-dev/2013/q3/549
This commit is contained in:
@@ -565,7 +565,7 @@ dialog where you can start NPF if you have administrator privileges.";
|
||||
fatal("--min-rate=%g must be less than or equal to --max-rate=%g", min_packet_send_rate, max_packet_send_rate);
|
||||
}
|
||||
|
||||
if (af() == AF_INET6 && (generate_random_ips|numdecoys|bouncescan|fragscan|idlescan)) {
|
||||
if (af() == AF_INET6 && (generate_random_ips|numdecoys|bouncescan|fragscan)) {
|
||||
fatal("Sorry -- IPv6 support is currently only available for TCP, UDP, and SCTP port scans and list scan (-sL). OS detection, random targets and decoys are also not supported with IPv6. Further support is under consideration.");
|
||||
}
|
||||
|
||||
|
||||
512
idle_scan.cc
512
idle_scan.cc
@@ -126,7 +126,7 @@
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
/* $Id$ */
|
||||
/* $Id: idle_scan.cc 2013-07-26 Mathias Morbitzer (mathias.morbitzer(at)fox-it.com) $ */
|
||||
|
||||
#include "idle_scan.h"
|
||||
#include "timing.h"
|
||||
@@ -169,6 +169,40 @@ struct idle_proxy_info {
|
||||
struct eth_nfo *ethptr; // points to eth if filled out, otherwise NULL
|
||||
};
|
||||
|
||||
/* Finds the IPv6 extension header for fragmentation in an IPv6 packet, and returns
|
||||
* the identification value of the fragmentation header
|
||||
*/
|
||||
int ipv6_get_fragment_id(const struct ip6_hdr *ip6, unsigned int len) {
|
||||
const unsigned char *p, *end;
|
||||
u8 hdr;
|
||||
struct ip6_ext_data_fragment *frag_header = NULL;
|
||||
|
||||
if (len < sizeof(*ip6))
|
||||
return -1;
|
||||
|
||||
p = (unsigned char *) ip6;
|
||||
end = p + len;
|
||||
|
||||
hdr = ip6->ip6_nxt;
|
||||
p += sizeof(*ip6);
|
||||
|
||||
/* If the first extension header is not the fragmentation, we search our way
|
||||
* through the extension headers until we find the fragmentation header */
|
||||
while (p < end && hdr != IP_PROTO_FRAGMENT) {
|
||||
if (p + 2 > end)
|
||||
return -1;
|
||||
hdr = *p;
|
||||
p += (*(p + 1) + 1) * 8;
|
||||
}
|
||||
|
||||
if ( hdr != IP_PROTO_FRAGMENT || (p + 2 + sizeof(ip6_ext_data_fragment)) > end)
|
||||
return -1;
|
||||
|
||||
frag_header = (struct ip6_ext_data_fragment *)( p + 2 );
|
||||
|
||||
return (ntohl(frag_header->ident));
|
||||
|
||||
}
|
||||
|
||||
/* Sends an IP ID probe to the proxy machine and returns the IP ID.
|
||||
This function handles retransmissions, and returns -1 if it fails.
|
||||
@@ -188,10 +222,18 @@ static int ipid_proxy_probe(struct idle_proxy_info *proxy, int *probes_sent,
|
||||
unsigned int bytes;
|
||||
int base_port;
|
||||
struct ip *ip;
|
||||
struct tcp_hdr *tcp;
|
||||
struct tcp_hdr *tcp = NULL;
|
||||
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 */
|
||||
u32 packetlen = 0;
|
||||
u8 *ipv6_packet = NULL;
|
||||
struct sockaddr_storage ss;
|
||||
size_t sslen;
|
||||
struct ip6_hdr *ip6 = NULL;
|
||||
const void *ipv6_data;
|
||||
u8 hdr;
|
||||
int res;
|
||||
|
||||
if (o.magic_port_set)
|
||||
base_port = o.magic_port;
|
||||
@@ -208,14 +250,30 @@ static int ipid_proxy_probe(struct idle_proxy_info *proxy, int *probes_sent,
|
||||
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);
|
||||
if (o.af() == AF_INET)
|
||||
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);
|
||||
else {
|
||||
ipv6_packet = build_tcp_raw_ipv6(proxy->host.v6sourceip(), proxy->host.v6hostip(),
|
||||
0x00, 0x0000,
|
||||
o.ttl,
|
||||
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,
|
||||
&packetlen);
|
||||
proxy->host.TargetSockAddr(&ss, &sslen);
|
||||
res = send_ip_packet(proxy->rawsd, proxy->ethptr, &ss, ipv6_packet, packetlen);
|
||||
if (res == -1)
|
||||
fatal("Error occured while trying to send IPv6 packet");
|
||||
free(ipv6_packet);
|
||||
}
|
||||
sent++;
|
||||
tries++;
|
||||
|
||||
@@ -227,15 +285,26 @@ static int ipid_proxy_probe(struct idle_proxy_info *proxy, int *probes_sent,
|
||||
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 *) readipv4_pcap(proxy->pd, &bytes, to_usec, &rcvdtime, NULL, true);
|
||||
ip = (struct ip *) readip_pcap(proxy->pd, &bytes, to_usec, &rcvdtime, NULL, true);
|
||||
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 (o.af() == AF_INET) {
|
||||
if (bytes < ( 4 * ip->ip_hl) + 14U)
|
||||
continue;
|
||||
if (ip->ip_p == IPPROTO_TCP)
|
||||
tcp = ((struct tcp_hdr *) (((char *) ip) + 4 * ip->ip_hl));
|
||||
} else if (o.af() == AF_INET6) {
|
||||
if (ip->ip_v != 6) {
|
||||
error("IPv6 packet with a version field != 6 received");
|
||||
} else {
|
||||
ip6 = (struct ip6_hdr *) ip;
|
||||
ipv6_data = ipv6_get_data(ip6, &packetlen, &hdr);
|
||||
if (hdr == IPPROTO_TCP && ipv6_data != NULL) {
|
||||
tcp = (struct tcp_hdr *) ipv6_data;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (tcp) {
|
||||
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) {
|
||||
@@ -245,7 +314,12 @@ static int ipid_proxy_probe(struct idle_proxy_info *proxy, int *probes_sent,
|
||||
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));
|
||||
char straddr[INET6_ADDRSTRLEN];
|
||||
if (o.af() == AF_INET)
|
||||
inet_ntop(AF_INET, &(ip->ip_src), straddr, sizeof(straddr));
|
||||
else if (o.af() == AF_INET6)
|
||||
inet_ntop(AF_INET6, &(ip6->ip6_src), straddr, sizeof(straddr));
|
||||
error("Received unexpected response packet from %s during IP ID zombie probing:", straddr);
|
||||
readtcppacket( (unsigned char *) ip, MIN(ntohs(ip->ip_len), bytes));
|
||||
}
|
||||
continue;
|
||||
@@ -254,7 +328,10 @@ static int ipid_proxy_probe(struct idle_proxy_info *proxy, int *probes_sent,
|
||||
trynum = ntohs(tcp->th_dport) - base_port;
|
||||
rcvd++;
|
||||
|
||||
ipid = ntohs(ip->ip_id);
|
||||
if (o.af() == AF_INET)
|
||||
ipid = ntohs(ip->ip_id);
|
||||
else if (o.af() == AF_INET6)
|
||||
ipid = ipv6_get_fragment_id(ip6, bytes);
|
||||
adjust_timeouts2(&(tv_sent[trynum]), &rcvdtime, &(proxy->host.to));
|
||||
}
|
||||
}
|
||||
@@ -288,6 +365,10 @@ static int ipid_distance(int seqclass , u32 startid, u32 endid) {
|
||||
return endid - startid;
|
||||
}
|
||||
|
||||
if (seqclass == IPID_SEQ_INCR_BY_2) {
|
||||
return (endid - startid)/2;
|
||||
}
|
||||
|
||||
return -1;
|
||||
|
||||
}
|
||||
@@ -303,22 +384,139 @@ static void initialize_proxy_struct(struct idle_proxy_info *proxy) {
|
||||
proxy->ethptr = NULL;
|
||||
}
|
||||
|
||||
/* Forces the permanent use of the IPv6 extension header for fragmentation in each IPv6 packet sent from
|
||||
* the idle host to the target or the attacker
|
||||
* This is achieved by first sending a ping, and afterwards an ICMPv6 Packet Too Big message
|
||||
* which states that the response from the ping was too big, our MTU is smaller than the IPv6 minimum MTU */
|
||||
static void ipv6_force_fragmentation(struct idle_proxy_info *proxy, Target *target) {
|
||||
int hardtimeout = 9000000; /* Generally don't wait more than 9 secs total */
|
||||
char filter[512]; /* Libpcap filter string */
|
||||
struct ip *ip;
|
||||
/* The maximum data size we can create without fragmenting, considering that the headers also need place */
|
||||
char data[IP6_MTU_MIN - IPv6_HEADER_LEN - ETH_HDR_LEN - ICMPv6_MIN_HEADER_LEN];
|
||||
unsigned int datalen, bytes;
|
||||
const unsigned int proxy_reply_timeout = 2000;
|
||||
const void *rdata; //the data received in the echo response
|
||||
struct timeval tmptv, rcvdtime, ipv6_packet_send_time;
|
||||
struct abstract_ip_hdr hdr;
|
||||
bool response_received = false;
|
||||
struct icmpv6_hdr *icmp6_header;
|
||||
u8 *ipv6_packet = NULL;
|
||||
u32 packetlen = 0;
|
||||
u16 pingid = 0;
|
||||
u16 seq = 0;
|
||||
struct sockaddr_storage ss;
|
||||
size_t sslen;
|
||||
int res;
|
||||
assert(proxy);
|
||||
|
||||
/* First, we force the proxy to provide us with a fragmentation header in each packet
|
||||
by sending an ping and afterwards an ICMPv6 Packet Too Big */
|
||||
memset(data,'A', sizeof(data));
|
||||
pingid = get_random_u16();
|
||||
seq = get_random_u16();
|
||||
|
||||
/* pcap, to get the answer. Max size here is the IPv6 minimum MTU */
|
||||
if ((proxy->pd = my_pcap_open_live(proxy->host.deviceName(), IP6_MTU_MIN, (o.spoofsource) ? 1 : 0, 50)) == NULL)
|
||||
fatal("%s", PCAP_OPEN_ERRMSG);
|
||||
|
||||
Snprintf(filter, sizeof(filter), "icmp6 and src host %s and dst host %s", proxy->host.targetipstr(), proxy->host.sourceipstr());
|
||||
if (o.debugging)
|
||||
log_write(LOG_STDOUT, "Packet capture filter (device %s): %s\n", proxy->host.deviceFullName(), filter);
|
||||
|
||||
/* Make a ping that is in total 1280 byte long and send it */
|
||||
proxy->host.TargetSockAddr(&ss, &sslen);
|
||||
ipv6_packet = build_icmpv6_raw(proxy->host.v6sourceip(), proxy->host.v6hostip(), 0x00, 0x0000, o.ttl, seq , pingid, ICMPV6_ECHO, 0x00, data, sizeof(data) , &packetlen);
|
||||
res = send_ip_packet(proxy->rawsd, proxy->ethptr, &ss, ipv6_packet, packetlen);
|
||||
if (res == -1)
|
||||
fatal("Error occured while trying to send ICMPv6 Echo Request to the idle host");
|
||||
free(ipv6_packet);
|
||||
gettimeofday(&ipv6_packet_send_time, NULL);
|
||||
|
||||
/* Now let's wait for the answer */
|
||||
while (!response_received) {
|
||||
gettimeofday(&tmptv, NULL);
|
||||
ip = (struct ip *) readip_pcap(proxy->pd, &bytes, proxy_reply_timeout, &rcvdtime, NULL, true);
|
||||
if (!ip) {
|
||||
if (TIMEVAL_SUBTRACT(tmptv, ipv6_packet_send_time) >= hardtimeout) {
|
||||
fatal("Idle scan zombie %s (%s) port %hu cannot be used because it has not returned any of our ICMPv6 Echo Requests -- perhaps it is down or firewalled.",
|
||||
proxy->host.HostName(), proxy->host.targetipstr(),
|
||||
proxy->probe_port);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
datalen = bytes;
|
||||
rdata = ip_get_data(ip, &datalen, &hdr);
|
||||
if (hdr.version == 6 && hdr.proto == IPPROTO_ICMPV6) {
|
||||
icmp6_header = (struct icmpv6_hdr *) rdata;
|
||||
if (icmp6_header->icmpv6_type == ICMPV6_ECHOREPLY) {
|
||||
const struct icmpv6_msg_echo *echo;
|
||||
echo = (struct icmpv6_msg_echo *) ((u8 *) icmp6_header + sizeof(*icmp6_header));
|
||||
if (ntohs(echo->icmpv6_id) == pingid && ntohs(echo->icmpv6_seq) == seq)
|
||||
response_received=true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (proxy->pd)
|
||||
pcap_close(proxy->pd);
|
||||
|
||||
/* Now we can tell the idle host that its reply was too big, we want it smaller than the IPV6 minimum MTU */
|
||||
/* the data contains first the MTU we want, and then the received IPv6 package */
|
||||
*(uint32_t *)&data = ntohl(IP6_MTU_MIN - 2);
|
||||
memcpy(&data[4], ip, sizeof(data)-4);
|
||||
|
||||
ipv6_packet = build_icmpv6_raw(proxy->host.v6sourceip(), proxy->host.v6hostip(), 0x00, 0x0000, o.ttl, 0x00 , 0x00, 0x02, 0x00, data, sizeof(data) , &packetlen);
|
||||
res = send_ip_packet(proxy->rawsd, proxy->ethptr, &ss, ipv6_packet, packetlen);
|
||||
if (res == -1)
|
||||
fatal("Error occured while trying to send spoofed ICMPv6 Echo Request to the idle host");
|
||||
|
||||
free(ipv6_packet);
|
||||
|
||||
/* Now we do the same in the name of the target */
|
||||
/* No pcap this time, we won't receive the answer */
|
||||
memset(data,'A', sizeof(data));
|
||||
pingid = get_random_u16();
|
||||
seq = get_random_u16();
|
||||
|
||||
ipv6_packet = build_icmpv6_raw(target->v6hostip(), proxy->host.v6hostip(), 0x00, 0x0000, o.ttl, seq , pingid, ICMPV6_ECHO, 0x00, data, sizeof(data) , &packetlen);
|
||||
res = send_ip_packet(proxy->rawsd, proxy->ethptr, &ss, ipv6_packet, packetlen);
|
||||
if (res == -1)
|
||||
fatal("Error occured while trying to send ICMPv6 Echo Request to the idle host");
|
||||
|
||||
free(ipv6_packet);
|
||||
|
||||
/* Now we guess what answer the decoy host sent to the target, so that we can piggyback this on the ICMPV6 Packet too Big message */
|
||||
ipv6_packet = build_icmpv6_raw(proxy->host.v6hostip(), target->v6hostip(), 0x00, 0x0000, o.ttl, seq , pingid, ICMPV6_ECHOREPLY, 0x00, data, sizeof(data) , &packetlen);
|
||||
*(uint32_t *)&data = ntohl(IP6_MTU_MIN - 2);
|
||||
memcpy(&data[4], ipv6_packet, sizeof(data)-4);
|
||||
free(ipv6_packet);
|
||||
|
||||
ipv6_packet = build_icmpv6_raw(target->v6hostip(), proxy->host.v6hostip(), 0x00, 0x0000, o.ttl, 0x00 , 0x00, 0x02, 0x00, data, sizeof(data) , &packetlen);
|
||||
/* give the decoy host time to reply to the target */
|
||||
usleep(10000);
|
||||
res = send_ip_packet(proxy->rawsd, proxy->ethptr, &ss, ipv6_packet, packetlen);
|
||||
if (res == -1)
|
||||
fatal("Error occured while trying to send ICMPv6 PTB to the idle host");
|
||||
free(ipv6_packet);
|
||||
}
|
||||
|
||||
/* takes a proxy name/IP, resolves it if necessary, 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 6
|
||||
static void initialize_idleproxy(struct idle_proxy_info *proxy, char *proxyName,
|
||||
const struct in_addr *first_target, const struct scan_lists *ports) {
|
||||
int probes_sent = 0, probes_returned = 0;
|
||||
Target *target, const struct scan_lists *ports) {
|
||||
unsigned 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 *p, *q = NULL, *r;
|
||||
char *endptr = NULL;
|
||||
int seq_response_num;
|
||||
int newipid;
|
||||
int i;
|
||||
unsigned int i;
|
||||
char filter[512]; /* Libpcap filter string */
|
||||
char name[MAXHOSTNAMELEN + 1];
|
||||
struct sockaddr_storage ss;
|
||||
@@ -333,8 +531,16 @@ static void initialize_idleproxy(struct idle_proxy_info *proxy, char *proxyName,
|
||||
int ipids[NUM_IPID_PROBES];
|
||||
u8 probe_returned[NUM_IPID_PROBES];
|
||||
struct route_nfo rnfo;
|
||||
assert(proxyName);
|
||||
u8 *ipv6_packet = NULL;
|
||||
u32 packetlen = 0;
|
||||
const struct ip6_hdr *ip6;
|
||||
u8 ip6hdr;
|
||||
const void *ip6data;
|
||||
bool retried_forcing_fragmentation = false;
|
||||
assert(proxy);
|
||||
assert(proxyName);
|
||||
int res;
|
||||
|
||||
ack = get_random_u32();
|
||||
|
||||
@@ -348,8 +554,26 @@ static void initialize_idleproxy(struct idle_proxy_info *proxy, char *proxyName,
|
||||
proxy->max_groupsz = MAX(proxy->min_groupsz, o.max_parallelism ? o.max_parallelism : 100);
|
||||
proxy->max_senddelay = 100000;
|
||||
|
||||
Strncpy(name, proxyName, sizeof(name));
|
||||
q = strchr(name, ':');
|
||||
|
||||
/* If we have an IPv6 address, we specify the port with [address]:port */
|
||||
if (o.af() == AF_INET)
|
||||
q = strchr(proxyName, ':');
|
||||
else if (o.af() == AF_INET6) {
|
||||
r = strstr(proxyName, "]:");
|
||||
if (r != NULL)
|
||||
q = strchr(r, ':');
|
||||
else
|
||||
q = NULL;
|
||||
}
|
||||
|
||||
/* If we have a : in IPv4 or [] in IPv6, we strip them off */
|
||||
if (o.af() == AF_INET && strchr(proxyName, ':') != NULL )
|
||||
strncpy(name, proxyName , MIN(strcspn(proxyName,":") , sizeof(name)));
|
||||
else if (o.af() == AF_INET6 && strchr(proxyName, '[') != NULL && strchr(proxyName, ']') != NULL)
|
||||
strncpy(name, strchr(proxyName, '[') + 1, MIN(strcspn(proxyName,"]") - strcspn(proxyName, "[") - 1, sizeof(name)));
|
||||
else
|
||||
strncpy(name, proxyName, sizeof(name));
|
||||
|
||||
if (q) {
|
||||
*q++ = '\0';
|
||||
proxy->probe_port = strtoul(q, &endptr, 10);
|
||||
@@ -427,18 +651,21 @@ static void initialize_idleproxy(struct idle_proxy_info *proxy, char *proxyName,
|
||||
proxy->ethptr = NULL;
|
||||
}
|
||||
|
||||
/* Now for the pcap opening nonsense ... */
|
||||
/* Note that the snaplen is 152 = 64 byte max IPhdr + 24 byte max link_layer
|
||||
* header + 64 byte max TCP header. */
|
||||
if ((proxy->pd = my_pcap_open_live(proxy->host.deviceName(), 152, (o.spoofsource) ? 1 : 0, 50)) == NULL)
|
||||
if (proxy->host.af() == AF_INET6)
|
||||
ipv6_force_fragmentation(proxy, target);
|
||||
|
||||
/* Now for the pcap opening nonsense ...
|
||||
Snaplen will be the IPv6 minimum MTU of 1280, because an IPv6 packet
|
||||
may have any number of extension header up to the minimal IPv6 MTU */
|
||||
if ((proxy->pd = my_pcap_open_live(proxy->host.deviceName(), IP6_MTU_MIN, (o.spoofsource) ? 1 : 0, 50)) == NULL)
|
||||
fatal("%s", PCAP_OPEN_ERRMSG);
|
||||
|
||||
|
||||
p = strdup(proxy->host.targetipstr());
|
||||
q = strdup(inet_ntoa(proxy->host.v4source()));
|
||||
Snprintf(filter, sizeof(filter), "tcp and src host %s and dst host %s and src port %hu", p, q, proxy->probe_port);
|
||||
free(p);
|
||||
free(q);
|
||||
p = (char *) proxy->host.targetipstr();
|
||||
q = (char *) proxy->host.sourceipstr();
|
||||
|
||||
/* libpcap doesn't find the source port in IPv6 if there is an extension header. So we check for this later in the tcp header. */
|
||||
Snprintf(filter, sizeof(filter), "tcp and src host %s and dst host %s", p, q);
|
||||
set_pcap_filter(proxy->host.deviceFullName(), proxy->pd, filter);
|
||||
if (o.debugging)
|
||||
log_write(LOG_STDOUT, "Packet capture filter (device %s): %s\n", proxy->host.deviceFullName(), filter);
|
||||
@@ -461,14 +688,30 @@ static void initialize_idleproxy(struct idle_proxy_info *proxy, char *proxyName,
|
||||
a response with the exact request for timing purposes. So I
|
||||
think I'll use TH_SYN, although it is a tough call. */
|
||||
/* We can't use decoys 'cause that would screw up the IP IDs */
|
||||
send_tcp_raw(proxy->rawsd, proxy->ethptr,
|
||||
proxy->host.v4sourceip(), proxy->host.v4hostip(),
|
||||
o.ttl, false,
|
||||
o.ipoptions, o.ipoptionslen,
|
||||
o.magic_port + probes_sent + 1, proxy->probe_port,
|
||||
sequence_base + probes_sent + 1, ack, 0, TH_SYN | TH_ACK, 0, 0,
|
||||
(u8 *) "\x02\x04\x05\xb4", 4,
|
||||
NULL, 0);
|
||||
if (o.af() == AF_INET)
|
||||
send_tcp_raw(proxy->rawsd, proxy->ethptr,
|
||||
proxy->host.v4sourceip(), proxy->host.v4hostip(),
|
||||
o.ttl, false,
|
||||
o.ipoptions, o.ipoptionslen,
|
||||
o.magic_port + probes_sent + 1, proxy->probe_port,
|
||||
sequence_base + probes_sent + 1, ack, 0, TH_SYN | TH_ACK, 0, 0,
|
||||
(u8 *) "\x02\x04\x05\xb4", 4,
|
||||
NULL, 0);
|
||||
else if (o.af() == AF_INET6) {
|
||||
ipv6_packet = build_tcp_raw_ipv6(proxy->host.v6sourceip(), proxy->host.v6hostip(),
|
||||
0x00, 0x0000,
|
||||
o.ttl,
|
||||
o.magic_port + probes_sent + 1, proxy->probe_port,
|
||||
sequence_base + probes_sent + 1, ack, 0, TH_SYN | TH_ACK, 0, 0,
|
||||
(u8 *) "\x02\x04\x05\xb4", 4,
|
||||
NULL, 0,
|
||||
&packetlen);
|
||||
res = send_ip_packet(proxy->rawsd, proxy->ethptr, &ss, ipv6_packet, packetlen);
|
||||
if (res == -1)
|
||||
fatal("Error occured while trying to send IPv6 packet");
|
||||
free(ipv6_packet);
|
||||
}
|
||||
|
||||
gettimeofday(&probe_send_times[probes_sent], NULL);
|
||||
probes_sent++;
|
||||
|
||||
@@ -476,7 +719,7 @@ static void initialize_idleproxy(struct idle_proxy_info *proxy, char *proxyName,
|
||||
while (probes_returned < probes_sent && !timedout) {
|
||||
|
||||
to_usec = (probes_sent == NUM_IPID_PROBES) ? hardtimeout : 1000;
|
||||
ip = (struct ip *) readipv4_pcap(proxy->pd, &bytes, to_usec, &rcvdtime, NULL, true);
|
||||
ip = (struct ip *) readip_pcap(proxy->pd, &bytes, to_usec, &rcvdtime, NULL, true);
|
||||
|
||||
gettimeofday(&tmptv, NULL);
|
||||
|
||||
@@ -491,32 +734,94 @@ static void initialize_idleproxy(struct idle_proxy_info *proxy, char *proxyName,
|
||||
timedout = 1;
|
||||
}
|
||||
|
||||
if (lastipid != 0 && ip->ip_id == lastipid) {
|
||||
continue; /* probably a duplicate */
|
||||
}
|
||||
lastipid = ip->ip_id;
|
||||
|
||||
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) < (o.magic_port + 1) || ntohs(tcp->th_dport) - o.magic_port > NUM_IPID_PROBES || ntohs(tcp->th_sport) != proxy->probe_port || ((tcp->th_flags & TH_RST) == 0)) {
|
||||
if (o.debugging > 1)
|
||||
error("Received unexpected response packet from %s during initial IP ID zombie testing", inet_ntoa(ip->ip_src));
|
||||
if (o.af() == AF_INET) {
|
||||
if (ip->ip_v != 4) {
|
||||
error("Received a packet with version field != 4");
|
||||
continue;
|
||||
}
|
||||
if (lastipid != 0 && ip->ip_id == lastipid) {
|
||||
continue; /* probably a duplicate */
|
||||
}
|
||||
lastipid = ip->ip_id;
|
||||
if (bytes < ( 4 * ip->ip_hl) + 14U)
|
||||
continue;
|
||||
|
||||
seq_response_num = probes_returned;
|
||||
if (ip->ip_p == IPPROTO_TCP) {
|
||||
tcp = ((struct tcp_hdr *) (((char *) ip) + 4 * ip->ip_hl));
|
||||
/* Checking now for the source port, which we were not able to do in the libpcap filter */
|
||||
if (ntohs(tcp->th_sport) != proxy->probe_port) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* The stuff below only works when we send SYN packets instead of
|
||||
SYN|ACK, but then are slightly less stealthy and have less chance
|
||||
of sneaking through the firewall. Plus SYN|ACK is what they will
|
||||
be receiving back from the target */
|
||||
probes_returned++;
|
||||
ipids[seq_response_num] = ntohs(ip->ip_id);
|
||||
probe_returned[seq_response_num] = 1;
|
||||
adjust_timeouts2(&probe_send_times[seq_response_num], &rcvdtime, &(proxy->host.to));
|
||||
if (ntohs(tcp->th_dport) < (o.magic_port + 1) || ntohs(tcp->th_dport) - o.magic_port > NUM_IPID_PROBES || ((tcp->th_flags & TH_RST) == 0)) {
|
||||
if (o.debugging > 1)
|
||||
error("Received unexpected response packet from %s during initial IP ID zombie testing", inet_ntoa(ip->ip_src));
|
||||
continue;
|
||||
}
|
||||
|
||||
seq_response_num = probes_returned;
|
||||
|
||||
/* The stuff below only works when we send SYN packets instead of
|
||||
SYN|ACK, but then are slightly less stealthy and have less chance
|
||||
of sneaking through the firewall. Plus SYN|ACK is what they will
|
||||
be receiving back from the target */
|
||||
probes_returned++;
|
||||
ipids[seq_response_num] = ntohs(ip->ip_id);
|
||||
probe_returned[seq_response_num] = 1;
|
||||
adjust_timeouts2(&probe_send_times[seq_response_num], &rcvdtime, &(proxy->host.to));
|
||||
}
|
||||
} else if (o.af() == AF_INET6) {
|
||||
if (ip->ip_v != 6) {
|
||||
error("Received a packet with version field != 6");
|
||||
continue;
|
||||
} else {
|
||||
ip6 = (struct ip6_hdr *) ip;
|
||||
newipid = ipv6_get_fragment_id(ip6, bytes);
|
||||
if (newipid < 0 ) {
|
||||
/* ok, the idle host does not seem to append the extension header for fragmentation. Let's try this once more,
|
||||
* maybe the idle host just adjusted its Path MTU. If we keep on having the problem, we quit */
|
||||
if (!retried_forcing_fragmentation) {
|
||||
ipv6_force_fragmentation(proxy, target);
|
||||
retried_forcing_fragmentation = true;
|
||||
} else
|
||||
fatal("IPv6 packet without fragmentation header received - issues with the zombie?");
|
||||
}
|
||||
/* now that the additional ipv6 stuff is done, we do as for IPv4 */
|
||||
if (lastipid != 0 && newipid == (int)lastipid) {
|
||||
continue; /* probably a duplicate */
|
||||
}
|
||||
lastipid = newipid;
|
||||
|
||||
ip6data = ipv6_get_data(ip6, &packetlen, &ip6hdr);
|
||||
if (ip6hdr == IPPROTO_TCP && ip6data != NULL) {
|
||||
tcp = (struct tcp_hdr *) ip6data;
|
||||
/* Checking now for the source port, which we were not able to do in the libpcap filter */
|
||||
if (ntohs(tcp->th_sport) != proxy->probe_port) {
|
||||
continue;
|
||||
}
|
||||
}else
|
||||
{
|
||||
error("Malformed packet received");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ntohs(tcp->th_dport) < (o.magic_port + 1) || ntohs(tcp->th_dport) - o.magic_port > NUM_IPID_PROBES || ((tcp->th_flags & TH_RST) == 0)) {
|
||||
if (o.debugging > 1)
|
||||
error("Received unexpected response packet from %s during initial IP ID zombie testing", inet_ntoa(ip->ip_src));
|
||||
continue;
|
||||
}
|
||||
|
||||
seq_response_num = probes_returned;
|
||||
|
||||
/* The stuff below only works when we send SYN packets instead of
|
||||
SYN|ACK, but then are slightly less stealthy and have less chance
|
||||
of sneaking through the firewall. Plus SYN|ACK is what they will
|
||||
be receiving back from the target */
|
||||
probes_returned++;
|
||||
ipids[seq_response_num] = newipid;
|
||||
probe_returned[seq_response_num] = 1;
|
||||
adjust_timeouts2(&probe_send_times[seq_response_num], &rcvdtime, &(proxy->host.to));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -535,9 +840,13 @@ static void initialize_idleproxy(struct idle_proxy_info *proxy, char *proxyName,
|
||||
proxy->host.HostName(), proxy->host.targetipstr(),
|
||||
proxy->probe_port);
|
||||
|
||||
proxy->seqclass = get_ipid_sequence(probes_returned, ipids, 0);
|
||||
if (o.af() == AF_INET)
|
||||
proxy->seqclass = get_ipid_sequence_16(probes_returned, ipids, 0);
|
||||
else
|
||||
proxy->seqclass = get_ipid_sequence_32(probes_returned, ipids, 0);
|
||||
switch (proxy->seqclass) {
|
||||
case IPID_SEQ_INCR:
|
||||
case IPID_SEQ_INCR_BY_2:
|
||||
case IPID_SEQ_BROKEN_INCR:
|
||||
log_write(LOG_PLAIN, "Idle scan using zombie %s (%s:%hu); Class: %s\n", proxy->host.HostName(), proxy->host.targetipstr(), proxy->probe_port, ipidclass2ascii(proxy->seqclass));
|
||||
break;
|
||||
@@ -568,19 +877,34 @@ static void initialize_idleproxy(struct idle_proxy_info *proxy, char *proxyName,
|
||||
changed. This will also catch the case where the Nmap user is
|
||||
behind an egress filter or other measure that prevents this sort of
|
||||
sp00fery */
|
||||
if (first_target) {
|
||||
/* this behavior gets quite common in IPv6 so now its even more important to check */
|
||||
if (target->v4hostip() || target->v6hostip()) {
|
||||
for (probes_sent = 0; probes_sent < 4; probes_sent++) {
|
||||
if (probes_sent != 0)
|
||||
usleep(50000);
|
||||
send_tcp_raw(proxy->rawsd, proxy->ethptr,
|
||||
first_target, proxy->host.v4hostip(),
|
||||
o.ttl, false,
|
||||
o.ipoptions, o.ipoptionslen,
|
||||
o.magic_port, proxy->probe_port,
|
||||
sequence_base + probes_sent + 1, ack, 0, TH_SYN | TH_ACK, 0, 0,
|
||||
(u8 *) "\x02\x04\x05\xb4",
|
||||
4, NULL, 0);
|
||||
|
||||
if (target->v4hostip()) {
|
||||
send_tcp_raw(proxy->rawsd, proxy->ethptr,
|
||||
target->v4hostip(), proxy->host.v4hostip(),
|
||||
o.ttl, false,
|
||||
o.ipoptions, o.ipoptionslen,
|
||||
o.magic_port, proxy->probe_port,
|
||||
sequence_base + probes_sent + 1, ack, 0, TH_SYN | TH_ACK, 0, 0,
|
||||
(u8 *) "\x02\x04\x05\xb4",
|
||||
4, NULL, 0);
|
||||
} else {
|
||||
ipv6_packet = build_tcp_raw_ipv6(target->v6hostip(), proxy->host.v6hostip(),
|
||||
0x00, 0x0000,
|
||||
o.ttl,
|
||||
o.magic_port, proxy->probe_port,
|
||||
sequence_base + probes_sent + 1, ack, 0, TH_SYN | TH_ACK, 0, 0,
|
||||
(u8 *) "\x02\x04\x05\xb4",
|
||||
4, NULL, 0,
|
||||
&packetlen);
|
||||
res = send_ip_packet(proxy->rawsd, proxy->ethptr, &ss, ipv6_packet, packetlen);
|
||||
if (res == -1)
|
||||
fatal("Error occured while trying to send IPv6 packet ");
|
||||
free(ipv6_packet);
|
||||
}
|
||||
}
|
||||
|
||||
/* Sleep a little while to give packets time to reach their destination */
|
||||
@@ -695,10 +1019,16 @@ static int idlescan_countopen2(struct idle_proxy_info *proxy,
|
||||
int lasttry = 0;
|
||||
int dotry3 = 0;
|
||||
struct eth_nfo eth;
|
||||
u8 *packet = NULL;
|
||||
struct sockaddr_storage ss;
|
||||
size_t sslen;
|
||||
u32 packetlen = 0;
|
||||
int res;
|
||||
|
||||
if (seq == 0)
|
||||
seq = get_random_u32();
|
||||
|
||||
target->TargetSockAddr(&ss, &sslen);
|
||||
memset(&end, 0, sizeof(end));
|
||||
memset(&latestchange, 0, sizeof(latestchange));
|
||||
gettimeofday(&start, NULL);
|
||||
@@ -727,13 +1057,27 @@ static int idlescan_countopen2(struct idle_proxy_info *proxy,
|
||||
but doing it the straightforward way (using the same decoys as
|
||||
we use in probing the proxy box is risky. I'll have to think
|
||||
about this more. */
|
||||
send_tcp_raw(proxy->rawsd, eth.ethsd ? ð : NULL,
|
||||
proxy->host.v4hostip(), target->v4hostip(),
|
||||
o.ttl, false,
|
||||
o.ipoptions, o.ipoptionslen,
|
||||
proxy->probe_port, ports[pr0be], seq, 0, 0, TH_SYN, 0, 0,
|
||||
(u8 *) "\x02\x04\x05\xb4", 4,
|
||||
o.extra_payload, o.extra_payload_length);
|
||||
if ( o.af() == AF_INET ) {
|
||||
send_tcp_raw(proxy->rawsd, eth.ethsd ? ð : NULL,
|
||||
proxy->host.v4hostip(), target->v4hostip(),
|
||||
o.ttl, false,
|
||||
o.ipoptions, o.ipoptionslen,
|
||||
proxy->probe_port, ports[pr0be], seq, 0, 0, TH_SYN, 0, 0,
|
||||
(u8 *) "\x02\x04\x05\xb4", 4,
|
||||
o.extra_payload, o.extra_payload_length);
|
||||
} else {
|
||||
packet = build_tcp_raw_ipv6(proxy->host.v6hostip(), target->v6hostip(),
|
||||
0x00, 0x0000,
|
||||
o.ttl,
|
||||
proxy->probe_port, ports[pr0be], seq, 0, 0, TH_SYN, 0, 0,
|
||||
(u8 *) "\x02\x04\x05\xb4", 4,
|
||||
o.extra_payload, o.extra_payload_length,
|
||||
&packetlen);
|
||||
res = send_ip_packet(proxy->rawsd, eth.ethsd ? ð : NULL, &ss, packet, packetlen);
|
||||
if (res == -1)
|
||||
fatal("Error occured while trying to send IPv6 packet");
|
||||
free(packet);
|
||||
}
|
||||
}
|
||||
gettimeofday(&end, NULL);
|
||||
|
||||
@@ -1044,7 +1388,7 @@ void idle_scan(Target *target, u16 *portarray, int numports,
|
||||
|
||||
/* If this is the first call, */
|
||||
if (!*lastproxy) {
|
||||
initialize_idleproxy(&proxy, proxyName, target->v4hostip(), ports);
|
||||
initialize_idleproxy(&proxy, proxyName, target, ports);
|
||||
strncpy(lastproxy, proxyName, sizeof(lastproxy));
|
||||
}
|
||||
|
||||
|
||||
2
nmap.cc
2
nmap.cc
@@ -2689,6 +2689,8 @@ const char *ipidclass2ascii(int seqclass) {
|
||||
return "Duplicated ipid (!)";
|
||||
case IPID_SEQ_INCR:
|
||||
return "Incremental";
|
||||
case IPID_SEQ_INCR_BY_2:
|
||||
return "Incrementing by 2";
|
||||
case IPID_SEQ_BROKEN_INCR:
|
||||
return "Broken little-endian incremental";
|
||||
case IPID_SEQ_RD:
|
||||
|
||||
1
nmap.h
1
nmap.h
@@ -410,6 +410,7 @@ void *realloc();
|
||||
#define IPID_SEQ_RD 4 /* Appears to select IPID using a "random" distributions (meaning it can go up or down) */
|
||||
#define IPID_SEQ_CONSTANT 5 /* Contains 1 or more sequential duplicates */
|
||||
#define IPID_SEQ_ZERO 6 /* Every packet that comes back has an IP.ID of 0 (eg Linux 2.4 does this) */
|
||||
#define IPID_SEQ_INCR_BY_2 7 /* simple increment by two each time */
|
||||
|
||||
#ifndef MAXHOSTNAMELEN
|
||||
#define MAXHOSTNAMELEN 64
|
||||
|
||||
99
osscan2.cc
99
osscan2.cc
@@ -198,6 +198,7 @@ static struct AVal *make_aval_ipid_seq(struct AVal *av, const char *attribute,
|
||||
case IPID_SEQ_CONSTANT:
|
||||
av->value = string_pool_sprintf("%X", ipids[0]);
|
||||
break;
|
||||
case IPID_SEQ_INCR_BY_2:
|
||||
case IPID_SEQ_INCR:
|
||||
av->value = "I";
|
||||
break;
|
||||
@@ -247,32 +248,9 @@ int get_initial_ttl_guess(u8 ttl) {
|
||||
one of the IPID_SEQ_* classifications defined in nmap.h . If the
|
||||
function cannot determine the sequence, IPID_SEQ_UNKNOWN is returned.
|
||||
This islocalhost argument is a boolean specifying whether these
|
||||
numbers were generated by scanning localhost. NOTE: the "ipids" argument
|
||||
may be modified if localhost is set to true. */
|
||||
int get_ipid_sequence(int numSamples, int *ipids, int islocalhost) {
|
||||
u16 ipid_diffs[32];
|
||||
int i, j, k;
|
||||
int allipideqz = 1; /* Flag that means "All IP.IDs returned during sequencing
|
||||
* are zero. This is unset if we find a nonzero */
|
||||
|
||||
assert(numSamples < (int) (sizeof(ipid_diffs) / 2));
|
||||
if (numSamples < 2)
|
||||
return IPID_SEQ_UNKNOWN;
|
||||
|
||||
for (i = 1; i < numSamples; i++) {
|
||||
if (ipids[i - 1] != 0 || ipids[i] != 0)
|
||||
allipideqz = 0; /* All IP.ID values do *NOT* equal zero */
|
||||
|
||||
if (ipids[i - 1] <= ipids[i]) {
|
||||
ipid_diffs[i - 1] = ipids[i] - ipids[i - 1];
|
||||
} else {
|
||||
ipid_diffs[i - 1] = (u16) (ipids[i] - ipids[i - 1] + 65536);
|
||||
}
|
||||
|
||||
/* Random */
|
||||
if (numSamples > 2 && ipid_diffs[i - 1] > 20000)
|
||||
return IPID_SEQ_RD;
|
||||
}
|
||||
numbers were generated by scanning localhost. */
|
||||
int identify_sequence(int numSamples, u32 *ipid_diffs, int islocalhost, int allipideqz) {
|
||||
int i, j, k, l;
|
||||
|
||||
/* ZERO */
|
||||
if (allipideqz)
|
||||
@@ -321,11 +299,16 @@ int get_ipid_sequence(int numSamples, int *ipids, int islocalhost) {
|
||||
j = 1; /* j is a flag meaning "all differences seen are < 10" */
|
||||
k = 1; /* k is a flag meaning "all difference seen are multiples of 256 and
|
||||
* no greater than 5120" */
|
||||
l = 1; /* l is a flag meaning "all differences are multiples of 2" */
|
||||
for (i = 0; i < numSamples - 1; i++) {
|
||||
if (k && (ipid_diffs[i] > 5120 || ipid_diffs[i] % 256 != 0)) {
|
||||
k = 0;
|
||||
}
|
||||
|
||||
if (l && ipid_diffs[i] % 2 != 0) {
|
||||
l = 0;
|
||||
}
|
||||
|
||||
if (j && ipid_diffs[i] > 9) {
|
||||
j = 0;
|
||||
}
|
||||
@@ -336,13 +319,69 @@ int get_ipid_sequence(int numSamples, int *ipids, int islocalhost) {
|
||||
return IPID_SEQ_BROKEN_INCR;
|
||||
}
|
||||
|
||||
/* Incremental */
|
||||
/* Incrementing by 2 */
|
||||
if (l == 1)
|
||||
return IPID_SEQ_INCR_BY_2;
|
||||
|
||||
/* Incremental by 1 */
|
||||
if (j == 1)
|
||||
return IPID_SEQ_INCR;
|
||||
|
||||
return IPID_SEQ_UNKNOWN;
|
||||
}
|
||||
|
||||
/* Calculate the distances between the ipids and write them
|
||||
into the ipid_diffs array */
|
||||
int get_diffs(u32 *ipid_diffs, int numSamples, int *ipids, int islocalhost) {
|
||||
int i;
|
||||
int allipideqz = 1;
|
||||
|
||||
if (numSamples < 2)
|
||||
return IPID_SEQ_UNKNOWN;
|
||||
|
||||
for (i = 1; i < numSamples; i++) {
|
||||
if (ipids[i - 1] != 0 || ipids[i] != 0)
|
||||
allipideqz = 0; /* All IP.ID values do *NOT* equal zero */
|
||||
|
||||
if (ipids[i - 1] <= ipids[i]) {
|
||||
ipid_diffs[i - 1] = ipids[i] - ipids[i - 1];
|
||||
} else {
|
||||
ipid_diffs[i - 1] = (u32) (ipids[i] - ipids[i - 1] + 4294967296);
|
||||
}
|
||||
|
||||
/* Random */
|
||||
if (numSamples > 2 && ipid_diffs[i - 1] > 20000)
|
||||
return IPID_SEQ_RD;
|
||||
}
|
||||
|
||||
return allipideqz;
|
||||
|
||||
}
|
||||
|
||||
/* Indentify the ipid sequence for 32-bit IPID values (IPv6) */
|
||||
int get_ipid_sequence_32(int numSamples, int *ipids, int islocalhost) {
|
||||
int allipideqz=1;
|
||||
u32 ipid_diffs[32];
|
||||
assert(numSamples < (int) (sizeof(ipid_diffs) / 2));
|
||||
allipideqz = get_diffs(ipid_diffs, numSamples, ipids, islocalhost);
|
||||
return identify_sequence(numSamples, ipid_diffs, islocalhost, allipideqz);
|
||||
}
|
||||
|
||||
/* Indentify the ipid sequence for 16-bit IPID values (IPv4) */
|
||||
int get_ipid_sequence_16(int numSamples, int *ipids, int islocalhost) {
|
||||
int i;
|
||||
int allipideqz=1;
|
||||
u32 ipid_diffs[32];
|
||||
assert(numSamples < (int) (sizeof(ipid_diffs) / 2));
|
||||
allipideqz = get_diffs(ipid_diffs, numSamples, ipids, islocalhost);
|
||||
/* AND with 0xffff so that in case the 16 bit counter was
|
||||
* flipped over we still have a continuous sequence */
|
||||
for (i = 0; i < numSamples; i++) {
|
||||
ipid_diffs[i] = ipid_diffs[i] & 0xffff;
|
||||
}
|
||||
return identify_sequence(numSamples, ipid_diffs, islocalhost, allipideqz);
|
||||
}
|
||||
|
||||
|
||||
/* Start the timeout clocks of any targets that aren't already timedout */
|
||||
static void startTimeOutClocks(OsScanInfo *OSI) {
|
||||
@@ -2374,7 +2413,7 @@ void HostOsScan::makeTSeqFP(HostOsScanStats *hss) {
|
||||
}
|
||||
|
||||
if (good_tcp_ipid_num >= 3) {
|
||||
tcp_ipid_seqclass = get_ipid_sequence(good_tcp_ipid_num, hss->ipid.tcp_ipids, islocalhost(hss->target->TargetSockAddr()));
|
||||
tcp_ipid_seqclass = get_ipid_sequence_16(good_tcp_ipid_num, hss->ipid.tcp_ipids, islocalhost(hss->target->TargetSockAddr()));
|
||||
} else {
|
||||
tcp_ipid_seqclass = IPID_SEQ_UNKNOWN;
|
||||
}
|
||||
@@ -2382,13 +2421,13 @@ void HostOsScan::makeTSeqFP(HostOsScanStats *hss) {
|
||||
hss->si.ipid_seqclass = tcp_ipid_seqclass;
|
||||
|
||||
if (good_tcp_closed_ipid_num >= 2) {
|
||||
tcp_closed_ipid_seqclass = get_ipid_sequence(good_tcp_closed_ipid_num, hss->ipid.tcp_closed_ipids, islocalhost(hss->target->TargetSockAddr()));
|
||||
tcp_closed_ipid_seqclass = get_ipid_sequence_16(good_tcp_closed_ipid_num, hss->ipid.tcp_closed_ipids, islocalhost(hss->target->TargetSockAddr()));
|
||||
} else {
|
||||
tcp_closed_ipid_seqclass = IPID_SEQ_UNKNOWN;
|
||||
}
|
||||
|
||||
if (good_icmp_ipid_num >= 2) {
|
||||
icmp_ipid_seqclass = get_ipid_sequence(good_icmp_ipid_num, hss->ipid.icmp_ipids, islocalhost(hss->target->TargetSockAddr()));
|
||||
icmp_ipid_seqclass = get_ipid_sequence_16(good_icmp_ipid_num, hss->ipid.icmp_ipids, islocalhost(hss->target->TargetSockAddr()));
|
||||
} else {
|
||||
icmp_ipid_seqclass = IPID_SEQ_UNKNOWN;
|
||||
}
|
||||
|
||||
@@ -187,8 +187,11 @@ typedef enum OFProbeType {
|
||||
void os_scan2(std::vector<Target *> &Targets);
|
||||
|
||||
int get_initial_ttl_guess(u8 ttl);
|
||||
int get_ipid_sequence(int numSamples, int *ipids, int islocalhost);
|
||||
|
||||
int identify_sequence(int numSamples, u32 *ipid_diffs, int islocalhost, int allipideqz);
|
||||
int get_diffs(u32 *ipid_diffs, int numSamples, int *ipids, int islocalhost);
|
||||
int get_ipid_sequence_16(int numSamples, int *ipids, int islocalhost);
|
||||
int get_ipid_sequence_32(int numSamples, int *ipids, int islocalhost);
|
||||
|
||||
/******************************************************************************
|
||||
* CLASS DEFINITIONS *
|
||||
|
||||
Reference in New Issue
Block a user