SQL注入 labs练习
Less 17
这一关是update注入。
update语句: update users(表名)set passwd(字段)= $_POST['passwd'](闭合方式未知)where uname(字段)= $_POST['uname'] (闭合方式未知);
对于update语句在User Name和New Password两处均可注入,但由于成功不会返回有用信息无法使用联合注入,可以考虑报错注入,延时注入,不能使用布尔注入。
第一步,判断闭合方式
在uname=admin1后加‘失败
在passwd=admin1后加‘成功,由此可以判断闭合方式是单引号闭合。判断闭合方式一般还是比较麻烦的,但原理简单就不过多讲了。
问题:为什么这里New Password可以注入而User Name不能注入呢?
通过查看17关的源码我们可以发现,作者使用了check_input($_POST['uname']);并强调这使得uname不能注入
我们先学习一下这个函数
mysql注入的两个重要条件是1. 注入语句不会被过滤 2.注入语句不会发生转义
在这个check_input()函数中,首先通过substr()函数限制密码最大长度为15,超过就会被截取舍弃,然后判断转义是否开启(当转义开启即get_magic_quotes_gpc()=on时get_magic_quotes_gpc()返回1,
同时通过stripslashes()函数去掉反斜杠。然后通过crype_digit()函数检查是不是十进制数,是则返回true,不是则返回false,可以看到在输入不是十进制的情况下,也会通过mysql_real_escape_string()函数过滤。
以上字符会受到影响,最后通过intval()函数转换为整数,进行数据类型转换,check_input()可以被视作是作者编写的安全过滤函数,通过各种过滤转义避免了sql注入的发生,但究竟是不是绝对安全的杜绝了sql注入,
由于水平有限无法回答,但至少避免了绝大部分的sql注入。
问题2 为什么不能布尔注入
先查看user表数据
然后执行一下SQL语句,发现虽然逻辑错误但是依旧显示语句成功执行
再次查看users表发现数据并没有改变,因为语句并没有执行但显示成功执行
如果是1=1呢?
虽然不能进行布尔注入但是还是能进行延时注入,由于无法直观显示就不展示了,可以自己尝试一下。
第二步,报错注入
通过updatexml语句成功爆出数据库名字,修改(select database())也能爆出其他信息,这里也不一一显示了
常用报错语句
1. union select 1,count(*),concat(0x7e,(查询语句),0x7e,floor(rand(0)*2))x from information_schema.columns group by x --+
2. and extractvalue(1,concat(0x7e,(查询语句),0x7e) --+
3. and updatexml(1,concat(0x7e,(查询语句),0x7e),1)
这三款最常用,也比较方便记忆。