2025-01-16 10:32:36 +08:00
|
|
|
|
package main
|
|
|
|
|
|
|
|
|
|
import (
|
2025-02-18 18:16:48 +08:00
|
|
|
|
"encoding/json"
|
2025-01-16 10:32:36 +08:00
|
|
|
|
"fmt"
|
|
|
|
|
"io"
|
|
|
|
|
"log"
|
|
|
|
|
"net/http"
|
|
|
|
|
"net/url"
|
|
|
|
|
"strings"
|
|
|
|
|
"time"
|
2025-02-25 14:20:40 +08:00
|
|
|
|
aiapis "yuequanScan/AIAPIS"
|
2025-01-16 10:32:36 +08:00
|
|
|
|
)
|
|
|
|
|
|
2025-02-18 18:16:48 +08:00
|
|
|
|
type Result struct {
|
2025-02-19 15:01:01 +08:00
|
|
|
|
Method string `json:"method"`
|
|
|
|
|
Host string `json:"host"` // JSON 标签用于自定义字段名
|
|
|
|
|
Path string `json:"path"`
|
|
|
|
|
RespBodyA string `json:"respBodyA"`
|
|
|
|
|
RespBodyB string `json:"respBodyB"`
|
|
|
|
|
Result string `json:"result"`
|
2025-02-25 15:40:26 +08:00
|
|
|
|
Reason string `json:"reason"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 扫描结果
|
|
|
|
|
type ScanResult struct {
|
|
|
|
|
Res string `json:"res"`
|
|
|
|
|
Reason string `json:"reason"`
|
2025-02-18 18:16:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-01-16 10:32:36 +08:00
|
|
|
|
func scan() {
|
|
|
|
|
for {
|
|
|
|
|
time.Sleep(3 * time.Second)
|
|
|
|
|
logs.Range(func(key any, value any) bool {
|
|
|
|
|
// fmt.Println("The type of x is", reflect.TypeOf(value))
|
|
|
|
|
var r *RequestResponseLog
|
|
|
|
|
if rr, ok := value.(*RequestResponseLog); ok {
|
|
|
|
|
r = rr
|
|
|
|
|
} else {
|
|
|
|
|
fmt.Printf("Value is not of type RequestResponseLog\n")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// fmt.Println(r)
|
2025-02-19 15:01:01 +08:00
|
|
|
|
if r.Request.Header != nil && r.Response.Header != nil && r.Response.Body != nil {
|
|
|
|
|
result, resp1, resp2, err := sendHTTPAndKimi(r) // 主要
|
2025-02-18 18:16:48 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
fmt.Println(err)
|
|
|
|
|
} else {
|
|
|
|
|
var resultOutput Result
|
2025-02-19 15:01:01 +08:00
|
|
|
|
resultOutput.Method = r.Request.Method
|
2025-02-18 18:16:48 +08:00
|
|
|
|
resultOutput.Host = r.Request.URL.Host
|
|
|
|
|
resultOutput.Path = r.Request.URL.Path
|
2025-02-19 15:01:01 +08:00
|
|
|
|
resultOutput.RespBodyA = resp1
|
|
|
|
|
resultOutput.RespBodyB = resp2
|
2025-02-25 15:40:26 +08:00
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
result1, err := parseResponse(result)
|
2025-02-18 18:16:48 +08:00
|
|
|
|
if err != nil {
|
2025-02-25 15:40:26 +08:00
|
|
|
|
log.Fatalf("解析失败: %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var scanR ScanResult
|
|
|
|
|
|
|
|
|
|
err = json.Unmarshal([]byte(result1), &scanR)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Println("解析 JSON 数据失败("+result+": )", err)
|
|
|
|
|
} else {
|
|
|
|
|
// fmt.Printf("Res: %s\n", scanR.Res)
|
|
|
|
|
// fmt.Printf("Reason: %s\n", scanR.Reason)
|
|
|
|
|
resultOutput.Result = scanR.Res
|
|
|
|
|
resultOutput.Reason = scanR.Reason
|
|
|
|
|
jsonData, err := json.Marshal(resultOutput)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Fatalf("Error marshaling to JSON: %v", err)
|
|
|
|
|
}
|
|
|
|
|
log.Println(string(jsonData))
|
|
|
|
|
fmt.Println(PrintYuequan(resultOutput.Result, resultOutput.Method, resultOutput.Host+resultOutput.Path, resultOutput.Reason))
|
|
|
|
|
logs.Delete(key)
|
|
|
|
|
return true // 返回true继续遍历,返回false停止遍历
|
2025-02-18 18:16:48 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2025-02-19 15:01:01 +08:00
|
|
|
|
} else {
|
|
|
|
|
// logs.Delete(key) // 不可以添加logs.Delete(key)
|
|
|
|
|
return true
|
2025-01-16 10:32:36 +08:00
|
|
|
|
}
|
|
|
|
|
return true
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-19 15:01:01 +08:00
|
|
|
|
func sendHTTPAndKimi(r *RequestResponseLog) (result string, respA string, respB string, err error) {
|
2025-01-16 10:32:36 +08:00
|
|
|
|
resp1 := string(r.Response.Body)
|
|
|
|
|
|
|
|
|
|
fullURL := &url.URL{
|
|
|
|
|
Scheme: r.Request.URL.Scheme,
|
|
|
|
|
Host: r.Request.URL.Host,
|
|
|
|
|
Path: r.Request.URL.Path,
|
|
|
|
|
RawQuery: r.Request.URL.RawQuery,
|
|
|
|
|
}
|
2025-02-19 15:01:01 +08:00
|
|
|
|
|
|
|
|
|
if isNotSuffix(r.Request.URL.Path, suffixes) && !containsString(r.Response.Header.Get("Content-Type"), allowedRespHeaders) {
|
2025-01-16 10:32:36 +08:00
|
|
|
|
req, err := http.NewRequest(r.Request.Method, fullURL.String(), strings.NewReader(string(r.Request.Body)))
|
|
|
|
|
if err != nil {
|
|
|
|
|
fmt.Println("创建请求失败:", err)
|
2025-02-19 15:01:01 +08:00
|
|
|
|
return "", "", "", err
|
2025-01-16 10:32:36 +08:00
|
|
|
|
}
|
|
|
|
|
req.Header = r.Request.Header
|
|
|
|
|
req.Header.Set("Cookie", cookie2)
|
|
|
|
|
client := &http.Client{}
|
|
|
|
|
resp, err := client.Do(req)
|
|
|
|
|
if err != nil {
|
|
|
|
|
fmt.Println("请求失败:", err)
|
2025-02-19 15:01:01 +08:00
|
|
|
|
return "", "", "", err
|
2025-01-16 10:32:36 +08:00
|
|
|
|
}
|
|
|
|
|
defer resp.Body.Close()
|
|
|
|
|
bodyBytes, err := io.ReadAll(resp.Body)
|
|
|
|
|
if err != nil {
|
|
|
|
|
fmt.Println("Error reading response body:", err)
|
2025-02-19 15:01:01 +08:00
|
|
|
|
return "", "", "", err
|
2025-01-16 10:32:36 +08:00
|
|
|
|
}
|
|
|
|
|
// 将响应体转换为字符串
|
|
|
|
|
resp2 := string(bodyBytes)
|
|
|
|
|
// 输出响应体字符串
|
2025-02-19 15:01:01 +08:00
|
|
|
|
// fmt.Println("Response1 Body:", resp1)
|
|
|
|
|
// fmt.Println("Response2 Body:", resp2)
|
|
|
|
|
if len(resp1+resp2) < 65535 {
|
|
|
|
|
result, err := detectPrivilegeEscalation(AI, resp1, resp2)
|
|
|
|
|
if err != nil {
|
|
|
|
|
fmt.Println("Error:", err)
|
|
|
|
|
return "", "", "", err
|
|
|
|
|
}
|
|
|
|
|
return result, resp1, resp2, nil
|
|
|
|
|
} else {
|
2025-02-25 15:40:26 +08:00
|
|
|
|
return `{"res": "white", "reason": "请求包太大"}`, resp1, resp2, nil
|
2025-01-16 10:32:36 +08:00
|
|
|
|
}
|
2025-02-19 15:01:01 +08:00
|
|
|
|
|
2025-02-18 18:16:48 +08:00
|
|
|
|
// log.Println("Result:", result)
|
2025-01-16 10:32:36 +08:00
|
|
|
|
|
2025-02-18 18:16:48 +08:00
|
|
|
|
}
|
2025-02-25 15:40:26 +08:00
|
|
|
|
return `{"res": "white", "reason": "白名单后缀或白名单Content-Type接口"}`, resp1, "", nil
|
2025-01-16 10:32:36 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-02-06 15:37:33 +08:00
|
|
|
|
func detectPrivilegeEscalation(AI string, resp1, resp2 string) (string, error) {
|
|
|
|
|
var result string
|
|
|
|
|
var err error
|
|
|
|
|
|
|
|
|
|
switch AI {
|
|
|
|
|
case "kimi":
|
2025-02-25 14:20:40 +08:00
|
|
|
|
result, err = aiapis.Kimi(resp1, resp2) // 调用 kimi 检测是否越权
|
2025-02-06 15:37:33 +08:00
|
|
|
|
case "deepseek":
|
2025-02-25 14:20:40 +08:00
|
|
|
|
result, err = aiapis.DeepSeek(resp1, resp2) // 调用 deepSeek 检测是否越权
|
2025-02-25 17:47:41 +08:00
|
|
|
|
case "qianwen":
|
|
|
|
|
result, err = aiapis.Qianwen(resp1, resp2) // 调用 qianwen 检测是否越权
|
2025-02-06 15:37:33 +08:00
|
|
|
|
default:
|
2025-02-25 14:20:40 +08:00
|
|
|
|
result, err = aiapis.Kimi(resp1, resp2) // 默认调用 kimi 检测是否越权
|
2025-02-06 15:37:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", err
|
|
|
|
|
}
|
|
|
|
|
return result, nil
|
|
|
|
|
}
|