0x00
花了些时间把dvwa重新看了一遍
虽然以前已经玩过这个 ,但是这次从源码出发的重读还是有新收获
决定写一个学习笔记
0x01
首先是环境搭建
类似的环境搭建文章网上有太多了
而且这篇文章也写的非常好(我就是参照这个搭建的)
http://www.freebuf.com/sectool/102661.html
顺便一提测试的时候记得要在php.ini中开启几个函数
0x02
首先是Brute Force 暴力破解
low
在low下源码的部分
$user = $_GET[ ‘username‘ ]; // Get password $pass = $_GET[ ‘password‘ ]; $pass = md5( $pass ); // Check the database $query = "SELECT * FROM `users` WHERE user = ‘$user‘ AND password = ‘$pass‘;";
很容易想到万能密码的绕过。。。同样直接爆破密码也是可以的
爆破密码可以写脚本也可以直接用burpsuite的intruder模块爆破 找个字典就行
medium
在medium下源码的部分
$user = $_GET[ ‘username‘ ]; $user = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $user ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : "")); // Sanitise password input $pass = $_GET[ ‘password‘ ]; $pass = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $pass ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : "")); $pass = md5( $pass ); // Check the database $query = "SELECT * FROM `users` WHERE user = ‘$user‘ AND password = ‘$pass‘;";
和low比加了一点东西 一个三元运算符
$GLOBALS["___mysqli_ston"]这只是一个自定义全局变量可以不用在意
(ps:MySQLConverter假定此全局变量设置为等于您的数据库连接对象; 如果转换器找到一个mysql_connect
它将(部分地,但是带有一个警告)将您的代码转换为包含$ GLOBALS [“___ mysqli_ston”]的赋值给mysqli_connect函数的结果的代码)
三元运算结果是用mysqli_real_escape_string()函数处理参数或者返回错误(和mysqli_escape_string()这个函数是完全一样的)
这个函数的作用是对一些特殊字符进行转义
- x00
- \n
- \r
- \
- ‘
- "
- \x1a
可见medium下不能使用万能密码的绕过了
但是如果是gbk编码的话 还是可以用宽字节绕过
抓包可以发现并未做token的验证
所以依然可以使用burpsuite爆破
high
在high下源码的部分
checkToken( $_REQUEST[ ‘user_token‘ ], $_SESSION[ ‘session_token‘ ], ‘index.php‘ ); // Sanitise username input $user = $_GET[ ‘username‘ ]; $user = stripslashes( $user ); $user = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $user ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : "")); // Sanitise password input $pass = $_GET[ ‘password‘ ]; $pass = stripslashes( $pass ); $pass = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $pass ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : "")); $pass = md5( $pass ); // Check database $query = "SELECT * FROM `users` WHERE user = ‘$user‘ AND password = ‘$pass‘;";
代码中可以看到增加了token参数 而且username和password参数同样进行的过滤防护
每次刷新页面都会获得一个随机的参数 这样就很难用burpsuite进行爆破了
那么如何获得token参数呢。。。high难度应该是有办法做出来的
看了下dvwa的源码 index.php有这样一段
if( $vulnerabilityFile == ‘high.php‘ || $vulnerabilityFile == ‘impossible.php‘ ) $page[ ‘body‘ ] .= " " . tokenField(); $page[ ‘body‘ ] .= " </form>
在high和impossible下会把token写到源码里 这样我们就可以获取了,如下
<form action="#" method="POST"> Username:<br /> <input type="text" name="username"><br /> Password:<br /> <input type="password" AUTOCOMPLETE="off" name="password"><br /> <br /> <input type="submit" value="Login" name="Login"> <input type=‘hidden‘ name=‘user_token‘ value=‘f7733a69e0bd2f43c9ab3f1c48d49b84‘ /> </form>
然后开始写python脚本吧