1. 程式人生 > 其它 >PHP檔案包含與phpinfo

PHP檔案包含與phpinfo

多版本通行

0x00 漏洞概述

當遇到PHP檔案包含漏洞時,如果找不到可以包含的檔案,可以通過包含臨時檔案來GetShell。由於臨時檔案的檔名是隨機的,如果目標網站存在phpinfo,則可以通過phpinfo來獲取臨時檔名,進而完成包含。

0x01 漏洞原理

在給PHP伺服器POST資料包時,如果資料包含有檔案區塊,無論訪問路徑的程式碼是否具有處理檔案上傳的邏輯,PHP都會將這個區塊(檔案)儲存為一個臨時檔案,通常位於/tmp/php[6個隨機字元]。檔名可以在$_FILES變數中找到。該臨時檔案會在請求結束後被刪除。

因為phpinfo會將當前請求的上下文全部打印出來,所以如果向phpinfo頁面傳送包含檔案區塊的資料包,則可以在返回包找到$_FILES

變數的內容,自然也包含臨時檔名。

實際情況下,檔案包含漏洞和phpinfo通常來自於兩個頁面,理論上需要先發送給phpinfo頁面,然後從返回包得到臨時檔名,再將這個檔名傳送給檔案包含漏洞頁面,進行GetShell。在第一個請求結束時,臨時檔案就被刪除了,第二個請求自然無法完成檔案包含。

此時需要用到條件競爭:

  1. 傳送包含webshell的上傳資料到phpinfo頁面,這個資料包的header、get等位置充滿了垃圾資料。
  2. 因為phpinfo頁面會將所有資料打印出來,垃圾資料會將整個phpinfo頁面過分填充。
  3. PHP預設的輸出緩衝區大小為4096,可理解為PHP每次返回4096個位元組給socket連線。直接操作原生socket,每次讀取4096個位元組,只要讀取到的字元裡包含臨時檔名,就立即傳送第二個資料包。
  4. 此時第一個資料包的socket連線還未結束,因為PHP還在繼續每次輸出4096個位元組,所以臨時檔案此時還未被刪除。
  5. 利用時間差完成包含臨時檔案,最終GetShell。

0x02 環境搭建

建立一個Docker專案,Apache部分直接依靠拉取,只需要編寫三個檔案。

執行

docker-compose up -d

等待完成即可。

~/docker-compose.yml

version: '2'
services:
 php:
   image: php:7.2-apache
   volumes:
    - ./www:/var/www/html
   ports:
    - "8080:80"

~/www/lfi.php

即檔案包含漏洞所在地。

<?php
include $_GET['file'];

~/www/phpinfo.php

<?php
phpinfo();

0x03 利用流程

訪問靶機

根目錄為403。通過目錄掃描等途徑可得/phpinfo.php和/lfi.php。

訪問/lfi.php,從報錯資訊可知服務端系統Linux、網站路徑、include函式。

由於不知道lfi.php所接受的引數名稱,需要爆破一下。

得到引數名為file

EXP

使用優質EXP,需要Python2。

因為已知網站路徑/var/www/html/,所以可以在Payload處做一點自定義(同時注意檔案包含路徑和phpinfo路徑是否正確):

執行:

python exp.py 192.168.31.39 8080 100

連線

剛才自定了Payload中的檔案路徑,所以訪問網站根目錄的cmd.php即可。

大功告成!