mirror of
https://github.com/nmap/nmap.git
synced 2025-12-07 13:11:28 +00:00
Fill in the destination MAC address before each probe sent in OS scan.
This fixes the following bug: When scanning with an Ethernet handle (as opposed to raw sockets), only the first host in an OS scan group would get a result. All others would be blank fingerprints with R=N for every probe. This was first noticed on Windows because Ethernet is the default sending method, but it affects other platforms with --send-eth. OS scan initialized an Ethernet handle once for each group, and recorded the first-hop MAC address of the first target at that time. That first-hop address was used for all targets. This failed on a switched LAN, when the first-hop address for every host is different (it's the MAC address of each target). All the various high-level probe sending functions now do their work through three low-level sending functions: one each for TCP, UDP, and ICMP. Those low-level functions take care of setting the MAC addresses before each send. I checked and the other places where Ethernet sends are used do not have this problem. ultra_scan, idle scan, and traceroute all set the addresses before every send.
This commit is contained in:
211
osscan2.cc
211
osscan2.cc
@@ -267,6 +267,8 @@ public:
|
|||||||
~HostOsScanStats();
|
~HostOsScanStats();
|
||||||
void initScanStats();
|
void initScanStats();
|
||||||
|
|
||||||
|
struct eth_nfo *fill_eth_nfo(struct eth_nfo *eth, eth_t *ethsd) const;
|
||||||
|
|
||||||
void addNewProbe(OFProbeType type, int subid);
|
void addNewProbe(OFProbeType type, int subid);
|
||||||
void removeActiveProbe(list<OFProbe *>::iterator probeI);
|
void removeActiveProbe(list<OFProbe *>::iterator probeI);
|
||||||
|
|
||||||
@@ -467,6 +469,19 @@ private:
|
|||||||
bool processTUdpResp(HostOsScanStats *hss, struct ip *ip);
|
bool processTUdpResp(HostOsScanStats *hss, struct ip *ip);
|
||||||
bool processTIcmpResp(HostOsScanStats *hss, struct ip *ip, int replyNo);
|
bool processTIcmpResp(HostOsScanStats *hss, struct ip *ip, int replyNo);
|
||||||
|
|
||||||
|
/* Generic sending functions used by the above probe functions. */
|
||||||
|
int send_tcp_probe(HostOsScanStats *hss,
|
||||||
|
int ttl, bool df, u8* ipopt, int ipoptlen,
|
||||||
|
u16 sport, u16 dport, u32 seq, u32 ack,
|
||||||
|
u8 reserved, u8 flags, u16 window, u16 urp,
|
||||||
|
u8 *options, int optlen,
|
||||||
|
char *data, u16 datalen);
|
||||||
|
int send_icmp_echo_probe(HostOsScanStats *hss,
|
||||||
|
u8 tos, bool df, u8 pcode,
|
||||||
|
unsigned short id, u16 seq, u16 datalen);
|
||||||
|
int send_closedudp_probe(HostOsScanStats *hss,
|
||||||
|
int ttl, u16 sport, u16 dport);
|
||||||
|
|
||||||
void makeTSeqFP(HostOsScanStats *hss);
|
void makeTSeqFP(HostOsScanStats *hss);
|
||||||
void makeTOpsFP(HostOsScanStats *hss);
|
void makeTOpsFP(HostOsScanStats *hss);
|
||||||
void makeTWinFP(HostOsScanStats *hss);
|
void makeTWinFP(HostOsScanStats *hss);
|
||||||
@@ -474,8 +489,7 @@ private:
|
|||||||
bool get_tcpopt_string(struct tcp_hdr *tcp, int mss, char *result, int maxlen);
|
bool get_tcpopt_string(struct tcp_hdr *tcp, int mss, char *result, int maxlen);
|
||||||
|
|
||||||
int rawsd; /* raw socket descriptor */
|
int rawsd; /* raw socket descriptor */
|
||||||
struct eth_nfo eth;
|
eth_t *ethsd; /* Ethernet handle */
|
||||||
struct eth_nfo *ethptr; /* for passing to send_ functions */
|
|
||||||
|
|
||||||
unsigned int tcpSeqBase, tcpAck; /* Seq&Ack value used in TCP probes */
|
unsigned int tcpSeqBase, tcpAck; /* Seq&Ack value used in TCP probes */
|
||||||
int tcpMss; /* tcp Mss value used in TCP probes */
|
int tcpMss; /* tcp Mss value used in TCP probes */
|
||||||
@@ -743,6 +757,21 @@ void HostOsScanStats::initScanStats() {
|
|||||||
memset(&upi, 0, sizeof(upi));
|
memset(&upi, 0, sizeof(upi));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Fill in an eth_nfo struct with the appropriate source and destination MAC
|
||||||
|
addresses and a given Ethernet handle. The return value is suitable to pass
|
||||||
|
to send_ip_packet: if ethsd is NULL, returns NULL; otherwise returns eth. */
|
||||||
|
struct eth_nfo *HostOsScanStats::fill_eth_nfo(struct eth_nfo *eth, eth_t *ethsd) const {
|
||||||
|
if (ethsd == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
memcpy(eth->srcmac, target->SrcMACAddress(), sizeof(eth->srcmac));
|
||||||
|
memcpy(eth->dstmac, target->NextHopMACAddress(), sizeof(eth->srcmac));
|
||||||
|
eth->ethsd = ethsd;
|
||||||
|
eth->devname[0] = '\0';
|
||||||
|
|
||||||
|
return eth;
|
||||||
|
}
|
||||||
|
|
||||||
/* Add a probe to the probe list. */
|
/* Add a probe to the probe list. */
|
||||||
void HostOsScanStats::addNewProbe(OFProbeType type, int subid) {
|
void HostOsScanStats::addNewProbe(OFProbeType type, int subid) {
|
||||||
OFProbe *probe = new OFProbe();
|
OFProbe *probe = new OFProbe();
|
||||||
@@ -912,14 +941,12 @@ bool ScanStats::sendOK() {
|
|||||||
HostOsScan::HostOsScan(Target *t) {
|
HostOsScan::HostOsScan(Target *t) {
|
||||||
pd = NULL;
|
pd = NULL;
|
||||||
rawsd = -1;
|
rawsd = -1;
|
||||||
|
ethsd = NULL;
|
||||||
|
|
||||||
if ((o.sendpref & PACKET_SEND_ETH) && t->ifType() == devt_ethernet) {
|
if ((o.sendpref & PACKET_SEND_ETH) && t->ifType() == devt_ethernet) {
|
||||||
memcpy(eth.srcmac, t->SrcMACAddress(), 6);
|
if ((ethsd = eth_open_cached(t->deviceName())) == NULL)
|
||||||
memcpy(eth.dstmac, t->NextHopMACAddress(), 6);
|
|
||||||
if ((eth.ethsd = eth_open_cached(t->deviceName())) == NULL)
|
|
||||||
fatal("%s: Failed to open ethernet device (%s)", __func__, t->deviceName());
|
fatal("%s: Failed to open ethernet device (%s)", __func__, t->deviceName());
|
||||||
rawsd = -1;
|
rawsd = -1;
|
||||||
ethptr = ð
|
|
||||||
} else {
|
} else {
|
||||||
/* Init our raw socket */
|
/* Init our raw socket */
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
@@ -932,8 +959,7 @@ HostOsScan::HostOsScan(Target *t) {
|
|||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
sethdrinclude(rawsd);
|
sethdrinclude(rawsd);
|
||||||
#endif
|
#endif
|
||||||
ethptr = NULL;
|
ethsd = NULL;
|
||||||
eth.ethsd = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tcpPortBase = o.magic_port_set? o.magic_port : o.magic_port + get_random_u8();
|
tcpPortBase = o.magic_port_set? o.magic_port : o.magic_port + get_random_u8();
|
||||||
@@ -947,8 +973,8 @@ HostOsScan::~HostOsScan() {
|
|||||||
if (rawsd >= 0) { close(rawsd); rawsd = -1; }
|
if (rawsd >= 0) { close(rawsd); rawsd = -1; }
|
||||||
if (pd) { pcap_close(pd); pd = NULL; }
|
if (pd) { pcap_close(pd); pd = NULL; }
|
||||||
/*
|
/*
|
||||||
* No need to close ethptr->ethsd due to caching
|
* No need to close ethsd due to caching
|
||||||
* if (eth.ethsd) { eth_close(eth.ethsd); eth.ethsd = NULL; }
|
* if (ethsd) { eth_close(ethsd); ethsd = NULL; }
|
||||||
*/
|
*/
|
||||||
delete stats;
|
delete stats;
|
||||||
}
|
}
|
||||||
@@ -1293,11 +1319,11 @@ void HostOsScan::sendTSeqProbe(HostOsScanStats *hss, int probeNo) {
|
|||||||
|
|
||||||
if(hss->openTCPPort == -1) return;
|
if(hss->openTCPPort == -1) return;
|
||||||
|
|
||||||
send_tcp_raw_decoys(rawsd, ethptr, hss->target->v4hostip(), o.ttl, false, NULL, 0,
|
send_tcp_probe(hss, o.ttl, false, NULL, 0,
|
||||||
tcpPortBase + probeNo, hss->openTCPPort,
|
tcpPortBase + probeNo, hss->openTCPPort,
|
||||||
tcpSeqBase + probeNo, tcpAck, 0,
|
tcpSeqBase + probeNo, tcpAck,
|
||||||
TH_SYN, prbWindowSz[probeNo], 0, prbOpts[probeNo].val, prbOpts[probeNo].len,
|
0, TH_SYN, prbWindowSz[probeNo], 0,
|
||||||
NULL, 0);
|
prbOpts[probeNo].val, prbOpts[probeNo].len, NULL, 0);
|
||||||
|
|
||||||
hss->seq_send_times[probeNo] = now;
|
hss->seq_send_times[probeNo] = now;
|
||||||
}
|
}
|
||||||
@@ -1308,11 +1334,11 @@ void HostOsScan::sendTOpsProbe(HostOsScanStats *hss, int probeNo) {
|
|||||||
|
|
||||||
if(hss->openTCPPort == -1) return;
|
if(hss->openTCPPort == -1) return;
|
||||||
|
|
||||||
send_tcp_raw_decoys(rawsd, ethptr, hss->target->v4hostip(), o.ttl, false, NULL, 0,
|
send_tcp_probe(hss, o.ttl, false, NULL, 0,
|
||||||
tcpPortBase + NUM_SEQ_SAMPLES + probeNo,
|
tcpPortBase + NUM_SEQ_SAMPLES + probeNo, hss->openTCPPort,
|
||||||
hss->openTCPPort, tcpSeqBase, tcpAck, 0, TH_SYN,
|
tcpSeqBase, tcpAck,
|
||||||
prbWindowSz[probeNo], 0, prbOpts[probeNo].val,
|
0, TH_SYN, prbWindowSz[probeNo], 0,
|
||||||
prbOpts[probeNo].len, NULL, 0);
|
prbOpts[probeNo].val, prbOpts[probeNo].len, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HostOsScan::sendTEcnProbe(HostOsScanStats *hss) {
|
void HostOsScan::sendTEcnProbe(HostOsScanStats *hss) {
|
||||||
@@ -1320,10 +1346,11 @@ void HostOsScan::sendTEcnProbe(HostOsScanStats *hss) {
|
|||||||
|
|
||||||
if(hss->openTCPPort == -1) return;
|
if(hss->openTCPPort == -1) return;
|
||||||
|
|
||||||
send_tcp_raw_decoys(rawsd, ethptr, hss->target->v4hostip(), o.ttl, false, NULL, 0,
|
send_tcp_probe(hss, o.ttl, false, NULL, 0,
|
||||||
tcpPortBase + NUM_SEQ_SAMPLES + 6, hss->openTCPPort,
|
tcpPortBase + NUM_SEQ_SAMPLES + 6, hss->openTCPPort,
|
||||||
tcpSeqBase, 0, 8, TH_CWR|TH_ECE|TH_SYN, prbWindowSz[6],
|
tcpSeqBase, 0,
|
||||||
63477, prbOpts[6].val, prbOpts[6].len, NULL, 0);
|
8, TH_CWR|TH_ECE|TH_SYN, prbWindowSz[6], 63477,
|
||||||
|
prbOpts[6].val, prbOpts[6].len, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HostOsScan::sendT1_7Probe(HostOsScanStats *hss, int probeNo) {
|
void HostOsScan::sendT1_7Probe(HostOsScanStats *hss, int probeNo) {
|
||||||
@@ -1335,52 +1362,59 @@ void HostOsScan::sendT1_7Probe(HostOsScanStats *hss, int probeNo) {
|
|||||||
switch(probeNo) {
|
switch(probeNo) {
|
||||||
case 0: /* T1 */
|
case 0: /* T1 */
|
||||||
if(hss->openTCPPort == -1) return;
|
if(hss->openTCPPort == -1) return;
|
||||||
send_tcp_raw_decoys(rawsd, ethptr, hss->target->v4hostip(), o.ttl, false, NULL, 0,
|
send_tcp_probe(hss, o.ttl, false, NULL, 0,
|
||||||
port_base, hss->openTCPPort, tcpSeqBase, tcpAck, 0,
|
port_base, hss->openTCPPort,
|
||||||
TH_SYN, prbWindowSz[0], 0, prbOpts[0].val,
|
tcpSeqBase, tcpAck,
|
||||||
prbOpts[0].len, NULL, 0);
|
0, TH_SYN, prbWindowSz[0], 0,
|
||||||
|
prbOpts[0].val, prbOpts[0].len, NULL, 0);
|
||||||
break;
|
break;
|
||||||
case 1: /* T2 */
|
case 1: /* T2 */
|
||||||
if(hss->openTCPPort == -1) return;
|
if(hss->openTCPPort == -1) return;
|
||||||
send_tcp_raw_decoys(rawsd, ethptr, hss->target->v4hostip(), o.ttl, true, NULL, 0,
|
send_tcp_probe(hss, o.ttl, true, NULL, 0,
|
||||||
port_base + 1, hss->openTCPPort, tcpSeqBase, tcpAck, 0,
|
port_base + 1, hss->openTCPPort,
|
||||||
0, prbWindowSz[7], 0, prbOpts[7].val,
|
tcpSeqBase, tcpAck,
|
||||||
prbOpts[7].len, NULL, 0);
|
0, 0, prbWindowSz[7], 0,
|
||||||
|
prbOpts[7].val, prbOpts[7].len, NULL, 0);
|
||||||
break;
|
break;
|
||||||
case 2: /* T3 */
|
case 2: /* T3 */
|
||||||
if(hss->openTCPPort == -1) return;
|
if(hss->openTCPPort == -1) return;
|
||||||
send_tcp_raw_decoys(rawsd, ethptr, hss->target->v4hostip(), o.ttl, false, NULL, 0,
|
send_tcp_probe(hss, o.ttl, false, NULL, 0,
|
||||||
port_base + 2, hss->openTCPPort, tcpSeqBase, tcpAck, 0,
|
port_base + 2, hss->openTCPPort,
|
||||||
TH_SYN|TH_FIN|TH_URG|TH_PUSH, prbWindowSz[8], 0, prbOpts[8].val,
|
tcpSeqBase, tcpAck,
|
||||||
prbOpts[8].len, NULL, 0);
|
0, TH_SYN|TH_FIN|TH_URG|TH_PUSH, prbWindowSz[8], 0,
|
||||||
|
prbOpts[8].val, prbOpts[8].len, NULL, 0);
|
||||||
break;
|
break;
|
||||||
case 3: /* T4 */
|
case 3: /* T4 */
|
||||||
if(hss->openTCPPort == -1) return;
|
if(hss->openTCPPort == -1) return;
|
||||||
send_tcp_raw_decoys(rawsd, ethptr, hss->target->v4hostip(), o.ttl, true, NULL, 0,
|
send_tcp_probe(hss, o.ttl, true, NULL, 0,
|
||||||
port_base + 3, hss->openTCPPort, tcpSeqBase, tcpAck, 0,
|
port_base + 3, hss->openTCPPort,
|
||||||
TH_ACK, prbWindowSz[9], 0, prbOpts[9].val,
|
tcpSeqBase, tcpAck,
|
||||||
prbOpts[9].len, NULL, 0);
|
0, TH_ACK, prbWindowSz[9], 0,
|
||||||
|
prbOpts[9].val, prbOpts[9].len, NULL, 0);
|
||||||
break;
|
break;
|
||||||
case 4: /* T5 */
|
case 4: /* T5 */
|
||||||
if(hss->closedTCPPort == -1) return;
|
if(hss->closedTCPPort == -1) return;
|
||||||
send_tcp_raw_decoys(rawsd, ethptr, hss->target->v4hostip(), o.ttl, false, NULL, 0,
|
send_tcp_probe(hss, o.ttl, false, NULL, 0,
|
||||||
port_base + 4, hss->closedTCPPort, tcpSeqBase, tcpAck,
|
port_base + 4, hss->closedTCPPort,
|
||||||
0, TH_SYN, prbWindowSz[10], 0, prbOpts[10].val,
|
tcpSeqBase, tcpAck,
|
||||||
prbOpts[10].len, NULL, 0);
|
0, TH_SYN, prbWindowSz[10], 0,
|
||||||
|
prbOpts[10].val, prbOpts[10].len, NULL, 0);
|
||||||
break;
|
break;
|
||||||
case 5: /* T6 */
|
case 5: /* T6 */
|
||||||
if(hss->closedTCPPort == -1) return;
|
if(hss->closedTCPPort == -1) return;
|
||||||
send_tcp_raw_decoys(rawsd, ethptr, hss->target->v4hostip(), o.ttl, true, NULL, 0,
|
send_tcp_probe(hss, o.ttl, true, NULL, 0,
|
||||||
port_base + 5, hss->closedTCPPort, tcpSeqBase, tcpAck,
|
port_base + 5, hss->closedTCPPort,
|
||||||
0, TH_ACK, prbWindowSz[11], 0, prbOpts[11].val,
|
tcpSeqBase, tcpAck,
|
||||||
prbOpts[11].len, NULL, 0);
|
0, TH_ACK, prbWindowSz[11], 0,
|
||||||
|
prbOpts[11].val, prbOpts[11].len, NULL, 0);
|
||||||
break;
|
break;
|
||||||
case 6: /* T7 */
|
case 6: /* T7 */
|
||||||
if(hss->closedTCPPort == -1) return;
|
if(hss->closedTCPPort == -1) return;
|
||||||
send_tcp_raw_decoys(rawsd, ethptr, hss->target->v4hostip(), o.ttl, false, NULL, 0,
|
send_tcp_probe(hss, o.ttl, false, NULL, 0,
|
||||||
port_base + 6, hss->closedTCPPort, tcpSeqBase, tcpAck,
|
port_base + 6, hss->closedTCPPort,
|
||||||
0, TH_FIN|TH_PUSH|TH_URG, prbWindowSz[12], 0, prbOpts[12].val,
|
tcpSeqBase, tcpAck,
|
||||||
prbOpts[12].len, NULL, 0);
|
0, TH_FIN|TH_PUSH|TH_URG, prbWindowSz[12], 0,
|
||||||
|
prbOpts[12].val, prbOpts[12].len, NULL, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1389,11 +1423,11 @@ void HostOsScan::sendTIcmpProbe(HostOsScanStats *hss, int probeNo) {
|
|||||||
assert(hss);
|
assert(hss);
|
||||||
assert(probeNo>=0&&probeNo<2);
|
assert(probeNo>=0&&probeNo<2);
|
||||||
if(probeNo==0) {
|
if(probeNo==0) {
|
||||||
send_icmp_echo_probe(rawsd, ethptr, hss->target->v4hostip(), IP_TOS_DEFAULT,
|
send_icmp_echo_probe(hss, IP_TOS_DEFAULT,
|
||||||
true, 9, icmpEchoId, icmpEchoSeq, 120);
|
true, 9, icmpEchoId, icmpEchoSeq, 120);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
send_icmp_echo_probe(rawsd, ethptr, hss->target->v4hostip(), IP_TOS_RELIABILITY,
|
send_icmp_echo_probe(hss, IP_TOS_RELIABILITY,
|
||||||
false, 0, icmpEchoId+1, icmpEchoSeq+1, 150);
|
false, 0, icmpEchoId+1, icmpEchoSeq+1, 150);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1402,9 +1436,7 @@ void HostOsScan::sendTUdpProbe(HostOsScanStats *hss, int probeNo) {
|
|||||||
assert(hss);
|
assert(hss);
|
||||||
|
|
||||||
if(hss->closedUDPPort == -1) return;
|
if(hss->closedUDPPort == -1) return;
|
||||||
send_closedudp_probe(hss->upi, rawsd, ethptr, hss->target->v4hostip(),
|
send_closedudp_probe(hss, udpttl, udpPortBase + probeNo, hss->closedUDPPort);
|
||||||
this->udpttl, udpPortBase + probeNo,
|
|
||||||
hss->closedUDPPort);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HostOsScan::processResp(HostOsScanStats *hss, struct ip *ip, unsigned int len, struct timeval *rcvdtime) {
|
bool HostOsScan::processResp(HostOsScanStats *hss, struct ip *ip, unsigned int len, struct timeval *rcvdtime) {
|
||||||
@@ -2999,22 +3031,45 @@ int OsScanInfo::removeCompletedHosts() {
|
|||||||
return hostsRemoved;
|
return hostsRemoved;
|
||||||
}
|
}
|
||||||
|
|
||||||
int send_icmp_echo_probe(int sd, struct eth_nfo *eth,
|
/* Send a TCP probe. This takes care of decoys and filling in Ethernet
|
||||||
const struct in_addr *victim, u8 tos, bool df,
|
addresses if necessary. Used for the SEQ, OPS, WIN, ECN, and T1-T7 probes. */
|
||||||
u8 pcode, unsigned short id, u16 seq, u16 datalen) {
|
int HostOsScan::send_tcp_probe(HostOsScanStats *hss,
|
||||||
|
int ttl, bool df, u8* ipopt, int ipoptlen,
|
||||||
|
u16 sport, u16 dport, u32 seq, u32 ack,
|
||||||
|
u8 reserved, u8 flags, u16 window, u16 urp,
|
||||||
|
u8 *options, int optlen,
|
||||||
|
char *data, u16 datalen) {
|
||||||
|
struct eth_nfo eth, *ethptr;
|
||||||
|
|
||||||
|
ethptr = hss->fill_eth_nfo(ð, ethsd);
|
||||||
|
|
||||||
|
return send_tcp_raw_decoys(rawsd, ethptr, hss->target->v4hostip(),
|
||||||
|
ttl, df, ipopt, ipoptlen, sport, dport, seq, ack,
|
||||||
|
reserved, flags, window, urp,
|
||||||
|
options, optlen, data, datalen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Send an echo probe. This takes care of decoys and filling in Ethernet
|
||||||
|
addresses if necessary. Used for the IE probes. */
|
||||||
|
int HostOsScan::send_icmp_echo_probe(HostOsScanStats *hss,
|
||||||
|
u8 tos, bool df, u8 pcode,
|
||||||
|
unsigned short id, u16 seq, u16 datalen) {
|
||||||
u8 *packet = NULL;
|
u8 *packet = NULL;
|
||||||
u32 packetlen = 0;
|
u32 packetlen = 0;
|
||||||
int decoy;
|
int decoy;
|
||||||
int res = -1;
|
int res = -1;
|
||||||
|
struct eth_nfo eth, *ethptr;
|
||||||
|
|
||||||
|
ethptr = hss->fill_eth_nfo(ð, ethsd);
|
||||||
|
|
||||||
for(decoy = 0; decoy < o.numdecoys; decoy++) {
|
for(decoy = 0; decoy < o.numdecoys; decoy++) {
|
||||||
packet = build_icmp_raw(&o.decoys[decoy], victim,
|
packet = build_icmp_raw(&o.decoys[decoy], hss->target->v4hostip(),
|
||||||
o.ttl, get_random_u16(), tos, df,
|
o.ttl, get_random_u16(), tos, df,
|
||||||
NULL, 0,
|
NULL, 0,
|
||||||
seq, id, ICMP_ECHO, pcode,
|
seq, id, ICMP_ECHO, pcode,
|
||||||
NULL, datalen, &packetlen);
|
NULL, datalen, &packetlen);
|
||||||
if(!packet) return -1;
|
if(!packet) return -1;
|
||||||
res = send_ip_packet(sd, eth, packet, packetlen);
|
res = send_ip_packet(rawsd, ethptr, packet, packetlen);
|
||||||
free(packet);
|
free(packet);
|
||||||
if(res==-1) return -1;
|
if(res==-1) return -1;
|
||||||
}
|
}
|
||||||
@@ -3022,8 +3077,9 @@ int send_icmp_echo_probe(int sd, struct eth_nfo *eth,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int send_closedudp_probe(struct udpprobeinfo &upi, int sd,
|
/* Send a UDP probe. This takes care of decoys and filling in Ethernet
|
||||||
struct eth_nfo *eth, const struct in_addr *victim,
|
addresses if necessary. Used for the U1 probe. */
|
||||||
|
int HostOsScan::send_closedudp_probe(HostOsScanStats *hss,
|
||||||
int ttl, u16 sport, u16 dport) {
|
int ttl, u16 sport, u16 dport) {
|
||||||
static int myttl = 0;
|
static int myttl = 0;
|
||||||
static u8 patternbyte = 0x43; /* character 'C' */
|
static u8 patternbyte = 0x43; /* character 'C' */
|
||||||
@@ -3037,6 +3093,9 @@ int send_closedudp_probe(struct udpprobeinfo &upi, int sd,
|
|||||||
unsigned short realcheck; /* the REAL checksum */
|
unsigned short realcheck; /* the REAL checksum */
|
||||||
int res;
|
int res;
|
||||||
int decoy;
|
int decoy;
|
||||||
|
struct eth_nfo eth, *ethptr;
|
||||||
|
|
||||||
|
ethptr = hss->fill_eth_nfo(ð, ethsd);
|
||||||
|
|
||||||
/* if (!patternbyte) patternbyte = (get_random_uint() % 60) + 65; */
|
/* if (!patternbyte) patternbyte = (get_random_uint() % 60) + 65; */
|
||||||
memset(data, patternbyte, datalen);
|
memset(data, patternbyte, datalen);
|
||||||
@@ -3050,7 +3109,7 @@ int send_closedudp_probe(struct udpprobeinfo &upi, int sd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* check that required fields are there and not too silly */
|
/* check that required fields are there and not too silly */
|
||||||
if ( !victim || !sport || !dport || (!eth && sd < 0)) {
|
if (!sport || !dport) {
|
||||||
error("%s: One or more of your parameters suck!", __func__);
|
error("%s: One or more of your parameters suck!", __func__);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -3065,7 +3124,7 @@ int send_closedudp_probe(struct udpprobeinfo &upi, int sd,
|
|||||||
udp->uh_ulen = htons(8 + datalen);
|
udp->uh_ulen = htons(8 + datalen);
|
||||||
|
|
||||||
/* OK, now we should be able to compute a valid checksum */
|
/* OK, now we should be able to compute a valid checksum */
|
||||||
realcheck = magic_tcpudp_cksum(source, victim, IPPROTO_UDP,
|
realcheck = magic_tcpudp_cksum(source, hss->target->v4hostip(), IPPROTO_UDP,
|
||||||
sizeof(struct udp_hdr) + datalen, (char *) udp);
|
sizeof(struct udp_hdr) + datalen, (char *) udp);
|
||||||
#if STUPID_SOLARIS_CHECKSUM_BUG
|
#if STUPID_SOLARIS_CHECKSUM_BUG
|
||||||
udp->uh_sum = sizeof(struct udp_hdr) + datalen;
|
udp->uh_sum = sizeof(struct udp_hdr) + datalen;
|
||||||
@@ -3081,27 +3140,27 @@ int send_closedudp_probe(struct udpprobeinfo &upi, int sd,
|
|||||||
ip->ip_ttl = myttl;
|
ip->ip_ttl = myttl;
|
||||||
ip->ip_p = IPPROTO_UDP;
|
ip->ip_p = IPPROTO_UDP;
|
||||||
ip->ip_src.s_addr = source->s_addr;
|
ip->ip_src.s_addr = source->s_addr;
|
||||||
ip->ip_dst.s_addr= victim->s_addr;
|
ip->ip_dst.s_addr= hss->target->v4hostip()->s_addr;
|
||||||
|
|
||||||
upi.ipck = in_cksum((unsigned short *)ip, sizeof(struct ip));
|
hss->upi.ipck = in_cksum((unsigned short *)ip, sizeof(struct ip));
|
||||||
#if HAVE_IP_IP_SUM
|
#if HAVE_IP_IP_SUM
|
||||||
ip->ip_sum = upi.ipck;
|
ip->ip_sum = hss->upi.ipck;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* OK, now if this is the real she-bang (ie not a decoy) then
|
/* OK, now if this is the real she-bang (ie not a decoy) then
|
||||||
we stick all the inph0 in our upi */
|
we stick all the inph0 in our upi */
|
||||||
if (decoy == o.decoyturn) {
|
if (decoy == o.decoyturn) {
|
||||||
upi.iptl = 28 + datalen;
|
hss->upi.iptl = 28 + datalen;
|
||||||
upi.ipid = id;
|
hss->upi.ipid = id;
|
||||||
upi.sport = sport;
|
hss->upi.sport = sport;
|
||||||
upi.dport = dport;
|
hss->upi.dport = dport;
|
||||||
upi.udpck = realcheck;
|
hss->upi.udpck = realcheck;
|
||||||
upi.udplen = 8 + datalen;
|
hss->upi.udplen = 8 + datalen;
|
||||||
upi.patternbyte = patternbyte;
|
hss->upi.patternbyte = patternbyte;
|
||||||
upi.target.s_addr = ip->ip_dst.s_addr;
|
hss->upi.target.s_addr = ip->ip_dst.s_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((res = send_ip_packet(sd, eth, packet, ntohs(ip->ip_len))) == -1)
|
if ((res = send_ip_packet(rawsd, ethptr, packet, ntohs(ip->ip_len))) == -1)
|
||||||
{
|
{
|
||||||
gh_perror("send_ip_packet in %s", __func__);
|
gh_perror("send_ip_packet in %s", __func__);
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -118,12 +118,6 @@ class Target;
|
|||||||
processed as smaller groups to improve accuracy */
|
processed as smaller groups to improve accuracy */
|
||||||
void os_scan2(std::vector<Target *> &Targets);
|
void os_scan2(std::vector<Target *> &Targets);
|
||||||
|
|
||||||
int send_closedudp_probe(struct udpprobeinfo &upi, int sd,
|
|
||||||
struct eth_nfo *eth, const struct in_addr *victim,
|
|
||||||
int ttl, u16 sport, u16 dport);
|
|
||||||
int send_icmp_echo_probe(int sd, struct eth_nfo *eth, const struct in_addr *victim,
|
|
||||||
u8 tos, bool df, u8 pcode, unsigned short id, u16 seq, u16 datalen);
|
|
||||||
|
|
||||||
int get_initial_ttl_guess(u8 ttl);
|
int get_initial_ttl_guess(u8 ttl);
|
||||||
int get_ipid_sequence(int numSamples, int *ipids, int islocalhost);
|
int get_ipid_sequence(int numSamples, int *ipids, int islocalhost);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user