fix: strip privileged groups from normal user token

This commit is contained in:
2026-09-06 14:02:07 +00:00
parent 09554a9b8c
commit 4e75524efa
@@ -572,15 +572,39 @@ func openTokenForAttempt(contextName ExecutionContext, candidate *SessionCandida
// privileges, disables the built-in Administrators SID, and verifies medium // privileges, disables the built-in Administrators SID, and verifies medium
// integrity before the token is returned to the launch path. // integrity before the token is returned to the launch path.
func createRestrictedMediumToken(source winapi.Token) (winapi.Token, error) { func createRestrictedMediumToken(source winapi.Token) (winapi.Token, error) {
adminSID, err := winapi.CreateWellKnownSid(winapi.WinBuiltinAdministratorsSid) // A full administrator token may carry several built-in groups that grant
// privileged access even after the administrator SID is hidden. Disable the
// complete known privilege-bearing built-in set before forcing medium
// integrity; membership itself is retained in the token evidence, but these
// groups cannot authorize the normal command.
disabledTypes := []winapi.WELL_KNOWN_SID_TYPE{
winapi.WinBuiltinAdministratorsSid,
winapi.WinBuiltinPowerUsersSid,
winapi.WinBuiltinAccountOperatorsSid,
winapi.WinBuiltinSystemOperatorsSid,
winapi.WinBuiltinPrintOperatorsSid,
winapi.WinBuiltinBackupOperatorsSid,
winapi.WinBuiltinRemoteDesktopUsersSid,
winapi.WinBuiltinNetworkConfigurationOperatorsSid,
winapi.WinBuiltinPerfMonitoringUsersSid,
winapi.WinBuiltinPerfLoggingUsersSid,
winapi.WinBuiltinDCOMUsersSid,
winapi.WinBuiltinCryptoOperatorsSid,
winapi.WinBuiltinHyperVAdminsSid,
winapi.WinBuiltinRemoteManagementUsersSid,
}
disabled := make([]winapi.SIDAndAttributes, len(disabledTypes))
for index, sidType := range disabledTypes {
sid, err := winapi.CreateWellKnownSid(sidType)
if err != nil { if err != nil {
return 0, err return 0, err
} }
disabled := winapi.SIDAndAttributes{Sid: adminSID} disabled[index] = winapi.SIDAndAttributes{Sid: sid}
}
var restricted winapi.Token var restricted winapi.Token
result, _, callErr := procCreateRestrictedToken.Call( result, _, callErr := procCreateRestrictedToken.Call(
uintptr(source), disableMaxPrivilege, uintptr(source), disableMaxPrivilege,
1, uintptr(unsafe.Pointer(&disabled)), uintptr(len(disabled)), uintptr(unsafe.Pointer(&disabled[0])),
0, 0, 0, 0,
0, 0, 0, 0,
uintptr(unsafe.Pointer(&restricted)), uintptr(unsafe.Pointer(&restricted)),