Skip to content

Commit

Permalink
add
Browse files Browse the repository at this point in the history
  • Loading branch information
login546 committed Aug 28, 2024
1 parent 8095869 commit 071b6b4
Show file tree
Hide file tree
Showing 12 changed files with 142 additions and 54 deletions.
Binary file removed README.assets/image-20240815120134576.png
Binary file not shown.
Binary file added README.assets/image-20240828135258064.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added README.assets/image-20240828135511437.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added README.assets/image-20240828135747673.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added README.assets/image-20240828135942331.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added README.assets/image-20240828140106825.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added README.assets/image-20240828140231253.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
52 changes: 32 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,48 +6,60 @@ 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)

### 批量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)

Expand Down
56 changes: 36 additions & 20 deletions cmd/httpgo/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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)
Expand Down Expand Up @@ -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
Expand Down
40 changes: 40 additions & 0 deletions pkg/httpgo/server.go
Original file line number Diff line number Diff line change
@@ -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)
})
}
22 changes: 22 additions & 0 deletions pkg/utils/random.go
Original file line number Diff line number Diff line change
@@ -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)
}
26 changes: 12 additions & 14 deletions pkg/utils/report.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"fmt"
"github.com/gofrs/flock"
"os"
"path/filepath"
)

// URLFingerprint 结构体表示每个 URL 的指纹信息
Expand All @@ -23,10 +22,9 @@ var HtmlHeaderA = "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charse
var HtmlHeaderB = "')\n .then(response => {\n if (!response.ok) {\n throw new Error('Network response was not ok');\n }\n return response.json();\n })\n .then(data => {\n originalData = data;\n updateStats(data);\n updateTable(data);\n updateAllButton(data);\n })\n .catch(error => console.error('Error loading JSON data:', error));\n });\n </script>\n</head>\n<body>\n <h1>URL Fingerprint Report</h1>\n <div class=\"stats\">\n <div id=\"cms-stats\"></div>\n <div id=\"other-stats\"></div>\n <div id=\"all-stats\"></div>\n </div>\n <div id=\"modal\" class=\"modal\">\n <div class=\"modal-content\">\n <span class=\"modal-close\">&times;</span>\n <img id=\"modal-img\" src=\"\" alt=\"Screenshot\">\n </div>\n </div>\n <table>\n <thead>\n <tr>\n <th>Details</th>\n </tr>\n </thead>\n <tbody>\n <!-- Data rows will be inserted here by JavaScript -->\n </tbody>\n </table>\n <button id=\"scroll-to-top\" title=\"Go to Top\">&#8679;</button>\n</body>\n</html>\n"

// 创建 HTML 报告
func InitializeHTMLReport(filename string) (*os.File, error) {
func InitializeHTMLReport(filename string, json string) (*os.File, error) {
// 去除.html后缀
reportJson := filename[:len(filename)-5] + ".json"
var HtmlHeader = HtmlHeaderA + reportJson + HtmlHeaderB
var HtmlHeader = HtmlHeaderA + json + HtmlHeaderB
file, err := os.Create(filename)
if err != nil {
return nil, err
Expand All @@ -39,16 +37,16 @@ func InitializeHTMLReport(filename string) (*os.File, error) {
return file, nil
}

// ReplaceHTMLWithJSON 函数将 HTML 文件名的扩展名替换为 JSON 扩展名
func ReplaceHTMLWithJSON(filePath string) string {
// 获取文件名和扩展名
base := filepath.Base(filePath)
ext := filepath.Ext(base)
nameWithoutExt := base[:len(base)-len(ext)]

// 生成新的 JSON 文件名
return filepath.Join(filepath.Dir(filePath), nameWithoutExt+".json")
}
//// ReplaceHTMLWithJSON 函数将 HTML 文件名的扩展名替换为 JSON 扩展名
//func ReplaceHTMLWithJSON(filePath string) string {
// // 获取文件名和扩展名
// base := filepath.Base(filePath)
// ext := filepath.Ext(base)
// nameWithoutExt := base[:len(base)-len(ext)]
//
// // 生成新的 JSON 文件名
// return filepath.Join(filepath.Dir(filePath), nameWithoutExt+".json")
//}

// AppendJSONReport 将 URLFingerprint 数据追加到指定的 JSON 文件中
func AppendJSONReport(filename string, data URLFingerprint) error {
Expand Down

0 comments on commit 071b6b4

Please sign in to comment.