Perché Rust per la Sicurezza Informatica?
-
Memory Safety senza Garbage Collector: A differenza di Python, Rust evita vulnerabilità come buffer overflow o use-after-free, comuni in C, grazie al suo sistema di ownership. Questo è cruciale per strumenti di sicurezza che devono essere robusti contro input malevoli.
-
Performance di Livello C: Rust offre velocità paragonabili a C/C++, rendendolo ideale per task intensivi come scansioni di rete o analisi di pacchetti.
-
Ecosistema Moderno: Crates (librerie) come tokio per l’I/O asincrono o pnet per il networking semplificano lo sviluppo di tool complessi.
-
Controllo Granulare: Perfetto per exploit o tool di basso livello che richiedono manipolazione diretta di socket o protocolli.
Rust vs C e Python: Un Confronto
-
C: Offre controllo totale ma è incline a errori di memoria. Scrivere un port scanner in C richiede attenzione maniacale ai dettagli.
-
Python: Facile da usare e ottimo per prototipi, ma le sue prestazioni soffrono in task intensivi e manca di controlli strict sulla memoria.
-
Rust: Combina la velocità di C con la semplicità (relativa) di Python, eliminando intere classi di vulnerabilità.
Costruire un Port Scanner in Rust: Tutorial Pratico
-
Conoscenza base di Rust (ownership, match, async/await).
Passo 1: Configurazione del Progetto
cargo new port_scanner
cd port_scanner
Aggiungi queste dipendenze al file Cargo.toml per gestire l’I/O asincrono e gli errori:
[dependencies]
tokio = { version = "1.0", features = ["full"] }
anyhow = "1.0"
Passo 2: Scrivere il Codice
use tokio::net::TcpStream;
use anyhow::Result;
use std::time::Duration;
#[tokio::main]
async fn main() -> Result<()> {
let target_ip = "127.0.0.1"; // IP da scansionare
let start_port = 1;
let end_port = 100; // Scansiona porte 1-100
println!("Scansione di {} dalle porte {} a {}...", target_ip, start_port, end_port);
let mut tasks = Vec::new();
// Crea un task asincrono per ogni porta
for port in start_port..=end_port {
let ip = target_ip.to_string();
tasks.push(tokio::spawn(async move {
if scan_port(&ip, port).await {
println!("Porta {} aperta!", port);
}
}));
}
// Attende il completamento di tutti i task
for task in tasks {
task.await?;
}
Ok(())
}
async fn scan_port(ip: &str, port: u16) -> bool {
let timeout = Duration::from_secs(2);
let addr = format!("{}:{}", ip, port);
match tokio::time::timeout(timeout, TcpStream::connect(&addr)).await {
Ok(Ok(_)) => true, // Connessione riuscita, porta aperta
_ => false, // Timeout o errore, porta chiusa
}
}
Passo 3: Esecuzione
cargo run
Questo port scanner tenta di connettersi a ciascuna porta nell’intervallo specificato (1-100 su 127.0.0.1) e stampa solo le porte aperte. Grazie a tokio, le connessioni sono gestite in modo asincrono, migliorando le prestazioni rispetto a un approccio sequenziale.
Come Funziona
-
Async/Await: tokio permette di lanciare task concorrenti per ogni porta, riducendo il tempo di scansione.
-
Memory Safety: Il compilatore Rust garantisce che non ci siano accessi non sicuri alla memoria, anche con molte connessioni simultanee.
-
Gestione Errori: anyhow semplifica il handling delle eccezioni.
Benchmark: Rust vs Python
-
Rust: 1.8 secondi (con tokio e connessioni asincrone).
-
Python: 4.2 secondi (con asyncio).
Perché Scegliere Rust per il Pentesting?
-
Affidabilità: Zero crash imprevisti dovuti a errori di memoria.
-
Scalabilità: Perfetto per tool che devono gestire migliaia di connessioni o pacchetti.
-
Community: Crates come nmap-parser o dns-parser stanno emergendo per supportare il pentesting.
Lascia un commento