-
Notifications
You must be signed in to change notification settings - Fork 134
/
ti.go
165 lines (155 loc) · 4.67 KB
/
ti.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
package grab
import (
"context"
"strconv"
"strings"
"github.com/imroc/req/v3"
"github.com/kataras/golog"
)
type TiCrawler struct {
client *req.Client
log *golog.Logger
}
func NewTiCrawler() Grabber {
client := wrapApiClient(NewHttpClient())
client.SetCommonHeader("Referer", "https: //ti.qianxin.com/")
client.SetCommonHeader("Origin", "https: //ti.qianxin.com")
c := &TiCrawler{
log: golog.Child("[qianxin-nox]"),
client: client,
}
return c
}
func (t *TiCrawler) ProviderInfo() *Provider {
return &Provider{
Name: "qianxin-ti",
DisplayName: "奇安信威胁情报中心",
Link: "https://ti.qianxin.com/",
}
}
func (t *TiCrawler) GetUpdate(ctx context.Context, _ int) ([]*VulnInfo, error) {
resp, err := t.client.R().
SetContext(ctx).
Post("https://ti.qianxin.com/alpha-api/v2/vuln/one-day")
if err != nil {
return nil, err
}
var body tiOneDayResp
if err = resp.UnmarshalJson(&body); err != nil {
return nil, err
}
var results []*VulnInfo
for _, d := range body.Data.KeyVulnAdd {
tags := make([]string, 0, len(d.Tag))
for _, tag := range d.Tag {
tags = append(tags, strings.TrimSpace(tag.Name))
}
severity := Low
switch d.RatingLevel {
case "低危":
severity = Low
case "中危":
severity = Medium
case "高危":
severity = High
case "极危":
severity = Critical
}
info := &VulnInfo{
UniqueKey: d.QvdCode,
Title: d.VulnName,
Description: d.Description,
Severity: severity,
CVE: d.CveCode,
Disclosure: d.PublishTime,
References: nil,
Tags: tags,
Solutions: "",
From: "https://ti.qianxin.com/vulnerability/detail/" + strconv.Itoa(d.Id),
Creator: t,
}
results = append(results, info)
}
// 根据 ID 去重
uniqResults := make(map[string]*VulnInfo)
for _, info := range results {
uniqResults[info.UniqueKey] = info
}
// 保持顺序
newResults := make([]*VulnInfo, 0, len(uniqResults))
for _, info := range results {
if uniqResults[info.UniqueKey] == nil {
continue
}
newResults = append(newResults, info)
uniqResults[info.UniqueKey] = nil
}
t.log.Infof("got %d vulns from oneday api", len(newResults))
return newResults, nil
}
func (t *TiCrawler) IsValuable(info *VulnInfo) bool {
if info.Severity != High && info.Severity != Critical {
return false
}
for _, tag := range info.Tags {
if tag == "奇安信CERT验证" ||
tag == "POC公开" ||
tag == "EXP公开" ||
tag == "技术细节公布" {
return true
}
}
return false
}
type tiVulnDetail struct {
Id int `json:"id"`
VulnName string `json:"vuln_name"`
VulnNameEn string `json:"vuln_name_en"`
QvdCode string `json:"qvd_code"`
CveCode string `json:"cve_code"`
CnvdId *string `json:"cnvd_id"`
CnnvdId string `json:"cnnvd_id"`
ThreatCategory string `json:"threat_category"`
TechnicalCategory string `json:"technical_category"`
ResidenceId *int `json:"residence_id"`
RatingId *int `json:"rating_id"`
NotShow int `json:"not_show"`
PublishTime string `json:"publish_time"`
Description string `json:"description"`
DescriptionEn string `json:"description_en"`
ChangeImpact int `json:"change_impact"`
OperatorHid string `json:"operator_hid"`
CreateHid *string `json:"create_hid"`
Channel *string `json:"channel"`
TrackingId *string `json:"tracking_id"`
Temp int `json:"temp"`
OtherRating int `json:"other_rating"`
CreateTime string `json:"create_time"`
UpdateTime string `json:"update_time"`
LatestUpdateTime string `json:"latest_update_time"`
RatingLevel string `json:"rating_level"`
VulnType string `json:"vuln_type"`
PocFlag int `json:"poc_flag"`
PatchFlag int `json:"patch_flag"`
DetailFlag int `json:"detail_flag"`
Tag []struct {
Name string `json:"name"`
FontColor string `json:"font_color"`
BackColor string `json:"back_color"`
} `json:"tag"`
TagLen int `json:"tag_len"`
IsRatingLevel int `json:"is_rating_level"`
}
type tiOneDayResp struct {
Status int `json:"status"`
Message string `json:"message"`
Data struct {
VulnAddCount int `json:"vuln_add_count"`
VulnUpdateCount int `json:"vuln_update_count"`
KeyVulnAddCount int `json:"key_vuln_add_count"`
PocExpAddCount int `json:"poc_exp_add_count"`
PatchAddCount int `json:"patch_add_count"`
KeyVulnAdd []tiVulnDetail `json:"key_vuln_add"`
PocExpAdd []tiVulnDetail `json:"poc_exp_add"`
} `json:"data"`
}