我們在滲透測試的過程中,如果存在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_fopen
和allow_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()
查看一些特殊的程序服務,比如redis
,memcache
,mysql
,Smtp
,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)
參考鏈接
- https://xz.aliyun.com/t/2222
- https://xz.aliyun.com/t/521
- https://www.k0rz3n.com/2019/02/12/PHPINFO 中的重要信息/
- https://xz.aliyun.com/t/5535
END
建了一個微信的安全交流群,歡迎添加我微信備注進群
,一起來聊天吹水哇,以及一個會發布安全相關內容的公眾號,歡迎關注 😃

