一、TCP扫描器
- TCP的握手有三个过程。
- 客户端发送一个 syn 的包,表示建立回话的开始
- 如果服务端应答 syn-ack 包,意味着这个端口是打开的,否则会返回 rst 包。最后,
- 客户端需要另外发送一个 ack 包。从这时起,连接就已经建立。
- 构建简易的TCP扫描器
package main
import (
"flag"
"fmt"
"net"
"sync"
"time"
)
func main() {
hostname := flag.String("hostname", "www.baidu.com", "hostname to test")
startPort := flag.Int("start-port", 80, "the port on which the scanning starts")
endPort := flag.Int("end-port", 100, "the port from which the scanning ends")
timeout := flag.Duration("timeout", time.Millisecond*200, "timeout")
flag.Parse()
ports := make([]int, 0)
//同步机制
wg := &sync.WaitGroup{}
for port := *startPort; port <= *endPort; port++ {
wg.Add(1)
go func(p int) {
opened := isOpen(*hostname, p, *timeout)
if opened {
ports = append(ports, p)
}
wg.Done()
}(port)
}
wg.Wait()
fmt.Printf("opened ports: %v\n", ports)
/**
opened ports: [80]
*/
}
/**
检测端口是否可连接
*/
func isOpen(host string, port int, timeout time.Duration) bool {
time.Sleep(time.Millisecond * 1)
conn, err := net.DialTimeout("tcp", fmt.Sprintf("%s:%d", host, port), timeout)
if err == nil {
_ = conn.Close()
return true
}
return false
}