diff --git a/README.md b/README.md index 359cbe5..83e92f2 100644 --- a/README.md +++ b/README.md @@ -99,6 +99,7 @@ Tested on [ubuntu18.04 LTS](docs/install_linux.md)、[macOS](docs/install_mac.md ## 版本更新 +- 2.4.3:2021-10-13,增加IP扫描的masscan+nmap方法,masscan快速进行端口开放扫描,nmap用-sV进行详细扫描; - 2.4.2:2021-10-9,增加IP扫描的“探测+扫描”模式任务,增加内网资产收集的便利性;去除whatweb的安装和使用(HTTPX已基本可替代其功能); - 2.4.1:2021-9-15,支持扫描任务按IP和端口进行多维度切分,使任务在多个worker之间均衡分布执行; - 2.4.0:2021-9-10,使用RPC架构,优化server与worker之间的同步、server与worker的配置文件分离;增加在线的IP信息、登录验证码、按发现时间筛选资产功能。 diff --git a/pkg/task/portscan/masscan.go b/pkg/task/portscan/masscan.go index e4a4acb..5afff00 100644 --- a/pkg/task/portscan/masscan.go +++ b/pkg/task/portscan/masscan.go @@ -17,6 +17,7 @@ type Masscan struct { // NewMasscan 创建masscan对象 func NewMasscan(config Config) *Masscan { + config.CmdBin = "masscan" return &Masscan{Config: config} } diff --git a/pkg/task/portscan/nmap.go b/pkg/task/portscan/nmap.go index 1d8ec1f..90b72ba 100644 --- a/pkg/task/portscan/nmap.go +++ b/pkg/task/portscan/nmap.go @@ -19,6 +19,7 @@ type Nmap struct { //NewNmap 创建nmap对象 func NewNmap(config Config) *Nmap { + config.CmdBin = "nmap" return &Nmap{Config: config} } diff --git a/pkg/task/workerapi/portscan.go b/pkg/task/workerapi/portscan.go index 0983001..b6463df 100644 --- a/pkg/task/workerapi/portscan.go +++ b/pkg/task/workerapi/portscan.go @@ -2,13 +2,19 @@ package workerapi import ( "context" + "fmt" "github.com/hanc00l/nemo_go/pkg/comm" "github.com/hanc00l/nemo_go/pkg/logging" "github.com/hanc00l/nemo_go/pkg/task/fingerprint" "github.com/hanc00l/nemo_go/pkg/task/portscan" + "github.com/remeh/sizedwaitgroup" "strings" ) +const ( + fpNmapThreadNumber = 10 +) + // PortScan 端口扫描任务 func PortScan(taskId, configJSON string) (result string, err error) { var ok bool @@ -21,14 +27,16 @@ func PortScan(taskId, configJSON string) (result string, err error) { } var resultPortScan portscan.Result // 端口扫描 - if config.CmdBin == "nmap" { + if config.CmdBin == "masnmap" { + resultPortScan = doMasscanPlusNmap(config) + } else if config.CmdBin == "nmap" { nmap := portscan.NewNmap(config) nmap.Do() resultPortScan = nmap.Result } else { - mascan := portscan.NewMasscan(config) - mascan.Do() - resultPortScan = mascan.Result + masscan := portscan.NewMasscan(config) + masscan.Do() + resultPortScan = masscan.Result } // IP位置 if config.IsIpLocation { @@ -52,12 +60,11 @@ func PortScan(taskId, configJSON string) (result string, err error) { wappalyzer.Do() } // 保存结果 - x := comm.NewXClient() - resultArgs := comm.ScanResultArgs{ IPConfig: &config, IPResult: resultPortScan.IPResult, } + x := comm.NewXClient() err = x.Call(context.Background(), "SaveScanResult", &resultArgs, &result) if err != nil { logging.RuntimeLog.Error(err) @@ -80,3 +87,49 @@ func PortScan(taskId, configJSON string) (result string, err error) { return SucceedTask(result), nil } + +// doMasscanPlusNmap masscan进行端口扫描,nmap -sV进行详细扫描 +func doMasscanPlusNmap(config portscan.Config) (resultPortScan portscan.Result) { + resultPortScan.IPResult = make(map[string]*portscan.IPResult) + //masscan扫描 + masscan := portscan.NewMasscan(config) + masscan.Do() + ipPortMap := getResultIPPortMap(masscan.Result.IPResult) + //nmap多线程扫描 + swg := sizedwaitgroup.New(fpNmapThreadNumber) + for ip, port := range ipPortMap { + nmapConfig := config + nmapConfig.Target = ip + nmapConfig.Port = port + nmapConfig.Tech = "-sV" + swg.Add() + go func(c portscan.Config) { + nmap := portscan.NewNmap(c) + nmap.Do() + resultPortScan.Lock() + for nip, r := range nmap.Result.IPResult { + resultPortScan.IPResult[nip] = r + } + resultPortScan.Unlock() + swg.Done() + }(nmapConfig) + } + swg.Wait() + + return +} + +// getResultIPPortMap 提取扫描结果的ip和port +func getResultIPPortMap(result map[string]*portscan.IPResult) (ipPortMap map[string]string) { + ipPortMap = make(map[string]string) + for ip, r := range result { + var ports []string + for p, _ := range r.Ports { + ports = append(ports, fmt.Sprintf("%d", p)) + } + if len(ports) > 0 { + ipPortMap[ip] = strings.Join(ports, ",") + } + } + return +} diff --git a/pkg/task/workerapi/portscan_test.go b/pkg/task/workerapi/portscan_test.go index 0199c30..b475e34 100644 --- a/pkg/task/workerapi/portscan_test.go +++ b/pkg/task/workerapi/portscan_test.go @@ -11,7 +11,7 @@ func TestPortScan(t *testing.T) { config := portscan.Config{ Target: "192.168.3.0/24", ExcludeTarget: "", - Port: "--top-ports 1000", + Port: "--top-ports 100", OrgId: nil, Rate: 1000, IsPing: true, @@ -19,7 +19,7 @@ func TestPortScan(t *testing.T) { IsIpLocation: true, IsHttpx: true, IsWhatWeb: false, - CmdBin: "nmap", + CmdBin: "masnmap", } configJSON, err := json.Marshal(config) diff --git a/pkg/web/controllers/task.go b/pkg/web/controllers/task.go index 31a3b6e..fd371f5 100644 --- a/pkg/web/controllers/task.go +++ b/pkg/web/controllers/task.go @@ -434,10 +434,10 @@ func (c *TaskController) doPortscan(target string, port string, req portscanRequ IsWhatWeb: req.IsWhatweb, IsScreenshot: req.IsScreenshot, IsWappalyzer: req.IsWappalyzer, - CmdBin: "masscan", + CmdBin: req.CmdBin, } - if req.CmdBin == "nmap" { - config.CmdBin = "nmap" + if req.CmdBin == "" { + config.CmdBin = conf.GlobalWorkerConfig().Portscan.Cmdbin } if config.Port == "" { config.Port = conf.GlobalWorkerConfig().Portscan.Port diff --git a/thirdparty/xray/xray b/thirdparty/xray/xray index bd3089f..1f3f489 160000 --- a/thirdparty/xray/xray +++ b/thirdparty/xray/xray @@ -1 +1 @@ -Subproject commit bd3089f14fb7029e6538ca04d85226645d445721 +Subproject commit 1f3f4891e75505ee1192f771d677bb2cf0bd76c1 diff --git a/web/views/ip-list.html b/web/views/ip-list.html index f2ea825..6bfb03b 100644 --- a/web/views/ip-list.html +++ b/web/views/ip-list.html @@ -225,6 +225,8 @@