
Bibliothèque Go idiomatique pour invoquer un binaire de scanner réseau, permettant la découverte d'hôtes, le scan de ports, la détection de services/systèmes d'exploitation et des vérifications de vulnérabilités scriptées pour l'audit de sécurité.
Cette bibliothèque a pour objectif de fournir des liaisons idiomatiques nmap pour les développeurs Go, afin de faciliter l'écriture d'outils d'audit de sécurité en golang.
Nmap (Network Mapper) est un scanner réseau gratuit et open-source créé par Gordon Lyon. Nmap est utilisé pour découvrir des hôtes et des services sur un réseau informatique en envoyant des paquets et en analysant les réponses.
Nmap fournit un certain nombre de fonctionnalités pour sonder les réseaux informatiques, notamment la découverte d'hôtes ainsi que la détection de services et de systèmes d'exploitation. Ces fonctionnalités sont extensibles grâce à des scripts qui offrent une détection de services plus avancée, une détection de vulnérabilités et d'autres fonctionnalités. Nmap peut s'adapter aux conditions du réseau, y compris la latence et la congestion, pendant un scan.
La plupart des outils de pentest sont actuellement écrits en Python plutôt qu'en Go, car il est facile d'écrire rapidement des scripts, de nombreuses bibliothèques sont disponibles et c'est un langage simple à utiliser. Cependant, pour écrire des applications robustes et fiables, Go est le meilleur outil. Il est compilé statiquement, possède un système de typage statique, de bien meilleures performances, c'est aussi un langage très simple à utiliser et les goroutines sont géniales... Mais je suis peut-être légèrement partial, alors n'hésitez pas à ne pas être d'accord.
Cette bibliothèque exécute le binaire nmap via le package exec de Go et analyse la sortie XML.
Cela signifie que nmap doit être installé et disponible dans votre PATH pour que cette bibliothèque fonctionne.
La compatibilité est confirmée avec la dernière version actuelle de nmap, 7.98.
Certains types de scan nécessitent des privilèges élevés (par exemple, les scans SYN, la détection d'OS ou l'utilisation de sockets bruts). Si vous activez ces options, vous devrez peut-être exécuter votre programme avec sudo ou les capacités appropriées pour votre plateforme.
[!TIP] Pour les exécutions sans privilèges, privilégiez les scans connect (par exemple
-sT).
package main
import (
"context"
"fmt"
"log"
"time"
"github.com/Ullaakut/nmap/v4"
)
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
defer cancel()
// Equivalent to `/usr/local/bin/nmap -p 80,443,843 google.com facebook.com youtube.com`,
// with a 5-minute timeout.
scanner, err := nmap.NewScanner(
nmap.WithTargets("scanme.nmap.org"),
nmap.WithPorts("80,443,843"),
)
if err != nil {
log.Fatalf("creating nmap scanner: %v", err)
}
result, err := scanner.Run(ctx)
if err != nil {
log.Fatalf("running network scan: %v", err)
}
warnings := result.Warnings()
if len(warnings) > 0 {
log.Printf("warning: %v\n", warnings) // Warnings are non-critical errors from nmap.
}
// Use the results to print an example output
for _, host := range result.Hosts {
if len(host.Ports) == 0 || len(host.Addresses) == 0 {
continue
}
fmt.Printf("Host %q:\n", host.Addresses[0])
for _, port := range host.Ports {
fmt.Printf("\tPort %d/%s %s %s\n", port.ID, port.Protocol, port.State, port.Service.Name)
}
}
fmt.Printf("Nmap done: %d hosts up scanned in %.2f seconds\n", len(result.Hosts), result.Stats.Finished.Elapsed)
}
Le programme ci-dessus affiche :
Host "45.33.32.156":
Port 80/tcp open http
Port 443/tcp closed https
Port 843/tcp closed
Nmap done: 1 hosts up scanned in 0.42 seconds
[!IMPORTANT] Cela repose sur les séquences d'échappement du terminal et ne fonctionne que lorsque le processus est attaché à un TTY.
[!NOTE] La progression n'est pas garantie d'augmenter de façon monotone : nmap estime le temps restant et peut réviser cette estimation, ce qui peut faire baisser le pourcentage rapporté.
package main
import (
"context"
"log"
"time"
"github.com/Ullaakut/nmap/v4"
)
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
defer cancel()
scanner, err := nmap.NewScanner(
nmap.WithTargets("scanme.nmap.org"),
nmap.WithPorts("1-1024"),
nmap.WithTimingTemplate(nmap.TimingAggressive),
nmap.WithProgress(time.Second, handleProgress),
)
if err != nil {
log.Fatalf("creating nmap scanner: %v", err)
}
_, err = scanner.Run(ctx)
if err != nil {
log.Fatalf("running network scan: %v", err)
}
}
func handleProgress(p nmap.TaskProgress) {
log.Println("Current progress: ", p.Percent)
}
Cet exemple affiche ce qui suit :
2026/01/27 16:13:02 task "Connect Scan": 2.59% remaining 38
2026/01/27 16:13:02 task "Connect Scan": 21.26% remaining 4
2026/01/27 16:13:04 task "Connect Scan": 42.61% remaining 5
2026/01/27 16:13:04 task "Connect Scan": 45.51% remaining 4
2026/01/27 16:13:05 task "Connect Scan": 53.44% remaining 4
2026/01/27 16:13:07 task "Connect Scan": 59.77% remaining 5
2026/01/27 16:13:07 task "Connect Scan": 62.77% remaining 4
2026/01/27 16:13:08 task "Connect Scan": 73.24% remaining 3
2026/01/27 16:13:09 task "Connect Scan": 81.71% remaining 2
2026/01/27 16:13:10 task "Connect Scan": 92.92% remaining 1
2026/01/27 16:13:11 task "Connect Scan": 100.00% remaining 0
package main
import (
"context"
"fmt"
"log"
"time"
"github.com/Ullaakut/nmap/v4"
)
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
defer cancel()
scanner, err := nmap.NewScanner(
nmap.WithTargets("scanme.nmap.org"),
nmap.WithPorts("1-1024"),
)
if err != nil {
log.Fatalf("creating nmap scanner: %v", err)
}
stdout, stderr, resultCh, err := scanner.RunAsync(ctx)
if err != nil {
log.Fatalf("running network scan: %v", err)
}
for {
select {
case <-ctx.Done():
log.Fatalf("scan timed out: %v", ctx.Err())
case out := <-stdout:
fmt.Printf("nmap output: %s\n", out)
case errOut := <-stderr:
fmt.Printf("nmap error output: %s\n", errOut)
case result := <-resultCh:
if result.Err != nil {
log.Fatalf("running network scan: %v", result.Err)
}
fmt.Printf("Nmap done: %d hosts up\n", len(result.Result.Hosts))
return
}
}
}
Consultez le répertoire examples pour plus d'exemples d'utilisation.
Cameradar utilise déjà cette bibliothèque en son cœur pour communiquer avec nmap, découvrir des flux RTSP et y accéder à distance.
Plus d'exemples :