|
PHP编码安全:请求伪造攻击
如果Web系统中存在服务器请求伪造漏洞,不仅会影响系统本身,而且会影响到与其相关的其他系统服务。一个被忽视的服务器请求伪造漏洞,很容易引起蝴蝶效应,可能给整个系统带来长期的巨大危害。
1、服务器请求伪造
服务器请求伪造(Server-Side Request Forgery,SSRF)漏洞是一种由攻击者利用某服务器请求来获取内网或外网系统资源,从服务器发起请求的一个安全漏洞。正因为它是由服务器发起的,所以它能够请求到与它相连而与外网隔离的内部系统。一般情况下,SSRF攻击的目标是企业的内网系统。
SSRF可以对外网、服务器所在内网、本地进行端口扫描,获取一些服务的banner信息。攻击运行于内网或本地的应用程序(比如攻击内部数据库系统),并通过扫描默认Web文件对内网Web应用进行指纹识别,同时可以利用file协议读取本地文件。
SSRF形成的原因大多是由于服务器提供了从其他服务器应用中获取数据的功能且没有对目标地址进行过滤与限制,比如从指定URL地址中获取网页文本内容、加载指定地址的图片、下载等。
SSRF漏洞流程如图1所示,即:
图1 SSRF攻击流程
1)攻击者构造请求;
2)服务器根据攻击者构造的请求对内网服务器进行请求;
3)内网服务器将请求反馈给服务器;
4)服务器将获取到的内网资源返回给攻击者。
2、SSRF漏洞的危害
SSRF漏洞的主要危害是使服务器资源泄露,内网服务任意扫描泄露内网信息。很多网站提供了通过用户指定的URL上传图片和文件的功能,可以将第三方的图片和文件直接保存在当前的Web系统上,如果用户输入的URL是无效的,大部分的Web应用会返回错误信息。
攻击者可以输入一些不常见但有效的URL,比如以下URL。
- http://127.0.0.1:8080/dir/images/
- http://127.0.0.1:22/dir/public/image.jpg
- http://127.0.0.1:3306/dir/images/
复制代码 然后根据服务器的返回信息来判断端口是否开放。大部分应用并不会去判断端口,只要是有效的URL,就会发出请求。而大部分的TCP服务,在建立socket连接时就会发送banner信息。banner信息是使用ASCII编码的,能够作为原始的HTML数据展示。当然,服务端在处理返回信息的时候一般不会直接展示,但是不同的错误码,返回信息的长度以及返回时间都可以作为依据来判断远程服务器的端口状态。
以下是一段未经过安全编码的代码,有很大概率被攻击者利用进行端口扫描。
- <?php
- if(isset($_GET['url']))
- {
- $url=$_GET['url'];
- $filename='/tmp/'.rand().'txt';
- $ch=curl_init();
- $timeout=5;
- curl_setopt($ch,CURLOPT_URL,$url);
- curl_setopt($ch,CURLOPT_FOLLOWLOCATION,1);
- curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
- curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,$timeout);
- $content=curl_exec($ch);
- $fp_in=fopen($filename,'w');
- fwrite($fp_in,$content);
- fclose($fp_in);
- $fp_out=fopen($filename,"r");
- $result=fread($fp_out,filesize($filename));
- fclose($fp_out);
- echo $result;
- } else {
- echo "请输入资源地址";
- }
复制代码 由于上面不安全编码的代码,容易被攻击者利用对内网Web应用进行指纹识别,识别内网应用所使用的框架、平台、模块以及cms,这实际上为潜在的攻击提供了很多“便利”。大多数Web应用框架有一些独特的文件和目录,通过这些文件可以识别出应用的类型,甚至是详细的版本。根据这些信息就可以有针对性地搜集漏洞进行攻击。比如可以通过访问下列文件来判断phpMyAdmin是否安装。
- http://127.0.0.1:8080/phpMyAdmin/themes/original/img/b_tblimport.png
- http://127.0.0.1:8081/wp-content/themes/default/images/audio.jpg
- http://127.0.0.1:8082/profiles/minimal/translations/README.txt
复制代码 3、在PHP中容易引起SSRF的函数
容易出现SSRF漏洞的功能代码通常是为了获取远程或本地内容,例如使用file_get_contents()、fsockopen()、curl()等函数。
如使用file_get_contents()函数从用户指定的URL中获取文件,然后把它输出到浏览器端用于下载。
<?php
$content=base64_decode(file_get_contents($_GET['url']));
echo $content;
正常情况下,用户的下载地址是通过服务端提供的base64编码后的路径回传到服务端进行下载操作的,不会造成SSRF漏洞,但是攻击者很容易识别base64的内容,如果攻击者将下载地址替换成自己伪造的编码内容,则可以下载服务器上的任意文件,以及对内网地址进行扫描。如将/etc/password进行base64编码之后放在URL参数中,会直接将/etc/password的内容展示在页面上,使得攻击者能直接获取服务器的所有用户列表,从而危害服务器的安全。
使用fsockopen()函数实现获取用户指定URL中的数据。这个函数会使用socket与服务器建立tcp连接,传输原始数据。在下面的示例代码中,由于研发人员的疏忽,用户一旦传入“主机名+端口+地址”之后,攻击者可以对内网服务器进行任意扫描。
[code]<?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 .= "Conn |
|