文件處理相關問題
概述:
在有些Web應用中,外界能夠通過傳入參數的形式來指定服務器中的文件名。比如由外界參數來指定模板文件的情況。這樣的Web應用可能會招致以下攻擊。
- 非法訪問Web服務器內的文件(目錄遍歷)
- 調用OS命令(OS命令注入)
目錄遍歷漏洞:
Web應用中允許外界以參數的形式來指定服務器上的文件名時,如果沒有對文件名進行充分的校驗 ,就可能會造成意料之外的問題,比如文件被瀏覽、篡改或刪除。該安全隱患被稱爲目錄遍歷漏洞。
目錄遍歷漏洞會造成以下影響。
-
瀏覽Web服務器中的文件
泄露重要信息
-
篡改或刪除Web服務器中的文件。
篡改網頁內容,散佈謠言或惡意誹謗他人
佈下圈套將用戶誘導至惡意網站
刪除腳本文件或配置文件導致服務器宕機
通過篡改腳本文件從而在服務器上執行任意腳本。
目錄遍歷漏洞的防範策略如下,執行其中一項即可。
- 避免由外界指定文件名
- 文件名中南不予許包含目錄名
- 限定文件名中僅包含字母和數字
目標遍歷漏洞總覽:
產生地點:
- 能夠由外界指定文件名的頁面。
影響範圍:
- 所有頁面。
影響類型:
- 泄露隱私信息、篡改或刪除信息、執行任意腳本、使應用停止服務
影響程度:
- 大
用戶參與程度:
- 不需要
對策概要:
執行其中一項即可。
- 避免由外界指定文件名
- 文件名中南不予許包含目錄名
- 限定文件名中僅包含字母和數字
安全隱患產生的原因:
當應用滿足一下3個條件時,就有可能產生目錄遍歷漏洞。
- 外界能夠指定文件名
- 能夠使用絕對路徑或相對路徑等形式來指定其他目錄的文件名。
- 沒有校驗是否允許訪問拼接後的文件名
如果從開發着的角度來考慮的話,漏洞產生的可能原因是因爲開發者沒有考慮到“外界能夠指定其他目錄”的可能性。
由於目錄遍歷漏洞的產生需要同時滿足以上3個條件,因此,只要使其中任意一項無法滿足也就能夠將漏洞消除。
防禦措施:
避免由外界指定文件名:
如果能避免文件名由外界指定,就能從根本上解決目錄遍歷漏洞。具體方法右如下幾種。
- 將文件名固定
- 將文件名保存在會話變量中
- 不直接指定文件名,而是使用編號等方法間接指定。
文件名中不允許包含目錄名:
如果文件名中不包括目錄名(包括…/)就能確保應用中只能訪問給定目錄中的文件,從而也就消除了目錄遍歷漏洞產生的可能性。
表示目錄的字符/ 、 \ : 等因操作系統而異,不同的操作系統應當採用不同的程序庫。在PHP中南則能夠使用basename函數。
basename函數會接收帶有目錄的文件名(也包括Windows的盤符),並返回末尾的文件名部分。例如basename(’…/…/…/etc/hosts’)返回的結果即爲hosts。
限定文件名中僅包含字母和數字:
如果能夠限定文件名的字符種類僅爲字母和數字,那麼用於目錄遍歷攻擊的字符就會無法使用,因此這個方法也能作爲目錄遍歷的防範策略。
<?php
define('TMPLDIR', '/var/www/html/web');
$templ = $_GET['template'];
if(!preg_match(/\A[a-z0-9]+\.html\z/ui', $tmpl)){
die('<h3>template僅僅能指定數字和字母</h3>')
}
?>
<?php readfile(TMPLDIR . $tmple); ?>
總結對策:
實施以下任一一項
- 避免由外界指定文件名
- 文件名中不允許包含目錄名
- 限定文件名中僅包含字母和數字
內部文件被公開
概述:
Web服務器的公開目錄中有時會放置對外保密的文件。這種情況下,外界一旦得知文件的URL,就能夠瀏覽這些內部文件。
內部文件被公開會造成如下影響。
- 重要信息被泄露。
防範內部文件被公開的對策爲,不在公開目錄中放置內部文件。或者保險起見,也可以直接禁用目錄列表功能。
在httpd.conf文件中:
Options Include ExecCGI FollowSymLinks Indexes
安全隱患的產生原因:
導致內部文件被公開的原因爲,內部文件被放在了公開目錄中。當應用滿足一下條件時,放置在公開目錄下的文件就能被外界訪問。
- 文件被放置在公開目錄中
- 有方法得知訪問文件的URL
- 沒有對文件設置訪問權限
其中,得知訪問文件的URL的手段有如下幾種:
- 目錄列表功能被設爲有效
- 文件名爲日期、用戶名或連續數值等能夠被推測的值
- user.dat、data.txt等常見文件名
- 通過錯誤消息或其他安全隱患而得知文件名
- 被外部網絡鏈接進而被搜索引擎收錄
文件上傳相關問題
概要:
針對文件上傳功能的攻擊類型有如下幾種:
- 針對上傳功能的DoS攻擊
- 上傳的文件在服務器上作爲腳本執行。
- 誘使用戶下載惡意文件。
防範策略:
防範DoS攻擊:
防範DoS攻擊的一種有效策略爲限制上傳文件的容量。PHP能夠在php.ini中設置上傳功能的容量限制。下表中列出了與文件上傳相關的配置項。建議在滿足應用需求的前提下禁令將值設置的小一些。如果應用不提供文件上傳功能,那麼只需要將file_uploads設置爲Off即可。
設置項目名 | 解說 | 默認值 |
---|---|---|
file_uploads | 是否允許使用文件上傳功能 | On |
upload_max_filesize | 單個文件的最大容量 | 2MB |
max_file_uploads | 單詞請求最大文件上傳個數 | 20 |
post_max_size | POST請求正文的最大限制 | 8MB |
memory_limit | 腳本所能申請到的最大內存值 | 128MB |
通過上傳文件使服務器執行腳本:
有些文件上傳處理會將用戶上傳的文件保存至Web服務器的公開目錄中。這時,如果應用中允許上傳文件的擴展名爲php、asp、aspx、jsp等腳本文件的擴展名,用戶就能在服務器上將啥概念車的文件作爲腳本執行。
如果外界傳入的腳本在服務器上被執行,就會造成與OS命令注入同樣的影響,具體如下:
- 瀏覽、篡改或刪除Web服務器內的文件。
- 對外發送郵件
- 攻擊其他服務器(稱爲墊腳石)
爲了防範通過上傳文件而在服務器上執行腳本,可以綜合實施以下兩種方法,或者實施其中的任意一種。
- 不將用戶上傳的文件保存在公開目錄中,瀏覽文件需要通過腳本。
- 將文件的擴展名限定爲不可執行的腳本文件。
<?php
define('UPLOADPATH', '/var/uplaod');
function get_upload_file_name($tofile){
$info = pathinfo($tofile);
$ext = strtolower($info['extension']);
if($ext != 'png' && $ext != 'jpg' && $ext != 'gif'){
die('只能上傳擴展名爲gif,jpg,png的圖像文件');
}
//下面的處理爲生成唯一的文件名
$count = 0;//嘗試生成文件名的次數
do{
$file = sprintf('%s%08x.%s', UPLOADPATH, mt_rand(), $ext);
$fp = @fopen($file, 'x');
}wihle($fp === FALSE && ++$count < 10);
if($fp === FALSE){
die('無法生成文件');
}
fclose($fp);
return $file;
}
學習過程中筆記的記錄與資料整理。