目錄
一、源碼分析
1、進入靶場
2、代碼審計
二、滲透實戰
1、根據提示輸入tmac
2、XSS探測
3、注入Payload1
4、注入Payload2
5、注入Payload3
6、注入Payload4
7、注入Payload5?
本系列為通過《pikachu靶場通關筆記》的XSS關卡(共10關)滲透集合,通過對XSS關卡源碼的代碼審計找到安全風險的真實原因,講解XSS的原理并進行滲透實踐,本文使用5種方法對XSS1第10關卡XSS之js輸出進行滲透。
一、源碼分析
1、進入靶場
打開pikachu靶場第09關XSS之js輸出,這是一個輸入框頁面,完整URL地址如下所示。
http://127.0.0.1/pikachu/vul/xss/xss_04.php
2、代碼審計
右鍵查看源碼,發現javascript代碼,具體如下所示。
接下來查看xss_04.php源碼內容,很明顯此代碼存在 XSS安全風險,核心原因在于直接將未經過濾和驗證的 PHP 變量 $jsvar 嵌入到 JavaScript 代碼中。$jsvar 的值來自用戶通過 GET 請求提交的 message 參數,攻擊者可以構造包含惡意 JavaScript 代碼的輸入,當這些惡意代碼被嵌入到 JavaScript 代碼塊中時,就會在頁面加載或執行相應邏輯時被瀏覽器執行。對應的完整JavaScript代碼注釋后如下所示。
<script>// 從 PHP 代碼中獲取 $jsvar 變量的值,并將其賦值給 JavaScript 變量 $ms// 這里是通過 PHP 的 echo 語句將 $jsvar 的值嵌入到 JavaScript 代碼中$ms = '<?php echo $jsvar;?>';// 檢查 $ms 變量的長度是否不為 0// 即判斷 $ms 是否有實際的內容if ($ms.length != 0) {// 檢查 $ms 變量的值是否等于 'tmac'if ($ms == 'tmac') {// 如果 $ms 的值等于 'tmac',使用 jQuery 的 text 方法// 將 ID 為 'fromjs' 的元素的文本內容設置為 'tmac確實厲害,看那小眼神..'$('#fromjs').text('tmac確實厲害,看那小眼神..');} else {// 如果 $ms 的值不等于 'tmac'// 注釋掉的代碼,原本想彈出一個包含 $ms 內容的警告框// alert($ms);// 使用 jQuery 的 text 方法// 將 ID 為 'fromjs' 的元素的文本內容設置為 '無論如何不要放棄心中所愛..'$('#fromjs').text('無論如何不要放棄心中所愛..');}}
</script>
如上代碼中提到了jvar變量,相關定義如下圖所示。如下所示使用htmlspecialchars函數且參數為ENT_QUOTES對輸入參數進行了過濾處理,這說明沒法用第08關卡的單引號進行XSS滲透了。
這段 PHP 代碼的主要功能是處理用戶通過 GET 請求提交的 message 參數。當用戶提交表單(即 submit 參數存在)且 message 參數有值時,將 message 的值賦給 $jsvar 變量。若 $jsvar 的值為 tmac,則在頁面上顯示一張名為 tmac.jpeg 的圖片。詳細注釋后的源碼如下所示。
<?php
// 初始化一個空字符串變量 $jsvar,用于存儲后續要在 JavaScript 中使用的變量值
$jsvar = '';
// 初始化一個空字符串變量 $html,用于存儲后續要輸出的 HTML 內容
$html = '';// 檢查 $_GET 數組中是否存在名為 'submit' 的元素,并且是否存在名為 'message' 的元素且其值不為 null
// 即判斷用戶是否通過 GET 請求提交了 'submit' 參數,同時也提交了 'message' 參數且該參數有值
if (isset($_GET['submit']) && $_GET['message'] != null) {// 將用戶通過 GET 請求提交的 'message' 參數的值賦給 $jsvar 變量$jsvar = $_GET['message'];// 檢查 $jsvar 變量的值是否等于 'tmac'if ($jsvar == 'tmac') {// 如果等于 'tmac',向 $html 變量中追加一個 img 標簽// img 標簽的 src 屬性使用預定義的常量 $PIKA_ROOT_DIR 拼接圖片的路徑// 用于在頁面上顯示一張名為 tmac.jpeg 的圖片$html .= "<img src='{$PIKA_ROOT_DIR}assets/images/nbaplayer/tmac.jpeg' />";}
}
?>
綜上,第10關的代碼存在 XSS安全風險,原因在于直接將用戶輸入的內容$_GET['message']賦值給 $jsvar 變量,且未對輸入進行任何過濾和驗證,接又將未經過濾和驗證的 PHP 變量 $jsvar 嵌入到 JavaScript 代碼中。$jsvar 的值來自用戶通過 GET 請求提交的 message 參數,攻擊者可以構造包含惡意 JavaScript 代碼的輸入,當這些惡意代碼被嵌入到 JavaScript 代碼塊中時,就會在頁面加載或執行相應邏輯時被瀏覽器執行。
二、滲透實戰
1、根據提示輸入tmac
進入到pikachu靶場XSS關卡最后一關,根據點擊提示獲得的信息“輸入被動態的生成到了javascript中,如何是好。輸入tmac試試-_-”,輸入tmac,效果如下所示。
頁面提示看那小眼神..“tmac確實厲害,看那小眼神..”,就這是因為js代碼種輸入為tmac,故而fromjs元素被賦值為“tmac確實厲害,看那小眼神..”,同時因為jvar為tmac,頁面顯示了圖片tmac.jpeg,相關源碼如下所示。
if ($jsvar == 'tmac') {// 如果等于 'tmac',向 $html 變量中追加一個 img 標簽// img 標簽的 src 屬性使用預定義的常量 $PIKA_ROOT_DIR 拼接圖片的路徑// 用于在頁面上顯示一張名為 tmac.jpeg 的圖片$html .= "<img src='{$PIKA_ROOT_DIR}assets/images/nbaplayer/tmac.jpeg' />";
}
如果輸入是tmac時,?將 ID 為 'fromjs' 的元素的文本內容設置為 'tmac確實厲害,看那小眼神..'
如果輸入不是tmac時,將 ID 為 'fromjs' 的元素的文本內容設置為 '無論如何不要放棄心中所愛..'
2、XSS探測
輸入Payload語句<script>alert('ljn')</script>探測XSS安全風險,如下所示。
<script>alert('ljn')</script>
輸入payload后沒有任何反應,右鍵源碼,搜索關鍵字ljn,可知因為ms不是tmac所以輸出“無論如何不要放棄心中所愛”。具體代碼邏輯如下所示。
由于ms參數未有任何過濾,故而滲透的思路可以通過與上圖綠色框中的<script>構造閉合,只要構造出一個js語句就好了。
3、注入Payload1
前提1:語句的開始與上圖中綠色的<script>構造閉合,如'</script>即可閉合。
重點:接下來是xss惡意腳本,如<script>alert('ljn')</script>,注入語句如下所示。
'</script><script>alert('ljn')</script>
右鍵源碼-搜索關鍵字ljn,分析滲透成功的原因,Payload1如何通過閉合語句來進行滲透的。紅色框中的閉合如下所示。
<script>$ms=''</script>
綠色框內為惡意彈窗<script>alert('ljn')</script>,效果如下所示。
4、注入Payload2
本次Paylaod的效果為彈框cookie值,注入Payload如下所示。
'</script><script> alert(document.cookie)</script>
右鍵查看源碼,搜索關鍵字cookie,閉合構造如下,故而可以彈框成功。
5、注入Payload3
首先要用’;閉合掉當前ms的賦值的語句,然后插入新js語句,然后再用//注釋掉老語句遺留下來的’;
開頭有<script>
結尾有</script>
只要中間包含xss惡意腳本,如彈框alert('ljn')
那么就變成了<script>alert('ljn')</script>
接下來我們嘗試進行閉合,目前可變參數為ms=’string’;
前提1:語句的開始為包含';閉合掉ms賦值語句,如';,在中間插入 xss惡意腳本,如alert('ljn')
前提2:語句的末尾為//,注釋掉后ms賦值語句最后的';
本次Paylaod的效果為彈框“ljn”,注入Payload設置為';alert('ljn')//或者或者';alert('ljn');//如下所示。
';alert('ljn')//
';alert('ljn');//
右鍵源碼,搜索關鍵字ljn,閉合構造的原因如下所示。
Payload中第一個';使得ms賦值函數聲明結束,接下來的alert('ljn')就可以是一個新的語句,但是原本ms賦值語句的最后為單引號和分號,故而在他們之前還需要加上//注釋掉,從而構造如下閉合語句。
$ms='';alert('ljn')//';
其中alert('ljn')與<script>和</script>生成如下腳本,構成彈框
<script>
alert('ljn')
</script>
6、注入Payload4
本次Paylaod的效果為彈框“1019”,注入Payload如下所示。
';alert(1019);//
';alert(1019)//
右鍵源碼,搜索關鍵字1019,閉合構造如下,故而可以彈框成功
7、注入Payload5?
本次Paylaod的效果為彈框cookie值,注入Payload如下所示。
';alert(document.cookie);//
';alert(document.cookie)//