From 1ce5ccf4ade2a2313f72cca1df0802267d85926c Mon Sep 17 00:00:00 2001 From: wjlin0 Date: Fri, 16 Jun 2023 17:39:05 +0800 Subject: [PATCH] =?UTF-8?q?v1.1.3=20=E6=96=B0=E5=A2=9E=20=E9=80=92?= =?UTF-8?q?=E5=BD=92=E6=89=AB=E6=8F=8F=20=E7=BB=93=E6=9E=9C=E5=9B=9E?= =?UTF-8?q?=E8=B0=83=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 71 ++++++++++++++++++++++++++++++++++++++++-- config/dict.zip | Bin 70319 -> 78381 bytes pkg/runner/banner.go | 4 +-- pkg/runner/options.go | 4 ++- pkg/runner/run.go | 8 +++++ 5 files changed, 82 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 1a348de..d60d9f4 100644 --- a/README.md +++ b/README.md @@ -13,11 +13,12 @@ - 快速发现路径 - 丰富的内置字典,自动下载字典,可远程加载目标或远程加载字典 -- 可恢复上次扫描进度 +- 可持续递归扫描,恢复上次扫描进度 - 从网络空间测绘中发现目标 - 支持使用HTTP/SOCKS5代理 - 可自定义请求头,可自定义指纹识别规则 - 通过hash,len指定跳过 +- 结果可回调处理 # 用法 @@ -36,11 +37,16 @@ Flags: -resume string 使用resume.cfg恢复扫描 -mf, -match-file string 指纹文件 +递归: + -r, -recursive 递归扫描 + -rt, -recursive-time int 递归扫描深度 (default 3) + -rf, -recursive-file string 递归扫描目录 (default "/root/.config/pathScan/dict/dir.txt") + 跳过: -su, -skip-url string[] 跳过的目标(以逗号分割) -sc, -skip-code string[] 跳过状态码 -sh, -skip-hash string 跳过指定hash - -sbl, -skip-body-len int 跳过body固定长度 + -sbl, -skip-body-len int 跳过body固定长度 (default -1) 扫描字典: -ps, -path string[] 路径(以逗号分割) @@ -137,6 +143,67 @@ rules: group: 1 # 指定后匹配的名字为正则匹配后的第1个元素 ``` +# 集成到自己的工具中 +```go +package main + +import ( + "fmt" + "github.com/projectdiscovery/gologger" + "github.com/wjlin0/pathScan/pkg/result" + "github.com/wjlin0/pathScan/pkg/runner" + "github.com/wjlin0/pathScan/pkg/util" + "os" + "os/signal" + "path/filepath" + "time" +) + +func main() { + options := &runner.Options{Url: []string{ + "https://localhost:8000", + }, + RateHttp: 2, + TimeoutTCP: 2 * time.Second, + TimeoutHttp: 2 * time.Second, + ResultBack: func(result *result.TargetResult) { + fmt.Println(result) + }, + Method: "GET", + Path: []string{ + "/", + }, + } + run, err := runner.NewRunner(options) + if err != nil { + gologger.Print().Msg(fmt.Sprintf("无法创建Runner: %s", err.Error())) + os.Exit(0) + } + if run == nil { + os.Exit(0) + } + + c := make(chan os.Signal, 1) + signal.Notify(c, os.Interrupt) + go func() { + for range c { + gologger.Info().Msg("CTRL+C 按下: Exiting") + filename := util.RandStr(30) + ".cfg" + fmt.Println(filepath.Join(runner.DefaultResumeFolderPath(), filename)) + err := run.Cfg.MarshalResume(filename) + if err != nil { + gologger.Error().Msgf("无法创建 resume 文件: %s", err.Error()) + } + os.Exit(1) + } + }() + err = run.Run() + if err != nil { + gologger.Fatal().Msgf("无法 运行: %s", err.Error()) + } + run.Cfg.CleanupResumeConfig() +} +``` pathScan 支持默认配置文件位于下面两个路径,它允许您在配置文件中定义任何标志并设置默认值以包括所有扫描。 diff --git a/config/dict.zip b/config/dict.zip index 24add0b21139358aa077b939c63bc0ffb02f5ad2..1d521f40f390bec20ba938cc526ade97eb4f2dbb 100644 GIT binary patch delta 8467 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 delta 317 zcmZ4cgk}9w7Ty4FW)=|!5LmgTa3ZfFGmzS7=%2tWHos!?iu!eHK?2(&bs5>1L9FRX z28@R4hnG$MaW~>7BRU=6&B!Fe05XmPWZd*!28>4Po$n!v?@zn2#y##PWBoY@A6YTb zvgtX7jMDXG2@DLmiJ5tNB^4!H3<^M#7#J8CBpA-B7;FY`HkK YumEF#H!B;+6c!-NW@KQ{69f_r03u#x9RL6T diff --git a/pkg/runner/banner.go b/pkg/runner/banner.go index 1fc9e5a..f5f6a42 100644 --- a/pkg/runner/banner.go +++ b/pkg/runner/banner.go @@ -6,11 +6,11 @@ const banner = ` __ __ ____ ___ ___ _ / /_ / / / __/____ ___ _ ___ / _ \/ _ // __// _ \ _\ \ / __// _ // _ \ - / .__/\_,_/ \__//_//_//___/ \__/ \_,_//_//_/ v1.1.2 + / .__/\_,_/ \__//_//_//___/ \__/ \_,_//_//_/ v1.1.3 /_/ ` -const Version = `1.1.2` +const Version = `1.1.3` // showBanner is used to show the banner to the user func showBanner() { diff --git a/pkg/runner/options.go b/pkg/runner/options.go index c610420..f2877b0 100644 --- a/pkg/runner/options.go +++ b/pkg/runner/options.go @@ -12,6 +12,7 @@ import ( "github.com/wjlin0/pathScan/pkg/common/identification" "github.com/wjlin0/pathScan/pkg/common/uncover" ucRunner "github.com/wjlin0/pathScan/pkg/projectdiscovery/uncover/runner" + "github.com/wjlin0/pathScan/pkg/result" "os" "path/filepath" "time" @@ -67,6 +68,7 @@ type Options struct { RecursiveRunTimes int `json:"recursive_run_times"` RecursiveRunFile string `json:"recursive_run_file"` GetHash bool `json:"get_hash"` + ResultBack func(result *result.TargetResult) } var defaultProviderConfigLocation = filepath.Join(folderutil.HomeDirOrDefault("."), ".config", "pathScan", "provider-config.yaml") @@ -93,7 +95,7 @@ func ParserOptions() *Options { set.StringSliceVarP(&options.SkipUrl, "skip-url", "su", nil, "跳过的目标(以逗号分割)", goflags.NormalizedStringSliceOptions), set.StringSliceVarP(&options.SkipCode, "skip-code", "sc", nil, "跳过状态码", goflags.NormalizedStringSliceOptions), set.StringVarP(&options.SkipHash, "skip-hash", "sh", "", "跳过指定hash"), - set.IntVarP(&options.SkipBodyLen, "skip-body-len", "sbl", 0, "跳过body固定长度"), + set.IntVarP(&options.SkipBodyLen, "skip-body-len", "sbl", -1, "跳过body固定长度"), ) set.CreateGroup("Dict", "扫描字典", set.StringSliceVarP(&options.Path, "path", "ps", nil, "路径(以逗号分割)", goflags.CommaSeparatedStringSliceOptions), diff --git a/pkg/runner/run.go b/pkg/runner/run.go index 05de209..b27b990 100644 --- a/pkg/runner/run.go +++ b/pkg/runner/run.go @@ -280,6 +280,10 @@ func (r *Runner) Run() error { } r.limiter.Take() targetResult, check, err := r.GoTargetPathByRetryable(target, path) + if r.Cfg.Options.ResultBack != nil { + r.Cfg.Options.ResultBack(targetResult) + return + } if targetResult != nil && err == nil { r.Cfg.Results.AddSkipped(targetResult.Path, targetResult.Target) // 跳过条件满足 @@ -340,6 +344,10 @@ func (r *Runner) Run() error { r.limiter.Take() targetResult, check, err := r.GoTargetPathByRetryable(target, path) + if r.Cfg.Options.ResultBack != nil { + r.Cfg.Options.ResultBack(targetResult) + return + } if targetResult != nil && err == nil { r.Cfg.Results.AddSkipped(targetResult.Path, targetResult.Target) // 跳过条件满足