upload-labs通關筆記-第12關 文件上傳之白名單GET法

目錄

一、白名單過濾

二、%00截斷

1、%00截斷原理

2、空字符

3、截斷條件

(1)PHP版本 < 5.3.4

(2)magic_quotes_gpc配置為Off

(3)代碼邏輯存在缺陷

三、源碼分析

1、代碼審計

(1)文件存儲依賴字符串截斷

(2)路徑拼接可控

2、攻擊思路

四、滲透實戰

1、構建腳本test12.jpg

2、配置php服務

(1)安裝php5.3.4以下的php版本

(2)切換php5.3.4以下的php版本

(3)關閉magic_quotes_gpc配置

(4)重啟Apache服務

3、打開靶場

4、bp開啟攔截

5、點擊上傳

6、bp攔截

7、GET參數增加test12.php%00

8、發包并獲取腳本地址

10、訪問腳本


本文通過《upload-labs靶場通關筆記系列》來進行upload-labs靶場的滲透實戰,本文講解upload-labs靶場第12關白名單GET法滲透實戰。

一、白名單過濾

在文件上傳功能中,白名單過濾的核心思想是"只允許明確許可的,其他一律禁止",這與黑名單的"禁止已知危險的"形成鮮明對比。文件上傳白名單過濾是一種嚴格的安全機制,它通過預先定義一組允許上傳的文件擴展名(如jpg、png、pdf等),系統僅接受符合白名單的文件類型,其他所有類型一律拒絕。相比黑名單過濾,白名單采用"默認禁止"原則,從根本上杜絕了攻擊者通過雙寫、大小寫變異、特殊擴展名等手法繞過防御的可能性,顯著提高了安全性。黑名單過濾方法和白名單的過濾方法的區別具體如下圖所示。

對比維度白名單機制黑名單機制
安全原則只允許明確許可的文件類型(默認拒絕所有)僅禁止已知危險文件類型(默認允許所有)
安全性★★★★★(難以繞過)★★☆☆☆(易被雙寫/大小寫等手法繞過)
典型實現in_array(strtolower(ext), ['jpg','png'])

str_ireplace(['php','jsp'], "", filename)

in_array(strtolower(ext), ['php','phtml'])

維護成本需隨業務需求更新白名單需持續追蹤新增危險擴展名
防御效果能防御未知攻擊類型僅能防御已知攻擊類型
常見繞過方式很難繞過雙寫(.pphphp)、大小寫(.PhP)、空字節等
適用場景嚴格管控的穩定業務(如頭像上傳)需支持動態擴展名的特殊場景

二、%00截斷

1、%00截斷原理

%00截斷是一種利用字符串處理特性和編程語言安全性風險的攻擊手段,%00截斷的原理如下:

  • 字符編碼與字符串結束符:在許多編程語言中,\0(在 URL 編碼中表示為%00)被用作字符串的結束符。當程序處理字符串時,遇到\0就會認為字符串在此處結束。
  • 文件名或路徑處理安全問題:如果程序在處理文件名或文件路徑時,沒有對用戶輸入進行嚴格的過濾和驗證,就可能導致%00截斷攻擊。例如,攻擊者上傳一個名為test12.php%00.jpg的文件,程序在拼接文件保存路徑時,可能會將%00之后的內容截斷,實際保存的文件路徑就變成了test12.php,從而繞過了文件類型檢查等安全機制。

2、空字符

在很多編程語言中,字符串是以字符數組的形式存儲的,并且以\0(ASCII 碼值為 0)作為字符串的結束標志。當程序對字符串進行處理時,遇到\0就會認為字符串到此結束。%00截斷主要利用的是 ASCII 碼為 0 的空字符\0(在 URL 中表示為%00)來實現字符串截斷,一般來說就是這一個特定字符起截斷作用。0x00,%00,/00之類的截斷,都是一樣的,只是不同表示而已。

字符ASCII 碼值十六進制表示URL 編碼表示作用
\000x00%00%00截斷攻擊中,用于截斷字符串,使服務器將其后面的字符忽略,從而達到繞過文件類型檢查等目的

3、截斷條件

