2020-12-29 17:17:10 +08:00
|
|
|
package WebScan
|
|
|
|
|
|
|
|
import (
|
|
|
|
"embed"
|
|
|
|
"fmt"
|
2024-12-18 22:00:18 +08:00
|
|
|
"github.com/shadow1ng/fscan/Common"
|
2020-12-29 17:17:10 +08:00
|
|
|
"github.com/shadow1ng/fscan/WebScan/lib"
|
|
|
|
"net/http"
|
2022-04-20 17:45:27 +08:00
|
|
|
"os"
|
|
|
|
"path/filepath"
|
2021-06-17 20:32:53 +08:00
|
|
|
"strings"
|
2022-04-20 17:45:27 +08:00
|
|
|
"sync"
|
2020-12-29 17:17:10 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
//go:embed pocs
|
|
|
|
var Pocs embed.FS
|
2022-04-20 17:45:27 +08:00
|
|
|
var once sync.Once
|
|
|
|
var AllPocs []*lib.Poc
|
2020-12-29 17:17:10 +08:00
|
|
|
|
2024-12-19 14:49:52 +08:00
|
|
|
// WebScan 执行Web漏洞扫描
|
2024-12-19 16:15:53 +08:00
|
|
|
func WebScan(info *Common.HostInfo) {
|
2024-12-19 14:49:52 +08:00
|
|
|
// 确保POC只初始化一次
|
2022-04-20 17:45:27 +08:00
|
|
|
once.Do(initpoc)
|
2024-12-19 14:49:52 +08:00
|
|
|
|
|
|
|
// 构建扫描信息
|
2024-12-18 22:00:18 +08:00
|
|
|
var pocinfo = Common.Pocinfo
|
2024-12-19 14:49:52 +08:00
|
|
|
urlParts := strings.Split(info.Url, "/")
|
|
|
|
pocinfo.Target = strings.Join(urlParts[:3], "/")
|
2022-01-08 13:31:52 +08:00
|
|
|
|
2024-12-19 14:49:52 +08:00
|
|
|
// 执行扫描
|
2022-03-11 16:13:31 +08:00
|
|
|
if pocinfo.PocName != "" {
|
2024-12-19 14:49:52 +08:00
|
|
|
// 指定POC扫描
|
2022-03-11 16:13:31 +08:00
|
|
|
Execute(pocinfo)
|
|
|
|
} else {
|
2024-12-19 14:49:52 +08:00
|
|
|
// 根据指纹信息选择POC扫描
|
2022-03-11 16:13:31 +08:00
|
|
|
for _, infostr := range info.Infostr {
|
|
|
|
pocinfo.PocName = lib.CheckInfoPoc(infostr)
|
2022-01-08 13:31:52 +08:00
|
|
|
Execute(pocinfo)
|
2022-01-07 17:58:34 +08:00
|
|
|
}
|
2020-12-29 17:17:10 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-12-19 14:49:52 +08:00
|
|
|
// Execute 执行具体的POC检测
|
2024-12-18 22:00:18 +08:00
|
|
|
func Execute(PocInfo Common.PocInfo) {
|
2024-12-19 14:49:52 +08:00
|
|
|
// 创建基础HTTP请求
|
2020-12-29 17:17:10 +08:00
|
|
|
req, err := http.NewRequest("GET", PocInfo.Target, nil)
|
|
|
|
if err != nil {
|
2024-12-19 14:49:52 +08:00
|
|
|
Common.LogError(fmt.Sprintf("初始化请求失败 %v: %v", PocInfo.Target, err))
|
2021-06-30 16:26:17 +08:00
|
|
|
return
|
2020-12-29 17:17:10 +08:00
|
|
|
}
|
2024-12-19 14:49:52 +08:00
|
|
|
|
|
|
|
// 设置请求头
|
2024-12-18 22:00:18 +08:00
|
|
|
req.Header.Set("User-agent", Common.UserAgent)
|
|
|
|
req.Header.Set("Accept", Common.Accept)
|
2022-11-19 17:04:13 +08:00
|
|
|
req.Header.Set("Accept-Language", "zh-CN,zh;q=0.9")
|
2024-12-18 22:00:18 +08:00
|
|
|
if Common.Cookie != "" {
|
|
|
|
req.Header.Set("Cookie", Common.Cookie)
|
2020-12-29 17:17:10 +08:00
|
|
|
}
|
2024-12-19 14:49:52 +08:00
|
|
|
|
|
|
|
// 根据名称筛选POC并执行
|
2022-04-20 17:45:27 +08:00
|
|
|
pocs := filterPoc(PocInfo.PocName)
|
2024-12-18 22:00:18 +08:00
|
|
|
lib.CheckMultiPoc(req, pocs, Common.PocNum)
|
2022-04-20 17:45:27 +08:00
|
|
|
}
|
|
|
|
|
2024-12-19 14:49:52 +08:00
|
|
|
// initpoc 初始化POC加载
|
2022-04-20 17:45:27 +08:00
|
|
|
func initpoc() {
|
2024-12-18 22:00:18 +08:00
|
|
|
if Common.PocPath == "" {
|
2024-12-19 14:49:52 +08:00
|
|
|
// 从嵌入的POC目录加载
|
2022-04-20 17:45:27 +08:00
|
|
|
entries, err := Pocs.ReadDir("pocs")
|
|
|
|
if err != nil {
|
2024-12-19 14:49:52 +08:00
|
|
|
Common.LogError(fmt.Sprintf("加载内置POC失败: %v", err))
|
2022-04-20 17:45:27 +08:00
|
|
|
return
|
|
|
|
}
|
2024-12-19 14:49:52 +08:00
|
|
|
|
|
|
|
// 加载YAML格式的POC文件
|
|
|
|
for _, entry := range entries {
|
|
|
|
filename := entry.Name()
|
|
|
|
if strings.HasSuffix(filename, ".yaml") || strings.HasSuffix(filename, ".yml") {
|
|
|
|
if poc, err := lib.LoadPoc(filename, Pocs); err == nil && poc != nil {
|
2022-04-20 17:45:27 +08:00
|
|
|
AllPocs = append(AllPocs, poc)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2024-12-19 14:49:52 +08:00
|
|
|
// 从指定目录加载POC
|
2025-01-01 07:18:36 +08:00
|
|
|
Common.LogSuccess(fmt.Sprintf("从目录加载POC: %s", Common.PocPath))
|
2024-12-19 14:49:52 +08:00
|
|
|
err := filepath.Walk(Common.PocPath, func(path string, info os.FileInfo, err error) error {
|
|
|
|
if err != nil || info == nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if !info.IsDir() && (strings.HasSuffix(path, ".yaml") || strings.HasSuffix(path, ".yml")) {
|
|
|
|
if poc, err := lib.LoadPocbyPath(path); err == nil && poc != nil {
|
|
|
|
AllPocs = append(AllPocs, poc)
|
2022-04-20 17:45:27 +08:00
|
|
|
}
|
2024-12-19 14:49:52 +08:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
|
2022-04-20 17:45:27 +08:00
|
|
|
if err != nil {
|
2025-01-01 07:18:36 +08:00
|
|
|
Common.LogError(fmt.Sprintf("加载外部POC失败: %v", err))
|
2022-04-20 17:45:27 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-12-19 14:49:52 +08:00
|
|
|
// filterPoc 根据POC名称筛选
|
|
|
|
func filterPoc(pocname string) []*lib.Poc {
|
2022-04-20 17:45:27 +08:00
|
|
|
if pocname == "" {
|
|
|
|
return AllPocs
|
|
|
|
}
|
2024-12-19 14:49:52 +08:00
|
|
|
|
|
|
|
var matchedPocs []*lib.Poc
|
2022-04-20 17:45:27 +08:00
|
|
|
for _, poc := range AllPocs {
|
|
|
|
if strings.Contains(poc.Name, pocname) {
|
2024-12-19 14:49:52 +08:00
|
|
|
matchedPocs = append(matchedPocs, poc)
|
2022-04-20 17:45:27 +08:00
|
|
|
}
|
|
|
|
}
|
2024-12-19 14:49:52 +08:00
|
|
|
return matchedPocs
|
2020-12-29 17:17:10 +08:00
|
|
|
}
|