高階JavaScript注入技術
原文:ofollow,noindex">https://brutelogic.com.br/blog/advanced-javascript-injections/
簡單的JavaScript/">JavaScript注入技術,如'-alert(1)-'
甚至’-alert(1)//
(請參見此處的案例#6和案例#7),只要指令碼塊內觸發輸入反射(input reflection),通常無需藉助HTML注入攻擊,就能引發易受攻擊頁面彈出警報框(具體請參見上面同一篇文章中的案例#5)。
但是在某些情況下,注入點可能會位於更加複雜的JS程式碼的中間,即在函式和條件語句內部(if或if+else),並且,它們還經常會巢狀在一起。
下面,我們將通過一個具體的示例,來講解如何利用這種型別的漏洞。實際上,@gustavorobertux提供過一個現實中的漏洞,跟這裡介紹的簡直如出一轍。
https://brutelogic.com.br/tests/jsfix.php?keyword=xss
我們發現,藉助於使用者互動的情況下,這很容易做到,但是如果您不熟悉JS語言的話,事情可能會變得比較複雜。
因此,我們有以下幾點思考。首先,它位於一些JS程式碼(keyword=aaaaa)的中間。
所以,我們可以嘗試進行簡單的JS注入,不過,雙引號之前反斜槓將被轉義。
Payload: “-confirm`1`-”
正如我們從Main XSS Cases(案例#_7)中所瞭解到的那樣,下一個技巧就是在第一個引號之前新增一個反斜槓來“實現對轉義的轉義”。此外,我們還需要對其餘的程式碼行進行註釋。
Payload: ”-confirm`1`//
如果我們改變(通過使用者互動)頁面上的select元素,這種方法就能奏效。
但是,為了達到這個目的,我們還有一種更好的方法,因為這種“功能”並非在所有情況下都是可用的,並且,它還需要使用者進行互動。
我們的計劃如下:“括住”所有巢狀的函式/條件,然後插入我們自己的程式碼
confirm`1`
然後,我們必須修復剩餘程式碼中的語法問題,才能執行我們的payload,因為只要存在任何語法錯誤,整個指令碼塊都無法正常執行。
為此,我們可以首先嚐試”}})})
,這是我們程式碼段的最後三行(不需要分號),用來括住“if”語句、“on+change”函式和“document.ready”函式。其餘部分與之前的嘗試相同。
Payload: ”}})})-confirm`1`//
當然,它肯定無法奏效,因為我們的payload的構造工作只完成了一半(並且是最簡單的部分)。但是,JS控制檯(瀏覽器的Developer Tools——按F12鍵 )返回的錯誤訊息,能夠指導我們完成後面的任務。
通過點選訊息右側的連結,我們就能找到問題之所在。
問題出現在“else”語句中,因為它不應該出現在那裡。我們已經括住了if語句和2個函式,所以,我們需要去掉它。
就這裡來說,我們需要處理雙重反射,因此,我們將嘗試通過在第一個反射中開啟一個註釋,在第二個反射中關閉它,從而將它們組合在一起,使它們變成一個。這足以“幹掉”這兩個反射之間的程式碼,即在“else”行加上“document.location”屬性。
對於JS來說,多行註釋使用的是/和 /,因此,只要在payload的末尾加上一個//就可以完成這項任務(在第一個反射中被解析為/ ,在第二個反射中被解析為*/ )。
Payload: ”}})})-confirm`1`/*/
讓我們考察一下這個錯誤訊息可能意味著什麼。
正如我們所看到的,第一個反射的結尾到第二個反射的結尾之間的內容現在是以綠色顯示的,表示被註釋掉了。因此,這裡
confirm`1`
之後被執行的程式碼,為&pageIndex=1&startFrom=0,其中&被解釋為進行逐位AND運算,而後面的變數賦值操作是無效的( PageIndex = 1 )。
解決這個問題的方法並不複雜,只需在我們當前payload的末尾新增//來註釋掉該行的其餘部分即可,具體如下所示(添加了一個分號) :
Payload: ”}})})-confirm`1`;/*///
現在正如預期的那樣,在注入分號之後,“if”語句的結尾處到“}”之間的程式碼都被註釋掉了。因此,讓我們在payload的後面、註釋符之前新增一個“{”。
Payload: ”}})})-confirm`1`;{/*///
現在,解析器將跳到下一行,並報錯!
為了解決這個問題,需要繼續嘗試修復被掛起的“})”,方法是在“{”之前新增“({”,以符合語法順序。
Payload: ”}})})-confirm`1`;({{/*///
發生了什麼事?由於新添加了 “({“, 現在我們的第一個 “{” 失去了它作為 “if” 語句的 “修復碼” 所具有的效果。為解決這個問題, 我們只需在 “({” 和 “{” 之間新增一個 “if ()”即可。
Payload: ”}})})-confirm`1`;({if(){/*///
太好了,現在我們進入最後一行了!這裡,我們只需重複上一步所做的工作,在分號之後、“({if(){”之前新增另一個“({”即可。
Payload: ”}})})-confirm`1`;({({if(){/*///
這次,我們又搞砸了什麼?實際上,我們以前見過這種情況,我們只是將以前的“修復”工作搞砸了。為了修復這個新問題,在前面新增的“(”和“{”之間加入一個“function()”即可。
Payload: ”}})})-confirm`1`;(function(){({if(){/*///