當前位置:首頁 » 編程語言 » php源碼審計

php源碼審計

發布時間: 2025-03-09 06:41:17

A. [紅日安全]代碼審計Day2 - filter_var函數缺陷

本文由紅日安全成員:七月火 編寫,如有不當,還望斧正。

前言

大家好,我們是紅日安全-代碼審計小組。最近我們小組正在做一個php代碼審計的項目,供大家學習交流,我們給這個項目起了一個名字叫PHP-Audit-Labs。現在大家所看到的系列文章,屬於項目第一階段的內容,本階段的內容題目均來自PHP SECURITY CALENDAR 2017。對於每一道題目,我們均給出對應的分析,並結合實際CMS進行解說。在文章的最後,我們還會留一道CTF題目,供大家練習,希望大家喜歡。下面是第二篇代碼審計文章:

Day 2 - Twig

題目叫做Twig,代碼如下:

漏洞解析

這一關題目實際上用的是PHP的一個模板引擎Twig,本題考察XSS(跨站腳本攻擊)漏洞。雖然題目代碼分別用了escape和filter_var兩個過濾方法,但是還是可以被攻擊者繞過。在上圖第8行中,程序使用Twig模板引擎定義的escape過濾器來過濾link,而實際上這里的escape過濾器,是用PHP內置函數htmlspecialchars來實現的,具體可以點擊這里了解escape過濾器,htmlspecialchars函數定義如下:

htmlspecialchars:(PHP 4, PHP 5, PHP 7) 功能:將特殊字元轉換為HTML實體 定義:string htmlspecialchars(string$string,[int$flags = ENT_COMPAT | ENT_HTML401,[string$encoding = ini_get("default_charset"),[bool$double_encode = TRUE]])

第二處過濾在第17行,這里用了filter_var函數來過濾nextSlide變數,且用了FILTER_VALIDATE_URL過濾器來判斷是否是一個合法的url,具體的filter_var定義如下:

filter_var:(PHP 5 >= 5.2.0, PHP 7) 功能:使用特定的過濾器過濾一個變數定義:mixed filter_var(mixed$variable,[int$filter = FILTER_DEFAULT,[mixed$options]])

針對這兩處的過濾,我們可以考慮使用javascript偽協議來繞過。為了讓大家更好理解,請看下面的demo代碼:
我們使用payload:?url=javascript://comment%0aalert(1),可以執行alert函數:
實際上,這里的//在JavaScript中表示單行注釋,所以後面的內容均為注釋,那為什麼會執行alert函數呢?那是因為我們這里用了字元%0a,該字元為換行符,所以alert語句與注釋符//就不在同一行,就能執行。當然,這里我們要對%百分號編碼成%25,因為程序將瀏覽器發來的payload:javascript://comment%250aalert(1)先解碼成:javascript://comment%0aalert(1)存儲在變數$url中(上圖第二行代碼),然後用戶點擊a標簽鏈接就會觸發alert函數。
實例分析

本次實例分析,我們選取的是Anchor 0.9.2版本,在該版本中,當用戶訪問一個不存在的URL鏈接時,程序會調用404模板,而這個模板則存在XSS漏洞,具體代碼如下:

該代碼在themes\default\404.php中,看第4行code標簽中的current_url函數,我們可在anchor\functions\helpers.php文件中,看到current_url函數是由Uri類的current方法實現的,具體代碼如下:
我們跟進到Uri類,在system\uri.php文件中,我們發現這里調用了static::detect方法(statci::是在PHP5.3版本之後引入的延遲靜態綁定寫法)。
在current方法下面,我們就可以找到detect方法,該方法會獲取$_SERVER數組中的'REQUEST_URI'、'PATH_INFO'、'ORIG_PATH_INFO'三個鍵的值(下圖第3-4行代碼),如果存在其中的某一個鍵,並且符合filter_var($uri, FILTER_SANITIZE_URL)和parse_url($uri, PHP_URL_PATH),則直接將$uri傳入static::format方法(下圖第10-14行代碼),具體代碼如下:
我們跟進static::format方法,可以發現程序過濾了三次(下圖第3-7行),但是都沒有針對XSS攻擊進行過濾,只是為了獲取用戶訪問的文件名,具體代碼如下:
由於沒有針對XSS攻擊進行過濾,導致攻擊十分容易,我們來看看XSS攻擊具體是如何進行的。
漏洞利用

我們構造payload如下:http://localhost/anchor/index.php/。根據上面的分析,當我們訪問這個並不存在的鏈接時,程序會調用404模板頁面,然後調用current_url函數來獲取當前用戶訪問的文件名,也就是最後一個/符號後面的內容,所以最終payload里的部分會嵌入到 標簽中,造成XSS攻擊,效果圖如下:

修復建議

這對XSS漏洞,我們最好就是過濾關鍵詞,將特殊字元進行HTML實體編碼替換,這里給出的修復代碼為Dedecms中防禦XSS的方法,大家可以在uploads/include/helpers/filter.helper.php路徑下找到對應代碼,具體防護代碼如下:

結語

看完了上述分析,不知道大家是否對filter_var函數繞過有了更加深入的理解,文中用到的CMS可以從這里下載,當然文中若有不當之處,還望各位斧正。如果你對我們的項目感興趣,歡迎發送郵件到[email protected]聯系我們。Day2的分析文章就到這里,我們最後留了一道CTF題目給大家練手,題目如下:

題解我們會階段性放出,如果大家有什麼好的解法,可以在文章底下留言,祝大家玩的愉快!

相關文章

Anchor CMS 0.9.2: XSS

B. PHP代碼審計-sprintf函數中的安全問題

在PHP代碼審計中,對sprintf函數的安全問題進行探討。sprintf與vsprintf相似,都是用於格式化字元串輸出,但vsprintf在傳參時使用數組,其餘行為與sprintf相同。需要注意的是,sprintf具有自動類型轉換功能。當格式與輸入數據類型不匹配時,sprintf會自動截斷輸入。這就導致程序員可能忽視對特定格式的強制類型轉換,使潛在危險的payload得以保留,最終可能引發安全問題,如WordPress SQL注入漏洞。

sprintf的format參數包含百分號%、美元符號$和單引號'。百分號用於識別格式模式的開始,後面的數字對應參數輸入數據;美元符號和單引號開啟padding模式,使用$'後的字元填充;長度參數規定輸入數據長度,不足時使用填充字元;類型參數s表示字元串,d表示整數。在使用單引號時,為了正確處理字元串中的單引號,需要進行轉義。

在不加$的情況下,單引號會被吞噬,無法正常帶入參數。當同時存在$和單引號時,理解為開啟padding模式,單引號被吞掉,導致單引號逃逸。使用$'兩個字元的模式會吞掉單引號後面的兩個字元,同樣引發單引號溢出問題。

另一個值得關注的細節是,盡管%y格式無明確規定,但在sprintf中使用%y並不會報錯,而是輸出空值。這使得利用這一特性吞噬反轉義符成為可能。

總結,除了寬位元組問題和substr問題,了解如何通過格式化字元串吞噬單引號的技巧對於安全審計工作至關重要。在CMS系統不斷成熟、資料庫操作日趨規范的背景下,這些安全問題的識別和防範對於確保系統的安全性具有重要意義。

熱點內容
python怎麼注釋多行 發布:2025-03-09 19:28:15 瀏覽:427
sql轉換函數to 發布:2025-03-09 19:18:03 瀏覽:636
sql查詢的藝術 發布:2025-03-09 19:17:30 瀏覽:899
怎麼在伺服器上修改ip 發布:2025-03-09 19:17:21 瀏覽:868
linux限制連接數 發布:2025-03-09 19:17:21 瀏覽:186
水密碼洗面奶怎麼樣 發布:2025-03-09 19:16:01 瀏覽:645
合金彈頭加密版 發布:2025-03-09 19:11:49 瀏覽:723
房屋解壓手續流程 發布:2025-03-09 18:56:50 瀏覽:1001
怎麼切換python版本 發布:2025-03-09 18:52:43 瀏覽:556
php與mysql權威指南pdf 發布:2025-03-09 18:46:14 瀏覽:661