(1)PHP版本 < 5.3.4

  • PHP 5.3.4之前:默認會解析%00(空字節)為字符串終止符,導致截斷。

  • PHP 5.3.4及之后:修復了%00自動截斷的問題,但仍需注意代碼邏輯缺陷。

(2)magic_quotes_gpc配置為Off

  • magic_quotes_gpc用于自動對來自GET、POST和COOKIE的數據進行轉義,在一些特殊字符(如單引號、雙引號、反斜杠和空字符等)前添加反斜杠\。其目的是防止 SQL 注入等攻擊,確保數據在數據庫操作中的安全性。
  • 當magic_quotes_gpc為Off時,對用戶輸入的數據不再進行自動轉義處理。這意味著攻擊者輸入的%00字符可以直接傳遞到程序中,而不會被轉義為\%00。如果程序在處理文件上傳或其他涉及字符串處理的功能時,沒有對%00進行額外的過濾,就更容易被利用來進行%00截斷攻擊。例如,在前面提到的文件上傳代碼中,如果magic_quotes_gpc為Off,攻擊者構造的evil.php%00.jpg文件名可以直接被程序接收,進而可能導致文件類型檢查被繞過。

(3)代碼邏輯存在缺陷

  • 未過濾%00:代碼直接使用$_FILES['file']['name']或用戶輸入拼接路徑,未做空字節過濾。

  • 未規范化路徑:未使用basename()realpath()等函數處理文件名,導致%00被保留。

三、源碼分析

1、代碼審計

對upload-labs 第12關的源碼進行審計,相對于第3-11關卡的黑名單過濾,本關卡變為了白名單過濾,僅允許文件后綴名為“jpg,png和gif”三種后綴的文件上傳,具體如下所示。

經過詳細注釋的代碼如下所示。

<?php
// 初始化變量,用于標記文件是否上傳成功,初始值為 false
$is_upload = false;
// 初始化變量,用于存儲上傳過程中的提示信息,初始值為 null
$msg = null;// 檢查是否通過 POST 方式提交了名為 submit 的表單數據
if(isset($_POST['submit'])){// 定義一個數組,包含允許上傳的文件擴展名$ext_arr = array('jpg','png','gif');// 獲取上傳文件的原始文件名,從最后一個點號(.)之后的部分作為文件擴展名$file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1);// 檢查獲取到的文件擴展名是否在允許上傳的擴展名數組中if(in_array($file_ext,$ext_arr)){// 獲取上傳文件在服務器臨時存儲的路徑$temp_file = $_FILES['upload_file']['tmp_name'];// 拼接上傳文件在目標目錄中的完整路徑// $_GET['save_path'] 從 URL 的 GET 參數中獲取保存路徑// rand(10, 99) 生成一個 10 到 99 之間的隨機數// date("YmdHis") 獲取當前的日期和時間,格式為年月日時分秒// 最后拼接上文件擴展名$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;// 嘗試將臨時文件移動到目標目錄if(move_uploaded_file($temp_file,$img_path)){// 如果移動成功,將 $is_upload 標記為 true$is_upload = true;} else {// 如果移動失敗,設置提示信息為上傳出錯$msg = '上傳出錯!';}} else{// 如果文件擴展名不在允許的列表中,設置提示信息為只允許上傳特定類型的文件$msg = "只允許上傳.jpg|.png|.gif類型文件!";}
}
?>

分析代碼可知存在的白名單%00截斷安全問題,具體原因如下所示。

(1)文件存儲依賴字符串截斷

