Skip to content

Instantly share code, notes, and snippets.

@MayerDaniel
Last active March 15, 2024 20:27
Show Gist options
  • Save MayerDaniel/22ea79fb4305773fb8567a6dd7915ef3 to your computer and use it in GitHub Desktop.
Save MayerDaniel/22ea79fb4305773fb8567a6dd7915ef3 to your computer and use it in GitHub Desktop.
Capstone notes

First function definition:

ms opendocs here:

https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-srvs/c30de0d7-f503-441a-8789-89c69f81ad39

create the function signature NET_API_STATUS NetrSessionEnum( SRVSVC_HANDLE ServerName, WCHAR* ClientName, WCHAR* UserName, PSESSION_ENUM_STRUCT InfoStruct, DWORD PreferedMaximumLength, DWORD* TotalEntries, DWORD* ResumeHandle)

For this cast to work you need to import two structs:


union SESSION_ENUM_UNION
{
  void *level;
};

When you're this many structs down, its ok to simplify and then worry about it more/revise if stuff is messed up later because of it

https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-srvs/719533a1-0f65-4f86-8027-8e0c9cabab29

typedef struct _SESSION_ENUM_STRUCT {
   DWORD Level;
   SESSION_ENUM_UNION SessionInfo;
 } SESSION_ENUM_STRUCT,
  *PSESSION_ENUM_STRUCT,
  *LPSESSION_ENUM_STRUCT;

https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-srvs/e560d8c6-13e1-47b6-bde3-5377251ab5ff

End up with this: DWORD NetrSessionEnum( wchar_t* ServerName, WCHAR* ClientName, WCHAR* UserName, PSESSION_ENUM_STRUCT InfoStruct, DWORD PreferedMaximumLength, DWORD* TotalEntries, DWORD* ResumeHandle)

https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-srvs/02b1f559-fda2-4ba3-94c2-806eb2777183

Some of the more specific types have to be replaced, such as ServerName with the underlying data type (SRVSVC_HANDLE -> wchar_t*). Google these to find their underlying types

https://github.com/selfrender/Windows-Server-2003/blob/5c6fe3db626b63a384230a1aa6b92ac416b0765f/ds/netapi/netlib/secobj2.c#L50

int __stdcall NetpAccessCheckAndAuditEx(LPTSTR SubsystemName, LPTSTR ObjectTypeName, PSECURITY_DESCRIPTOR SecurityDescriptor, ACCESS_MASK DesiredAccess, PGENERIC_MAPPING GenericMapping);

http://undocumented.ntinternals.net/index.html?page=UserMode%2FUndocumented%20Functions%2FSecurity%2FNtAccessCheckAndAuditAlarm.html

NTSTATUS __stdcall NtAccessCheckAndAuditAlarm(PUNICODE_STRING SubsystemName, PVOID HandleId, PUNICODE_STRING ObjectTypeName, PUNICODE_STRING ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, ACCESS_MASK DesiredAccess, PGENERIC_MAPPING GenericMapping, BOOLEAN ObjectCreation, PACCESS_MASK GrantedAccess, PNTSTATUS AccessStatus, PBOOLEAN GenerateOnClose);
@MayerDaniel
Copy link
Author

Import-Module NtObjectManager
$value = Get-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\DefaultSecurity -Name SrvsvcSessionInfo
$sd = New-NtSecurityDescriptor -Byte $value.SrvsvcSessionInfo
$sd.Dacl

Get-NtAccessMask -AccessMask 0x00F0013 -ToSpecificAccess Registry

@MayerDaniel
Copy link
Author

MayerDaniel commented Feb 22, 2024

# Construct a security descriptor object from the security descriptor's bytes that are stored in the registry
$value = Get-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\DefaultSecurity -Name SrvsvcSessionInfo
$valuecontent = $value.SrvsvcSessionInfo
$originalSD = [System.Security.AccessControl.RawSecurityDescriptor]::new($valuecontent,0)
$origSddl = $originalSD.GetSddlForm([System.Security.AccessControl.AccessControlSections]::All)
Write-Warning "Original SD SDDL: $($origSddl)"


# Create a new Audit ACE (a SACL ACE) that alerts anytime the security descriptor is accessed
$AceFlags = [System.Security.AccessControl.AceFlags]::SuccessfulAccess
$AceQualifier = [System.Security.AccessControl.AceQualifier]::SystemAudit
$AccessMask = 0xFFFFFFFF
$Sid = New-Object System.Security.Principal.SecurityIdentifier @([System.Security.Principal.WellKnownSidType]::WorldSid, $Null)
$newAce = New-Object System.Security.AccessControl.CommonAce @($AceFlags, $AceQualifier, $AccessMask, $Sid, $true, $data)

# Add the ACE to the SACL
$originalSD.SystemAcl = New-Object System.Security.AccessControl.RawAcl @(2,1)
$originalSD.SystemAcl.InsertAce(0, $newAce)
# Get the byte representation of the new security descriptor
$sdbytes = New-Object byte[] $originalSD.BinaryLength
$originalSD.GetBinaryForm($sdbytes, 0)
Set-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\DefaultSecurity -Name SrvsvcSessionInfo -Value $buffer
# Get a list of all Audit Policy Categories
$categories = auditpol /list /Category | Select -Skip 1
# Remove the extra white space
$categories = $categories | ForEach-Object {$_.trim()}
# Create a command separated list with quotes
$auditpol_categories = '"' + ($categories -join '","') + '"'
# Enable all the audit policies
auditpol /set /category:$auditpol_categories /failure:enable /success:enable

Now you can look for EventID 4656 in the security log

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment