diff --git a/README.assets/image-20240815120134576.png b/README.assets/image-20240815120134576.png deleted file mode 100644 index c447184..0000000 Binary files a/README.assets/image-20240815120134576.png and /dev/null differ diff --git a/README.assets/image-20240828135258064.png b/README.assets/image-20240828135258064.png new file mode 100644 index 0000000..681ecc2 Binary files /dev/null and b/README.assets/image-20240828135258064.png differ diff --git a/README.assets/image-20240828135511437.png b/README.assets/image-20240828135511437.png new file mode 100644 index 0000000..08ac2b2 Binary files /dev/null and b/README.assets/image-20240828135511437.png differ diff --git a/README.assets/image-20240828135747673.png b/README.assets/image-20240828135747673.png new file mode 100644 index 0000000..b1174c0 Binary files /dev/null and b/README.assets/image-20240828135747673.png differ diff --git a/README.assets/image-20240828135942331.png b/README.assets/image-20240828135942331.png new file mode 100644 index 0000000..383f48a Binary files /dev/null and b/README.assets/image-20240828135942331.png differ diff --git a/README.assets/image-20240828140106825.png b/README.assets/image-20240828140106825.png new file mode 100644 index 0000000..bcff5f0 Binary files /dev/null and b/README.assets/image-20240828140106825.png differ diff --git a/README.assets/image-20240828140231253.png b/README.assets/image-20240828140231253.png new file mode 100644 index 0000000..9e1f0f7 Binary files /dev/null and b/README.assets/image-20240828140231253.png differ diff --git a/README.md b/README.md index 9c0bc79..9d8d601 100644 --- a/README.md +++ b/README.md @@ -6,26 +6,26 @@ httpgo是一个web指纹识别工具,支持多线程、HTTP代理、批量识 ## 使用 ### 帮助 ``` -[shym]% ./httpgo_mac -h +[shym]% ./httpgo_mac -h Usage of ./httpgo_mac: -file string - 请求的文件 (default "target.txt") + 请求的文件 (default "target.txt") -fingers string - 指纹文件 (default "fingers.json") + 指纹文件 (default "fingers.json") -hash string - 计算hash - -outputcsv string - 输出文件 (default "output.csv") - -outputhtml string - 输出文件 (default "report.html") + 计算hash + -output string + 输出结果文件夹名称,不用加后缀(包含csv,json,html文件) (default "output") -proxy string - 添加代理 + 添加代理 + -server string + 指定output路径,启动web服务,自带随机密码,增加安全性 -thead int - 并发数 (default 20) + 并发数 (default 20) -timeout duration - 超时时间 (default 15ns) + 超时时间 (default 15ns) -url string - 请求的url + 请求的url ``` ### 单个url识别 ![image-20240815115840552](README.assets/image-20240815115840552.png) @@ -33,21 +33,33 @@ Usage of ./httpgo_mac: ### 批量url识别 -file 指定批量url文件,每行一个url --outputcsv 保存结果到文件,仅支持csv格式,未设置默认输出到output.csv - --outputhtml 保存结果到文件,仅支持html格式,未设置默认输出到report.html +-output 指定输出文件夹名称,不用加后缀,会在指定的文件夹生成csv,json,html文件 -thead 指定并发数,未设置默认20 -![image-20240815120134576](README.assets/image-20240815120134576.png) +![image-20240828135258064](README.assets/image-20240828135258064.png) + +会在指定的-output的路径下生成对应的result.csv表格文件 + +![image-20240828135511437](README.assets/image-20240828135511437.png) + +同时也会生成result.html网页文件和指纹信息result.json文件 + +如果想查看result.html页面,可以使用-server 开启web服务,自动生成一个加密的web服务 + +![image-20240828135747673](README.assets/image-20240828135747673.png) + +![image-20240828135942331](README.assets/image-20240828135942331.png) + +![image-20240828140106825](README.assets/image-20240828140106825.png) + +当输入账号密码认证过后,可直接访问根目录,下载csv文件,方便在服务器部署时,下载csv结果 -会在程序路径下生成target.csv表格文件 +![image-20240828140231253](README.assets/image-20240828140231253.png) -![image-20240815120206444](README.assets/image-20240815120206444.png) -同时也会生成target.html网页文件和指纹信息target.json文件 -在当前路径下使用python3 -m http.server 3333起一个web服务 +或在html结果路径下使用python3 -m http.server 3333起一个web服务 ![image-20240815120249467](README.assets/image-20240815120249467.png) diff --git a/cmd/httpgo/main.go b/cmd/httpgo/main.go index 879108f..fdc9791 100644 --- a/cmd/httpgo/main.go +++ b/cmd/httpgo/main.go @@ -29,9 +29,15 @@ func main() { thead := flag.Int("thead", 20, "并发数") fingers := flag.String("fingers", "fingers.json", "指纹文件") hash := flag.String("hash", "", "计算hash") - output := flag.String("outputcsv", "output.csv", "输出文件") - outputhtml := flag.String("outputhtml", "report.html", "输出文件") - server := flag.Bool("server", false, "启动web服务") + output := flag.String("output", "output", "输出结果文件夹名称,不用加后缀(包含csv,json,html文件)") + //outputhtml := flag.String("outputhtml", "report.html", "输出文件") + server := flag.String("server", "", "指定output路径,启动web服务,自带随机密码,增加安全性") + + //取当前路径 + dir, err := os.Getwd() + if err != nil { + log.Fatal(err) + } // 解析命令行标志 flag.Parse() @@ -47,20 +53,17 @@ func main() { return } // 如果指定了server,则启动web服务 - if *server != false { - dir, err := os.Getwd() - if err != nil { - log.Fatal(err) - } + if *server != "" { + newdir := dir + "/" + *server + "/" // 取随机字符串作为密码 Spasswd := utils.GenerateRandomString(10) + fmt.Printf("Serving:http://127.0.0.1:%d/%s.html\n", 6231, *server) + fmt.Printf("Serving:http://0.0.0.1:%d/%s.html\n", 6231, *server) fmt.Printf("UserInfo: admin/%s\n", Spasswd) - fmt.Printf("Serving:http://127.0.0.1:%d\n", 6231) - err = httpgo.ServeDirectoryWithAuth(dir, "admin", Spasswd, 6231) + err := httpgo.ServeDirectoryWithAuth(newdir, "admin", Spasswd, 6231) if err != nil { log.Fatal(err) } - } fingerlist, err := utils.LoadFingerprints(*fingers) @@ -93,25 +96,38 @@ func main() { return } + // 创建一个通道来控制并发数量 + sem := make(chan struct{}, *thead) + + // 使用WaitGroup和goroutines并发处理URL + var wg sync.WaitGroup + + outdir := dir + "/" + *output + outdircsv := outdir + "/" + *output + ".csv" + outdirhtml := outdir + "/" + *output + ".html" + outdirjson := outdir + "/" + *output + ".json" + outhtmljson := *output + ".json" + + // 创建目录(如果不存在) + err = os.MkdirAll(outdir, os.ModePerm) + if err != nil { + fmt.Println("创建目录出错:", err) + return + } + // 替换.html为.json - reportJson := utils.ReplaceHTMLWithJSON(*outputhtml) + reportJson := outdirjson // 创建HTML报告 - htmlfile, err := utils.InitializeHTMLReport(*outputhtml) + htmlfile, err := utils.InitializeHTMLReport(outdirhtml, outhtmljson) if err != nil { fmt.Println("Error creating HTML report:", err) return } defer htmlfile.Close() - // 创建一个通道来控制并发数量 - sem := make(chan struct{}, *thead) - - // 使用WaitGroup和goroutines并发处理URL - var wg sync.WaitGroup - // 创建CSV文件 - file, err := os.Create(*output) + file, err := os.Create(outdircsv) if err != nil { fmt.Println("创建CSV文件出错:", err) return diff --git a/pkg/httpgo/server.go b/pkg/httpgo/server.go new file mode 100644 index 0000000..d09f7e9 --- /dev/null +++ b/pkg/httpgo/server.go @@ -0,0 +1,40 @@ +package httpgo + +import ( + "log" + "net/http" + "os" + "strconv" +) + +// ServeDirectoryWithAuth 启动一个带有基本身份验证的文件服务器 +func ServeDirectoryWithAuth(dir, username, password string, port int) error { + // 检查目录是否存在 + if _, err := os.Stat(dir); os.IsNotExist(err) { + return err + } + + // 创建一个文件服务器处理程序 + fs := http.FileServer(http.Dir(dir)) + + // 使用 BasicAuth 中间件保护文件服务器 + protectedFS := BasicAuth(fs, username, password) + + // 启动 Web 服务器 + addr := ":" + strconv.Itoa(port) + log.Printf("Serving %s on HTTP port %d\n", dir, port) + return http.ListenAndServe(addr, protectedFS) +} + +// BasicAuth 是一个中间件函数,用于实现基本身份验证 +func BasicAuth(next http.Handler, username, password string) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + user, pass, ok := r.BasicAuth() + if !ok || user != username || pass != password { + w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`) + http.Error(w, "Unauthorized", http.StatusUnauthorized) + return + } + next.ServeHTTP(w, r) + }) +} diff --git a/pkg/utils/random.go b/pkg/utils/random.go new file mode 100644 index 0000000..ab8443f --- /dev/null +++ b/pkg/utils/random.go @@ -0,0 +1,22 @@ +package utils + +import ( + "math/rand" + "time" +) + +var Charset1 = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + +func GenerateRandomString(length int) string { + rand.Seed(time.Now().UnixNano()) + + // 创建一个字节数组来存储生成的随机字符 + b := make([]byte, length) + + // 随机选择字符集中的字符并填充到字节数组中 + for i := range b { + b[i] = Charset1[rand.Intn(len(Charset1))] + } + + return string(b) +} diff --git a/pkg/utils/report.go b/pkg/utils/report.go index ddf4f3a..8fa45e7 100644 --- a/pkg/utils/report.go +++ b/pkg/utils/report.go @@ -5,7 +5,6 @@ import ( "fmt" "github.com/gofrs/flock" "os" - "path/filepath" ) // URLFingerprint 结构体表示每个 URL 的指纹信息 @@ -23,10 +22,9 @@ var HtmlHeaderA = "\n\n
\n \n \n \n \n \nDetails | \n
---|