文件存儲的過程使用了move_uploaded_file()這個C底層函數:PHP的文件操作函數(如move_uploaded_file()底層是C語言實現,會按\0截斷字符串。

(2)路徑拼接可控

攻擊者能控制文件保存路徑或文件名的一部分(如通過$_GET的save_path參數傳入)。?\0(在 URL 編碼中表示為?%00)被視為字符串的結束符。

此代碼在拼接文件保存路徑時,使用了?$_GET['save_path']?從 URL 的 GET 參數中獲取保存路徑,并且沒有對這個參數進行嚴格的過濾和驗證。

2、攻擊思路

在文件上傳功能中,如果程序只是簡單地通過檢查文件名的后綴來驗證文件類型,而沒有對整個文件名進行嚴格的安全檢查。假設上傳的圖片名為$_FILES['upload_file']['name']=test12.jpg,save_path為“../upload/”。

  • 攻擊者構造$_GET參數傳入的save_path包含腳本名與%00拼接的特殊文件名。

save_path:../upload/test12.php%00
  • 前端驗證看到的是".jpg"擴展名,file_ext為“jpg”,可以通過檢查

$_FILES['upload_file']['name']:test12.jpg
file_ext:jpg
  • 由于$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;得知圖片的路徑為“test12.php%00”與“/”和“rand(10, 99).date("YmdHis").”和".jpg"的結合。假設rand(10, 99).date("YmdHis")的輸出為8820250428,那么

save_path:../upload/test12.php%00
重命名后的圖片:8820250428.jpg
img_path:../upload/test12.php%00/8820250428.jpg
  • 后端move_uploaded_file()處理時,遇到%00即停止解析,實際存儲的文件名變為"test12.php"

img_path:../upload/test12.php

四、滲透實戰

1、構建腳本test12.jpg

注意此時文件的后綴為jpg,這是因為本關卡為白名單,故腳本的后綴需要與上傳允許的后綴“jpg,png和gif”中的任意一個保持一致。

<?php
phpinfo();
?>

2、配置php服務

需要將php版本號切換到5.3.4以下,具體步驟如下所示。

(1)安裝php5.3.4以下的php版本

如果當前phpstudy沒有安裝5.3.4以下的版本,需要安裝對應版本的php,如下所示。

(2)切換php5.3.4以下的php版本

網站——>管理——>php版本——>選擇php5.3.4以下的php版本,具體如下所示。

(3)關閉magic_quotes_gpc配置

打開phpstudy保存目錄——>選擇Extensions目錄——>php目錄——>選擇php5.2.17nts版本——>找到php.ini文件

將magic_quotes_gpc值修改為off,修改前如下所示。

將magic_quotes_gpc值修改為off,修改后如下所示。

(4)重啟Apache服務

修改后需要重啟小皮的Apache服務,具體如下所示。

3、打開靶場

?打開靶場第12關,瀏覽選擇該腳本,但不點擊上傳。

4、bp開啟攔截

5、點擊上傳

6、bp攔截

bp捕獲到上傳報文,下圖紅框的部分即為需要修改的部分。

這時候注意,雖然這個報文為POST報文,但是savepath確實在GET參數中,具體如下所示。

POST /upload-labs/Pass-12/index.php?save_path=../upload/ HTTP/1.1

由于需要將savepath的"save_path=../upload/"后綴改為"save_path=../upload/test12.php%00",修改之前文件名為"test12.php",如下所示。?

POST /upload-labs/Pass-12/index.php?save_path=../upload/test12.php%00 HTTP/1.1

7、GET參數增加test12.php%00

將save_path改為"../upload/test12.php%00",修改后效果如下所示。

8、發包并獲取腳本地址

將bp的inception設置為off,此時修改后的報文發送成功。

回到靶場的Pass12關卡,圖片已經上傳成功,在圖片處右鍵復制圖片地址。

右鍵圖片獲取圖片地址,如下所示獲取到圖片URL。

http://127.0.0.1/upload-labs/upload/test12.php /9620211121160947.jpg

但由于%00截斷,可將test12.php之后的內容截斷,因此上傳的腳本url地址變為:

http://127.0.0.1/upload-labs/upload/test12.php

以本實驗為例我們上傳文件時修改的文件名../upload/test12.php%00

上傳成功后的路徑和文件名為upload/test12.php /9620211121160947.jpg

很明顯圖片被上傳到upload目錄中且test12.php被重命名為test12.php /9620211121160947.jpg

但由于%00截斷,可將test12.php之后的內容截斷,所以最后得到的文件名為test12.php

10、訪問腳本

?如下所示訪問test12.php腳本獲取到服務器的php信息,證明文件上傳成功。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/906410.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/906410.shtml
英文地址,請注明出處:http://en.pswp.cn/news/906410.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Node.js數據抓取技術實戰示例

Node.js常用的庫有哪些呢&#xff1f;比如axios或者node-fetch用來發送HTTP請求&#xff0c;cheerio用來解析HTML&#xff0c;如果是動態網頁的話可能需要puppeteer這樣的無頭瀏覽器。這些工具的組合應該能滿足大部分需求。 然后&#xff0c;可能遇到的難點在哪里&#xff1f;…

數據結構(3)線性表-鏈表-單鏈表

我們學習過順序表時&#xff0c;一旦對頭部或中間的數據進行處理&#xff0c;由于物理結構的連續性&#xff0c;為了不覆蓋&#xff0c;都得移&#xff0c;就導致時間復雜度為O&#xff08;n&#xff09;&#xff0c;還有一個潛在的問題就是擴容&#xff0c;假如我們擴容前是10…

【Unity】DOTween的常用函數解釋

DOTween插件常用函數解釋 1.DOTween.To&#xff08;通用變化動畫&#xff09; 解釋&#xff1a;將某一個值在一定的時間內變化到另一個值&#xff08;通用的函數&#xff09;&#xff0c;可用于大部分的動畫變化 使用示例&#xff1a; using UnityEngine; using DG.Tweenin…

數據結構測試模擬題(1)

1、約瑟夫問題 #include<bits/stdc.h> using namespace std; const int N25; int e[N],ne[N],head-1,idx1; int n,m; void add_to_head(int x){e[idx]x;ne[idx]head;headidx; } void add(int k,int x){e[idx]x;ne[idx]ne[k];ne[k]idx; } int main(){cin>>n>>…

Helm配置之為特定Deployment配置特定Docker倉庫(覆蓋全局配置)

文章目錄 Helm配置之為特定Deployment配置特定Docker倉庫(覆蓋全局配置)需求方法1:使用Helm覆蓋值方法2: 在Lens中臨時修改Deployment配置步驟 1: 創建 Docker Registry Secret步驟 2: 在 Deployment 中引用 Secret參考資料Helm配置之為特定Deployment配置特定Docker倉庫(覆…

BERT 作為Transformer的Encoder 為什么采用可學習的位置編碼

摘要 BERT 在位置編碼上與原始 Transformer 論文中的 sin/cos 公式不同&#xff0c;選擇了可學習&#xff08;learned&#xff09;的位置嵌入方案。本文將從 Transformer 原始位置編碼選項入手&#xff0c;分析 BERT 選擇 learned positional embeddings 的四大核心原因&#x…

【Linux 學習計劃】-- gcc、g++、動靜態庫鏈接

目錄 什么是gcc、g gcc、g 相關操作詳解 預處理、編譯、匯編、鏈接來源 動靜態鏈接是什么 結語 什么是gcc、g gcc、g其實就是編譯器&#xff0c;是幫助我們從.c或者.cc&#xff0c;.cpp文件編譯成可執行程序的 其中&#xff0c;我們如果要編譯c語言文件的話&#xff0c;…

前端讀取本地項目中 public/a.xlsx 文件中的數據 vue3

前端讀取本地項目中 public/a.xlsx 文件中的數據 vue3 項目中需要在 Vue3 項目中讀取 public/a.xlsx 文件&#xff0c;可以使用 fetch API 來獲取文件內容 一、安裝 xlsx 首先&#xff0c;你需要安裝 xlsx 庫&#xff1a; npm install xlsx二、在需要用的頁面里引入xlsx im…

MySQL:to many connections連接數過多

當你遇到 MySQL: Too many connections 錯誤時&#xff0c;意味著當前連接數已達到 MySQL 配置的最大限制。這通常是由于并發連接過多或連接未正確關閉導致的。 一、查看當前連接數 查看 MySQL 當前允許的最大連接數 SHOW VARIABLES LIKE max_connections;查看當前使用的最大…

2024年熱門AI趨勢及回顧

人工智能的崛起 2024 年可能會被銘記為人工智能不再是一種技術新奇事物&#xff0c;而是成為現實的一年。微軟、Salesforce 和 Intuit 等巨頭將人工智能融入主流企業解決方案&#xff1b;從文案寫作到數據分析&#xff0c;專門的人工智能應用程序和服務如雨后春筍般涌現&#…

LangFlow技術深度解析:可視化編排LangChain應用的新范式 -(2)流編輯器系統

Flow Editor System | langflow-ai/langflow | DeepWiki 流編輯器系統 相關源文件 流編輯器系統是 Langflow 的核心交互式組件&#xff0c;允許用戶直觀地創建、編輯和管理 LLM 驅動的應用程序。它提供了一個直觀的畫布&#xff0c;用戶可以在其中添加節點、將其與邊緣連接并…

驅動-定時-秒-字符設備

文章目錄 目的相關資料參考實驗驅動程序-timer_dev.c編譯文件-Makefile測試程序-timer.c分析 加載驅動-運行測試程序總結 目的 通過定時器timer_list、字符設備、規避競爭關系-原子操作&#xff0c;綜合運用 實現一個程序&#xff0c;加深之前知識的理解。 實現字符設備驅動框…

[Java實戰]Spring Boot整合Kafka:高吞吐量消息系統實戰(二十七)

[Java實戰]Spring Boot整合Kafka&#xff1a;高吞吐量消息系統實戰&#xff08;二十七&#xff09; 一、引言 Apache Kafka作為一款高吞吐量、低延遲的分布式消息隊列系統&#xff0c;廣泛應用于實時數據處理、日志收集和事件驅動架構。結合Spring Boot的自動化配置能力&…

Kotlin Multiplatform--04:經驗總結(持續更新)

Kotlin Multiplatform--04&#xff1a;經驗總結&#xff08;持續更新&#xff09; 引言 引言 本章用來記載筆者開發過程中的一些經驗總結 一、Ktor設置Header 在官方文檔中&#xff0c;想要設置Header的示例代碼如下&#xff1a; client.get("https://ktor.io&qu…

在 Ubuntu 系統中,將 JAR 包安裝為服務

在 Ubuntu 系統中&#xff0c;將 JAR 包安裝為服務可以通過 systemd 來實現。以下是詳細的操作步驟&#xff1a; 準備工作 確保 JAR 文件路徑和 Java 運行時環境已準備好。驗證 Java 是否可用&#xff1a; java -version創建 systemd 服務文件 systemd 的服務文件通常位于 …

電商項目-商品微服務-品牌管理微服務開發

一、功能分析 品牌管理微服務包括&#xff1a; &#xff08;1&#xff09;查詢全部列表數據 &#xff08;2&#xff09;根據ID查詢實體數據 &#xff08;3&#xff09;增加 &#xff08;4&#xff09;修改 &#xff08;5&#xff09;刪除 &#xff08;6&#xff09;分頁…

Spring Boot開發—— 整合Lucene構建輕量級毫秒級響應的全文檢索引擎

文章目錄 一、為什么選擇 Lucene?輕量級搜索的底層密碼二、核心原理:Lucene 的倒排索引2.1 倒排索引:速度之源2.2 段合并優化策略三、Spring Boot集成Lucene實戰3.1 依賴配置3.2 實體與索引設計3.3 核心索引服務(含異常處理)3.4 使用示例(測試類)四、高級優化技巧4.1 索…

SpringBootDay1|面試題

目錄 一、springboot框架 1、什么是springboot 2、Spring Boot的主要優點 3、springboot核心注解 4、定義banner&#xff08;springboot的logo&#xff09; 5、springboot配置文件 6、springboot 整合 jdbc 二、面試題 1&#xff09;springmvc的作用 ?編輯 2&#x…

jQuery Ajax中dataType 和 content-type 參數的作用詳解

jQuery Ajax中dataType與contentType參數解析 一、核心概念對比 參數作用對象數據類型默認值dataType響應數據預期接收的數據格式jQuery自動判斷&#xff08;根據響應頭MIME類型&#xff09;contentType請求數據發送數據的編碼格式application/x-www-form-urlencoded 二、da…

幾款常用的虛擬串口模擬器

幾款常用的虛擬串口模擬器&#xff08;Virtual Serial Port Emulator&#xff09;&#xff0c;適用于 Windows 系統&#xff0c;可用于開發和調試串口通信應用&#xff1a; 1. com0com (開源免費) 特點&#xff1a; 完全開源免費&#xff0c;無功能限制。 可創建多個虛擬串口…