ctf.show 萌新模块 web4关,这一关考察的是 intval()函数转换字符串的特性,以及SQL注入漏洞的绕过方式,源码中过滤了or,加减乘除(+-*/),左右移,括号,|,select等关键字,我们使用短路逻辑或(||)来替替代 or 即可
页面中展示了部分源码,提示我们 id=1000 时,即可获取flag
首先分析一下思路,源码中过滤了参数中的 or - / * < > ! ( ) + select 等关键字,所以我们的参数中不能包含这些关键字,否则会直接 die;而后intval()函数会将参数转换成整数,我们可以利用特殊则字符( 逻辑或 ||)来绕过intval()函数的转换;最后就是控制SQL语句查询 id=1000 时的flag;构造payload如下
?id=2 || id = 1000
intval()函数在转换整数时,如果被转换的是字符串,则会从最左边第一个字符开始转换,直到遇到非整数的字符才会停止转换
我们构造的参数,被后端通过get请求获取后,拿到的是一个字符串 ‘2 || id = 1000’
这个字符串被intval() 函数转换后的结果是 2 (因为字符 | 是非整数的字符,所以会停止转换), 2 > 999 if 判断返回false, 从而进入else中执行SQL语句
我们构造的参数拼接到SQL中,会变成下面这个样子
select * from article where id = 2 || id = 1000 order by id limit 1
id=1 时的查询结果
id=2时的查询结果
id=1时正常查询结果,而 id=2 时查询结果为空,也就是说,id=2没有对应的信息
SQL会查询 id=2 或者 id=1000的信息,由于 id=2 时,没有返回的信息,所以这里只会返回 id=1000 时的信息,从而获取flag