当前位置:网站首页>Golang port scanning design
Golang port scanning design
2022-07-26 13:20:00 【Lingmu LSJ】
1 TCP Full connection implementation
TCP The fully connected port scanner is the most basic scanner , Its principle is to call Socket Of connect Function to connect to the target IP On a specific port , If the connection is successful, the port is open , If the connection fails , Indicates that the port is not open .
1) Connection access implementation
Go Linguistic net Provided by the package Dial And DialTimeout function , To the traditional socket Function is encapsulated , No matter what protocol connection you want to create , You only need to call these two functions . The difference between these two functions is DialTimeout Increased timeout .
func Connect(ip string, port int) (string, int, error) {
conn, err := net.DialTimeout("tcp", fmt.Sprintf("%v:%v", ip, port), 2*time.Second)
defer func() {
if conn != nil {
_ = conn.Close()
}
}()
return ip, port, err
}2)IP Handle
iprange Library will Nmap Style IP It can be interpreted as AddressRange object , And then call AddressRange Of Expand Method returns a []net.IP, The format supported is as follows .
- 10.0.0.1
- 10.0.0.0/24
- 10.0.0.∗
- 10.0.0.1-10
- 10.0.0.1,10.0.0.5-10,192.168.1.∗,192.168.10.0/24
func GetIpList(ips string) ([]net.IP, error) {
addressList, err := iprange.ParseList(ips)
if err != nil {
return nil, err
}
list := addressList.Expand()
return list, err
}3)port Handle
Multi port processing needs to support “,” And “-” Split port list , have access to strings Bag Split The function is split first to “,” Connected ipList, Then split to “-” Connected ipList, The last one to return []int section
func GetPorts(selection string) ([]int, error) {
ports := []int{}
if selection == "" {
return ports, nil
}
ranges := strings.Split(selection, ",")
for _, r := range ranges {
r = strings.TrimSpace(r)
if strings.Contains(r, "-") {
parts := strings.Split(r, "-")
if len(parts) != 2 {
return nil, fmt.Errorf("Invalid port selection segment: '%s'", r)
}
p1, err := strconv.Atoi(parts[0])
if err != nil {
return nil, fmt.Errorf("Invalid port number: '%s'", parts[0])
}
p2, err := strconv.Atoi(parts[1])
if err != nil {
return nil, fmt.Errorf("Invalid port number: '%s'", parts[1])
}
if p1 > p2 {
return nil, fmt.Errorf("Invalid port range: %d-%d", p1, p2)
}
for i := p1; i <= p2; i++ {
ports = append(ports, i)
}
} else {
if port, err := strconv.Atoi(r); err != nil {
return nil, fmt.Errorf("Invalid port number: '%s'", r)
} else {
ports = append(ports, port)
}
}
}
return ports, nil
}4)main Function call
func main() {
if len(os.Args) == 3 {
ipList := os.Args[1]
portList := os.Args[2]
ips, err := util.GetIpList(ipList)
ports, err := util.GetPorts(portList)
_ = err
for _,ip := range ips {
for _,port := range ports{
_,err := scanner.Connect(ip.String(),port)
if err != nil{
continue
}
fmt.Printf("IP %v , Port %v is open \n",ip,port)
}
}
} else {
fmt.Printf("%v iplist port\n", os.Args[0])
}
}2 TCP Semi connected implementation
TCP The half connected port scanner will only send one... To the target port SYN package , If the server port is open , Returns the SYN/ACK package , If the port is not open , Will return RST/ACK package .
Will perform a full connection scan Connect(ip string, port int) The function is modified to the function of half connection scanning :
func SynScan(dstIp string, dstPort int) (string, int, error) {
srcIp, srcPort, err := localIPPort(net.ParseIP(dstIp))
dstAddrs, err := net.LookupIP(dstIp)
if err != nil {
return dstIp, 0, err
}
dstip := dstAddrs[0].To4()
var dstport layers.TCPPort
dstport = layers.TCPPort(dstPort)
srcport := layers.TCPPort(srcPort)
// structure IP Headlines
ip := &layers.IPv4{
SrcIP: srcIp,
DstIP: dstip,
Protocol: layers.IPProtocolTCP,
}
// structure TCP Headlines
tcp := &layers.TCP{
SrcPort: srcport,
DstPort: dstport,
SYN: true,
}
// Calculate the check sum
err = tcp.SetNetworkLayerForChecksum(ip)
buf := gopacket.NewSerializeBuffer()
opts := gopacket.SerializeOptions{
ComputeChecksums: true,
FixLengths: true,
}
// fill buf
if err := gopacket.SerializeLayers(buf, opts, tcp); err != nil {
return dstIp, 0, err
}
// Create local listener TCP Of conn
conn, err := net.ListenPacket("ip4:tcp", "0.0.0.0")
if err != nil {
return dstIp, 0, err
}
defer conn.Close()
// Send... To the destination address TCP SYN message
if _, err := conn.WriteTo(buf.Bytes(), &net.IPAddr{IP: dstip}); err != nil {
return dstIp, 0, err
}
if err := conn.SetDeadline(time.Now().Add(4 * time.Second)); err != nil {
return dstIp, 0, err
}
// Constantly from conn Read data in connection
for {
b := make([]byte, 4096)
n, addr, err := conn.ReadFrom(b)
if err != nil {
return dstIp, 0, err
} else if addr.String() == dstip.String() {
// Decode a packet
packet := gopacket.NewPacket(b[:n], layers.LayerTypeTCP, gopacket.Default)
// Get the TCP layer from this packet
if tcpLayer := packet.Layer(layers.LayerTypeTCP); tcpLayer != nil {
tcp, _ := tcpLayer.(*layers.TCP)
if tcp.DstPort == srcport {
if tcp.SYN && tcp.ACK {
// log.Printf("%v:%d is OPEN\n", dstIp, dstport)
return dstIp, dstPort, err
} else {
return dstIp, 0, err
}
}
}
}
}
}
3 Combine the two detection methods
1) Use github.com/urfave/cli Package to handle command line arguments
var Scan = cli.Command{
Name: "scan",
Usage: "start to scan port",
Description: "start to scan port",
Action: util.Scan,
Flags: []cli.Flag{
stringFlag("iplist, i", "", "ip list"),
stringFlag("port, p", "", "port list"),
stringFlag("mode, m", "", "scan mode"),
intFlag("timeout, t", 3, "timeout"),
intFlag("concurrency, c", 1000, "concurrency"),
},
}
func stringFlag(name, value, usage string) cli.StringFlag {
return cli.StringFlag{
Name: name,
Value: value,
Usage: usage,
}
}
func boolFlag(name, usage string) cli.BoolFlag {
return cli.BoolFlag{
Name: name,
Usage: usage,
}
}
func intFlag(name string, value int, usage string) cli.IntFlag {
return cli.IntFlag{
Name: name,
Value: value,
Usage: usage,
}
}
2) Get the command line parameters and handle them accordingly
func Scan(ctx *cli.Context) error {
if ctx.IsSet("iplist") {
vars.Host = ctx.String("iplist")
}
if ctx.IsSet("port") {
vars.Port = ctx.String("port")
}
if ctx.IsSet("mode") {
vars.Mode = ctx.String("mode")
}
if ctx.IsSet("timeout") {
vars.Timeout = ctx.Int("timeout")
}
if ctx.IsSet("concurrency") {
vars.ThreadNum = ctx.Int("concurrency")
}
if strings.ToLower(vars.Mode) == "syn" {
CheckRoot()
}
ips, err := GetIpList(vars.Host)
ports, err := GetPorts(vars.Port)
tasks, n := scanner.GenerateTask(ips, ports)
_ = n
scanner.RunTask(tasks)
scanner.PrintResult()
return err
}3) Start different scanning modes according to different modes
func Scan(taskChan chan map[string]int, wg *sync.WaitGroup) {
// Every process starts from channel Start scanning and warehousing after reading data in
for task := range taskChan {
for ip, port := range task {
if strings.ToLower(vars.Mode) == "syn" {
err := SaveResult(SynScan(ip, port))
_ = err
} else {
err := SaveResult(Connect(ip, port))
_ = err
}
wg.Done()
}
}
}Excerpt from :《 White hat security development practice 》
边栏推荐
- B+树索引使用(8)排序使用及其注意事项(二十)
- 12 brand management of commodity system in gulimall background management
- Extra (5) - MySQL execution plan (51)
- PostgreSQL official website download error
- 如何构建以客户为中心的产品蓝图:来自首席技术官的建议
- Guys, how can CDC Oracle set the reading from the specified SCN number, or how to set the read-only full archive, not to read fast
- File upload and download performance test based on the locust framework
- 目标检测网络R-CNN 系列
- Solution: unable to load the file c:\users\user\appdata\roaming\npm\npx PS1, because running scripts is prohibited on this system.
- 《Kotlin系列》之MVVM架构封装(kotlin+mvvm)
猜你喜欢

