수색…
통사론
- 문자열 serialize (혼합 $ 값)
매개 변수
매개 변수 | 세부 |
---|---|
값 | 직렬화되는 값입니다. serialize () 는 리소스 유형을 제외한 모든 유형을 처리합니다. 자체에 대한 참조를 포함하는 배열을 직렬화 할 수도 있습니다. 직렬화하는 배열 / 객체 내부의 순환 참조도 저장됩니다. 다른 참조는 없어집니다. 객체를 직렬화 할 때 PHP는 직렬화 이전에 멤버 함수 __sleep () 을 호출하려고 시도합니다. 이것은 객체가 직렬화되기 전에 마지막 순간 정화 작업을 수행 할 수 있도록하기위한 것입니다. 마찬가지로 unserialize ()를 사용하여 객체를 복원하면 __wakeup () 멤버 함수가 호출됩니다. Object의 private 멤버는 멤버 이름 앞에 클래스 이름이 있습니다. 보호 된 회원은 회원 이름 앞에 '*'가 붙습니다. 이러한 prepended 값은 양쪽에 null 바이트를 갖습니다. |
비고
직렬화는 다음 문자열 구조를 사용합니다.
[..]
는 자리 표시 자입니다.
유형 | 구조 |
---|---|
끈 | s:[size of string]:[value] |
정수 | i:[value] |
더블 | d:[value] |
부울 | b:[value (true = 1 and false = 0)] |
없는 | N |
목적 | O:[object name size]:[object name]:[object size]:{[property name string definition]:[property value definition];(repeated for each property)} |
정렬 | a:[size of array]:{[key definition];[value definition];(repeated for each key value pair)} |
다른 유형의 직렬화
값의 저장 가능 표현을 생성합니다.
이것은 PHP의 값과 유형을 잃지 않고 저장하거나 전달할 때 유용합니다.
직렬화 된 문자열을 다시 PHP 값으로 만들려면 unserialize ()를 사용하십시오.
문자열 직렬화
$string = "Hello world";
echo serialize($string);
// Output:
// s:11:"Hello world";
이중 직렬화
$double = 1.5;
echo serialize($double);
// Output:
// d:1.5;
float 직렬화
플로트는 두 개로 직렬화됩니다.
정수의 직렬화
$integer = 65;
echo serialize($integer);
// Output:
// i:65;
boolean 직렬화
$boolean = true;
echo serialize($boolean);
// Output:
// b:1;
$boolean = false;
echo serialize($boolean);
// Output:
// b:0;
null를 직렬화한다
$null = null;
echo serialize($null);
// Output:
// N;
배열 직렬화
$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;}
객체 직렬화
객체를 직렬화 할 수도 있습니다.
객체를 직렬화 할 때 PHP는 직렬화 이전에 멤버 함수 __sleep () 을 호출하려고 시도합니다. 이것은 객체가 직렬화되기 전에 마지막 순간 정화 작업을 수행 할 수 있도록하기위한 것입니다. 마찬가지로 unserialize ()를 사용하여 객체를 복원하면 __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;}
클로저는 직렬화 할 수 없습니다.
$function = function () { echo 'Hello World!'; };
$function(); // prints "hello!"
$serializedResult = serialize($function); // Fatal error: Uncaught exception 'Exception' with message 'Serialization of 'Closure' is not allowed'
비 직렬화와 관련된 보안 문제
unserialize
함수를 사용하여 사용자 입력에서 데이터를 병합 해제하면 위험 할 수 있습니다.
php.net의 경고
경고 untrusted 사용자 입력을 unserialize ()에 전달하지 마십시오. 비 직렬화는 객체 인스턴스화 및 자동 로딩으로 인해 코드가로드되고 실행될 수 있으며 악의적 인 사용자가이를 악용 할 수 있습니다. 직렬화 된 데이터를 사용자에게 전달해야하는 경우 JSON (json_decode () 및 json_encode ()를 통해)과 같은 안전하고 표준적인 데이터 교환 형식을 사용하십시오.
가능한 공격
- PHP 객체 삽입
PHP 객체 삽입
PHP Object Injection은 공격자가 상황에 따라 코드 삽입, SQL 삽입, 경로 통과 및 응용 프로그램 서비스 거부와 같은 다양한 종류의 악의적 인 공격을 수행 할 수있는 응용 프로그램 수준의 취약점입니다. 이 취약점은 unserialize () PHP 함수에 전달되기 전에 사용자가 입력 한 내용이 제대로 정리되지 않을 때 발생합니다. PHP는 객체 직렬화를 허용하기 때문에 공격자는 임시 직렬화 된 문자열을 취약한 unserialize () 호출에 전달할 수 있으므로 응용 프로그램 범위에 임의의 PHP 객체를 주입 할 수 있습니다.
PHP Object Injection 취약점을 성공적으로 악용하려면 두 가지 조건이 충족되어야합니다.
- 응용 프로그램에는 악의적 인 공격을 수행하거나 "POP 체인"을 시작하는 데 사용할 수있는 PHP 마법 메서드 (예 :
__wakeup
또는__destruct
)를 구현하는 클래스가 있어야합니다. - 공격 중에 사용 된 모든 클래스는 취약한
unserialize()
가 호출 될 때 선언되어야합니다. 그렇지 않으면 객체 자동로드가 해당 클래스에 대해 지원되어야합니다.
예 1 - 경로 순회 공격
아래 예제는 악용 가능한 __destruct
메소드가있는 PHP 클래스를 보여줍니다.
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...
이 예에서 공격자는 Path Traversal 공격을 통해 임의의 파일을 삭제할 수 있습니다 (예 : 다음 URL 요청).
http://testsite.com/vuln.php?data=O:8:"Example1":1:{s:10:"cache_file";s:15:"../../index.php";}
예 2 - 코드 삽입 공격
아래 예제는 악용 가능한 __wakeup 메소드가있는 PHP 클래스를 보여줍니다.
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...
이 예에서 공격자는 다음과 같이 HTTP 요청을 전송하여 코드 삽입 공격을 수행 할 수 있습니다.
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
쿠키 매개 변수 "data"가 다음 스크립트에 의해 생성 된 위치 :
class Example2
{
private $hook = "phpinfo();";
}
print urlencode(serialize(new Example2));