2022-09-08 15:57:17 +08:00
|
|
|
package internal
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
2022-09-19 14:42:29 +08:00
|
|
|
"github.com/chainreactors/parsers"
|
2022-09-08 17:04:41 +08:00
|
|
|
"github.com/chainreactors/spray/pkg"
|
2022-10-26 18:28:40 +08:00
|
|
|
"github.com/chainreactors/spray/pkg/ihttp"
|
|
|
|
"strconv"
|
2022-09-08 15:57:17 +08:00
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
2022-10-26 18:28:40 +08:00
|
|
|
func NewBaseline(u, host string, resp *ihttp.Response) *baseline {
|
2022-09-08 15:57:17 +08:00
|
|
|
bl := &baseline{
|
2022-10-26 18:28:40 +08:00
|
|
|
//Url: u,
|
|
|
|
UrlString: u,
|
|
|
|
Host: host,
|
2022-09-23 01:20:01 +08:00
|
|
|
Status: resp.StatusCode(),
|
|
|
|
IsValid: true,
|
2022-09-08 15:57:17 +08:00
|
|
|
}
|
|
|
|
|
2022-09-23 01:20:01 +08:00
|
|
|
bl.Body = resp.Body()
|
2022-10-26 18:28:40 +08:00
|
|
|
bl.BodyLength = resp.ContentLength()
|
|
|
|
bl.Header = resp.Header()
|
|
|
|
bl.HeaderLength = len(bl.Header)
|
|
|
|
bl.RedirectURL = resp.GetHeader("Location")
|
2022-09-23 01:20:01 +08:00
|
|
|
bl.Raw = append(bl.Header, bl.Body...)
|
2022-09-23 01:47:24 +08:00
|
|
|
return bl
|
2022-09-08 15:57:17 +08:00
|
|
|
}
|
|
|
|
|
2022-10-26 18:28:40 +08:00
|
|
|
func NewInvalidBaseline(u, host string, resp *ihttp.Response) *baseline {
|
2022-09-08 15:57:17 +08:00
|
|
|
bl := &baseline{
|
2022-10-26 18:28:40 +08:00
|
|
|
//Url: u,
|
|
|
|
UrlString: u,
|
|
|
|
Host: host,
|
2022-09-23 11:20:41 +08:00
|
|
|
Status: resp.StatusCode(),
|
|
|
|
IsValid: false,
|
2022-09-08 15:57:17 +08:00
|
|
|
}
|
|
|
|
|
2022-10-26 18:28:40 +08:00
|
|
|
bl.RedirectURL = string(resp.GetHeader("Location"))
|
2022-09-08 15:57:17 +08:00
|
|
|
|
|
|
|
return bl
|
|
|
|
}
|
|
|
|
|
|
|
|
type baseline struct {
|
2022-10-26 18:28:40 +08:00
|
|
|
UrlString string `json:"url"`
|
|
|
|
Host string `json:"host"`
|
2022-09-15 19:27:07 +08:00
|
|
|
Body []byte `json:"-"`
|
2022-09-23 01:20:01 +08:00
|
|
|
BodyLength int `json:"body_length"`
|
|
|
|
Header []byte `json:"-"`
|
|
|
|
Raw []byte `json:"-"`
|
2022-09-15 19:27:07 +08:00
|
|
|
HeaderLength int `json:"header_length"`
|
|
|
|
RedirectURL string `json:"redirect_url"`
|
|
|
|
Status int `json:"status"`
|
|
|
|
IsDynamicUrl bool `json:"is_dynamic_url"` // 判断是否存在动态的url
|
|
|
|
Spended int `json:"spended"` // 耗时, 毫秒
|
2022-10-26 18:28:40 +08:00
|
|
|
Title string `json:"title"`
|
2022-09-15 19:27:07 +08:00
|
|
|
Frameworks pkg.Frameworks `json:"frameworks"`
|
2022-09-19 14:42:29 +08:00
|
|
|
Extracteds pkg.Extracteds `json:"extracts"`
|
|
|
|
Err error `json:"-"`
|
|
|
|
IsValid bool `json:"-"`
|
2022-09-23 01:20:01 +08:00
|
|
|
*parsers.Hashes
|
2022-09-08 15:57:17 +08:00
|
|
|
}
|
|
|
|
|
2022-09-23 01:20:01 +08:00
|
|
|
// Collect 深度收集信息
|
|
|
|
func (bl *baseline) Collect() {
|
|
|
|
bl.Hashes = parsers.NewHashes(bl.Raw)
|
2022-10-26 18:28:40 +08:00
|
|
|
bl.Title = parsers.MatchTitle(string(bl.Body))
|
2022-09-23 01:20:01 +08:00
|
|
|
// todo extract
|
|
|
|
bl.Extracteds = pkg.Extractors.Extract(string(bl.Raw))
|
|
|
|
// todo 指纹识别
|
|
|
|
bl.Frameworks = pkg.FingerDetect(string(bl.Raw))
|
|
|
|
}
|
|
|
|
|
|
|
|
// Equal if this equal other return true
|
|
|
|
func (bl *baseline) Equal(other *baseline) bool {
|
|
|
|
if other.RedirectURL != "" && bl.RedirectURL == other.RedirectURL {
|
|
|
|
// 如果重定向url不为空, 且与bl不相同, 则说明不是同一个页面
|
2022-09-08 15:57:17 +08:00
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2022-09-23 01:20:01 +08:00
|
|
|
if bl.BodyLength == other.BodyLength {
|
|
|
|
// 如果body length相等且md5相等, 则说明是同一个页面
|
|
|
|
if bl.BodyMd5 == parsers.Md5Hash(other.Raw) {
|
|
|
|
return true
|
|
|
|
} else {
|
|
|
|
return true
|
|
|
|
}
|
2022-09-08 15:57:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2022-09-23 01:20:01 +08:00
|
|
|
func (bl *baseline) FuzzyEqual(other *baseline) bool {
|
2022-09-08 15:57:17 +08:00
|
|
|
// todo 模糊匹配
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
func (bl *baseline) String() string {
|
2022-09-20 18:09:06 +08:00
|
|
|
var line strings.Builder
|
2022-09-23 11:20:41 +08:00
|
|
|
//line.WriteString("[+] ")
|
2022-09-20 18:09:06 +08:00
|
|
|
line.WriteString(bl.UrlString)
|
2022-10-26 18:28:40 +08:00
|
|
|
line.WriteString(" (" + bl.Host + ")")
|
|
|
|
line.WriteString(" - ")
|
|
|
|
line.WriteString(strconv.Itoa(bl.Status))
|
|
|
|
line.WriteString(" - ")
|
|
|
|
line.WriteString(strconv.Itoa(bl.BodyLength))
|
2022-09-20 18:09:06 +08:00
|
|
|
if bl.RedirectURL != "" {
|
2022-10-26 18:28:40 +08:00
|
|
|
line.WriteString(" -> ")
|
2022-09-20 18:09:06 +08:00
|
|
|
line.WriteString(bl.RedirectURL)
|
2022-10-26 18:28:40 +08:00
|
|
|
line.WriteString(" ")
|
2022-09-20 18:09:06 +08:00
|
|
|
}
|
2022-10-26 18:28:40 +08:00
|
|
|
line.WriteString(" [" + bl.Title + "]")
|
|
|
|
if bl.Hashes != nil {
|
|
|
|
line.WriteString(" [" + bl.Hashes.BodyMd5 + "]")
|
|
|
|
}
|
|
|
|
|
2022-09-20 18:09:06 +08:00
|
|
|
line.WriteString(bl.Frameworks.ToString())
|
|
|
|
//line.WriteString(bl.Extracteds)
|
2022-09-23 11:20:41 +08:00
|
|
|
//line.WriteString("\n")
|
|
|
|
if bl.Err != nil {
|
|
|
|
line.WriteString("err: ")
|
|
|
|
line.WriteString(bl.Err.Error())
|
|
|
|
}
|
2022-09-20 18:09:06 +08:00
|
|
|
return line.String()
|
2022-09-08 15:57:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func (bl *baseline) Jsonify() string {
|
|
|
|
bs, err := json.Marshal(bl)
|
|
|
|
if err != nil {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
return string(bs)
|
|
|
|
}
|