
Idiomatische Go-Bibliothek zum Aufrufen einer Netzwerkscanner-Binärdatei, die Host-Erkennung, Port-Scans, Erkennung von Diensten/Betriebssystemen und skriptbasierte Schwachstellenprüfungen für Sicherheitsaudits ermöglicht.
Diese Bibliothek zielt darauf ab, idiomatische nmap-Anbindungen für Go-Entwickler bereitzustellen, um das Schreiben von Sicherheits-Audit-Tools mit Golang zu erleichtern.
Nmap (Network Mapper) ist ein freier und quelloffener Netzwerkscanner, der von Gordon Lyon entwickelt wurde. Nmap wird verwendet, um Hosts und Dienste in einem Computernetzwerk zu entdecken, indem Pakete gesendet und die Antworten analysiert werden.
Nmap bietet eine Reihe von Funktionen zur Untersuchung von Computernetzwerken, darunter Host-Erkennung sowie Erkennung von Diensten und Betriebssystemen. Diese Funktionen sind durch Skripte erweiterbar, die erweiterte Diensterkennung, Schwachstellenerkennung und weitere Funktionen bereitstellen. Nmap kann sich während eines Scans an Netzwerkbedingungen wie Latenz und Überlastung anpassen.
Die meisten Pentest-Tools werden derzeit mit Python und nicht mit Go geschrieben, weil sich damit schnell Skripte erstellen lassen, viele Bibliotheken verfügbar sind und es eine einfach zu verwendende Sprache ist. Für die Entwicklung robuster und zuverlässiger Anwendungen ist Go jedoch das bessere Werkzeug. Es ist statisch kompiliert, verfügt über ein statisches Typsystem, eine deutlich bessere Leistung, ist ebenfalls eine sehr einfach zu verwendende Sprache, und Goroutinen sind großartig ... Aber ich bin vielleicht etwas voreingenommen, also fühle dich frei, anderer Meinung zu sein.
Diese Bibliothek führt über das exec-Paket von Go das nmap-Binärprogramm aus und parst die XML-Ausgabe.
Das bedeutet, dass nmap installiert und über deinen PATH verfügbar sein muss, damit diese Bibliothek funktioniert.
Die Kompatibilität ist mit der aktuellsten Version von nmap, 7.98, bestätigt.
Einige Scan-Typen erfordern erweiterte Berechtigungen (z. B. SYN-Scans, Betriebssystemerkennung oder die Verwendung von Raw-Sockets). Wenn du diese Optionen aktivierst, musst du dein Programm möglicherweise mit sudo oder den entsprechenden Capabilities für deine Plattform ausführen.
[!TIP] Für Ausführungen ohne Privilegien sind Connect-Scans (z. B.
-sT) zu bevorzugen.
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)
}
Das obige Programm gibt Folgendes aus:
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] Dies basiert auf Terminal-Escape-Sequenzen und funktioniert nur, wenn der Prozess an ein TTY gebunden ist.
[!NOTE] Der Fortschritt steigt nicht garantiert monoton: nmap schätzt die verbleibende Zeit und kann diese Schätzung revidieren, wodurch der gemeldete Prozentsatz sinken kann.
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)
}
Dieses Beispiel gibt Folgendes aus:
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
}
}
}
Siehe das Verzeichnis Beispiele für weitere Anwendungsbeispiele.
Cameradar verwendet diese Bibliothek bereits im Kern, um mit nmap zu kommunizieren, RTSP-Streams zu entdecken und aus der Ferne darauf zuzugreifen.
Weitere Beispiele: