
مكتبة Go اصطلاحية لاستدعاء البرنامج الثنائي لماسح الشبكة، تتيح اكتشاف المضيفين، وفحص المنافذ، وكشف الخدمات/نظام التشغيل، وتنفيذ فحوصات الثغرات الأمنية عبر النصوص البرمجية لأغراض التدقيق الأمني.
تهدف هذه المكتبة إلى توفير روابط (bindings) بأسلوب idiomatic للغة go لمطوّري البرامج، من أجل تسهيل كتابة أدوات تدقيق أمني باستخدام golang.
Nmap (Network Mapper) هو ماسح شبكات مجاني ومفتوح المصدر أنشأه Gordon Lyon. يُستخدم Nmap لاكتشاف المضيفين والخدمات على شبكة حاسوبية عن طريق إرسال الحزم وتحليل الاستجابات.
يوفر Nmap عددًا من الميزات لاستكشاف شبكات الحاسوب، بما في ذلك اكتشاف المضيفين واكتشاف الخدمات وأنظمة التشغيل. هذه الميزات قابلة للتوسعة عبر سكربتات توفر كشفًا أكثر تقدمًا للخدمات وكشف الثغرات وميزات أخرى. يمكن لـ Nmap التكيف مع ظروف الشبكة بما في ذلك زمن الاستجابة والازدحام أثناء الفحص.
معظم أدوات اختبار الاختراق مكتوبة حاليًا باستخدام Python وليس Go، لأنه من السهل كتابة سكربتات بسرعة، وتتوفر الكثير من المكتبات، وهي لغة بسيطة الاستخدام. ومع ذلك، لكتابة تطبيقات قوية وموثوقة، فإن Go هي الأداة الأفضل. فهي تُترجم بشكل ثابت (statically compiled)، ولديها نظام أنواع ثابت، وأداء أفضل بكثير، وهي أيضًا لغة بسيطة جدًا في الاستخدام، والـ goroutines رائعة... لكن قد أكون متحيزًا بعض الشيء، فلا تتردد في الاختلاف معي.
تقوم هذه المكتبة باستدعاء ملف nmap الثنائي باستخدام حزمة exec في Go وتحلل مخرجات XML.
هذا يعني أنه يجب تثبيت nmap وأن يكون متاحًا في PATH الخاص بك حتى تعمل هذه المكتبة.
تم تأكيد التوافق مع أحدث إصدار حالي من nmap، وهو 7.98.
تتطلب بعض أنواع الفحص صلاحيات مرتفعة (على سبيل المثال، فحوصات SYN، كشف نظام التشغيل، أو استخدام raw sockets). إذا قمت بتفعيل هذه الخيارات، فقد تحتاج إلى تشغيل برنامجك باستخدام sudo أو بالصلاحيات المناسبة لمنصتك.
[!TIP] بالنسبة للتشغيل بدون صلاحيات، يُفضّل استخدام فحوصات connect (مثل
-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)
}
يُخرج البرنامج أعلاه:
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] يعتمد هذا على تسلسلات هروب الطرفية (terminal escape sequences) ويعمل فقط عندما تكون العملية مرتبطة بـ TTY.
[!NOTE] ليس من المضمون أن يزداد التقدم بشكل رتيب: يقوم nmap بتقدير الوقت المتبقي وقد يراجع هذا التقدير، مما قد يؤدي إلى انخفاض النسبة المئوية المعروضة.
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)
}
يُخرج هذا المثال ما يلي:
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
}
}
}
انظر إلى مجلد examples لمزيد من أمثلة الاستخدام.
يستخدم Cameradar هذه المكتبة بالفعل في جوهره للتواصل مع nmap، واكتشاف تدفقات RTSP والوصول إليها عن بُعد.
مزيد من الأمثلة: