任意文件讀取和上傳
任意文件讀取
任意文件讀取,也可以稱為任意文件下載或文件包含(File Inclusion),指的是代碼中沒有對參數進行嚴格限制,導致攻擊者可以通過目錄穿越或修改讀取的文件名從而達到讀取任意文件的目的
危害
- 配置文件泄露:攻擊者通過任意文件讀取漏洞查看配置文件,從而獲取數據庫連接等相關的敏感信息;也可以讀取業務代碼,造成源碼泄露
- 執行shell命令:攻擊者首先可以通過任意文件上傳的漏洞,將包含惡意代碼的文件上傳到服務器的某處,然后通過任意文件讀取的漏洞來執行該文件
存在位置
- 通常具有附件、文檔或圖片等資源,涉及到文件讀取或下載的地方可能會存在這個漏洞
在Java中,存在任意文件讀取漏洞的代碼大概如下:
String fileName = request.getParameter("fileName"); String path = "/tmp/"; File file = new File(path + fileName);
在這串代碼中,由於沒有校驗從請求中獲取的參數fileName,如果fileName的值是
../../../../etc/passwd
,在new File(path + fileName)
時會對參數路徑計算,就會導致多個../
穿越到了根目錄下,然后便會讀取到/etc/passwd
的值
防御手段
- 在使用前端傳遞過來的參數前,首先對參數進行校驗,去掉參數值中包含的
../
,從而防止目錄穿越 - 上傳的文件名以隨機數的形式存放在文件夾內,實際的文件名則存放於數據庫中。這樣攻擊者無法得知具體的文件名是什么,從而無法讀取文件
例1
-
此處以靶場pikachu為例
-
該處存在文件讀取的漏洞,在選擇某項后點擊submit query按鈕,並使用burp抓包
-
修改filename的值為另一個文件名
file2.php
,然后發包,可以看到顯示的內容變成了新文件的內容(原本是科比)
造成這個漏洞的原因是文件在存儲時沒有使用隨機數命名文件,因此攻擊者可以輕易的猜出文件名並讀取它
例2
-
此處以靶場DVWA為例,級別為low
-
點擊file1.php,並抓包
-
將page參數修改為payload:
../../../../../../../../../../../../../etc/passwd
后發包(注意../
一定要足夠多,否則穿越不到根目錄,從而導致文件讀取失敗) -
在頁面中可以看到
passwd
的內容造成該漏洞是因為代碼中沒有過濾掉
../
導致可以路徑穿越,從而讀取了任意路徑下的文件
任意文件上傳
任意文件上傳(File upload),指繞過代碼中對上傳文件的檢查,從而達到上傳任意類型文件,甚至上傳到任意的位置。它配合任意文件讀取漏洞可以實現遠程命令執行,甚至getshell
危害
- GetShell
- 上傳木馬文件,導致服務癱瘓
防御手段
- 根據繞過的方式來指定白名單,校驗上傳文件的類型
- 過濾
../
,防止目錄穿越 - 對上傳文件的內容進行校驗
繞過姿勢
前端JS校驗
- 繞過JS校驗可以先將文件后綴名修改為符合格式的文件后綴,然后上傳后抓包再修改回來,從而繞過
代碼校驗
-
截斷繞過。通過
%00, 0x00, \x00
等截斷繞過,比如test,php%00.jpg
-
雙后綴名繞過。比如
test.php.jpg
-
切換大小寫繞過。比如
test.PHp
-
.htaccess繞過。PHP環境可以通過上傳
.htaccess
繞過-
.htaccess
文件時Apache服務器中的一個配置文件,它負責相關目錄下的網頁配置。通過.htaccess
文件,可以幫我們實現自定義文件解析方式(改變擴展名),比如<FileMatch "dd"> SetHandler application/x-httpd-php </FileMatch>
當遇到文件名中有dd的文件時,便會以php的形式來進行解析該文件(無論后綴名是什么)。如果不加
<FileMatch>
則表示所有文件都按照php形式來解析。上傳成功后,本地新建一個text.php,里邊寫入php的payload,然后將后綴名改為符合格式的后綴並上傳,最后便可上傳成功 -
使用該方式繞過需要滿足以下兩個條件:
- mod_rewrite模塊開啟
- AllowOverrideAll
-
-
上傳特殊但可被解析的后綴繞過
- PHP:
.php, .php2, .php3, .php4, .php5, .php6, .php7, .phps, .phps, .pht, .phtm, .phtml, .pgif, .shtml, .htaccess, .phar, .inc
- ASP:
.asp, .aspx, .config, .ashx, .asmx, .aspq, .axd, .cshtm, .cshtml, .rem, .soap, .vbhtm, .vbhtml, .asa, .cer, .shtml
- Jsp:
.jsp, .jspx, .jsw, .jsv, .jspf, .wss, .do, .action
- Coldfusion:
.cfm, .cfml, .cfc, .dbm
- **Flash: **
.swf
- Perl:
.pl, .cgi
- Erlang Yaws Web Server:
.yaws
- PHP:
-
特殊字符繞過。在文件名最后增加特殊的字符,比如:
%20, %0a, %00, %0d%0a, /, .\, .
-
::$DATA繞過。在windows環境下,可以使用NTFS文件系統的特性來實現繞過。NTFS文件系統中支持備用數據流,它允許文件中包含多個數據流,而每個文件都至少包含一個數據流。如果在文件名后添加
::$data
,則:
號及之后的內容會被windows作為數據流而不是文件名,從而實現繞過文件名的校驗 -
MIME繞過。有的代碼會在客戶端校驗
content-type
來實現上傳文件類型的檢查,因此在上傳文件時便可將content-type
修改,從而繞過檢查 -
使用圖片木馬。圖片木馬是指在一張圖片后增加一串payload,比如增加了php的payload,上傳成功后便可通過php環境解析該文件,從而執行payload。圖片木馬制作方式如下:
-
windows環境。
-
准備一張圖片(1.jpg)和一個包含payload的php文件(a.php)
-
然后在該文件夾中打開cmd,執行代碼:
copy 1.jpg/b+a.php/a 2.jpg
。(jpg后邊的b表示二進制文件,php后邊的a表示ASCII碼文件) -
使用文本打開生成的2.jpg,在最后即可看到payload
-
-
linux環境。
-
同樣的准備,執行命令:
cat 1.png a.php > 2.jpg
-
打開文件即可在末尾看到
-
-
-
有的地方上傳了壓縮包,上傳后會將壓縮包內的文件放在目錄里。此時便可將含有payload的文件放在壓縮包里上傳到服務器
例子
(隨便舉個)
-
使用pikachu靶場,准備一個php文件(a.php),包含代碼
<?php phpinfo() ?>
,並將后綴名改為.jpg
-
上傳a.jpg,並抓包
-
將filename修改為繞過的名字后上傳
-
根據地址即可訪問到