OrientDB远程代码执行漏洞利用与分析

2022-04-14 00:00:00 用户 数据库 执行 命令 漏洞

OrientDB数据库是一个支持分布式的NoSQL数据库,主要针对文档以及图形等进行检索,通过研究发现其默认配置admin、reader和writer三个角色,在处理where”或“fetchplan”或“order by”函数时,由于在OrientDB中有一个执行groovy函数,groovy包装类没有沙箱,暴露了系统函数,因此我们可以运行我们想要的任何命令。该漏洞在国外被命名为CVE-2017-11467,本文主要对该漏洞的分析方法和实战进行探讨。


一、OrientDB简介

OrientDB是分布式兼具文档数据库的灵活性和图形数据库管理链接能力的可深层次扩展的文档-图形数据库管理系统,也是可升级,高性能的操作NoSQL数据库。可选无模式、全模式或混合模式下。支持许多特性,诸如ACID事务、快速索引,原生和SQL查询功能。可以JSON格式导入、导出文档。若不执行昂贵的JOIN操作的话,如同关系数据库可在几毫秒内可检索数以百G的链接文档图,其新版本为OrientDB v2.2.26。
官方网站:http://orientdb.com和https://github.com/Orientechnologies。

图1  Orientdb


二、OrientDB基础

2.1  OrientDB的一些基本概念

Classes : 类比关系型数据库系统中的Table与传统文档数据库的collections。这个概念来自于OOP(Object-oriented programming)的理念。class用于定义数据结构的模型。

Record:record是OrientDB中小的加载和存储的单位。record有四种类型:Document、RecordBytes(BLOB)、Vertex、Edge。

Document:是OrientDB中灵活的record。Document支持schema-less,schemal-full,schema-mixed,即可以在定义数据结构的时候指定属性及约定条件,也可以不指定。它通过create class语法来定义一个数据结构。

Vertex:在OrientDB的graph模型下,每个结点叫作Vertex,每个Vertex也是一个Document。

Edge:在OrientDB的graph模型下,连接两个Vertex的边叫作Edge。Edge是有向性的而且仅能连接两个Vertex。

Clusters : 用于存储record。每个数据库多有32767个cluster。每个class都必须至少有一个对应的cluster。默认情况下OrientDB会自动为每个class创建与当前cpu核数相同的cluster,其中有一个默认的cluster。

Cluster Selection:当新增加一条reocrd时OrientDB会根据cluster section为这条记录选择一个cluster。cluster section有四条类型:detault、round-robin、balanced、local。

Record ID :每个record都有一个record id。 record id的格式如下:

# <cluster-id>:<cluster-position>

Relationships: OrientDB中不使用join,它通过在每个reocrd中定义一个关系类型的属性来维护关系。这个关系属性存储的实际是record id,就像定义一个指针在内存中将两个record联系起来。

Inheritance & Polymorphic: OrientDB支持面向对象的继承和多态特性。


2.2  OrientDB的特性

OrientDB是用Java语言实现的,运行在JVM之上。

Multi-Model:OrientDB支持多种模型:Key/Value, Object, Document, and Graph。

Multi-Master Replication: OrientDB集群部署时每个点都是Master,每个Master上都有完整的数据。一旦一个Master上的数据发生变更,会将发生变更的数据同步通知其它Master。

Extended SQL : OrientDB支持大部分标准的SQL,同时在标准的SQL之上扩展了部分功能以方便图的操作。

Easy Integration :使用teleporter可以很容易地将数据从RDBMS迁移到OrientDB上。

OOP:OrientDB定义数据结构的Class符合OOP(Object-oriented programming)的理念,支持继承和多态的特性。


2.3  OrientDB的SQL

在写图数据库的SQL时,步是要确认起始点(这个也是图数据库比较耗时的地方),一旦起始点确认后,我们便可以近乎物理连接的方式查询这个起始点相关联的数据。

基本的SQL:OrientDB支持大部分标准的SQL查询。

Traverse:traverse语法可以遍历获取一个record联结的reocrd。它比select使用起来更简单和快速。

Match:match是一种表述力很强的查询语法结构,类比Neo4j的Cypher语法结构。它以一种说明式的方式来查询。


三. OrientDB漏洞 CVE-2017-11467分析

3.1搭建测试环境

(1)docker安装,这个安装的是新版本,有可能修补了漏洞

(2)linux下安装orientdb

注意:

(1)如果是虚拟机,则需要修改内存大小,默认64位是512G,修改为1G!需要修改/opt/orientdb/bin下的所有bat文件和sh的文件。否则会报“Invalid maximum direct memory size: -XX:MaxDirectMemorySize=512g”错误。

