深度理解rustscan----端口扫描工具

rustscan是一个网络扫描工具,它相比于nmap的最明显的一个优势是扫描端口速度快。

当然,rustscan命令也可以通过追加参数实现nmap的部分功能。

注:本文对rustscan的理解是基于rustscan2.0.0版本的

rustscan常用命令解析

rustscan调用方式:rustscan [FLAGS] [OPTIONS] [-- <command>...]

rustscan -a 10.121.110.36 -p 22,80,3306 -b 10000 -- -sV --version-light

参数解析:

  • -a    指定扫描ip(多个ip用逗号隔开,支持扫描192.168.0.0/30格式、主机文件扫描-a 'hosts.txt',不支持192.168.0.0-192.168.0.255格式)
  • -p    指定扫描端口(单个端口的集合,端口之间用逗号分隔)
  • -r    指定扫描端口段(1-65535)
  • --timeout    指定端口扫描超时时间ms,默认为1500ms
  • --tries    端口扫描尝试次数
  • -b    指并发发包数量(-b数值越大,则扫描速度越快,同时可能导致部分端口扫描不出来),默认为4500
  • --   之后的追加的参数都是调用的nmap的参数
  • -sV --version-light    是nmap的参数,表示开启轻量级端口服务探测

rustscan本身重点在于端口探活这一类检测任务,若是需要指定主机探活及主机探活方式(TCP SYN Ping、ICMP Ping等)可以通过拼接nmap参数实现

正则提取rustscan结果

在使用rustscan2.0.0版本时,调用nmap的参数-oX nmap.xml将扫描结果输出到一个xml文件中,发现扫描多个ip(已知存活),结果文件nmap.xml中也只有一个ip的结果

于是写了一个正则表达式,用于提取有用的信息

Nmap scan report for ((?:(?:\\d+\\.){3}\\d+)|([0-9a-fA-F]+(?:(?:[0-9a-fA-F]+)|:){0,6}[0-9a-fA-F]))\nHost is up(?:.*\n+)+?PORT\\s+STATE.*\n(?:\\d+/(?:tcp|udp).*\n)+MAC\\sAddress

在以上正则表达式的基础上,可以通过go语言编程实现功能:执行rustscan命令扫描目标ip和目标端口,并且将结果简化输出。代码如下:

package main

import (
        "bytes"
        "flag"
        "fmt"
        "os/exec"
        "regexp"
)

var ip = flag.String("i", "", "ip")
var port = flag.String("o", "", "port")

func main() {
        flag.Parse()
        cmd := exec.Command("rustscan", "-a", *ip, "-r", *port, "-b", "10000", "--", "-n", "-T4", "-sV")
        var out bytes.Buffer
        cmd.Stdout = &out
        if err := cmd.Run(); err != nil {
                fmt.Println("cmdRun error:", err)
                return
        }

        rustRes := out.String()

        reg1, err := regexp.Compile("Nmap scan report for ((?:(?:\\d+\\.){3}\\d+)|([0-9a-fA-F]+(?:(?:[0-9a-fA-F]+)|:){0,6}[0-9a-fA-F]))\nHost is up(?:.*\n+)+?PORT\\s+STATE.*\n(?:\\d+/(?:tcp|udp).*\n)+MAC\\sAddress")
        if err != nil {
                fmt.Println("regexp error1:", err)
        }
        allInfo := reg1.FindAllStringSubmatch(rustRes, -1)
        //fmt.Println(allInfo[0][0])                                           //所有结果
        //fmt.Println("************************************", allInfo[0][1])   //ip
        for _, al := range allInfo {
                reg2, err := regexp.Compile("(\\d+)/(tcp|udp)\\s+open\\s+(.*)\\s+(?:syn-ack|reset|no-response)\\s+(?:ttl\\s+\\d+)?(.*)\n")
                if err != nil {
                        fmt.Println("regexp error2:", err)
                }
                portServices := reg2.FindAllStringSubmatch(al[0], -1)
                for _, ps := range portServices {
                        //fmt.Println("=====", ps[0]) //单个端口行
                        //fmt.Println("=====", ps[1]) //端口
                        //fmt.Println("=====", ps[2]) //protocol
                        //fmt.Println("=====", ps[3]) //service
                        //fmt.Println("=====", ps[4]) //service version, 前提是开启端口扫描服务
                        fmt.Println("the opening port of ip", al[1], "is ", ps[1], ps[2], ps[3])
                }
        }
}

代码中,第一次正则拿到了ip和该ip的所有端口,第二次正则拿到了第一次正则中每一个ip中的所有开放端口的信息(协议、服务、端口号)

在linux上编译后生成二进制文件anaRustscan,执行命令./anaRustscan -i 扫描目标 -o 端口范围,即可运行

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

八月和我

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值