Websec level 30


前言

昨天在易霖博搞的網絡安全與執法競賽看到的一道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 30

payload:

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


免責聲明!

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



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