亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > PHP > 正文

如何防范用戶上傳PHP可執行文件(附示例)

2020-03-22 19:59:00
字體:
來源:轉載
供稿:網友
本篇文章給大家帶來的內容是關于如何防范用戶上傳PHP可執行文件,有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。

每個專業的 PHP 開發者都知道用戶上傳的文件都是極其危險的。不論是后端和前端的黑客都可以利用它們搞事情。

大約在一個月前,我在 reddit 上看了一篇 PHP 上傳漏洞檢測 ,因此, 我決定寫一篇文章。用戶 darpernter 問了一個棘手的問題:

盡管我將其重命名為 helloworld.txt , 攻擊者是否仍然能夠運行他的php 腳本?

置頂的答復是:

如果文件后綴修改為 .txt ,那么它不會被當做php文件執行,這樣你安心了吧,不過再三確保不是 .php.txt 的后綴上傳。

不好意思,問題的正確答案并非如此 . 雖然上面的答復并非全部錯誤,但顯然不全面。讓人驚訝的是,大多數的答案都非常相似。

我想解釋清楚這個問題。所以我要討論的東西變得有點大,我決定讓它變得更大。

問題

人們允許用戶上傳文件,但是擔心用戶上傳的文件在服務器上被執行。

從 php 文件如何被執行開始看。假設一個有 php 環境的服務器,那么它通常有兩種方法在外部執行 php 文件。一是直接用 URL 請求文件,像 http://example.com/somefile.php 。第二種是 php 現在常用的,將所有請求轉發到 index.php ,并在這個文件中以某種方式引入其他文件。所以,從 php 文件中運行代碼有兩種方式:執行文件或用 include/include_once/require/require_once 的方法引入其他需要運行的文件。

其實還有第三種方法:eval() 函數。它能將傳入的字符串當做 php 代碼執行。這個函數在大多數 CMS 系統中被用來執行存儲在數據庫里的代碼。eval() 函數非常危險,但如果你用了它,通常就意味著你確認自己在做危險的操作,并確認你已經沒有其他選擇。實際上, eval() 有它的用途,并且在某些情況下非常有用。但如果你是新手的話,我不推薦你使用它。請看 這篇在 OWASP 的文章。我在上面寫了很多。

所以,有兩種方法執行文件里的代碼:直接執行或者在被執行的文件中引入它。那么如何避免這種事情發生呢?

解決方法?

我們怎樣才能知道一個文件包含 php 代碼呢?看拓展名,如果以 .php 結尾的,像 somefile.php 我們就認為它里面有 php 代碼。

如果在網站根目錄下有一個 somefile.php 文件,那么在瀏覽器訪問 http://example.com/somefile.php ,這個文件就會被執行并且輸出內容到瀏覽器上。

但是如果我重命名這個文件會怎樣?如果我把它重命名為 somefile.txt 或者是 somefile.jpg 呢?我會得到什么?我會得到它的內容。它不會被執行。它會從硬盤(或者緩存)直接被發送過來。

在這點上 reddit 社區上的答案是對的。重命名能防止一個文件被非預期的執行,那么為什么我認為這種解決方法是錯的呢?

我相信你注意到我在 “解決方法” 后面加的問號。這個問號是有意義的?,F在大多數網站的 URL 上幾乎看不到單獨的 php 文件。并且就算有,也是人為故意偽造的,因為 URL 上需要有 .php 來實現對老版本 URL 的向后兼容。

現在絕大部分 php 代碼是在運行中被引入的,因為所有請求都被發送到了網站根目錄的 index.php。這個文件會根據特定的規則引入其他 php 文件。這種規則可能(或者在將來會)被惡意使用。如果你應用的規則允許引入用戶的文件,那么應用會容易遭到攻擊,你應該立即采取措施防止用戶的文件被執行。

如何防止引入用戶上傳的文件?

重命名文件名可以嗎??---?不,辦不到!

PHP解析器不關心文件的后綴名。事實上,所有程序都不關心。雙擊文件,文件會被對應的程序打開。文件后綴名只是幫助操作系統識別用什么程序打開文件。只要程序有讀取文件的能力,程序就可以打開任何文件。有時程序拒絕打開和操作文件。但那并不是因為后綴名,是文件內容所致。

服務器通常被設置成執行 .php 文件并將執行結果回復輸出。如果你請求圖片 .jpg ?---?將從磁盤上原樣的返回。如果你要求服務器以某種方式運行一張 jpeg 圖片,會發生?服務器會執行還是不呢?

程序不關心文件名。甚至不關心文件是否有名字,也不關心它究竟是不是文件。

從文件執行PHP代碼需要什么?

有至少兩個情況可以讓PHP執行代碼:

代碼介于 ?php 和 ? 標記之間

代碼介于 ?= 和 ? 標記之間

即使文件中填充了一些奇怪的二進制數據或一些奇怪的保護名稱,該標記中的代碼仍然會被執行。

1838082011-5c3d36ea782cd_articlex.png

該圖片沒有問題

它現在很純凈。但是您可能知道 JPEG 格式允許在文件中添加一些注釋。比如,拍攝照片的相機型號或坐標地址。如果我們試圖在里面放一些PHP代碼并嘗試 include 或 require 呢?讓我們來看看吧!

問題! 1

下載這個圖片到你的硬盤上?;蛘吣阕约喝ヅ粡?JPEG 圖片也行。你隨便用什么格式的文件都無所謂。我建議用一個 JPEG 文件來演示,主要是因為它是一張圖片且易于在其中進行文本編輯。我用的是一個 Windows的筆記本,目前我手頭上沒有 Apple 或 Linux(或其他UNIX系的系統)的筆記本。所以一會我會發一個這個 OS 下的屏幕快照。但是我確信你肯定也能做這個事。

用以下這段 PHP 代碼建個文件:

 h1 Problem? /h1  img src= troll-face.jpg  ?phpinclude ./troll-face.jpg 

保存一個圖片命名為troll-face.jpg

把圖片和 php 腳本文件都放在同一個文件夾下

打開瀏覽器請求這個 php 文件

如果你把你的 php 文件命名為 index.php,然后把它放在文件根目錄或者放在你網站目錄下的任何一個文件目錄中。

如果你準確完成了上述步驟,你就可以看到這個畫面:

2351909572-5c3d36ea7f4d7_articlex.png

到此這都沒毛病。沒 PHP 代碼展示,也沒有 PHP 代碼被執行。

現在,我們來添加一個問題:

打開文件屬性對話框或運行一些允許編輯 EXIF 信息的html' target='_blank'>應用程序

切換到 Details 選項卡或以其他方式編輯該信息

向下滾動到 camera 參數

將下面代碼復制到 “camera maker” 字段后面:

 ?php echo h2 Yep, a problem! /h2 phpinfo(); ? 

3615874909-5c3d36ea8b11f_articlex.png

刷新頁面!

1095134251-5c3d36ea98c51_articlex.png

很明顯出現了一點問題!

您在頁面上看到了該圖片。相同的圖片還存在頁面的 PHP 代碼中。圖片的代碼也被執行了。

我們該怎么做?!!1

長話短說: 如果我們不在程序種引入這些不安全的文件,文件中的腳本就不會執行。

仔細看下面的例子。

最終答案?

如果有人在某處看到我錯了 - 請糾正我,這是一個嚴重的問題。

PHP是一種腳本語言。您總是需要引用一些動態組合路徑的文件。因此,為了保護服務器,您必須檢查路徑并防止混淆您的站點文件和用戶上傳或創建的文件。如果用戶的文件與應用程序文件分開,則可以在使用上傳或創建文件之前檢查文件的路徑。如果它位于您的應用程序腳本允許的文件夾中 - 那么它可以使用 include_once 或 require 或 require_once 引入這個文件。如果不是--那么就不引入它。

如何進行檢查?這很簡單。你只需要將 $folder (文件)路徑與一個允許程序引入文件 ( $file ) 的路徑文件夾進行比較。

// 不好的例子,不要用!if (substr($file, 0, strlen($folder)) === $folder) { include $file;}

如果 $folder 的存放路徑是 /path/to/folder 而且 $file 的存放路徑是 /path/to/folder/and/file , 然后我們在代碼中使用 substr() 函數把他們的路徑都變成字負串進行判斷,如果文件位于不同的文件夾中---這個字符串將不相等。反之則反。

上面的代碼有兩個重要的問題。如果 file 路徑是 /path/to/folderABC/and/file,很明顯,該文件也不在允許引入的文件夾中。通過向兩個路徑添加斜杠可以防止這種情況。我們在這里向文件路徑添加斜杠并不重要,因為我們只需要比較兩個字符串。

舉個例子: 如果 folder 路徑是 /path/to/folder 并且 file 路徑是 /path/to/folder/and/file ,那么從 file 提取和 folder 具有相同數量的字符,那么 $ folder 將是 /path/to/folder 。

再比如 folder 路徑是 /path/to/folder 并且 file 路徑是 /path/to/folderABC/and/file, 那么從 file 中提取 folder 具有相同數量的字符,和 $folder一樣,并且將再次成為/path/to/folder,這種都是錯誤的,這不是我們期望的結果。

因此,在 /path/to/folder/ 添加斜杠后,與 /path/to/folder/and/file 的提取部分 /path/to/folder/ 相同就是安全的。

如果將 /path/to/folder/ 與 /path/to/folderABC/and/file 的提取部分 / path/to/folderA ,很明顯二個字符串不一樣。

這就是我們期望得到的。但還有另一個問題。這并不明顯。我敢肯定,如果我問你,你看到這里有一個災難性的漏洞 - 你不會猜到它在哪里。你也許已經在經驗中使用過這個東西,甚至可能就在今天?,F在,您將看到漏洞是如何隱晦和顯而易見。往下看。

/../

假想一個很常見的場景。

有這么一個網站。用戶可以上傳文件到該站點。所有的文件都位于一個特定的目錄下。有一個包含用戶文件的腳本。腳本自上而下進行查找是否包含用戶的輸入(直接或間接)路徑---那這個腳本可以通過如下方式進行路徑偽造:

/path/to/folder/../../../../../../../another/path/from/root/

舉例。用戶發起請求,你的腳本中包含了一個基于類似如下用戶輸入路徑的文件:

include $folder . / . $_GET[ some // or $_POST, or whatever

你麻煩大了。有天用戶發送一個 ../../../../../../etc/.passwd 這種或其他請求,你就哭吧。

再不然。假如有人讓你的腳本加載一個他想要的文件,你就廢了。它不一定就只是出現在用戶文件中。它可能是你的CMS或你自己文件的一些插件(別相信任何人),甚至是應用程序邏輯中的錯誤等。

或者

用戶可能會上傳一個名為 file.php 的文件,你會把它和其他的用戶文件一樣放在一個特定的文件夾里面:

move_uploaded_file($filename, $folder . / . $filename);

用戶的文件就存放在那里,你必須常常檢查從來沒有包含該文件夾中的文件,目前來看,所有的東西都挺正常的。通常,用戶發給你的文件不會包含斜杠或者其他特殊字符,因為這是被系統文件系統禁止的。之所以這樣,是因為通常情況下瀏覽器發給你的文件是在真實文件系統中創建的,同時它的名字是一些真實存在的文件的名字。

但是 http 請求允許用戶發送任何字符。所以如果某人偽造請求創建名為 ../../../../../../var/www/yoursite.com/index.php 的文件---這行代碼會覆蓋你的 index.php 文件,如果 index.php 處于在上述路徑的話。

所有的初學者都希望通過過濾 「..」或者斜杠來解決這個問題,但是這種做法是錯誤的,由于你在安全方面還缺乏經驗。同時你必須(是的,必須)明白一個簡單的事情:你永遠無法在安全和密碼學方面的獲得足夠的知識。這句話的意思是,如果你懂得了「兩個點和斜杠」的漏洞,但這不代表你知道所有其他的缺陷、攻擊和其他特殊字符,你也不知道在文件寫入文件系統或數據庫時可能發生的代碼轉換。

解決方案和答案

為了解決這個問題,PHP中內置了一些特殊函數方法,只是為了在這種情況下使用。

basename()

第一個解決方案?---?basename() 它從路徑結束時提取路徑的一部分,直到它遇到第一個斜杠,但忽略字符串末尾的斜杠,參見示例。無論如何,你會收到一個安全的文件名。如果你覺得安全 - 那么是的這很安全。如果它被不法上傳利用 - 你可以使用它來校驗文件名是否安全。

realpath()

另一個解決方案?---?realpath()它將上傳文件路徑轉換規范化的絕對路徑名,從根開始,并且根本不包含任何不安全因素。它甚至會將符號鏈接轉換為此符號鏈接指向的路徑。

因此,您可以使用這兩個函數來檢查上傳文件的路徑。要檢查這個文件路徑到底是否真正屬于此文件夾路徑。

我的代碼

我編寫了一個函數來提供如上的檢查。我并不是專家,所以風險請自行承擔。代碼如下。

 ?php * Example for the article at medium.com * Created by Igor Data. * User: igordata * Date: 2017-01-23 * @link https://medium.com/@igordata/php-running-jpg-as-php-or-how-to-prevent-execution-of-user-uploaded-files-6ff021897389 Read the article * 檢查某個路徑是否在指定文件夾內。若為真,返回此路徑,否則返回 false。 * @param String $path 被檢查的路徑 * @param String $folder 文件夾的路徑,$path 必須在此文件夾內 * @return bool|string 失敗返回 false,成功返回 $pathfunction checkPathIsInFolder($path, $folder) { if ($path === OR $path === null OR $path === false OR $folder === OR $folder === null OR $folder === false) { /* 不能使用 empty() 因為有可能像 0 這樣的字符串也是有效的路徑 */ return false; $folderRealpath = realpath($folder); $pathRealpath = realpath($path); if ($pathRealpath === false OR $folderRealpath === false) { // Some of paths is empty return false; $folderRealpath = rtrim($folderRealpath, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; $pathRealpath = rtrim($pathRealpath, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; if (strlen($pathRealpath) strlen($folderRealpath)) { // 文件路徑比文件夾路徑短,那么這個文件不可能在此文件夾內。 return false; if (substr($pathRealpath, 0, strlen($folderRealpath)) !== $folderRealpath) { // 文件夾的路徑不等于它必須位于的文件夾的路徑。 return false; // OK return $path;}

結語。

必須過濾用戶輸入,文件名也屬于用戶輸入,所以一定要檢查文件名。記得使用 basename() 。

必須檢查你想存放用戶文件的路徑,永遠不要將這個路徑和應用目錄混合在一起。文件路徑必須由某個文件夾的字符串路徑,以及 basename($filename) 組成。文件被寫入之前,一定要檢查最終組成的文件路徑。

在你引用某個文件前,必須檢查路徑,并且是嚴格檢查。

記得使用一些特殊的函數,因為你可能并不了解某些弱點或漏洞。

并且,很明顯,這與文件后綴或 mime-type 無關。JPEG 允許字符串存在于文件內,所以一張合法的 JPEG 圖片能夠同時包含合法的 PHP 腳本。

不要信任用戶。不要信任瀏覽器。構建似乎所有人都在提交病毒的后端。

當然,也不必害怕,這其實比看起來的簡單。只要記住 “不要信任用戶” 以及 “有功能解決此問題” 便可。

以上就是如何防范用戶上傳PHP可執行文件(附示例)的詳細內容,PHP教程

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产一区二区三区日韩欧美| 亚洲自拍小视频| 欧美亚洲在线观看| 91麻豆国产语对白在线观看| 精品无码久久久久久国产| 欧美亚洲国产精品| 97国产精品视频| 一区二区中文字幕| 麻豆国产精品va在线观看不卡| 亚洲第一福利网| 日韩精品极品在线观看| 丝袜美腿亚洲一区二区| 欧美综合激情网| 亚洲精品永久免费精品| 91影视免费在线观看| 欧美在线播放视频| 在线观看精品国产视频| 97碰碰碰免费色视频| 欧美性猛交xxxx偷拍洗澡| 97香蕉久久超级碰碰高清版| 中文字幕不卡在线视频极品| 91系列在线观看| 日韩av手机在线观看| 精品久久久久久久久国产字幕| 国产精品视频在线播放| 1769国内精品视频在线播放| 国产经典一区二区| 黑人巨大精品欧美一区二区一视频| 精品久久久久久久久久久久久久| 日韩美女在线播放| 欧美大人香蕉在线| 国产精品久久久久久久久久久新郎| 欧美日韩亚洲高清| 亚洲国产精品人人爽夜夜爽| 国产精品视频一| 欧美福利视频网站| 久久精品电影网| 97国产suv精品一区二区62| 日韩中文字幕在线看| 欧美激情国产日韩精品一区18| 亚洲综合一区二区不卡| 亚洲人成在线一二| 91人人爽人人爽人人精88v| 深夜精品寂寞黄网站在线观看| 欧美精品一本久久男人的天堂| 国内精品久久久久久久| 亚洲国产小视频| 国产精品久久久久久久久免费看| 亚洲va欧美va国产综合剧情| 亚洲精品一区久久久久久| 久久精品成人一区二区三区| www.欧美免费| 亚洲欧美三级在线| 亚洲国产小视频| 国产精品精品久久久| 欧美午夜片欧美片在线观看| 日韩免费中文字幕| 欧美激情亚洲国产| 日韩精品在线看| 欧美午夜片欧美片在线观看| 色噜噜久久综合伊人一本| 欧美亚洲国产另类| xxx成人少妇69| 九九精品在线观看| 日韩中文娱乐网| 亚洲欧美一区二区三区在线| 亚洲成人网在线观看| 欧美激情区在线播放| 久久香蕉频线观| 中文字幕日韩欧美在线| 亚洲高清色综合| 91国产美女在线观看| 狠狠躁夜夜躁人人爽超碰91| 亚洲美女精品成人在线视频| 日本伊人精品一区二区三区介绍| 影音先锋欧美在线资源| 亚洲一区二区三区四区在线播放| 性色av一区二区三区在线观看| 黑人巨大精品欧美一区二区一视频| 国产精品99蜜臀久久不卡二区| 日韩精品黄色网| 日韩高清人体午夜| 久久久国产成人精品| 青青久久av北条麻妃海外网| 亚洲精品资源美女情侣酒店| 最近中文字幕mv在线一区二区三区四区| 国产精品video| 亚洲摸下面视频| 久久免费国产精品1| 欧美精品久久久久久久久久| 精品亚洲国产成av人片传媒| 欧洲亚洲女同hd| 在线一区二区日韩| 欧美激情2020午夜免费观看| 日韩中文字幕网| 韩国三级电影久久久久久| 欧美精品在线免费观看| 日韩欧美国产视频| 日韩精品一区二区三区第95| 麻豆国产va免费精品高清在线| 亚洲男人av在线| 欧美精品18videosex性欧美| 亚洲高清不卡av| 亚洲毛茸茸少妇高潮呻吟| 欧美激情亚洲另类| 国产999精品久久久影片官网| 欧美午夜视频在线观看| 日本亚洲欧洲色| 2018国产精品视频| 成人女保姆的销魂服务| 91在线|亚洲| 国产精品视频专区| 精品综合久久久久久97| 中文字幕亚洲综合久久筱田步美| 亚洲老司机av| 中文国产成人精品| 久久久久国产一区二区三区| 成人激情视频免费在线| 成人性生交xxxxx网站| xxxxx成人.com| 国产suv精品一区二区| 亚洲国内精品视频| 日本成熟性欧美| 一区二区国产精品视频| 欧美精品videosex性欧美| 久久露脸国产精品| 中文字幕av一区中文字幕天堂| 欧美日韩在线视频首页| 国产精品久久综合av爱欲tv| 揄拍成人国产精品视频| 久久久999国产精品| 亚洲a在线播放| 亚洲精品视频二区| 91中文字幕在线| 一区二区三区久久精品| 欧美人在线观看| 成人精品在线视频| 亚洲欧美精品在线| 欧美日韩国产123| 欧美性视频精品| 日韩电影中文 亚洲精品乱码| 欧美极品美女电影一区| 欧美性猛交xxxx乱大交| 黑人狂躁日本妞一区二区三区| 色婷婷av一区二区三区久久| 91av网站在线播放| 黑丝美女久久久| 欧美激情手机在线视频| 日韩成人在线电影网| 久久精品国产亚洲| 日韩免费观看在线观看| 主播福利视频一区| 国产网站欧美日韩免费精品在线观看| 国产成人精品日本亚洲专区61| 中文字幕亚洲无线码在线一区| 亚洲国产天堂网精品网站| 成人免费在线视频网站| 精品久久久久久久久久久| 性欧美xxxx交| 亚洲综合日韩中文字幕v在线| 成人网址在线观看| 97在线视频免费| 亚洲美腿欧美激情另类| 欧美日本高清视频|