PHP
Serializacja
Szukaj…
Składnia
- serializacja ciągów (mieszana wartość $)
Parametry
Parametr | Detale |
---|---|
wartość | Wartość do serializacji. serialize () obsługuje wszystkie typy, z wyjątkiem typu zasobu . Możesz nawet serializować () tablice, które zawierają odniesienia do siebie. Zapamiętywane będą również odwołania cykliczne w tablicy / obiekcie, który szeregujesz. Wszelkie inne odniesienia zostaną utracone. Podczas serializowania obiektów PHP spróbuje wywołać funkcję członka __sleep () przed serializacją. Ma to na celu umożliwienie obiektowi czyszczenia w ostatniej chwili itp. Przed serializacją. Podobnie, gdy obiekt jest odtwarzany za pomocą unserialize (), wywoływana jest funkcja elementu __wakeup () . Prywatni członkowie obiektu mają nazwę klasy dodaną do nazwy członka; członkowie chronieni mają znak „*” dodany do nazwy członka. Te poprzedzone wartości mają po każdej stronie bajty zerowe. |
Uwagi
Serializacja wykorzystuje następujące struktury ciągów:
[..]
są symbolami zastępczymi.
Rodzaj | Struktura |
---|---|
Strunowy | s:[size of string]:[value] |
Liczba całkowita | i:[value] |
Podwójnie | d:[value] |
Boolean | b:[value (true = 1 and false = 0)] |
Zero | N |
Obiekt | O:[object name size]:[object name]:[object size]:{[property name string definition]:[property value definition];(repeated for each property)} |
Szyk | a:[size of array]:{[key definition];[value definition];(repeated for each key value pair)} |
Serializacja różnych typów
Generuje przechowalną reprezentację wartości.
Jest to przydatne do przechowywania lub przekazywania wartości PHP bez utraty ich typu i struktury.
Aby ponownie przekształcić szeregowany ciąg w wartość PHP, użyj unserialize () .
Serializacja ciągu
$string = "Hello world";
echo serialize($string);
// Output:
// s:11:"Hello world";
Serializacja podwójnego
$double = 1.5;
echo serialize($double);
// Output:
// d:1.5;
Serializacja liczby zmiennoprzecinkowej
Float jest szeregowany jako podwójny.
Serializacja liczby całkowitej
$integer = 65;
echo serialize($integer);
// Output:
// i:65;
Serializacja wartości logicznej
$boolean = true;
echo serialize($boolean);
// Output:
// b:1;
$boolean = false;
echo serialize($boolean);
// Output:
// b:0;
Serializacja null
$null = null;
echo serialize($null);
// Output:
// N;
Serializacja tablicy
$array = array(
25,
'String',
'Array'=> ['Multi Dimension','Array'],
'boolean'=> true,
'Object'=>$obj, // $obj from above Example
null,
3.445
);
// This will throw Fatal Error
// $array['function'] = function() { return "function"; };
echo serialize($array);
// Output:
// a:7:{i:0;i:25;i:1;s:6:"String";s:5:"Array";a:2:{i:0;s:15:"Multi Dimension";i:1;s:5:"Array";}s:7:"boolean";b:1;s:6:"Object";O:3:"abc":1:{s:1:"i";i:1;}i:2;N;i:3;d:3.4449999999999998;}
Serializacja obiektu
Możesz także serializować Obiekty.
Podczas serializowania obiektów PHP spróbuje wywołać funkcję członka __sleep () przed serializacją. Ma to na celu umożliwienie obiektowi czyszczenia w ostatniej chwili itp. Przed serializacją. Podobnie, gdy obiekt jest odtwarzany za pomocą unserialize (), wywoływana jest funkcja elementu __wakeup () .
class abc {
var $i = 1;
function foo() {
return 'hello world';
}
}
$object = new abc();
echo serialize($object);
// Output:
// O:3:"abc":1:{s:1:"i";i:1;}
Pamiętaj, że zamknięć nie można serializować:
$function = function () { echo 'Hello World!'; };
$function(); // prints "hello!"
$serializedResult = serialize($function); // Fatal error: Uncaught exception 'Exception' with message 'Serialization of 'Closure' is not allowed'
Kwestie bezpieczeństwa z unserialize
Użycie funkcji unserialize
do usunięcia danych z danych wprowadzonych przez użytkownika może być niebezpieczne.
Ostrzeżenie od php.net
Ostrzeżenie Nie należy przekazywać niezaufanych danych wejściowych użytkownika do unserialize (). Unserializacja może spowodować załadowanie i wykonanie kodu ze względu na tworzenie instancji obiektu i automatyczne ładowanie, a złośliwy użytkownik może to wykorzystać. Użyj bezpiecznego, standardowego formatu wymiany danych, takiego jak JSON (przez json_decode () i json_encode ()), jeśli chcesz przekazać dane szeregowe użytkownikowi.
Możliwe ataki
- Zastrzykiwanie obiektów PHP
Zastrzykiwanie obiektów PHP
PHP Object Injection to luka na poziomie aplikacji, która może umożliwić atakującemu przeprowadzenie różnego rodzaju złośliwych ataków, takich jak wstrzyknięcie kodu, wstrzyknięcie SQL, przejście ścieżki i odmowa usługi w zależności od kontekstu. Luka występuje, gdy dane wejściowe dostarczone przez użytkownika nie są odpowiednio odkażone przed przekazaniem ich do funkcji PHP unserialize (). Ponieważ PHP pozwala na serializację obiektów, osoby atakujące mogą przekazywać serializowane ciągi ad-hoc do podatnego wywołania unserialize (), co powoduje dowolne wstrzykiwanie obiektów PHP do zakresu aplikacji.
Aby z powodzeniem wykorzystać lukę PHP Object Injection, muszą być spełnione dwa warunki:
- Aplikacja musi mieć klasę, która implementuje magiczną metodę PHP (taką jak
__wakeup
lub__destruct
), której można użyć do przeprowadzenia złośliwych ataków lub uruchomienia „łańcucha POP”. - Wszystkie klasy używane podczas ataku muszą zostać zadeklarowane, gdy wywoływana jest wrażliwa funkcja
unserialize()
, w przeciwnym razie dla takich klas musi być obsługiwane automatyczne ładowanie obiektu.
Przykład 1 - Atak przemierzania ścieżki
Poniższy przykład pokazuje klasę PHP z __destruct
wykorzystania metodą __destruct
:
class Example1
{
public $cache_file;
function __construct()
{
// some PHP code...
}
function __destruct()
{
$file = "/var/www/cache/tmp/{$this->cache_file}";
if (file_exists($file)) @unlink($file);
}
}
// some PHP code...
$user_data = unserialize($_GET['data']);
// some PHP code...
W tym przykładzie osoba atakująca może usunąć dowolny plik za pomocą ataku Path Traversal, na przykład żądając następującego adresu URL:
http://testsite.com/vuln.php?data=O:8:"Example1":1:{s:10:"cache_file";s:15:"../../index.php";}
Przykład 2 - atak polegający na wstrzyknięciu kodu
Poniższy przykład pokazuje klasę PHP z możliwą do wykorzystania metodą __wakeup:
class Example2
{
private $hook;
function __construct()
{
// some PHP code...
}
function __wakeup()
{
if (isset($this->hook)) eval($this->hook);
}
}
// some PHP code...
$user_data = unserialize($_COOKIE['data']);
// some PHP code...
W tym przykładzie osoba atakująca może wykonać atak typu Injection, wysyłając żądanie HTTP w następujący sposób:
GET /vuln.php HTTP/1.0
Host: testsite.com
Cookie: data=O%3A8%3A%22Example2%22%3A1%3A%7Bs%3A14%3A%22%00Example2%00hook%22%3Bs%3A10%3A%22phpinfo%28%29%3B%22%3B%7D
Connection: close
Gdzie parametr cookie „data” został wygenerowany przez następujący skrypt:
class Example2
{
private $hook = "phpinfo();";
}
print urlencode(serialize(new Example2));