當我們看到phpinfo時在談論什么


我們在滲透測試的過程中,如果存在phpinfo界面,我們會想到什么?

大部分內容摘抄自:https://www.k0rz3n.com/2019/02/12/PHPINFO 中的重要信息/

關於phpinfo

PHP中提供了PHPInfo()函數,該函數返回 PHP 的所有信息,包括了 PHP 的編譯選項及擴充配置、PHP 版本、服務器信息及環境變量、PHP 環境變量、操作系統版本信息、路徑及環境變量配置、HTTP 標頭、及版權宣告等信息。

我們編寫test.php文件

<?php 
    phpinfo(); 
?>


很多PHP站點在測試搭建PHP環境是否正確后沒有及時刪除,這些敏感信息的泄露將會增大服務器被滲透的風險

敏感信息查看與利用

  • php版本信息

方便本地搭建環境,不同版本之間也參在函數參數和安全性機制的差異

  • 系統的版本信息
  • Loaded Configuration File(配置文件位置)
    php.ini的位置
  • Registered PHP Streams(支持的流)
    這個在文件包含,反序列化還有一些關鍵的bypass的時候非常有用
  • Registered Stream Filters(支持的流過濾器)
    這個同樣是在文件包含,反序列化還有一些關鍵的bypass的時候有用
  • allow_url_fopen & allow_url_include

文件包含必看選項之一,如果allow_url_fopenallow_url_include都為On的時候,則文件包含函數是可以加載遠程文件的,可以利用遠程文件包含漏洞直接執行任意命令。

攻擊者在自己的web服務器上放一個可執行的惡意文件,通過目標網站存在的遠程文件包含漏洞來加載文件,從而實現執行任意命令的目的

  • disable_functions
    命令執行,代碼執行必看選項之一。該指令可用於禁止某些函數,接收逗號分隔的函數名列表作為參數,通過bypass目標站點的disable_functions達成RCE

  • display_errors & display_startup_errors

調試過程中經常使用的錯誤提示在沒有關閉的情況下放入生產環境是不堪設想的

  • open_basedir

這個選項設置了文件讀取的時候的目錄限制,將用戶可操作的文件限制在某目錄下

但是這個限制是可以繞過的,之前P牛給出了繞過方法-PHP繞過open_basedir列目錄的研究

  • short_open_tag

判斷服務器是否支持短標簽,方便寫入shell

  • phar

文件包含還有反序列化重點關注,在文件系統函數 ( file_get_contents 、 unlink 等)參數可控的情況下,配合 phar://偽協議 ,可以不依賴反序列化函數 unserialize() 直接進行反序列化的操作

  • session
    查看session的相關配置,在文件包含和反序列化的時候有用

  • SERVER_ADDR

真實IP

  • _FILE["file"]

獲取臨時文件名字和路徑,本地文件包含GetShell

  • _SERVER["PATH"]

這是windows下特有的,能顯示出系統的所有環境變量

  • _SERVER["SCRIPT_FILENAME"]

找到網站的絕對路徑

  • Gopher

可以配合SSRF發起攻擊

  • Fastcgi

查看是否開啟Fastcgi和Fastcgi的版本,可能導致解析漏洞,遠程命令執行,任意文件讀取等問題

  • 支持的程序

可以通過phpinfo()查看一些特殊的程序服務,比如redismemcachemysqlSmtp,curl等等。如果服務器裝了redis或者memcache,可以嘗試尋找SSRF來getshell

檢測POC

基於pocsuite3的phpinfo泄露檢測腳本

from pocsuite3.api import requests
from pocsuite3.api import register_poc
from pocsuite3.api import Output, POCBase, logger
import ssl


ssl._create_default_https_context = ssl._create_unverified_context

class TestPOC(POCBase):
    vulLevel = 3
    vulID = ''
    version = '1.0'
    vulDate = ''
    references = ['']
    name = 'phpinfo敏感信息泄露'
    appPowerLink = ''
    appName = 'phpinfo'
    appVersion = ''
    vulType = 'phpinfo敏感信息泄露'
    desc = '''
    '''
    samples = ['']

    def _verify(self):
        result = {}
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36',
        }
        phpinfoList=[
            '/phpinfo.php','/1.php','/test.php'
        ]

        for path in phpinfoList:
            vulurl = "{}{}".format(
                self.url.rstrip('/'), path)
            try:
                resp = requests.get(url=vulurl, headers=headers, timeout=3, verify=False)
                if "PHP Version" in resp.text and resp.status_code == 200:
                    result['VerifyInfo'] = {}
                    result['VerifyInfo']['url'] = vulurl
                    return self.parse_attack(result)
            except Exception as e:
                logger.error("connect target '{} failed!'".format(vulurl))
                pass

        return self.parse_attack(result)



    def parse_attack(self, result):
        output = Output(self)
        if result:
            output.success(result)
        else:
            output.fail('Internet nothing returned')
        return output

register_poc(TestPOC)

參考鏈接

END

建了一個微信的安全交流群,歡迎添加我微信備注進群,一起來聊天吹水哇,以及一個會發布安全相關內容的公眾號,歡迎關注 😃

GIF GIF


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM