mirror of
https://github.com/nmap/nmap.git
synced 2025-12-10 17:59:04 +00:00
Fixing another bug found by Ilja where a pointer in ippackethdrinfo() could have gone outside of the buffer it was referencing (reading, not writing)
This commit is contained in:
30
tcpip.cc
30
tcpip.cc
@@ -424,8 +424,8 @@ static void tcppacketoptinfo(u8 *optp, int len, char *result, int bufsize) {
|
|||||||
static const char *ippackethdrinfo(const u8 *packet, u32 len) {
|
static const char *ippackethdrinfo(const u8 *packet, u32 len) {
|
||||||
static char protoinfo[512];
|
static char protoinfo[512];
|
||||||
struct ip *ip = (struct ip *) packet;
|
struct ip *ip = (struct ip *) packet;
|
||||||
struct tcp_hdr *tcp;
|
struct tcp_hdr *tcp = NULL;
|
||||||
struct udp_hdr *udp;
|
struct udp_hdr *udp = NULL;
|
||||||
char ipinfo[512];
|
char ipinfo[512];
|
||||||
char srchost[INET6_ADDRSTRLEN], dsthost[INET6_ADDRSTRLEN];
|
char srchost[INET6_ADDRSTRLEN], dsthost[INET6_ADDRSTRLEN];
|
||||||
char *p;
|
char *p;
|
||||||
@@ -560,15 +560,23 @@ static const char *ippackethdrinfo(const u8 *packet, u32 len) {
|
|||||||
unsigned short checksum;
|
unsigned short checksum;
|
||||||
unsigned short id;
|
unsigned short id;
|
||||||
unsigned short seq;
|
unsigned short seq;
|
||||||
} *ping;
|
} *ping = NULL;
|
||||||
|
unsigned pktlen = (ip->ip_hl * 4) + sizeof(struct ppkt);
|
||||||
|
if (pktlen > len)
|
||||||
|
goto icmpbad;
|
||||||
ping = (struct ppkt *) ((ip->ip_hl * 4) + (char *) ip);
|
ping = (struct ppkt *) ((ip->ip_hl * 4) + (char *) ip);
|
||||||
switch(ping->type) {
|
switch(ping->type) {
|
||||||
case 0:
|
case 0:
|
||||||
strcpy(icmptype, "echo reply"); break;
|
strcpy(icmptype, "echo reply"); break;
|
||||||
case 3:
|
case 3:
|
||||||
ip2 = (struct ip *) ((char *) ip + (ip->ip_hl * 4) + 8);
|
ip2 = (struct ip *) ((char *) ip + (ip->ip_hl * 4) + 8);
|
||||||
|
pktlen += (ip2->ip_hl * 4);
|
||||||
|
if (pktlen > len)
|
||||||
|
goto icmpbad;
|
||||||
|
if (pktlen + 8 < len) {
|
||||||
tcp = (struct tcp_hdr *) ((char *) ip2 + (ip2->ip_hl * 4));
|
tcp = (struct tcp_hdr *) ((char *) ip2 + (ip2->ip_hl * 4));
|
||||||
udp = (struct udp_hdr *) ((char *) ip2 + (ip2->ip_hl * 4));
|
udp = (struct udp_hdr *) ((char *) ip2 + (ip2->ip_hl * 4));
|
||||||
|
}
|
||||||
ip2dst = inet_ntoa(ip2->ip_dst);
|
ip2dst = inet_ntoa(ip2->ip_dst);
|
||||||
switch (ping->code) {
|
switch (ping->code) {
|
||||||
case 0:
|
case 0:
|
||||||
@@ -581,9 +589,9 @@ static const char *ippackethdrinfo(const u8 *packet, u32 len) {
|
|||||||
Snprintf(icmptype, sizeof icmptype, "protocol %u unreachable", ip2->ip_p);
|
Snprintf(icmptype, sizeof icmptype, "protocol %u unreachable", ip2->ip_p);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
if (ip2->ip_p == IPPROTO_UDP)
|
if (ip2->ip_p == IPPROTO_UDP && udp)
|
||||||
Snprintf(icmptype, sizeof icmptype, "port %u unreachable", ntohs(udp->uh_dport));
|
Snprintf(icmptype, sizeof icmptype, "port %u unreachable", ntohs(udp->uh_dport));
|
||||||
else if (ip2->ip_p == IPPROTO_TCP)
|
else if (ip2->ip_p == IPPROTO_TCP && tcp)
|
||||||
Snprintf(icmptype, sizeof icmptype, "port %u unreachable", ntohs(tcp->th_dport));
|
Snprintf(icmptype, sizeof icmptype, "port %u unreachable", ntohs(tcp->th_dport));
|
||||||
else
|
else
|
||||||
strcpy(icmptype, "port unreachable");
|
strcpy(icmptype, "port unreachable");
|
||||||
@@ -678,8 +686,20 @@ static const char *ippackethdrinfo(const u8 *packet, u32 len) {
|
|||||||
strcpy(icmptype, "Unknown type"); break;
|
strcpy(icmptype, "Unknown type"); break;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (pktlen > len) {
|
||||||
|
icmpbad:
|
||||||
|
if (ping) {
|
||||||
|
/* We still have this information */
|
||||||
|
Snprintf(protoinfo, sizeof(protoinfo), "ICMP %s > %s (type=%d/code=%d) %s",
|
||||||
|
srchost, dsthost, ping->type, ping->code, ipinfo);
|
||||||
|
} else {
|
||||||
|
Snprintf(protoinfo, sizeof(protoinfo), "ICMP %s > %s [??] %s",
|
||||||
|
srchost, dsthost, ipinfo);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
Snprintf(protoinfo, sizeof(protoinfo), "ICMP %s > %s %s (type=%d/code=%d) %s",
|
Snprintf(protoinfo, sizeof(protoinfo), "ICMP %s > %s %s (type=%d/code=%d) %s",
|
||||||
srchost, dsthost, icmptype, ping->type, ping->code, ipinfo);
|
srchost, dsthost, icmptype, ping->type, ping->code, ipinfo);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Snprintf(protoinfo, sizeof(protoinfo), "Unknown protocol (%d) %s > %s: %s",
|
Snprintf(protoinfo, sizeof(protoinfo), "Unknown protocol (%d) %s > %s: %s",
|
||||||
ip->ip_p, srchost, dsthost, ipinfo);
|
ip->ip_p, srchost, dsthost, ipinfo);
|
||||||
|
|||||||
Reference in New Issue
Block a user