mirror of
https://github.com/nmap/nmap.git
synced 2025-12-11 10:19:03 +00:00
Fixing more bugs reported by Ilja, mostly bounds checking
This commit is contained in:
@@ -2426,7 +2426,7 @@ bool HostOsScan::processTUdpResp(HostOsScanStats *hss, struct ip *ip) {
|
|||||||
assert(icmp->icmp_type == 3 && icmp->icmp_code == 3);
|
assert(icmp->icmp_type == 3 && icmp->icmp_code == 3);
|
||||||
|
|
||||||
ip2 = (struct ip*)((char *)icmp + 8);
|
ip2 = (struct ip*)((char *)icmp + 8);
|
||||||
udp = (struct udp_hdr *)((char *)ip2 + 4 * ip->ip_hl);
|
udp = (struct udp_hdr *)((char *)ip2 + 4 * ip2->ip_hl);
|
||||||
|
|
||||||
/* The ports should match. */
|
/* The ports should match. */
|
||||||
if (ntohs(udp->uh_sport) != hss->upi.sport || ntohs(udp->uh_dport) != hss->upi.dport) {
|
if (ntohs(udp->uh_sport) != hss->upi.sport || ntohs(udp->uh_dport) != hss->upi.dport) {
|
||||||
|
|||||||
@@ -3732,7 +3732,7 @@ static bool get_pcap_result(UltraScanInfo *USI, struct timeval *stime) {
|
|||||||
/* ICMPLen */ 8 +
|
/* ICMPLen */ 8 +
|
||||||
/* IP2 Len */ 4 * ip2->ip_hl;
|
/* IP2 Len */ 4 * ip2->ip_hl;
|
||||||
if (USI->tcp_scan || USI->udp_scan)
|
if (USI->tcp_scan || USI->udp_scan)
|
||||||
bytes += 8; /* UDP hdr, or TCP hdr up to seq # */
|
requiredbytes += 8; /* UDP hdr, or TCP hdr up to seq # */
|
||||||
/* prot scan has no headers coming back, so we don't reserve the
|
/* prot scan has no headers coming back, so we don't reserve the
|
||||||
8 xtra bytes */
|
8 xtra bytes */
|
||||||
if (bytes < requiredbytes) {
|
if (bytes < requiredbytes) {
|
||||||
@@ -3961,6 +3961,7 @@ static int get_ping_pcap_result(UltraScanInfo *USI, struct timeval *stime) {
|
|||||||
UltraProbe *probe = NULL;
|
UltraProbe *probe = NULL;
|
||||||
unsigned int trynum = 0;
|
unsigned int trynum = 0;
|
||||||
unsigned int pingseq = 0;
|
unsigned int pingseq = 0;
|
||||||
|
unsigned int requiredbytes;
|
||||||
bool goodseq;
|
bool goodseq;
|
||||||
int newstate = HOST_UNKNOWN;
|
int newstate = HOST_UNKNOWN;
|
||||||
unsigned int probenum;
|
unsigned int probenum;
|
||||||
@@ -4094,16 +4095,12 @@ static int get_ping_pcap_result(UltraScanInfo *USI, struct timeval *stime) {
|
|||||||
}
|
}
|
||||||
// Destination unreachable, source quench, or time exceeded
|
// Destination unreachable, source quench, or time exceeded
|
||||||
else if (ping->type == 3 || ping->type == 4 || ping->type == 11 || o.debugging) {
|
else if (ping->type == 3 || ping->type == 4 || ping->type == 11 || o.debugging) {
|
||||||
if (bytes < ip->ip_hl * 4 + 28U) {
|
|
||||||
if (o.debugging)
|
|
||||||
error("ICMP type %d code %d packet is only %d bytes", ping->type, ping->code, bytes);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ip *ip2 = (struct ip *) ((char *) ip + ip->ip_hl * 4 + 8);
|
struct ip *ip2 = (struct ip *) ((char *) ip + ip->ip_hl * 4 + 8);
|
||||||
|
|
||||||
|
requiredbytes = ip->ip_hl * 4 + 8U + ip2->ip_hl * 4 + 8U;
|
||||||
|
|
||||||
/* IPProto Scan (generally) sends bare IP headers, so no extra payload */
|
/* IPProto Scan (generally) sends bare IP headers, so no extra payload */
|
||||||
if (bytes < ip->ip_hl * 4 + 8U + ip2->ip_hl * 4 + 8U && !USI->ptech.rawprotoscan) {
|
if (bytes < requiredbytes && !USI->ptech.rawprotoscan) {
|
||||||
if (o.debugging)
|
if (o.debugging)
|
||||||
error("ICMP (embedded) type %d code %d packet is only %d bytes", ping->type, ping->code, bytes);
|
error("ICMP (embedded) type %d code %d packet is only %d bytes", ping->type, ping->code, bytes);
|
||||||
continue;
|
continue;
|
||||||
@@ -4155,9 +4152,17 @@ static int get_ping_pcap_result(UltraScanInfo *USI, struct timeval *stime) {
|
|||||||
error("Got ICMP error referring to TCP msg which we did not send");
|
error("Got ICMP error referring to TCP msg which we did not send");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
/* We need to check for a few more bytes because
|
||||||
|
* tcp_trynum_pingseq_decode() below can use th_ack (which is beyond
|
||||||
|
* the +8 bytes checked for above)
|
||||||
|
*/
|
||||||
|
requiredbytes += 4U;
|
||||||
|
if (bytes < requiredbytes) {
|
||||||
|
if (o.debugging)
|
||||||
|
error("Got ICMP error with a TCP header that was too short");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
struct tcp_hdr *tcp = (struct tcp_hdr *) (((char *) ip2) + 4 * ip2->ip_hl);
|
struct tcp_hdr *tcp = (struct tcp_hdr *) (((char *) ip2) + 4 * ip2->ip_hl);
|
||||||
/* No need to check size here, the "+8" check a ways up takes care
|
|
||||||
of it */
|
|
||||||
/* Now ensure this host is even in the incomplete list */
|
/* Now ensure this host is even in the incomplete list */
|
||||||
memset(&sin, 0, sizeof(sin));
|
memset(&sin, 0, sizeof(sin));
|
||||||
sin.sin_addr.s_addr = ip2->ip_dst.s_addr;
|
sin.sin_addr.s_addr = ip2->ip_dst.s_addr;
|
||||||
|
|||||||
@@ -435,12 +435,18 @@ Traceroute::readTraceResponses () {
|
|||||||
ip2 = (struct ip *) (((char *) ip) + 4 * ip->ip_hl + 8);
|
ip2 = (struct ip *) (((char *) ip) + 4 * ip->ip_hl + 8);
|
||||||
if (ip2->ip_p == IPPROTO_TCP) {
|
if (ip2->ip_p == IPPROTO_TCP) {
|
||||||
tcp = (struct tcp_hdr *) ((u8 *) ip2 + ip2->ip_hl * 4);
|
tcp = (struct tcp_hdr *) ((u8 *) ip2 + ip2->ip_hl * 4);
|
||||||
|
if (ntohs(ip2->ip_len) - (ip2->ip_hl * 4) < 2)
|
||||||
|
break;
|
||||||
sport = htons (tcp->th_sport);
|
sport = htons (tcp->th_sport);
|
||||||
} else if (ip2->ip_p == IPPROTO_UDP) {
|
} else if (ip2->ip_p == IPPROTO_UDP) {
|
||||||
udp = (struct udp_hdr *) ((u8 *) ip2 + ip2->ip_hl * 4);
|
udp = (struct udp_hdr *) ((u8 *) ip2 + ip2->ip_hl * 4);
|
||||||
|
if (ntohs(ip2->ip_len) - (ip2->ip_hl * 4) < 2)
|
||||||
|
break;
|
||||||
sport = htons (udp->uh_sport);
|
sport = htons (udp->uh_sport);
|
||||||
} else if (ip2->ip_p == IPPROTO_ICMP) {
|
} else if (ip2->ip_p == IPPROTO_ICMP) {
|
||||||
icmp2 = (struct icmp *) ((char *) ip2 + 4 * ip2->ip_hl);
|
icmp2 = (struct icmp *) ((char *) ip2 + 4 * ip2->ip_hl);
|
||||||
|
if (ntohs(ip2->ip_len) - (ip2->ip_hl * 4) < 8)
|
||||||
|
break;
|
||||||
sport = ntohs(icmp2->icmp_id);
|
sport = ntohs(icmp2->icmp_id);
|
||||||
} else {
|
} else {
|
||||||
sport = htons(ip2->ip_id);
|
sport = htons(ip2->ip_id);
|
||||||
|
|||||||
Reference in New Issue
Block a user