(2)设置路径和用户,在对应的sh的文件中设置

ORIENTDB_DIR="/opt/orientdb/"
ORIENTDB_USER="orientdb"


3.2漏洞分析

1.用户权限
OrientDB使用RBAC模型进行认证方案。默认情况下,OrientDB有3个角色:管理员(admin),作者(writer)和读者(reader)。这些用户名与角色相同。对于在服务器上创建的每个数据库,默认情况下分配这3个用户。

用户的权限是:
admin:访问数据库上的所有功能,没有任何限制
reader:只读用户。读者可以查询数据库中的任何记录,但不能修改或删除它们。它不能访问内部信息,例如用户和角色本身。
writer:与“读者”相同,但也可以创建,更新和删除记录

2.越权导致命令执行
ORole结构处理用户及其角色,只能由管理员访问。OrientDB需要oRole读取权限来允许用户显示用户的权限以及与oRole权限相关联的其他查询。但在版本2.2.x中,每当上述oRole查询包含where、fetchplan和ORDER BY语句,则不需要此权限的要求和信息,而返回给未经授权的用户从而导致命令执行。

例:

select * from <em>oRole</em> order by name;

当每个数据库创建时会创建writer用户,这样,即使db管理员更改管理员用户密码,攻击者仍然可以使用writer用户获取代码执行。由于我们启用了where、fetchplan和ORDER BY函数,在OrientDB中有一个执行groovy函数,groovy包装类没有沙箱,暴露了系统函数,因此我们可以运行我们想要的任何命令。

示例Groovy函数:

3.概念证明

(1)监听8081端口
在8081端口运行Netcat:nc -lv 8081
运行以下命令:

python PoC.py ip [port]

(2)poc.py


四、历史漏洞

  • CVE-2017-11467(高危)
    OrientDB通过2.2.22在“where”或“fetchplan”或“order by”使用期间不执行特权要求,允许远程攻击者通过精心制作的请求执行任意操作系统命令。

  • CVE-2015-2918
    在2.0.1之前的2.0.15和2.1.x之前的OrientDB Server Community Edition中的Studio组件没有适当地限制使用FRAME元素,这使远程攻击者更容易通过精心设计的网站进行劫持攻击。

  • CVE-2015-2913
    server/network/protocol/http/OHttpSessionManager.java在OrientDB Server社区版的Studio组件2.0.15、2.1.x和2.1.1之前版本不正确地依赖于java.util.Random类来生成随机Session ID值,这使远程攻击者更容易通过确定此类中的PRNG的内部状态来预测值。

  • CVE-2015-2912
    在2.0.1之前的2.0.15和2.1.x之前的OrientDB Server Community Edition的Studio组件中的JSONP端点没有适当地限制回调值,这允许远程攻击者通过精心设计的HTTP请求进行跨站点请求伪造(CSRF)攻击,并获得敏感信息。


五、实战CVE-2017-11467漏洞利用

1.安装poc.py所需的组件

直接执行python CVE-2017-11467.py 127.0.0.1后,出现错误,如图2所示,则表示需要requests组件的支持,可以到https://pypi.python.org/pypi/requests/#downloads下载requests-2.18.4.tar.gz,可参考下载地址:
https://pypi.python.org/packages/b0/e1/eab4fc3752e3d240468a8c0b284607899d2fbfb236a56b7377a329aa8d09/requests-2.18.4.tar.gz
解压requests-2.18.4.tar.gz文件后,使用python setup.py install进行安装。

图2需要安装requests组件

2.寻找OrientDB
zoomeye目前在升级,因此用https://fofa.sol来进行搜索效果比较佳,关键词“orientdb  && port=2480”,对于2.2.X版本基本是通杀。获取结果后,通过单击链接来查看可否正常访问。能够正常访问,登录密码一般都是admin/admin。

3.执行命令

(1)检测是否存在漏洞

(2)设置反弹的IP

如果检测到目标对象存在漏洞,则提示输入一个反弹的IP地址,该IP地址事先需要进行8081端口监听,如果命令执行成功则获取反弹的shell,执行效果如图3和图4所示。

图3命令执行漏洞检测

图4获取反弹的shell

注意:

  1. 由于命令是针对linux,因此反弹IP前不能有空格,否则执行不成功。

  2. 反弹端口可以更改poc中的8081。

  3. OrientDB数据库密码是加密的。例如获取某数据库配置文件中的数据库用户和密码:



来自:https://mp.weixin.qq.com/s/OZYvciu1j3H3o25zLFj8RA


相关文章