Unicode文件解析方法及存在问题

3D modeling and rendering based on B é zier curve

Today in history: IBM obtained the first patent; Verizon acquires Yahoo; Amazon releases fire phone
Exploration on cache design optimization of community like business
![[typescript] typescript common types (Part 1)](/img/80/5c8c51b92d3a9d76f38beba7be0aa6.png)
[typescript] typescript common types (Part 1)

Solution 5g technology helps build smart Parks

基于Locust框架进行文件上传下载性能测试

Hcip day 11 comparison (BGP configuration and release)

如何构建以客户为中心的产品蓝图:来自首席技术官的建议

【上位机教程】CANopen通信下一体化步进电机与台达PLC(AS228T)的应用
随机推荐
二叉树的初阶笔记
B+树索引使用(8)排序使用及其注意事项(二十)
【TypeScript】TypeScript常用类型(上篇)
维度灾难 维数灾难 暂记
Extra (5) - MySQL execution plan (51)
Exploration on cache design optimization of community like business
Guys, please ask me, I have configured CDC to connect to Oracle according to the document, and I always run error reports and can't find the class validstione
基于Bézier曲线的三维造型与渲染
JSON format execution plan (6) - MySQL execution plan (52)
B+树索引使用(7)匹配列前缀,匹配值范围(十九)
B+树(5)myISAM简介 --mysql从入门到精通(十七)
Can I take your subdomain? Exploring Same-Site Attacks in the Modern Web
Kubernetes flannel: host-gw mode
SLAM 02.整体框架
LeetCode 2119. 反转两次的数字
目标检测网络R-CNN 系列
B+ tree selection index (1) -- MySQL from entry to proficiency (22)
Reflection, an implementation of automatic repeated call interface
LeetCode 1523. 在区间范围内统计奇数数目
1-6月中国ADAS供应商占比9% 又一家零部件巨头全面布局智驾新赛道