mirror of
https://github.com/nmap/nmap.git
synced 2026-05-13 08:46:45 +00:00
Ensure packet buffers are long enough for headers
This commit is contained in:
parent
b2a7459609
commit
21557e7b2f
4 changed files with 45 additions and 20 deletions
|
|
@ -721,6 +721,8 @@ const u8 *ipv4_get_data(const struct ip *ip, const u8 *p, unsigned int *len)
|
|||
const u8 *ipv4_get_data(const u8 *p, unsigned int *len)
|
||||
{
|
||||
struct ip ip;
|
||||
if (*len < sizeof(ip))
|
||||
return NULL;
|
||||
memcpy(&ip, p, sizeof(ip));
|
||||
return ipv4_get_data(&ip, p, len);
|
||||
}
|
||||
|
|
@ -736,6 +738,8 @@ const u8 *ipv6_get_data(const struct ip6_hdr *ip6, const u8 *p, unsigned int *le
|
|||
const u8 *ipv6_get_data(const u8 *p, unsigned int *len, u8 *nxt)
|
||||
{
|
||||
struct ip6_hdr ip6;
|
||||
if (*len < sizeof(ip6))
|
||||
return NULL;
|
||||
memcpy(&ip6, p, sizeof(ip6));
|
||||
return ipv6_get_data(&ip6, p, len, nxt);
|
||||
}
|
||||
|
|
@ -751,6 +755,8 @@ const u8 *ipv6_get_data_any(const struct ip6_hdr *ip6, const u8 *p, unsigned int
|
|||
const u8 *ipv6_get_data_any(const u8 *p, unsigned int *len, u8 *nxt)
|
||||
{
|
||||
struct ip6_hdr ip6;
|
||||
if (*len < sizeof(ip6))
|
||||
return NULL;
|
||||
memcpy(&ip6, p, sizeof(ip6));
|
||||
return ipv6_get_data_any(&ip6, p, len, nxt);
|
||||
}
|
||||
|
|
@ -759,6 +765,8 @@ const u8 *icmp_get_data(const u8 *icmp, unsigned int *len)
|
|||
{
|
||||
unsigned int header_len;
|
||||
struct icmp_hdr hdr;
|
||||
if (*len < sizeof(hdr))
|
||||
return NULL;
|
||||
memcpy(&hdr, icmp, sizeof(hdr));
|
||||
|
||||
if (hdr.icmp_type == ICMP_TIMEXCEED || hdr.icmp_type == ICMP_UNREACH)
|
||||
|
|
@ -776,6 +784,8 @@ const u8 *icmpv6_get_data(const u8 *icmpv6, unsigned int *len)
|
|||
{
|
||||
unsigned int header_len;
|
||||
struct icmpv6_hdr hdr;
|
||||
if (*len < sizeof(hdr))
|
||||
return NULL;
|
||||
memcpy(&hdr, icmpv6, sizeof(hdr));
|
||||
|
||||
if (hdr.icmpv6_type == ICMPV6_TIMEXCEED || hdr.icmpv6_type == ICMPV6_UNREACH)
|
||||
|
|
|
|||
|
|
@ -441,19 +441,12 @@ int get_ping_pcap_result(UltraScanInfo *USI, struct timeval *stime) {
|
|||
if (sockaddr_storage_cmp(USI->SourceSockAddr(), &hdr.dst) != 0)
|
||||
continue;
|
||||
|
||||
struct ip ip_tmp;
|
||||
memcpy(&ip_tmp, pkt, sizeof(ip_tmp));
|
||||
|
||||
/* First check if it is ICMP, TCP, or UDP */
|
||||
if (hdr.proto == IPPROTO_ICMP || hdr.proto == IPPROTO_ICMPV6) {
|
||||
/* if it is our response */
|
||||
if (bytes < 8U) {
|
||||
if (!ip_tmp.ip_off)
|
||||
error("Supposed ping packet is only %d bytes long!", bytes);
|
||||
continue;
|
||||
}
|
||||
|
||||
struct ppkt ping;
|
||||
if (datalen < sizeof(ppkt))
|
||||
continue;
|
||||
memcpy(&ping, data, sizeof(ping));
|
||||
current_reason = icmp_to_reason(hdr.proto, ping.type, ping.code);
|
||||
|
||||
|
|
@ -559,12 +552,16 @@ int get_ping_pcap_result(UltraScanInfo *USI, struct timeval *stime) {
|
|||
if ((encaps_hdr.proto == IPPROTO_ICMP || encaps_hdr.proto == IPPROTO_ICMPV6)
|
||||
&& USI->ptech.rawicmpscan) {
|
||||
/* The response was based on a ping packet we sent */
|
||||
if (encaps_len < ICMP_LEN_MIN)
|
||||
continue;
|
||||
struct icmp icmp;
|
||||
memcpy(&icmp, encaps_data, sizeof(icmp));
|
||||
memcpy(&icmp, encaps_data, MIN(encaps_len, sizeof(icmp)));
|
||||
if (probe->icmpid() != ntohs(icmp.icmp_id))
|
||||
continue;
|
||||
} else if (encaps_hdr.proto == IPPROTO_TCP && USI->ptech.rawtcpscan) {
|
||||
struct tcp_hdr tcp;
|
||||
if (encaps_len < sizeof(tcp))
|
||||
continue;
|
||||
memcpy(&tcp, encaps_data, sizeof(tcp));
|
||||
if (probe->dport() != ntohs(tcp.th_dport) ||
|
||||
probe->sport() != ntohs(tcp.th_sport) ||
|
||||
|
|
@ -572,12 +569,16 @@ int get_ping_pcap_result(UltraScanInfo *USI, struct timeval *stime) {
|
|||
continue;
|
||||
} else if (encaps_hdr.proto == IPPROTO_UDP && USI->ptech.rawudpscan) {
|
||||
struct udp_hdr udp;
|
||||
if (encaps_len < sizeof(udp))
|
||||
continue;
|
||||
memcpy(&udp, encaps_data, sizeof(udp));
|
||||
if (probe->dport() != ntohs(udp.uh_dport) ||
|
||||
probe->sport() != ntohs(udp.uh_sport))
|
||||
continue;
|
||||
} else if (encaps_hdr.proto == IPPROTO_SCTP && USI->ptech.rawsctpscan) {
|
||||
struct sctp_hdr sctp;
|
||||
if (encaps_len < sizeof(sctp))
|
||||
continue;
|
||||
memcpy(&sctp, encaps_data, sizeof(sctp));
|
||||
if (probe->dport() != ntohs(sctp.sh_dport) ||
|
||||
probe->sport() != ntohs(sctp.sh_sport) ||
|
||||
|
|
@ -658,6 +659,8 @@ int get_ping_pcap_result(UltraScanInfo *USI, struct timeval *stime) {
|
|||
}
|
||||
} else if (hdr.proto == IPPROTO_TCP && USI->ptech.rawtcpscan) {
|
||||
struct tcp_hdr tcp;
|
||||
if (datalen < sizeof(tcp))
|
||||
continue;
|
||||
memcpy(&tcp, data, sizeof(tcp));
|
||||
/* Check that the packet has useful flags. */
|
||||
if (o.discovery_ignore_rst
|
||||
|
|
@ -709,7 +712,8 @@ int get_ping_pcap_result(UltraScanInfo *USI, struct timeval *stime) {
|
|||
}
|
||||
} else if (hdr.proto == IPPROTO_UDP && USI->ptech.rawudpscan) {
|
||||
struct udp_hdr udp;
|
||||
memcpy(&udp, data, sizeof(udp));
|
||||
if (datalen < sizeof(udp))
|
||||
continue;
|
||||
/* Search for this host on the incomplete list */
|
||||
hss = USI->findHost(&hdr.src);
|
||||
if (!hss)
|
||||
|
|
@ -719,6 +723,7 @@ int get_ping_pcap_result(UltraScanInfo *USI, struct timeval *stime) {
|
|||
listsz = hss->num_probes_outstanding();
|
||||
goodone = false;
|
||||
|
||||
memcpy(&udp, data, sizeof(udp));
|
||||
u16 sport = ntohs(udp.uh_sport);
|
||||
u16 dport = ntohs(udp.uh_dport);
|
||||
|
||||
|
|
@ -745,6 +750,10 @@ int get_ping_pcap_result(UltraScanInfo *USI, struct timeval *stime) {
|
|||
log_write(LOG_STDOUT, "In response to UDP-ping, we got UDP packet back from %s port %hu (trynum = %d)\n", inet_ntop_ez(&hdr.src, sizeof(hdr.src)), sport, probe->get_tryno());
|
||||
}
|
||||
} else if (hdr.proto == IPPROTO_SCTP && USI->ptech.rawsctpscan) {
|
||||
struct sctp_hdr sctp;
|
||||
struct dnet_sctp_chunkhdr chunk;
|
||||
if (datalen < sizeof(sctp) + sizeof(chunk))
|
||||
continue;
|
||||
/* Search for this host on the incomplete list */
|
||||
hss = USI->findHost(&hdr.src);
|
||||
if (!hss)
|
||||
|
|
@ -753,10 +762,8 @@ int get_ping_pcap_result(UltraScanInfo *USI, struct timeval *stime) {
|
|||
listsz = hss->num_probes_outstanding();
|
||||
goodone = false;
|
||||
|
||||
struct sctp_hdr sctp;
|
||||
memcpy(&sctp, data, sizeof(sctp));
|
||||
struct dnet_sctp_chunkhdr chunk;
|
||||
memcpy(&chunk, (u8 *)data + 12, sizeof(chunk));
|
||||
memcpy(&chunk, (u8 *)data + sizeof(sctp), sizeof(chunk));
|
||||
|
||||
u16 sport = ntohs(sctp.sh_sport);
|
||||
u16 dport = ntohs(sctp.sh_dport);
|
||||
|
|
|
|||
10
tcpip.cc
10
tcpip.cc
|
|
@ -1312,17 +1312,13 @@ static bool validateTCPhdr(const u8 *tcpc, unsigned len) {
|
|||
*/
|
||||
static bool validatepkt(const u8 *ipc, unsigned *len) {
|
||||
struct ip ip;
|
||||
if (*len < sizeof(ip))
|
||||
return false;
|
||||
memcpy(&ip, ipc, sizeof(ip));
|
||||
const void *data;
|
||||
unsigned int datalen, iplen;
|
||||
u8 hdr;
|
||||
|
||||
if (*len < 1) {
|
||||
if (o.debugging >= 3)
|
||||
error("Rejecting tiny, supposed IP packet (size %u)", *len);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ip.ip_v == 4) {
|
||||
unsigned fragoff, iplen;
|
||||
|
||||
|
|
@ -1352,6 +1348,8 @@ static bool validatepkt(const u8 *ipc, unsigned *len) {
|
|||
hdr = ip.ip_p;
|
||||
} else if (ip.ip_v == 6) {
|
||||
struct ip6_hdr ip6;
|
||||
if (*len < sizeof(ip6))
|
||||
return false;
|
||||
memcpy(&ip6, ipc, sizeof(ip6));
|
||||
|
||||
datalen = *len;
|
||||
|
|
|
|||
|
|
@ -1132,6 +1132,8 @@ static bool decode_reply(const u8 *ip, unsigned int len, Reply *reply) {
|
|||
if (hdr.version == 4 && hdr.proto == IPPROTO_ICMP) {
|
||||
/* ICMP responses comprise all the TTL exceeded messages we expect from all
|
||||
probe types, as well as actual replies from ICMP probes. */
|
||||
if (len < ICMP_LEN_MIN)
|
||||
return false;
|
||||
ALIGN_HEADER(struct icmp_hdr, icmp, data, 0, len);
|
||||
if ((icmp.icmp_type == ICMP_TIMEXCEED
|
||||
&& icmp.icmp_code == ICMP_TIMEXCEED_INTRANS)
|
||||
|
|
@ -1158,6 +1160,8 @@ static bool decode_reply(const u8 *ip, unsigned int len, Reply *reply) {
|
|||
} else if (hdr.version == 6 && hdr.proto == IP_PROTO_ICMPV6) {
|
||||
/* ICMPv6 responses comprise all the TTL exceeded messages we expect from
|
||||
all probe types, as well as actual replies from ICMP probes. */
|
||||
if (len < ICMP_LEN_MIN)
|
||||
return false;
|
||||
ALIGN_HEADER(struct icmpv6_hdr, icmpv6, data, 0, len);
|
||||
/* TIMEXCEED, UNREACH */
|
||||
if ((icmpv6.icmpv6_type == ICMPV6_TIMEXCEED
|
||||
|
|
@ -1181,14 +1185,20 @@ static bool decode_reply(const u8 *ip, unsigned int len, Reply *reply) {
|
|||
return false;
|
||||
}
|
||||
} else if (hdr.proto == IPPROTO_TCP) {
|
||||
if (len < sizeof(struct tcp_hdr))
|
||||
return false;
|
||||
ALIGN_HEADER(struct tcp_hdr, tcp, data, 0, len);
|
||||
reply->token = ntohs(tcp.th_dport) ^ global_id;
|
||||
reply->target_addr = reply->from_addr;
|
||||
} else if (hdr.proto == IPPROTO_UDP) {
|
||||
if (len < sizeof(struct udp_hdr))
|
||||
return false;
|
||||
ALIGN_HEADER(struct udp_hdr, udp, data, 0, len);
|
||||
reply->token = ntohs(udp.uh_dport) ^ global_id;
|
||||
reply->target_addr = reply->from_addr;
|
||||
} else if (hdr.proto == IPPROTO_SCTP) {
|
||||
if (len < sizeof(struct sctp_hdr))
|
||||
return false;
|
||||
ALIGN_HEADER(struct sctp_hdr, sctp, data, 0, len);
|
||||
reply->token = ntohs(sctp.sh_dport) ^ global_id;
|
||||
reply->target_addr = reply->from_addr;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue