手搓渗透测试发包检测工具
2024-10-13 01:38:0 Author: mp.weixin.qq.com(查看原文) 阅读量:0 收藏

    在进行端口相关WEB服务漏洞验证的时候,为了绕过特征码被动检测型安全防护探针设备的拦截,需要无攻击代码验证确认设备指纹信息。
    像burp、yakit这种太大,不适合放在跳板上扫描验证操作,之前也写了相关的GUI版本的windows跳板使用的验证工具。
    正好最近学了几个go语言的库,手搓了一个go写的脚本,放出来给大家玩玩。


0x01 具体功能

1、自定义URL文件的路径(支持带协议头和不带协议头的域名:端口和IP:PORT)2、自定义HTTP 请求方法(支持GET、POST、OPTIONS、PUT、DELETE等)
3、自定义请求路径(支持任何带URI的路径指纹)
4、多线程
5、自定义正则表达式
6、自定义请求 body
7、自定义请求头
0x02 利用场景

内网WEB (OPTIONS协议探测WEB响应)

外网WEB (MASSCAN扫描端口后的资产根据指纹对用漏洞进行分类)

WEB漏洞指纹 (侵入性识别和无侵入性响应包关键词探测)

WEB漏洞利用 (授权情况下根据选项发送带有载荷的攻击包)


域名背后真实IP(MASSCAN全网扫描开放端口结果匹配响应包关键词)

0x03 编译方法
#linux环境wget https://go.dev/dl/go1.23.2.linux-amd64.tar.gzsudo tar -C /usr/local -xzf go1.23.2.linux-amd64.tar.gzecho "export PATH=$PATH:/usr/local/go/bin" >> ~/.bashrcsource ~/.bashrcgo versiongo mod init searchgo mod tidygo build search.go

使用:

./search -u 10.txt -m GET -ph "/ooxx.php" -t 1000 -o cg.txt -r "xxx"

0x04 代码

