Fix bug with empty or misformed payload

This commit is contained in:
_Frky 2022-05-30 14:47:30 +02:00
parent d2d916239d
commit e34f3a6bcd
3 changed files with 57 additions and 9 deletions

View file

@ -123,7 +123,13 @@ pub fn reply<'a, 'b>(
match eth_req.get_ethertype() { match eth_req.get_ethertype() {
/* Construct answer to ARP request */ /* Construct answer to ARP request */
EtherTypes::Arp => { EtherTypes::Arp => {
let arp_req = ArpPacket::new(eth_req.payload()).expect("error parsing ARP packet"); let arp_req = if let Some(p) = ArpPacket::new(eth_req.payload()) {
p
} else {
warn!("error parsing ARP packet");
masscanned.log.eth_drop(eth_req, &client_info);
return None;
};
if let Some(arp_repl) = arp::repl(&arp_req, masscanned) { if let Some(arp_repl) = arp::repl(&arp_req, masscanned) {
let arp_len = arp_repl.packet().len(); let arp_len = arp_repl.packet().len();
let eth_len = EthernetPacket::minimum_packet_size() + arp_len; let eth_len = EthernetPacket::minimum_packet_size() + arp_len;
@ -162,7 +168,13 @@ pub fn reply<'a, 'b>(
} }
/* Construct answer to IPv6 packet */ /* Construct answer to IPv6 packet */
EtherTypes::Ipv6 => { EtherTypes::Ipv6 => {
let ipv6_req = Ipv6Packet::new(eth_req.payload()).expect("error parsing IPv6 packet"); let ipv6_req = if let Some(p) = Ipv6Packet::new(eth_req.payload()) {
p
} else {
warn!("error parsing IPv6 packet");
masscanned.log.eth_drop(eth_req, &client_info);
return None;
};
if let Some(ipv6_repl) = layer_3::ipv6::repl(&ipv6_req, masscanned, &mut client_info) { if let Some(ipv6_repl) = layer_3::ipv6::repl(&ipv6_req, masscanned, &mut client_info) {
let ipv6_len = ipv6_repl.packet().len(); let ipv6_len = ipv6_repl.packet().len();
let eth_len = EthernetPacket::minimum_packet_size() + ipv6_len; let eth_len = EthernetPacket::minimum_packet_size() + ipv6_len;

View file

@ -59,7 +59,13 @@ pub fn repl<'a, 'b>(
match ip_req.get_next_level_protocol() { match ip_req.get_next_level_protocol() {
/* Answer to an ICMP packet */ /* Answer to an ICMP packet */
IpNextHeaderProtocols::Icmp => { IpNextHeaderProtocols::Icmp => {
let icmp_req = IcmpPacket::new(ip_req.payload()).expect("error parsing ICMP packet"); let icmp_req = if let Some(p) = IcmpPacket::new(ip_req.payload()) {
p
} else {
warn!("error parsing ICMP packet");
masscanned.log.ipv4_drop(&ip_req, &client_info);
return None;
};
if let Some(mut icmp_repl) = layer_4::icmpv4::repl(&icmp_req, masscanned, &client_info) if let Some(mut icmp_repl) = layer_4::icmpv4::repl(&icmp_req, masscanned, &client_info)
{ {
icmp_repl.set_checksum(ipv4_checksum_icmp(&icmp_repl.to_immutable())); icmp_repl.set_checksum(ipv4_checksum_icmp(&icmp_repl.to_immutable()));
@ -79,7 +85,13 @@ pub fn repl<'a, 'b>(
} }
/* Answer to a TCP packet */ /* Answer to a TCP packet */
IpNextHeaderProtocols::Tcp => { IpNextHeaderProtocols::Tcp => {
let tcp_req = TcpPacket::new(ip_req.payload()).expect("error parsing TCP packet"); let tcp_req = if let Some(p) = TcpPacket::new(ip_req.payload()) {
p
} else {
warn!("error parsing TCP packet");
masscanned.log.ipv4_drop(&ip_req, &client_info);
return None;
};
if let Some(mut tcp_repl) = layer_4::tcp::repl(&tcp_req, masscanned, &mut client_info) { if let Some(mut tcp_repl) = layer_4::tcp::repl(&tcp_req, masscanned, &mut client_info) {
tcp_repl.set_checksum(ipv4_checksum_tcp( tcp_repl.set_checksum(ipv4_checksum_tcp(
&tcp_repl.to_immutable(), &tcp_repl.to_immutable(),
@ -102,7 +114,13 @@ pub fn repl<'a, 'b>(
} }
/* Answer to an UDP packet */ /* Answer to an UDP packet */
IpNextHeaderProtocols::Udp => { IpNextHeaderProtocols::Udp => {
let udp_req = UdpPacket::new(ip_req.payload()).expect("error parsing UDP packet"); let udp_req = if let Some(p) = UdpPacket::new(ip_req.payload()) {
p
} else {
warn!("error parsing UDP packet");
masscanned.log.ipv4_drop(&ip_req, &client_info);
return None;
};
if let Some(mut udp_repl) = layer_4::udp::repl(&udp_req, masscanned, &mut client_info) { if let Some(mut udp_repl) = layer_4::udp::repl(&udp_req, masscanned, &mut client_info) {
udp_repl.set_checksum(ipv4_checksum_udp( udp_repl.set_checksum(ipv4_checksum_udp(
&udp_repl.to_immutable(), &udp_repl.to_immutable(),

View file

@ -14,6 +14,7 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Masscanned. If not, see <http://www.gnu.org/licenses/>. // along with Masscanned. If not, see <http://www.gnu.org/licenses/>.
use log::*;
use std::net::IpAddr; use std::net::IpAddr;
use pnet::packet::{ use pnet::packet::{
@ -61,8 +62,13 @@ pub fn repl<'a, 'b>(
match ip_req.get_next_header() { match ip_req.get_next_header() {
/* Answer to ICMPv6 */ /* Answer to ICMPv6 */
IpNextHeaderProtocols::Icmpv6 => { IpNextHeaderProtocols::Icmpv6 => {
let icmp_req = let icmp_req = if let Some(p) = Icmpv6Packet::new(ip_req.payload()) {
Icmpv6Packet::new(ip_req.payload()).expect("error parsing ICMPv6 packet"); p
} else {
warn!("error parsing ICMPv6 packet");
masscanned.log.ipv6_drop(&ip_req, &client_info);
return None;
};
if let (Some(mut icmp_repl), dst_addr) = if let (Some(mut icmp_repl), dst_addr) =
layer_4::icmpv6::repl(&icmp_req, masscanned, &client_info) layer_4::icmpv6::repl(&icmp_req, masscanned, &client_info)
{ {
@ -92,7 +98,13 @@ pub fn repl<'a, 'b>(
} }
/* Answer to TCP */ /* Answer to TCP */
IpNextHeaderProtocols::Tcp => { IpNextHeaderProtocols::Tcp => {
let tcp_req = TcpPacket::new(ip_req.payload()).expect("error parsing TCP packet"); let tcp_req = if let Some(p) = TcpPacket::new(ip_req.payload()) {
p
} else {
warn!("error parsing TCP packet");
masscanned.log.ipv6_drop(&ip_req, &client_info);
return None;
};
if let Some(mut tcp_repl) = layer_4::tcp::repl(&tcp_req, masscanned, &mut client_info) { if let Some(mut tcp_repl) = layer_4::tcp::repl(&tcp_req, masscanned, &mut client_info) {
/* Compute and set TCP checksum */ /* Compute and set TCP checksum */
tcp_repl.set_checksum(ipv6_checksum_tcp( tcp_repl.set_checksum(ipv6_checksum_tcp(
@ -117,7 +129,13 @@ pub fn repl<'a, 'b>(
} }
/* Answer to UDP */ /* Answer to UDP */
IpNextHeaderProtocols::Udp => { IpNextHeaderProtocols::Udp => {
let udp_req = UdpPacket::new(ip_req.payload()).expect("error parsing UDP packet"); let udp_req = if let Some(p) = UdpPacket::new(ip_req.payload()) {
p
} else {
warn!("error parsing UDP packet");
masscanned.log.ipv6_drop(&ip_req, &client_info);
return None;
};
if let Some(mut udp_repl) = layer_4::udp::repl(&udp_req, masscanned, &mut client_info) { if let Some(mut udp_repl) = layer_4::udp::repl(&udp_req, masscanned, &mut client_info) {
/* Compute and set UDP checksum */ /* Compute and set UDP checksum */
udp_repl.set_checksum(ipv6_checksum_udp( udp_repl.set_checksum(ipv6_checksum_udp(