Go Pentester

Simple Port Scanner with Golang

Use Go‘s net package: net.Dial(network, address string)

package main

import (
	"fmt"
	"net"
)

func main() {
	_, err := net.Dial("tcp", "scanme.nmap.org:80")
	if err == nil {
		fmt.Println("Connection successful")
	}

Nonconcurrent Scanning

Scan TCP ports range from 1 to  2014 slowly.

package main

import (
	"fmt"
	"net"
)

func main() {

	for i := 1; i <=1024; i ++ {
		address := fmt.Sprintf("scame.nmap.org:%d", i)
		conn, err := net.Dial("tcp", address)
		if err != nil {
			// port is closed or filtered.
			continue
		}

		conn.Close()
		fmt.Printf("%d open
", i)
	}
}

 Concurrent scanning

Harness the power of goroutines to scan multiple ports concurrently.

package main

import (
	"fmt"
	"net"
)

func main() {
	for i := 1; i <= 1024; i++ {
		go func(j int) {
			address := fmt.Sprintf("scanme.nmap.org:%d", j)
			conn, err := net.Dial("tcp", address)
			if err != nil {
				return
			}
			conn.Close()
			fmt.Printf("%d open
", j)
		}(i)
	}
}

But it is too fast to wait for the connection to take place, so you may not get accurate results for ports whose packets were still in-flight.

Method 1:

Synchronized Scanning Using WaitGroup

Use WaitGroup from the sync package to control concurrency in a thread-safe way.

package main

import (
	"fmt"
	"net"
	"sync"
)

func main() {
	var wg sync.WaitGroup
	for i := 1; i <= 1024; i++ {
		wg.Add(1)
		go func(j int) {
			defer wg.Done()
			address := fmt.Sprintf("10.0.0.24:%d", j)
			conn, err := net.Dial("tcp", address)
			if err != nil {
				return
			}
			conn.Close()
			fmt.Printf("%d open
", j)
		}(i)
	}
	wg.Wait()
}

This program is better, but still incorrect.

 Port Scanning Using a Worker Pool

To avoid inconsistencies, use a pool of goroutines to manage the concurrent work being performed.

package main

import (
	"fmt"
	"sync"
)

func worker(ports chan int, wg *sync.WaitGroup) {
	for p := range ports {
		fmt.Println(p)
		wg.Done()
	}
}

func main() {
	ports := make(chan int, 100)
	var wg sync.WaitGroup
	for i := 0; i < cap(ports); i++ {
		go worker(ports, &wg)
	}
	for i := 1; i <= 1024; i++ {
		wg.Add(1)
		ports <- i
	}
	wg.Wait()
	close(ports)
}

The numbers printed to the screen in no particular order.

Method 2: 

Multichannel Communication

Remove the dependency of a WaitGroup

package main

import (
	"fmt"
	"net"
	"sort"
)

func worker(ports, results chan int) {
	for p:= range ports {
		address := fmt.Sprintf("10.0.0.24:%d", p)
		conn, err := net.Dial("tcp", address)
		if err != nil {
			results <-0
			continue
		}
		conn.Close()
		results <- p
	}
}

func main() {
	ports := make(chan int, 100)
	results := make(chan int)
	var openports []int

	for i := 0; i < cap(ports); i++ {
		go worker(ports, results)
	}

	go func() {
		for i := 1; i <= 1024; i++ {
			ports <- i
		}
	}()

	for i := 0; i < 1024; i++ {
		port := <-results
		if port != 0 {
			openports = append(openports, port)
		}
	}

	close(ports)
	close(results)
	sort.Ints(openports)
	for _, port := range openports {
		fmt.Printf("%d open
", port)
	}
}

A highly efficient port scanner. 

 You can modify the program to allow users to provide the number of workers as an option.

相信未来 - 该面对的绝不逃避,该执著的永不怨悔,该舍弃的不再留念,该珍惜的好好把握。
原文地址:https://www.cnblogs.com/keepmoving1113/p/12345932.html