Курс — Хакинг на Rust. #18 Инструменты хакера на Rust. Сетевые атаки. Написание сетевых сканеров и снифферов
Здравствуйте, дорогие друзья.
Сетевые атаки — основа кибербезопасности, позволяющая выявлять уязвимости в инфраструктуре. Rust идеален для их реализации:
- Скорость: Асинхронные операции и нулевые накладные расходы.
- Безопасность: Гарантии языка предотвращают ошибки в обработке пакетов.
- Гибкость: Работа с сырыми сокетами, TCP/UDP, сетевыми протоколами.
Сетевые сканеры
Сканеры анализируют порты и сервисы, ища открытые двери в систему.
TCP-сканер
TCP-сканер проверяет доступность портов через установку соединений (SYN-ACK).
Пример кода:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
use std::net::{TcpStream, SocketAddr}; use std::time::Duration; use std::thread; fn scan_port(ip: &str, port: u16) -> bool { let addr = format!("{}:{}", ip, port); if let Ok(_) = TcpStream::connect_timeout(&addr.parse().unwrap(), Duration::from_secs(1)) { println!("[+] Port {}: open", port); return true; } false } fn tcp_scanner(ip: &str, ports: Vec<u16>) { for port in ports { thread::spawn(move || { scan_port(ip, port); }); } } fn main() { let ip = "127.0.0.1"; let ports: Vec<u16> = (1..=1024).collect(); // Сканируем первые 1024 порта tcp_scanner(ip, ports); thread::sleep(Duration::from_secs(2)); // Ждём завершения потоков } |
Оптимизации:
- Асинхронность: Используйте
tokio
для массового сканирования. - Обработка ошибок: Добавьте проверку на ICMP-ответы (например, «порт недоступен»).
UDP-сканер
UDP-сканирование сложнее: протокол без подтверждений. Открытый порт может не ответить, а закрытый — прислать ICMP-пакет.
Пример с библиотекой pnet
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
use pnet::transport::{TransportChannelType, TransportProtocol, transport_channel}; use pnet::packet::udp::{UdpPacket, MutableUdpPacket}; use pnet::packet::ip::IpNextHeaderProtocols; use std::net::Ipv4Addr; fn udp_scan(target: Ipv4Addr, port: u16) { let (mut sender, mut receiver) = match transport_channel(4096, TransportChannelType::Layer4(TransportProtocol::Ipv4(IpNextHeaderProtocols::Udp))) { Ok((tx, rx)) => (tx, rx), Err(e) => panic!("Ошибка создания сокета: {}", e), }; let mut udp_buffer = [0u8; 8]; let mut udp_packet = MutableUdpPacket::new(&mut udp_buffer).unwrap(); udp_packet.set_source(44444); // Исходный порт udp_packet.set_destination(port); udp_packet.set_length(8); sender.send_to(udp_packet, target).unwrap(); // Анализ ответа (например, ICMP Port Unreachable) } |
Снифферы пакетов
Снифферы перехватывают и анализируют сетевой трафик. В Rust это реализуется через:
- Raw sockets: Для чтения всех пакетов на интерфейсе.
- Библиотеки:
pcap
,pnet
,etherparse
.
Пример сниффера с pnet
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
use pnet::datalink::{self, NetworkInterface}; use pnet::packet::{ethernet::EthernetPacket, ip::IpNextHeaderProtocol, ipv4::Ipv4Packet, tcp::TcpPacket}; fn handle_packet(packet: &[u8]) { if let Some(ethernet) = EthernetPacket::new(packet) { match ethernet.get_ethertype() { pnet::packet::ethernet::EtherTypes::Ipv4 => { if let Some(ipv4) = Ipv4Packet::new(ethernet.payload()) { if ipv4.get_next_level_protocol() == IpNextHeaderProtocol(6) { // TCP if let Some(tcp) = TcpPacket::new(ipv4.payload()) { println!( "[TCP] {}:{} -> {}:{}", ipv4.get_source(), tcp.get_source(), ipv4.get_destination(), tcp.get_destination() ); } } } } _ => {} } } } fn main() { let interface = NetworkInterface::from_name("eth0").unwrap(); let (_, mut rx) = match datalink::channel(&interface, Default::default()) { Ok(pnet::datalink::Channel::Ethernet(tx, rx)) => (tx, rx), _ => panic!("Не удалось открыть канал"), }; loop { match rx.next() { Ok(packet) => handle_packet(packet), Err(e) => panic!("Ошибка чтения пакета: {}", e), } } } |
Возможности сниффера:
- Фильтрация по протоколам (HTTP, DNS).
- Утечка данных: перехват паролей в незашифрованном трафике.
ARP-спуфинг
ARP-спуфинг — атака, подменяющая таблицы ARP для MITM.
Пример отправки ARP-ответа:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
use pnet::packet::arp::{ArpPacket, ArpOperations, MutableArpPacket}; use pnet::packet::ethernet::{EtherTypes, MutableEthernetPacket}; use pnet::datalink::NetworkInterface; fn send_arp_spoof(interface: &NetworkInterface, target_ip: Ipv4Addr, gateway_ip: Ipv4Addr) { let mut buffer = [0u8; 42]; let mut eth_packet = MutableEthernetPacket::new(&mut buffer).unwrap(); eth_packet.set_destination(MacAddr::broadcast()); // Широковещательный MAC eth_packet.set_source(interface.mac.unwrap()); eth_packet.set_ethertype(EtherTypes::Arp); let mut arp_packet = MutableArpPacket::new(eth_packet.payload_mut()).unwrap(); arp_packet.set_operation(ArpOperations::Reply); arp_packet.set_sender_hw(interface.mac.unwrap()); arp_packet.set_sender_proto(target_ip); // Жертва думает, что мы — шлюз arp_packet.set_target_hw(MacAddr::zero()); // Или MAC жертвы arp_packet.set_target_proto(gateway_ip); // Отправка пакета через raw socket... } |
Инструменты для анализа
- Wireshark: Визуализация и фильтрация трафика.
- Nmap: Сравнение результатов сканирования.
- Scapy (Python): Генерация кастомных пакетов для тестирования.
Этические аспекты
- Только с разрешения: Сканирование сетей и ARP-спуфинг без согласия владельца — нарушение закона.
- Защита: Используйте снифферы для анализа утечек в собственной сети.
Задание для самостоятельной работы:
- Модифицируйте TCP-сканер для асинхронной работы с
tokio
. - Добавьте в сниффер анализ DNS-запросов.
- Реализуйте защиту от ARP-спуфинга через проверку ARP-таблиц.
Итог:
Rust позволяет создавать высокопроизводительные сетевые инструменты с минимальными затратами ресурсов. Понимание работы протоколов и практика с сырыми сокетами делают язык незаменимым для этического хакинга.

На этом все. Всем хорошего дня!