netscan_os/
fingerprinter.rs

1use netscan_pcap::listener::Listner;
2use netscan_pcap::PacketCaptureOptions;
3use netscan_pcap::PacketFrame;
4use std::collections::HashSet;
5use std::net::{IpAddr, Ipv4Addr};
6use std::sync::{Arc, Mutex};
7use std::thread;
8use std::time::Duration;
9use xenet::datalink::DataLinkSender;
10use xenet::net::interface::Interface;
11use xenet::net::mac::MacAddr;
12use xenet::packet::frame::{Frame, ParseOption};
13use xenet::packet::icmp::IcmpType;
14use xenet::packet::icmpv6::Icmpv6Type;
15use xenet::packet::ip::IpNextLevelProtocol;
16use xenet::packet::ipv4::{Ipv4Flags, Ipv4Packet};
17use xenet::packet::ipv6::Ipv6Packet;
18use xenet::packet::tcp::TcpFlags;
19use xenet::packet::udp::UdpPacket;
20use xenet::util::packet_builder::util::PacketBuildOption;
21
22use crate::interface;
23
24use super::result::ProbeResult;
25use super::send;
26use super::setting::LISTENER_WAIT_TIME_MILLIS;
27use super::setting::{ProbeSetting, ProbeTarget, ProbeType};
28
29const DEFAULT_SRC_PORT: u16 = 54433;
30const ICMP_UNUSED_BYTE_SIZE: usize = 4;
31
32/// Struct for fingerprint probe
33pub struct Fingerprinter {
34    /// Probe setting
35    pub probe_setting: ProbeSetting,
36    /// Result of probes  
37    pub probe_result: ProbeResult,
38}
39
40impl Fingerprinter {
41    /// Create new fingerprinter with Interfece IP
42    pub fn new(src_ip: IpAddr) -> Result<Fingerprinter, String> {
43        let network_interface =
44            if let Some(network_interface) = interface::get_interface_by_ip(src_ip) {
45                network_interface
46            } else {
47                return Err(String::from(
48                    "Failed to create Scanner. Network Interface not found.",
49                ));
50            };
51        let use_tun = network_interface.is_tun();
52        let loopback = network_interface.is_loopback();
53        let probe_setting: ProbeSetting = ProbeSetting {
54            if_index: network_interface.index,
55            if_name: network_interface.name.clone(),
56            src_mac: if use_tun {
57                MacAddr::zero()
58            } else {
59                interface::get_interface_macaddr(&network_interface)
60            },
61            dst_mac: if use_tun {
62                MacAddr::zero()
63            } else {
64                interface::get_gateway_macaddr(&network_interface)
65            },
66            src_ip: src_ip,
67            src_port: DEFAULT_SRC_PORT,
68            probe_target: ProbeTarget::new(),
69            probe_types: vec![],
70            timeout: Duration::from_millis(30000),
71            wait_time: Duration::from_millis(200),
72            send_rate: Duration::from_millis(1),
73            tunnel: use_tun,
74            loopback: loopback,
75        };
76        let fingerprinter = Fingerprinter {
77            probe_setting: probe_setting,
78            probe_result: ProbeResult::new(IpAddr::V4(Ipv4Addr::LOCALHOST)),
79        };
80        Ok(fingerprinter)
81    }
82    /// Create new fingerprinter with Interfece Index
83    pub fn new_with_index(if_index: u32) -> Result<Fingerprinter, String> {
84        let network_interface =
85            if let Some(network_interface) = interface::get_interface_by_index(if_index) {
86                network_interface
87            } else {
88                return Err(String::from(
89                    "Failed to create Scanner. Network Interface not found.",
90                ));
91            };
92        let src_ip: IpAddr = match interface::get_interface_ipv4(&network_interface) {
93            Some(ip) => ip,
94            None => match interface::get_interface_ipv6(&network_interface) {
95                Some(ip) => ip,
96                None => {
97                    return Err(String::from(
98                        "Failed to create Fingerprinter. Invalid Interface IP address.",
99                    ))
100                }
101            },
102        };
103        let use_tun = network_interface.is_tun();
104        let loopback = network_interface.is_loopback();
105        let probe_setting: ProbeSetting = ProbeSetting {
106            if_index: network_interface.index,
107            if_name: network_interface.name.clone(),
108            src_mac: if use_tun {
109                MacAddr::zero()
110            } else {
111                interface::get_interface_macaddr(&network_interface)
112            },
113            dst_mac: if use_tun {
114                MacAddr::zero()
115            } else {
116                interface::get_gateway_macaddr(&network_interface)
117            },
118            src_ip: src_ip,
119            src_port: DEFAULT_SRC_PORT,
120            probe_target: ProbeTarget::new(),
121            probe_types: vec![],
122            timeout: Duration::from_millis(30000),
123            wait_time: Duration::from_millis(200),
124            send_rate: Duration::from_millis(1),
125            tunnel: use_tun,
126            loopback: loopback,
127        };
128        let fingerprinter = Fingerprinter {
129            probe_setting: probe_setting,
130            probe_result: ProbeResult::new(IpAddr::V4(Ipv4Addr::LOCALHOST)),
131        };
132        Ok(fingerprinter)
133    }
134    /// Create new fingerprinter with Interfece Name
135    pub fn new_with_name(if_name: String) -> Result<Fingerprinter, String> {
136        let network_interface =
137            if let Some(network_interface) = interface::get_interface_by_name(if_name) {
138                network_interface
139            } else {
140                return Err(String::from(
141                    "Failed to create Scanner. Network Interface not found.",
142                ));
143            };
144        let src_ip = interface::get_interface_ipv4(&network_interface).unwrap_or(
145            interface::get_interface_ipv6(&network_interface)
146                .unwrap_or(IpAddr::V4(std::net::Ipv4Addr::UNSPECIFIED)),
147        );
148        let use_tun = network_interface.is_tun();
149        let loopback = network_interface.is_loopback();
150        let probe_setting: ProbeSetting = ProbeSetting {
151            if_index: network_interface.index,
152            if_name: network_interface.name.clone(),
153            src_mac: if use_tun {
154                MacAddr::zero()
155            } else {
156                interface::get_interface_macaddr(&network_interface)
157            },
158            dst_mac: if use_tun {
159                MacAddr::zero()
160            } else {
161                interface::get_gateway_macaddr(&network_interface)
162            },
163            src_ip: src_ip,
164            src_port: DEFAULT_SRC_PORT,
165            probe_target: ProbeTarget::new(),
166            probe_types: vec![],
167            timeout: Duration::from_millis(30000),
168            wait_time: Duration::from_millis(200),
169            send_rate: Duration::from_millis(1),
170            tunnel: use_tun,
171            loopback: loopback,
172        };
173        let fingerprinter = Fingerprinter {
174            probe_setting: probe_setting,
175            probe_result: ProbeResult::new(IpAddr::V4(Ipv4Addr::LOCALHOST)),
176        };
177        Ok(fingerprinter)
178    }
179    /// Create new fingerprinter with interfece IP and gateway IP
180    pub fn new_with_gateway_ip(
181        src_ip: IpAddr,
182        gateway_ip: IpAddr,
183    ) -> Result<Fingerprinter, String> {
184        let network_interface =
185            if let Some(network_interface) = interface::get_interface_by_ip(src_ip) {
186                network_interface
187            } else {
188                return Err(String::from(
189                    "Failed to create Scanner. Network Interface not found.",
190                ));
191            };
192        let use_tun = network_interface.is_tun();
193        let loopback = network_interface.is_loopback();
194        let dst_mac: MacAddr = match gateway_ip {
195            IpAddr::V4(ip) => get_mac_through_arp(network_interface.clone(), ip),
196            IpAddr::V6(_) => {
197                return Err(String::from(
198                    "Failed to create Fingerprinter. Invalid Gateway IP address.",
199                ))
200            }
201        };
202        let probe_setting: ProbeSetting = ProbeSetting {
203            if_index: network_interface.index,
204            if_name: network_interface.name,
205            src_mac: if use_tun {
206                MacAddr::zero()
207            } else {
208                network_interface.mac_addr.unwrap_or(MacAddr::zero())
209            },
210            dst_mac: dst_mac,
211            src_ip: src_ip,
212            src_port: DEFAULT_SRC_PORT,
213            probe_target: ProbeTarget::new(),
214            probe_types: vec![],
215            timeout: Duration::from_millis(30000),
216            wait_time: Duration::from_millis(200),
217            send_rate: Duration::from_millis(1),
218            tunnel: use_tun,
219            loopback: loopback,
220        };
221        let fingerprinter = Fingerprinter {
222            probe_setting: probe_setting,
223            probe_result: ProbeResult::new(IpAddr::V4(Ipv4Addr::LOCALHOST)),
224        };
225        Ok(fingerprinter)
226    }
227    /// Set source port number
228    pub fn set_src_port(&mut self, src_port: u16) {
229        self.probe_setting.src_port = src_port;
230    }
231    /// Set probe target (IP address and tcp/udp port)
232    pub fn set_probe_target(&mut self, probe_target: ProbeTarget) {
233        self.probe_setting.probe_target = probe_target;
234    }
235    /// Add probe type
236    pub fn add_probe_type(&mut self, probe_type: ProbeType) {
237        self.probe_setting.probe_types.push(probe_type);
238    }
239    /// Set probe types
240    pub fn set_probe_types(&mut self, probe_types: Vec<ProbeType>) {
241        self.probe_setting.probe_types = probe_types;
242    }
243    /// Set all probe types
244    pub fn set_full_probe(&mut self) {
245        self.probe_setting.probe_types.clear();
246        self.probe_setting
247            .probe_types
248            .push(ProbeType::IcmpEchoProbe);
249        if self.probe_setting.src_ip.is_ipv4() {
250            self.probe_setting
251                .probe_types
252                .push(ProbeType::IcmpTimestampProbe);
253            self.probe_setting
254                .probe_types
255                .push(ProbeType::IcmpAddressMaskProbe);
256            self.probe_setting
257                .probe_types
258                .push(ProbeType::IcmpInformationProbe);
259        }
260        self.probe_setting
261            .probe_types
262            .push(ProbeType::IcmpUnreachableProbe);
263        self.probe_setting
264            .probe_types
265            .push(ProbeType::TcpSynAckProbe);
266        self.probe_setting
267            .probe_types
268            .push(ProbeType::TcpRstAckProbe);
269        self.probe_setting.probe_types.push(ProbeType::TcpEcnProbe);
270        self.probe_setting.probe_types.push(ProbeType::TcpProbe);
271    }
272    /// Set probe timeout  
273    pub fn set_timeout(&mut self, timeout: Duration) {
274        self.probe_setting.timeout = timeout;
275    }
276    /// Set wait-time after the sending task is completed  
277    pub fn set_wait_time(&mut self, wait_time: Duration) {
278        self.probe_setting.wait_time = wait_time;
279    }
280    /// Set packet send rate
281    pub fn set_send_rate(&mut self, send_rate: Duration) {
282        self.probe_setting.send_rate = send_rate;
283    }
284    /// Get probe result
285    pub fn get_probe_result(&self) -> ProbeResult {
286        self.probe_result.clone()
287    }
288    /// Run probe with the current settings
289    pub fn run_probe(&mut self) {
290        let interface: Interface =
291            match crate::interface::get_interface_by_index(self.probe_setting.if_index) {
292                Some(interface) => interface,
293                None => {
294                    return;
295                }
296            };
297        let config = xenet::datalink::Config {
298            write_buffer_size: 4096,
299            read_buffer_size: 4096,
300            read_timeout: Some(self.probe_setting.wait_time),
301            write_timeout: None,
302            channel_type: xenet::datalink::ChannelType::Layer2,
303            bpf_fd_attempts: 1000,
304            linux_fanout: None,
305            promiscuous: false,
306        };
307        let (mut tx, mut _rx) = match xenet::datalink::channel(&interface, config) {
308            Ok(xenet::datalink::Channel::Ethernet(tx, rx)) => (tx, rx),
309            Ok(_) => panic!("Unhandled channel type"),
310            Err(e) => panic!("Failed to create channel: {}", e),
311        };
312        let result: ProbeResult = probe(&mut tx, &mut self.probe_setting);
313        self.probe_result = result;
314    }
315    /// Run probe and return result
316    pub fn probe(&mut self) -> ProbeResult {
317        self.run_probe();
318        self.probe_result.clone()
319    }
320}
321
322fn probe(sender: &mut Box<dyn DataLinkSender>, probe_setting: &ProbeSetting) -> ProbeResult {
323    let capture_options: PacketCaptureOptions = PacketCaptureOptions {
324        interface_index: probe_setting.if_index,
325        interface_name: probe_setting.if_name.clone(),
326        src_ips: [probe_setting.probe_target.ip_addr]
327            .iter()
328            .cloned()
329            .collect(),
330        dst_ips: HashSet::new(),
331        src_ports: HashSet::new(),
332        dst_ports: HashSet::new(),
333        ether_types: HashSet::new(),
334        ip_protocols: HashSet::new(),
335        duration: probe_setting.timeout,
336        read_timeout: probe_setting.wait_time,
337        promiscuous: false,
338        store: true,
339        store_limit: u32::MAX,
340        receive_undefined: false,
341        tunnel: probe_setting.tunnel,
342        loopback: probe_setting.loopback,
343    };
344    let listener: Listner = Listner::new(capture_options);
345    let stop_handle = listener.get_stop_handle();
346    let fingerprints: Arc<Mutex<Vec<PacketFrame>>> = Arc::new(Mutex::new(vec![]));
347    let receive_fingerprints: Arc<Mutex<Vec<PacketFrame>>> = Arc::clone(&fingerprints);
348
349    let handler = thread::spawn(move || {
350        let packets: Vec<PacketFrame> = listener.start();
351        for f in packets {
352            match receive_fingerprints.lock() {
353                Ok(mut fingerprints) => {
354                    fingerprints.push(f);
355                }
356                Err(e) => {
357                    eprintln!("Error: {:?}", e);
358                }
359            }
360        }
361    });
362
363    // Wait for listener to start (need fix for better way)
364    thread::sleep(Duration::from_millis(LISTENER_WAIT_TIME_MILLIS));
365
366    send::send_packets(sender, &probe_setting);
367    thread::sleep(probe_setting.wait_time);
368
369    // Stop listener
370    match stop_handle.lock() {
371        Ok(mut stop) => {
372            *stop = true;
373        }
374        Err(e) => {
375            eprintln!("Error: {:?}", e);
376        }
377    }
378
379    // Wait for listener to stop
380    match handler.join() {
381        Ok(_) => {}
382        Err(e) => {
383            eprintln!("Error: {:?}", e);
384        }
385    }
386    // Parse fingerprints and set result
387    let mut result: ProbeResult = ProbeResult::new_with_types(
388        probe_setting.probe_target.ip_addr,
389        probe_setting.probe_types.clone(),
390    );
391    match fingerprints.lock() {
392        Ok(fingerprints) => {
393            for f in fingerprints.iter() {
394                let ip_next_protocol: IpNextLevelProtocol = if let Some(ip_packet) = &f.ipv4_header
395                {
396                    ip_packet.next_level_protocol
397                } else {
398                    if let Some(ip_packet) = &f.ipv6_header {
399                        ip_packet.next_header
400                    } else {
401                        continue;
402                    }
403                };
404                match ip_next_protocol {
405                    IpNextLevelProtocol::Tcp => {
406                        if let Some(tcp_fingerprint) = &f.tcp_header {
407                            if tcp_fingerprint.flags == TcpFlags::SYN | TcpFlags::ACK
408                                && tcp_fingerprint.flags
409                                    != TcpFlags::SYN | TcpFlags::ACK | TcpFlags::ECE
410                            {
411                                if let Some(tcp_syn_ack_result) = &mut result.tcp_syn_ack_result {
412                                    tcp_syn_ack_result.syn_ack_response = true;
413                                    tcp_syn_ack_result.fingerprints.push(f.clone());
414                                }
415                            } else if tcp_fingerprint.flags == TcpFlags::RST | TcpFlags::ACK {
416                                if let Some(tcp_rst_ack_result) = &mut result.tcp_rst_ack_result {
417                                    tcp_rst_ack_result.rst_ack_response = true;
418                                    tcp_rst_ack_result.fingerprints.push(f.clone());
419                                }
420                            } else if tcp_fingerprint.flags
421                                == TcpFlags::SYN | TcpFlags::ACK | TcpFlags::ECE
422                            {
423                                if let Some(tcp_rst_ack_result) = &mut result.tcp_ecn_result {
424                                    tcp_rst_ack_result.syn_ack_ece_response = true;
425                                    tcp_rst_ack_result.fingerprints.push(f.clone());
426                                }
427                            }
428                        }
429                    }
430                    IpNextLevelProtocol::Udp => {}
431                    IpNextLevelProtocol::Icmp => {
432                        if let Some(icmp_fingerprint) = &f.icmp_header {
433                            match icmp_fingerprint.icmp_type {
434                                IcmpType::EchoReply => {
435                                    if let Some(icmp_echo_result) = &mut result.icmp_echo_result {
436                                        icmp_echo_result.icmp_echo_reply = true;
437                                        icmp_echo_result.fingerprints.push(f.clone());
438                                    }
439                                }
440                                IcmpType::DestinationUnreachable => {
441                                    if let Some(icmp_unreachable_ip_result) =
442                                        &mut result.icmp_unreachable_ip_result
443                                    {
444                                        icmp_unreachable_ip_result.icmp_unreachable_reply = true;
445                                        if let Some(ipv4_packet) = Ipv4Packet::new(
446                                            &f.payload[ICMP_UNUSED_BYTE_SIZE
447                                                ..xenet::packet::ipv4::IPV4_HEADER_LEN
448                                                    + ICMP_UNUSED_BYTE_SIZE],
449                                        ) {
450                                            if let Some(_udp_packet) = UdpPacket::new(
451                                                &f.payload[xenet::packet::ipv4::IPV4_HEADER_LEN
452                                                    + ICMP_UNUSED_BYTE_SIZE..],
453                                            ) {
454                                                // TODO
455                                            }
456                                            icmp_unreachable_ip_result.ip_total_length =
457                                                ipv4_packet.get_total_length();
458                                            icmp_unreachable_ip_result.ip_id =
459                                                ipv4_packet.get_identification();
460                                            if ipv4_packet.get_flags() == Ipv4Flags::DontFragment {
461                                                icmp_unreachable_ip_result.ip_df = true;
462                                            }
463                                            icmp_unreachable_ip_result.ip_ttl =
464                                                ipv4_packet.get_ttl();
465                                        }
466                                        icmp_unreachable_ip_result.icmp_unreachable_size =
467                                            f.payload.len() - ICMP_UNUSED_BYTE_SIZE;
468                                        icmp_unreachable_ip_result.fingerprints.push(f.clone());
469                                    }
470                                }
471                                IcmpType::TimestampReply => {
472                                    if let Some(icmp_timestamp_result) =
473                                        &mut result.icmp_timestamp_result
474                                    {
475                                        icmp_timestamp_result.icmp_timestamp_reply = true;
476                                        icmp_timestamp_result.fingerprints.push(f.clone());
477                                    }
478                                }
479                                IcmpType::AddressMaskReply => {
480                                    if let Some(icmp_address_mask_result) =
481                                        &mut result.icmp_address_mask_result
482                                    {
483                                        icmp_address_mask_result.icmp_address_mask_reply = true;
484                                        icmp_address_mask_result.fingerprints.push(f.clone());
485                                    }
486                                }
487                                IcmpType::InformationReply => {
488                                    if let Some(icmp_information_result) =
489                                        &mut result.icmp_information_result
490                                    {
491                                        icmp_information_result.icmp_information_reply = true;
492                                        icmp_information_result.fingerprints.push(f.clone());
493                                    }
494                                }
495                                _ => {}
496                            }
497                        }
498                    }
499                    IpNextLevelProtocol::Icmpv6 => {
500                        if let Some(icmpv6_fingerprint) = &f.icmpv6_header {
501                            match icmpv6_fingerprint.icmpv6_type {
502                                Icmpv6Type::EchoReply => {
503                                    if let Some(icmp_echo_result) = &mut result.icmp_echo_result {
504                                        icmp_echo_result.icmp_echo_reply = true;
505                                        icmp_echo_result.fingerprints.push(f.clone());
506                                    }
507                                }
508                                Icmpv6Type::DestinationUnreachable => {
509                                    if let Some(icmp_unreachable_ip_result) =
510                                        &mut result.icmp_unreachable_ip_result
511                                    {
512                                        icmp_unreachable_ip_result.icmp_unreachable_reply = true;
513                                        if let Some(ipv6_packet) = Ipv6Packet::new(
514                                            &f.payload[ICMP_UNUSED_BYTE_SIZE
515                                                ..xenet::packet::ipv6::IPV6_HEADER_LEN
516                                                    + ICMP_UNUSED_BYTE_SIZE],
517                                        ) {
518                                            if let Some(_udp_packet) = UdpPacket::new(
519                                                &f.payload[xenet::packet::ipv6::IPV6_HEADER_LEN
520                                                    + ICMP_UNUSED_BYTE_SIZE..],
521                                            ) {
522                                                // TODO
523                                            }
524                                            icmp_unreachable_ip_result.ip_ttl =
525                                                ipv6_packet.get_hop_limit();
526                                        }
527                                        icmp_unreachable_ip_result.icmp_unreachable_size =
528                                            f.payload.len() - ICMP_UNUSED_BYTE_SIZE;
529                                        icmp_unreachable_ip_result.ip_total_length =
530                                            (f.payload.len() - ICMP_UNUSED_BYTE_SIZE) as u16;
531                                        icmp_unreachable_ip_result.fingerprints.push(f.clone());
532                                    }
533                                }
534                                _ => {}
535                            }
536                        }
537                    }
538                    _ => {}
539                }
540            }
541        }
542        Err(e) => {
543            eprintln!("Error: {:?}", e);
544        }
545    }
546    return result;
547}
548
549fn get_mac_through_arp(interface: Interface, target_ip: Ipv4Addr) -> MacAddr {
550    // Create new socket
551    let config = xenet::datalink::Config {
552        write_buffer_size: 4096,
553        read_buffer_size: 4096,
554        read_timeout: Some(Duration::from_millis(100)),
555        write_timeout: None,
556        channel_type: xenet::datalink::ChannelType::Layer2,
557        bpf_fd_attempts: 1000,
558        linux_fanout: None,
559        promiscuous: false,
560    };
561    let (mut tx, mut rx) = match xenet::datalink::channel(&interface, config) {
562        Ok(xenet::datalink::Channel::Ethernet(tx, rx)) => (tx, rx),
563        Ok(_) => panic!("Unhandled channel type"),
564        Err(e) => panic!("Failed to create channel: {}", e),
565    };
566    let src_mac = match interface.mac_addr {
567        Some(mac) => mac,
568        None => {
569            return MacAddr::zero();
570        }
571    };
572    // Packet option for ARP request
573    let mut packet_option = PacketBuildOption::new();
574    packet_option.src_mac = src_mac;
575    packet_option.dst_mac = MacAddr::zero();
576    packet_option.ether_type = xenet::packet::ethernet::EtherType::Arp;
577    packet_option.src_ip = IpAddr::V4(interface.ipv4[0].addr);
578    packet_option.dst_ip = IpAddr::V4(target_ip);
579
580    let arp_packet: Vec<u8> =
581        xenet::util::packet_builder::util::build_full_arp_packet(packet_option);
582    // Send ARP request
583    match tx.send(&arp_packet) {
584        Some(_) => {}
585        None => {}
586    }
587
588    let timeout = Duration::from_millis(10000);
589    let start = std::time::Instant::now();
590    // Receive packets until timeout
591    loop {
592        if start.elapsed() > timeout {
593            return MacAddr::zero();
594        }
595        match rx.next() {
596            Ok(packet) => {
597                let frame: Frame = Frame::from_bytes(&packet, ParseOption::default());
598                if let Some(datalink) = frame.datalink {
599                    if let Some(ethernet_header) = datalink.ethernet {
600                        if ethernet_header.ethertype == xenet::packet::ethernet::EtherType::Arp {
601                            if let Some(arp_header) = datalink.arp {
602                                if arp_header.sender_hw_addr.address() != src_mac.address()
603                                    && arp_header.sender_proto_addr == target_ip
604                                {
605                                    return arp_header.sender_hw_addr;
606                                }
607                            }
608                        }
609                    }
610                }
611            }
612            Err(_) => {}
613        }
614    }
615}