índice
Instância de desserialização de matriz
Exemplos de objetos desserializados
Instância de serialização de array
Instância de serialização de objeto
Análise de formato de string serializado
A diferença entre público, privado e protegido após a serialização
Princípio de vulnerabilidade de desserialização
O que é serialização php?
As duas funções usadas
serialize() //函数用于序列化对象或数组,并返回一个字符串。
unserialize() //函数用于将通过 serialize() 函数序列化后的对象或数组进行反序列化,并返回原始的对象结构。
serialize () instance
Instância de serialização de array
Após serializar um conjunto de matrizes, obtenha uma string de strings
<?php
highlight_file(__FILE__);
$a = array('a' => 'Apple' ,'b' => 'banana' , 'c' => 'Coconut');
$s = serialize($a);
echo $s;
//a:3:{s:1:"a";s:5:"Apple";s:1:"b";s:6:"banana";s:1:"c";s:7:"Coconut";}
?>
Instância de serialização de objeto
Depois de serializar um objeto, obtenha uma string de strings
<?php
highlight_file(__FILE__);
class test_class{ //创建类
var $test = '123'; //在类中新建一个test变量
}
$class1 = new test_class; //创建对象
$class_str = serialize($class1);//序列化对象
echo $class_str;//输出序列化后的字符串
//O:10:"test_class":1:{s:4:"test";s:3:"123";}
?>
instância unserialize ()
Instância de desserialização de matriz
Desserialize uma string serializada em um formato padrão e você obterá a seguinte matriz
<?php
highlight_file(__FILE__);
$str = 'a:3:{s:1:"a";s:5:"Apple";s:1:"b";s:6:"banana";s:1:"c";s:7:"Coconut";} ';
$un_str=unserialize($str);
var_dump($un_str);
?>
Instância de desserialização de objeto
Desserialize uma string serializada em um formato padrão para obter um novo objeto
<?php
highlight_file(__FILE__);
$str = 'O:10:"test_class":1:{s:4:"test";s:3:"123";}';
$un_str=unserialize($str);
var_dump($un_str);
?>
Análise de formato de string serializado
O: 10: "test_class" : 1 : {s: 4 : "teste" ; s : 3 : "123" ;}
Objecto tipo: comprimento nome de classe : nome de classe: número de variáveis na classe : {variável: variável comprimento nome: nome da variável; tipo variável : comprimento variável conteúdo : conteúdo variável }
a: 3 : {s: 1 : "a" ; s : 5 : "Maçã" ; s: 1: "b"; s: 6: "banana"; s: 1: "c"; s: 7: "Coco";}
Tipo de matriz: número de matrizes : {variável: variável comprimento do nome : nome da variável ; tipo de variável : comprimento de conteúdo variável : conteúdo variável ; ...}
- Existem dois tipos de serialização:
- Tipo de objeto
- Tipo de matriz
- Pode-se ver que nas chaves, dois pontos e vírgulas (;) formam um grupo, e os dois pontos e vírgulas representam o conteúdo de uma variável.
- {s: 4 : "teste" ; s : 3 : "123" ;}
Tipo de variável
Diferentes tipos de armazenamento serão convertidos em diferentes letras após a serialização
a - array b - boolean
d - double i - integer
o - common object r - reference
s - string C - custom object
O - class N - null
R - pointer reference U - unicode string
A diferença entre público, privado e protegido após a serialização
- Público (público): pode ser acessado dentro desta classe, classes externas e subclasses
- Privado (privado): disponível apenas dentro desta classe
- Protegido (protegido): apenas esta classe ou subclasse ou pai pode acessar
Após serializar de acordo com os 3 modificadores acima, os seguintes resultados são obtidos:
O: 10: "test_class": 3: {
s: 6: "teste_1"; s: 3: "str";
s: 18: "test_classtest_3"; i: 123;
s: 9: "* teste_2"; i: 123;
}
- público: basicamente nenhuma mudança após a serialização
- privado: Após a serialização, o nome da classe será adicionado ao nome da variável, e o comprimento do nome da variável também aumentará
- protegido: Após a serialização, haverá um * extra antes do nome da variável, mas por que o comprimento do nome da variável torna-se 9 bytes?
- Na verdade, quando o atributo protegido é serializado, o formato é% 00 *% 00 nome do membro
Método mágico
Ao usar a desserialização do PHP, geralmente é necessário usar o método mágico na desserialização para verificar se há operações confidenciais no método.
O PHP reserva todos os métodos de classe começando com __ (dois sublinhados) como métodos mágicos.
Métodos de magia comuns
__construct()//创建对象时触发
__destruct() //对象被销毁时触发
__call() //在对象上下文中调用不可访问的方法时触发
__callStatic() //在静态上下文中调用不可访问的方法时触发
__get() //用于从不可访问的属性读取数据
__set() //用于将数据写入不可访问的属性
__isset() //在不可访问的属性上调用isset()或empty()触发
__unset() //在不可访问的属性上使用unset()时触发
__invoke() //当脚本尝试将对象调用为函数时触发
__sleep() //此功能可以用于清理对象,并返回一个包含对象中所有应被序列化的变量名称的数组。
__wakeup() //经常用在反序列化操作中,例如重新建立数据库连接,或执行其它初始化操作。
documento oficial do método mágico php
Exemplo de chamada de método
__dormir()
A função serialize () verifica se há um método mágico __sleep () na classe. Se existir, o método será chamado primeiro, antes que a operação de serialização seja executada. Esta função pode ser usada para limpar o objeto e retornar um array contendo os nomes de todas as variáveis no objeto que devem ser serializadas. Se o método não retornar nada, NULL será serializado e um erro de nível E_NOTICE será gerado.
__acorde()
unserialize () irá verificar se existe um método __wakeup (). Se existir, o método __wakeup será chamado primeiro para preparar os recursos necessários para o objeto com antecedência.
__para sequenciar()
O método __toString () é usado para responder quando uma classe é tratada como uma string. Por exemplo echo $ obj; o que deve ser exibido. Este método deve retornar uma string, caso contrário, um erro fatal do nível E_RECOVERABLE_ERROR será emitido.
Princípio de vulnerabilidade de desserialização
Quando os parâmetros de desserialização unserialize () são controláveis, podemos construir uma string serializada para modificar as variáveis internas e até funções do objeto.
Caso:
<?php
error_reporting(0);
show_source(__FILE__);
class c{
public $str = 111;
function __wakeup(){
echo $this->str;
}
}
$str = $_GET['str'];
if (isset($str)){
unserialize($str);
}
?>
Quando podemos controlar a desserialização, seremos capazes de modificar o conteúdo das variáveis na classe
poc
?str=O:1:"c":1:{s:3:"str";s:3:"123";}
Claro que não é tão simples, apenas modifique o conteúdo do valor, também podemos digitar xss
poc
?str=O:1:"c":1:{s:3:"str";s:24:"<script>alert()</script>";}
Claro, este é apenas um caso simples, explicarei o conhecimento avançado de desserialização de php na próxima vez.