package main
import ( "bufio" "bytes" "flag" "fmt" "github.com/common-nighthawk/go-figure" "io/ioutil" "net/http" "os" "regexp" "strings" "sync" "time")
// 检查 URL 是否包含目标关键词或匹配正则表达式func checkWebmin(url, path, method, body, keyword string, headers map[string]string, useRegex bool) (bool, error) { // 创建一个 HTTP 客户端,设置超时时间为 10 秒 client := &http.Client{    Timeout: 8 * time.Second, }
// 构建完整的请求 URL fullURL := url + path
// 创建 HTTP 请求,根据是否存在 body 来设置请求体 var req *http.Request var err error if body != "" { req, err = http.NewRequest(method, fullURL, bytes.NewBufferString(body)) } else { req, err = http.NewRequest(method, fullURL, nil) } if err != nil { return false, err // 请求创建失败 }
// 如果自定义了 headers,则设置请求头 for key, value := range headers { req.Header.Set(key, value) }
// 如果 body 不为空,默认设置 Content-Type 为表单数据格式 if body != "" { req.Header.Set("Content-Type", "application/x-www-form-urlencoded") }
// 发送请求 resp, err := client.Do(req) if err != nil { return false, err // 请求失败 } defer resp.Body.Close()
// 读取响应体 responseBody, err := ioutil.ReadAll(resp.Body) if err != nil { return false, err // 读取响应体失败 }
// 将响应体转换为字符串 bodyStr := string(responseBody)
// 根据是否使用正则表达式来匹配关键词 if useRegex { re, err := regexp.Compile(keyword) if err != nil { return false, fmt.Errorf("正则表达式编译错误: %v", err) } if re.MatchString(bodyStr) { return true, nil } } else { if strings.Contains(bodyStr, keyword) { return true, nil } }
return false, nil}
// 工作线程函数,从任务通道中获取 URL 并处理func worker(taskChan <-chan string, resultsChan chan<- string, wg *sync.WaitGroup, path, method, body, keyword string, headers map[string]string, useRegex bool) { defer wg.Done()
for url := range taskChan { // 检查 URL 是否包含协议 if !strings.HasPrefix(url, "http://") && !strings.HasPrefix(url, "https://") { // 优先尝试 https httpsURL := "https://" + url if found, err := checkWebmin(httpsURL, path, method, body, keyword, headers, useRegex); found && err == nil { fmt.Println("找到sURL:", httpsURL," ","关键词",keyword) resultsChan <- httpsURL continue }
// 如果 https 失败,尝试 http httpURL := "http://" + url if found, err := checkWebmin(httpURL, path, method, body, keyword, headers, useRegex); found && err == nil { fmt.Println("找到URL:", httpURL," ","关键词",keyword) resultsChan <- httpURL continue } } else { // 如果 URL 已经包含协议,直接检查 if found, err := checkWebmin(url, path, method, body, keyword, headers, useRegex); found && err == nil { fmt.Println("找到关键词:", url," ","关键词",keyword) resultsChan <- url } } }}
func parseHeaders(headerStr string) map[string]string { headers := make(map[string]string)
// 解析自定义的 headers,格式为 key:value;key:value headerPairs := strings.Split(headerStr, ";") for _, pair := range headerPairs { headerParts := strings.SplitN(pair, ":", 2) if len(headerParts) == 2 { key := strings.TrimSpace(headerParts[0]) value := strings.TrimSpace(headerParts[1]) headers[key] = value } }
return headers}
func main() { // 处理长选项和短选项的参数  figure := figure.NewFigure("Fingerprint Scanner"""true)  figure.Print() urlsFile := flag.String("urls", "urls.txt", "URL 文件的路径 (-u)") flag.StringVar(urlsFile, "u", "urls.txt", "URL 文件的路径")
  numWorkers := flag.Int("threads"10"并发线程数 (-t)") flag.IntVar(numWorkers, "t", 10, "并发线程数")
  requestPath := flag.String("path""""要访问的路径 (-ph)") flag.StringVar(requestPath, "ph", "", "要访问的路径")
requestMethod := flag.String("method", "GET", "HTTP 请求方法 (-m)") flag.StringVar(requestMethod, "m", "GET", "HTTP 请求方法")
outputFilePath := flag.String("output", "sucss.txt", "保存结果的文件路径 (-o)") flag.StringVar(outputFilePath, "o", "sucss.txt", "保存结果的文件路径")
// 自定义关键词或正则表达式参数 searchKeyword := flag.String("regex", "btc", "要匹配的关键词或正则表达式 (-r)") flag.StringVar(searchKeyword, "r", "btc", "要匹配的关键词或正则表达式")
// 自定义请求 body 参数 requestBody := flag.String("body", "", "自定义请求 body (-b)") flag.StringVar(requestBody, "b", "", "自定义请求 body")
// 自定义 header 参数 requestHeaders := flag.String("headers", "", "自定义请求头,格式为 key:value;key:value (-H)") flag.StringVar(requestHeaders, "H", "", "自定义请求头,格式为 key:value;key:value")
// 自定义帮助信息  flag.Usage = func() {    fmt.Println("用法: search Bitcoin [选项]")    fmt.Println("     手搓 by Reee     ") fmt.Println("选项:") fmt.Println(" -urls, -u URL 文件的路径 (默认为 urls.txt)") fmt.Println(" -method, -m HTTP 请求方法 (默认为 GET)")    fmt.Println("  -path, -ph        要访问的路径 (默认为 空)") fmt.Println(" -threads, -t 并发线程数 (默认为 10)") fmt.Println(" -output, -o 保存结果的文件路径 (默认为 sucss.txt)") fmt.Println(" -regex, -r 要匹配的关键词或正则表达式 (默认为 btc)") fmt.Println(" -body, -b 自定义请求 body (默认为空)") fmt.Println(" -headers, -H 自定义请求头,格式为 key:value;key:value (默认为空)") fmt.Println(" -h, --help 显示帮助信息") }
flag.Parse()
// 判断是否使用正则表达式 useRegex := false if _, err := regexp.Compile(*searchKeyword); err == nil { useRegex = true }
// 解析自定义的请求头 headers := parseHeaders(*requestHeaders)
// 打开 URL 文件 file, err := os.Open(*urlsFile) if err != nil { fmt.Println("打开 URL 文件出错:", err) return } defer file.Close()
// 打开输出文件 outputFile, err := os.OpenFile(*outputFilePath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644) if err != nil { fmt.Println("打开输出文件出错:", err) return } defer outputFile.Close()
// 创建任务和结果通道 taskChan := make(chan string, 100) resultsChan := make(chan string, 100)
var wg sync.WaitGroup
// 启动 worker for i := 0; i < *numWorkers; i++ { wg.Add(1) go worker(taskChan, resultsChan, &wg, *requestPath, *requestMethod, *requestBody, *searchKeyword, headers, useRegex) }
// 读取 URL 并将其发送到任务通道 scanner := bufio.NewScanner(file) go func() { for scanner.Scan() { url := strings.TrimSpace(scanner.Text()) if url != "" { taskChan <- url } } close(taskChan) }()
// 处理结果并写入输出文件 go func() { for result := range resultsChan { outputFile.WriteString(result + "\n") } }()
// 等待所有 worker 完成 wg.Wait() close(resultsChan)
// 检查读取 URL 文件时是否有错误 if err := scanner.Err(); err != nil { fmt.Println("读取 URL 文件出错:", err) }}

0x05 命令行界面美化
自己弄一个ascii放进去,或者用go的figure库
https://patorjk.com/software/taag/#p=display&f=Star%20Wars&t=%E6%8C%87%E7%BA%B9%E6%89%AB%E6%8F%8F%E5%99%A8

0x05 功能缺陷

多线程文件锁没写,多线程可能会互斥覆盖,自己加个文件锁,另外可以优化一下线程,用CPU的核数来提高线程处理速度。

end

下期预告

继续写工具

投稿方式

欢迎投稿并加入我们,请联系公众号:Golden-Qianjiang


文章来源: https://mp.weixin.qq.com/s?__biz=Mzg5NTY3NTMxMQ==&mid=2247484493&idx=1&sn=9dfce902ffe82ec0679658d28e791e44&chksm=c00dfa8df77a739bedf76971df3fb51d26281422d57830eb784fb5cf3489141f4dc4e0020ba5&scene=58&subscene=0#rd
如有侵权请联系:admin#unsafe.sh