Websec level 30

前言php

昨天在易霖博搞的網絡安全與執法競賽看到的一道web題,實際上就是用兩個原題湊起來的。。git

不事後面的一關沒見過這裏簡單記錄一下github

第一關web

打開是個登陸界面,和BJDCTF的簡單注入如出一轍,連密碼都同樣。。數組

第二關瀏覽器

登陸後獲得安全

網絡

<?php
ini_set('display_errors', 1);
error_reporting(E_ALL);

include 'flag.php'; //defines $flag

class B {
  function __destruct() {//當一個對象銷燬時被調用或者腳本結束時調用
    global $flag;
    echo $flag;
  }
}

if (isset($_POST['payload'])) {
    ob_start();//打開輸出緩衝區,全部的輸出信息不在直接發送到瀏覽器,而是保存在輸出緩衝區裏面,可選得回調函數用於處理輸出結果信息。 
    $a = unserialize($_POST['payload']);
    if ($a === False) {
        ob_end_clean();//清空(擦除)緩衝區並關閉輸出緩衝
    }
    throw new Exception('Something tragic happened');//拋出一個錯誤
}
?>

仍是原題 Websec level 30app

payload:ide

a:2:{i:0;O:1:"B":0:{}i:0;i:1;}

詳細能夠參考:
[https://kangwoosun.github.io/webhacking/2020/03/28/Websec/]
[https://www.evonide.com/breaking-phps-garbage-collection-and-unserialize/#comments]
[https://www.evonide.com/fuzzing-unserialize/]

如下是我的的淺薄理解
若是傳入一個序列化的數組,而且這個數組中存在兩個或多個key相等的變量,那麼反序列化的時侯將刪除首先輸入的變量。所以,若是將類 B 對象做爲value冗餘,則將調用析構函數,而不會致使反序列化錯誤,即先解析 O:1:"B":0:{} 生成一個對象,而後在向後解析又遇到 i:0 因而將前一個 i:0 的值改成1,就至關於消滅了以前生成的對象因而觸發__destruct函數,以後也是冗餘的關係使得反序列化的結果返回的是 array(0=>1) ,不爲False,因而不會進入到ob_end_clean(),最後輸出flag

這題若是直接傳入

O:1:"B":0:{}

是不會輸出flag,由於雖然這樣反序列化獲得的a是一個對象不等於False,可是以後會經過throw new 拋出一個錯誤,它這裏的拋出錯誤就相似於下了一個斷點同樣,使得腳本程序的運行中止在了這裏,並無結束,因此反序列化後的B對象仍然存在,不會觸發__destruct

相關文章
相關標籤/搜索