Analysis of Windows access permission check mechanism

Source: Internet
Author: User

Analysis of Windows access permission check mechanism

Author: DanielKing

0x00 Introduction

In the operating system, when we mention security, it means that some resources need to be protected. In the Windows operating system, most of these resources are protected by objects) object is an abstraction of resources. Each object can have its own Security Descriptor to describe who it can be accessed in what way. If these objects are objects, what are the subjects accessing these objects? These subjects are all processes in the operating system, and more accurately each thread in these processes. Each process has a basic Token that can be shared by every thread in the process. Some threads are special and they are simulating the identity of a client, therefore, they have an Impersonation Token. For these threads, the valid Token is the simulated Token, while the valid Token of other threads is the basic Token of the process to which they belong. When the subject tries to Access the object, the operating system will perform an Access Check. Specifically, it compares the valid token of the subject with the security descriptor of the object, to determine whether the access is valid. To improve efficiency, Access Check provides a caching mechanism that checks Access permissions only when an object is created or opened by a process, the results of the access permission check will be cached in the Handle Table of the process. Subsequent operations of the process on this object only need to query the content in the Handle Table to determine the access validity, instead of performing an Access Check with higher overhead every time ). Because both objects and processes have their own inheritance layers, the object's Security Descriptor and process token can also be logically inherited, for example, a file in a file system can inherit the security descriptor of its directory, and a sub-process can inherit the token of the parent process. This Inheritance Mechanism gives objects and processes a default security attribute. Therefore, in a system, the number of security descriptors and tokens is very limited. In most cases, it is the default value inherited from the fathers.

0x01 access permission check

The access permission check includes multiple checks:

DACL check

DACL (autonomous Access Control table, Discretionary Access Control List) check is the most basic Access permission check.

There is a DACL table in the Security Descriptor (see the security descriptor illustration), which describes the identity of the subject applied for access permissions will be allowed or rejected. Each table item in the DACL table has the following structure:

We'll define the structure of the predefined ACE types.  Pictorallythe structure of the predefined ACE's is as follows:     3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1     1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0    +---------------+-------+-------+---------------+---------------+    |    AceFlags   | Resd  |Inherit|    AceSize    |     AceType   |    +---------------+-------+-------+---------------+---------------+    |                              Mask                             |    +---------------------------------------------------------------+    |                                                               |    +                                                               +    |                                                               |    +                              Sid                              +    |                                                               |    +                                                               +    |                                                               |    +---------------------------------------------------------------+Mask is the access mask associated with the ACE.  This is either theaccess allowed, access denied, audit, or alarm mask.Sid is the Sid associated with the ACE.

For DACL, AceType can have

#!cpp#define ACCESS_ALLOWED_ACE_TYPE                 (0x0)#define ACCESS_DENIED_ACE_TYPE                  (0x1)

There are two possibilities: Mask is a bitmap that represents a set of related permissions. The identity of a subject is represented by a Security Identifier. This is a variable-length data structure:

#!cppkd> dt nt!_SID   +0x000 Revision         : UChar   +0x001 SubAuthorityCount : UChar   +0x002 IdentifierAuthority : _SID_IDENTIFIER_AUTHORITY   +0x008 SubAuthority     : [1] Uint4B

Sid is a basic type in Windows security system. It can be used to uniquely identify multiple types of entities, such as user identity and group identity, Integrity Level, and trustworthiness level, capability in AppContainer.

The DACL check process is like this. If the object's security descriptor is empty, it means that the object is not protected and can be accessed by the entity represented by any token; if the object has a non-empty security descriptor, but the Dacl member in the security descriptor is empty, it means that the object does not explicitly grant any access permission to any subject, that is, access is not allowed; if the Dacl member is not empty, compare it with the identity Sid of the current subject one by one in the order in the table until all the permissions requested by the subject are explicitly allowed, or the permission of a request is explicitly rejected and the check is completed. If the permission applied by the subject is not explicitly allowed until the Dacl table check is completed, the request is rejected.

According to the above rules, the order of table items in DACL is crucial to the result of the access permission check. For example, a table item explicitly rejected by a subject is located at the end of the table, if the table item that is located before it explicitly permits the permission applied by the subject, this explicitly rejected table item does not play any role. For this reason, if you add a DACL table item through the Windows right-click Security Options menu, the explicitly rejected table items will always be placed before the explicitly allowed table items to ensure their validity. This restriction is not imposed if you directly add an API.

Privileges and Super Privileges check

The so-called privilege refers to the access permissions that are not related to a specific object and affect the entire system. Super privilege is such a privilege. Once you have a super privilege, you have the potential to gain all other privileges and permissions, such as SeDebugPrivilege. In general, once you have this privilege, you can read and write the memory of the target process at will, not just the permissions and privileges obtained when the process is opened to obtain the handle.

Integrity Level and Mandatory Policy Check

Integrity Level (IL) mechanism is an important security mechanism introduced by Windows Vista. The Sandbox mechanism built on it is very simple and extremely powerful.

Restricted Token (Restricted Token) Check

By creating a restricted Token, you can obtain a subset of all the permissions of a common token, which is used for some low-Permission operations to reduce security risks.

AppContainer's Capabilities check

The LowBox token and AppContainer's Capabilities group identity are security mechanisms introduced from Windows 8. It provides a more complex sandbox mechanism. Capabilities and Android systems have very similar restrictions on App permissions.

Trust Level Check

Integrity Level Check is a coarse-grained and relatively stable access permission control method. With the continuous evolution of Windows, the dependence on signature mechanisms becomes more and more obvious, A signature represents a degree of trustworthiness. I believe that Windows is gradually establishing a complete set of trusted-level permission check mechanism. The Protected Process is part of this mechanism.

The content above briefly introduces the Windows permission check model and the permission check dimension. The following describes some implementation details.

0x02 token TOKEN struct

The Token struct is the core data structure that represents the identity of the subject in the access permission check. It is shown below in Windows 10 x64 platform.

#!cppkd> dt nt!_TOKEN   +0x000 TokenSource      : _TOKEN_SOURCE   +0x010 TokenId          : _LUID   +0x018 AuthenticationId : _LUID   +0x020 ParentTokenId    : _LUID   +0x028 ExpirationTime   : _LARGE_INTEGER   +0x030 TokenLock        : Ptr64 _ERESOURCE   +0x038 ModifiedId       : _LUID   +0x040 Privileges       : _SEP_TOKEN_PRIVILEGES   +0x058 AuditPolicy      : _SEP_AUDIT_POLICY   +0x078 SessionId        : Uint4B   +0x07c UserAndGroupCount : Uint4B   +0x080 RestrictedSidCount : Uint4B   +0x084 VariableLength   : Uint4B   +0x088 DynamicCharged   : Uint4B   +0x08c DynamicAvailable : Uint4B   +0x090 DefaultOwnerIndex : Uint4B   +0x098 UserAndGroups    : Ptr64 _SID_AND_ATTRIBUTES   +0x0a0 RestrictedSids   : Ptr64 _SID_AND_ATTRIBUTES   +0x0a8 PrimaryGroup     : Ptr64 Void   +0x0b0 DynamicPart      : Ptr64 Uint4B   +0x0b8 DefaultDacl      : Ptr64 _ACL   +0x0c0 TokenType        : _TOKEN_TYPE   +0x0c4 ImpersonationLevel : _SECURITY_IMPERSONATION_LEVEL   +0x0c8 TokenFlags       : Uint4B   +0x0cc TokenInUse       : UChar   +0x0d0 IntegrityLevelIndex : Uint4B   +0x0d4 MandatoryPolicy  : Uint4B   +0x0d8 LogonSession     : Ptr64 _SEP_LOGON_SESSION_REFERENCES   +0x0e0 OriginatingLogonSession : _LUID   +0x0e8 SidHash          : _SID_AND_ATTRIBUTES_HASH   +0x1f8 RestrictedSidHash : _SID_AND_ATTRIBUTES_HASH   +0x308 pSecurityAttributes : Ptr64 _AUTHZBASEP_SECURITY_ATTRIBUTES_INFORMATION   +0x310 Package          : Ptr64 Void   +0x318 Capabilities     : Ptr64 _SID_AND_ATTRIBUTES   +0x320 CapabilityCount  : Uint4B   +0x328 CapabilitiesHash : _SID_AND_ATTRIBUTES_HASH   +0x438 LowboxNumberEntry : Ptr64 _SEP_LOWBOX_NUMBER_ENTRY   +0x440 LowboxHandlesEntry : Ptr64 _SEP_LOWBOX_HANDLES_ENTRY   +0x448 pClaimAttributes : Ptr64 _AUTHZBASEP_CLAIM_ATTRIBUTES_COLLECTION   +0x450 TrustLevelSid    : Ptr64 Void   +0x458 TrustLinkedToken : Ptr64 _TOKEN   +0x460 IntegrityLevelSidValue : Ptr64 Void   +0x468 TokenSidValues   : Ptr64 _SEP_SID_VALUES_BLOCK   +0x470 IndexEntry       : Ptr64 _SEP_LUID_TO_INDEX_MAP_ENTRY   +0x478 VariablePart     : Uint8B

We pay more attention to the privileged bitmap and three Sid arrays representing the Subject Identity: UserAndGroups, RestrictedSids, and Capabilities.

Privileges bitmap

In the user State, the privilege is represented by LUID. In the kernel struct _ TOKEN, three bitmaps are used for representation:

#!cppkd> dt _SEP_TOKEN_PRIVILEGESnt!_SEP_TOKEN_PRIVILEGES   +0x000 Present          : Uint8B   +0x008 Enabled          : Uint8B   +0x010 EnabledByDefault : Uint8B

It represents the Present, Enabled, and EnabledByDefault that can be selected by the current subject, respectively ), the last two sets should be the subset of the Present set.

Unlike the Sid array that represents the subject identity, the representation of the privileged set is simple and there is no protection. From the user State, you can only open or close an existing privilege through the API, but cannot add optional privileges. In other words, the user State can only modify the Enabled privileged set, rather than the Present privileged set; you can directly modify the Present privilege set from the kernel state. For example, you can add the SeAssignPrimaryTokenPrivilege privilege to a common process to explicitly specify a token for the child process, rather than inheriting the token of the current process, the sub-process permissions can be expanded.

Sid array representing the Subject Identity

The three Sid arrays representing the subject identity are:

UserAndGroups:

Represents the identity of the common user and group of the subject, and is an indispensable member;

RestrictedSids:

Optional members. If it is not empty, it indicates that the current token is a restricted token. The Restricted token is converted by filtering out some sensitive identities from the common token, the UserAndGroups member in the restricted token is the same as the normal token, but the RestriectedSids member is not empty, and the filtered subset of the identity is saved in it. Because the access permission check is performed, the three ID Sid arrays must be checked at the same time. This access is allowed only when all results pass. Therefore, by adding a RestrictedSids member representing the restricted permission set, both the purpose of limiting the token permission and the complete identity information of the original token is retained in the UserAndGroups member.

Capabilities:

Optional members. They are only used for AppContainer. The Sid represents an App-related identity, such as an identity with the permission to connect to the network or access the current location.

The three Sid arrays are associated with hash information to protect their integrity. Therefore, even if you modify the information directly from the kernel state, it will fail because it cannot pass integrity verification. However, the hash algorithm is very simple. The following shows the C ++ DEMO code of this algorithm on Windows 10 x64:

#!cppstaticNTSTATUSRtlSidHashInitialize(    __in PSID_AND_ATTRIBUTES Groups,    __in size_t GroupsCount,    __inout PSID_AND_ATTRIBUTES_HASH HashBuffer){    if (NULL == HashBuffer)        return 0xC000000D;    memset(HashBuffer, 0, 0x110);      if (0 == GroupsCount || NULL == Groups)        return 0;    HashBuffer->SidCount = GroupsCount;    HashBuffer->SidAttr = Groups;    if (GroupsCount > 0x40)        GroupsCount = 0x40;      if (0 == GroupsCount)        return 0;    size_t bit_pos = 1;    for (size_t i = 0; i < GroupsCount; i++)    {        PISID sid = reinterpret_cast
 
  ((Groups + i)->Sid);         size_t sub_authority_count = sid->SubAuthorityCount;        DWORD sub_authority = sid->SubAuthority[sub_authority_count - 1];        *(size_t*)(&HashBuffer->Hash[(sub_authority & 0x0000000F)]) |= bit_pos;        *(size_t*)(&HashBuffer->Hash[((sub_authority & 0x000000F0) >> 4) + 0x10]) |= bit_pos;        bit_pos <<= 1;    }    return 0;}
 

This algorithm has two obvious limitations: only the second byte of the last Sub Authority of each Sid is calculated, and only the first 64 Sid can be involved in the calculation.

UAC and associated token

UAC is an important security mechanism introduced by Vista. Many users complain about its inconvenience. However, it is like sudo in Linux, it is an important barrier for protecting system security. When a user logs on to Windows, the operating system will generate an initial token for the user, representing the complete version token (namely, the Administrator permission token) for all permissions of the user ), and the general token after the restricted administrator permissions, the two are associated tokens; afterwards, the tokens used by the process representing the user are inherited by the General token, it is used for general and non-sensitive operations. When you need to perform operations that require administrator permissions, such as installing software and modifying important system settings, the Elevation of Privilege dialog box is displayed, prompting users of risks and requesting users' consent. Once the user agrees, the system switches to the Administrator permission token associated with the current common token for sensitive operations. This mode of interaction with users prevents some malicious programs from slightly performing sensitive operations in the background.

The associated token is implemented through Logon Session and shows its general principle:

Not all tokens have associated tokens. For example, tokens that run continuously without permission escalation are not required.

0x03 object Object Structure

An object is an abstraction of resources that need to be protected and centrally managed in the operating system. An object has a uniform header and stores abstract information.

#!cppkd> dt _OBJECT_HEADERnt!_OBJECT_HEADER   +0x000 PointerCount     : Int8B   +0x008 HandleCount      : Int8B   +0x008 NextToFree       : Ptr64 Void   +0x010 Lock             : _EX_PUSH_LOCK   +0x018 TypeIndex        : UChar   +0x019 TraceFlags       : UChar   +0x019 DbgRefTrace      : Pos 0, 1 Bit   +0x019 DbgTracePermanent : Pos 1, 1 Bit   +0x01a InfoMask         : UChar   +0x01b Flags            : UChar   +0x01b NewObject        : Pos 0, 1 Bit   +0x01b KernelObject     : Pos 1, 1 Bit   +0x01b KernelOnlyAccess : Pos 2, 1 Bit   +0x01b ExclusiveObject  : Pos 3, 1 Bit   +0x01b PermanentObject  : Pos 4, 1 Bit   +0x01b DefaultSecurityQuota : Pos 5, 1 Bit   +0x01b SingleHandleEntry : Pos 6, 1 Bit   +0x01b DeletedInline    : Pos 7, 1 Bit   +0x01c Spare            : Uint4B   +0x020 ObjectCreateInfo : Ptr64 _OBJECT_CREATE_INFORMATION   +0x020 QuotaBlockCharged : Ptr64 Void   +0x028 SecurityDescriptor : Ptr64 Void   +0x030 Body             : _QUAD

The object header contains a pointer to the security descriptor.

Security Descriptor

The security descriptor stores the main information of the object used as the object for access permission check. It contains four key members. Based on whether these four members are embedded at the end of the struct or referenced from the external cache location, they can be divided into two different structures:

#!cppkd> dt _SECURITY_DESCRIPTORntdll!_SECURITY_DESCRIPTOR   +0x000 Revision         : UChar   +0x001 Sbz1             : UChar   +0x002 Control          : Uint2B   +0x008 Owner            : Ptr64 Void   +0x010 Group            : Ptr64 Void   +0x018 Sacl             : Ptr64 _ACL   +0x020 Dacl             : Ptr64 _ACLkd> dt _SECURITY_DESCRIPTOR_RELATIVEnt!_SECURITY_DESCRIPTOR_RELATIVE   +0x000 Revision         : UChar   +0x001 Sbz1             : UChar   +0x002 Control          : Uint2B   +0x004 Owner            : Uint4B   +0x008 Group            : Uint4B   +0x00c Sacl             : Uint4B   +0x010 Dacl             : Uint4B

Owner and Group represent the Owner Sid of the security descriptor. Sacl is short for the System Access Control List, which can contain the Audit of the current object (Audit) integrity Level, Trust Level, and other information, share the same struct with the Dacl mentioned above.

Optional Header

In addition to common fixed headers, an object can also have optional headers and save optional information such as names. The position of the optional Header can be obtained through the InfoMask member table with a fixed header ,:

Object directory

Only some objects have name information, which is called named objects. The main function of a named object is to facilitate the sharing of objects in different processes. They are compiled into object directories by category. Therefore, the object can be found through the path information in the object directory. The implementation of the Object directory is shown in:

Object Type

The object type is a very important information in the object. In Windows, the object type information is abstracted from the same class object and saved as a separate type object. All types of objects in the system are centrally placed in a table. The object indicates the type of the current object by maintaining an index (TypeIndex) pointing to the table. This index value is directly stored in the object header, and the Object Body is directly adjacent to the object header. If the Object Body is damaged, the index value of the object header may be changed, it is possible to exploit the so-called Type Confusion. To alleviate this problem, Windows 10 provides special protection for this index value, as shown in:

This protection method is simple and powerful. The new index value is obtained by performing an exclusive or operation on three parts: the actual index value of the type object in the type object table, the second byte (8th to 15th bits) of the object's header address, which is saved in the global variable of the ObHeaderCookie because each system starts. Among them, the introduction of ObHeaderCookie makes the index values of the same type of objects on different machines, or even between the two startups on the same machine different, but this is not enough to alleviate type obfuscation, we can also use Info Leak to Bypass this protection, so we also introduce the object header address, so that the index values of two instances of the same type of objects in the same system at the same time are also different, thus effectively alleviating type obfuscation.

0x04 Integrity Level Check

Integrity Level (IL) check is the simplest implementation method of sandbox. Through the inheritance relationship between the object and the process level of integrity level, it is like setting up a "hereditary System" in the operating system ". By strictly controlling the inheritance rules of the Integrity Level and setting a strict Integrity Level Check System, the "low-level" subject cannot access the "noble" Object resources.

Integrity has the following levels:

#!bashSeUntrustedMandatorySidSeLowMandatorySidSeMediumMandatorySidSeHighMandatorySidSeSystemMandatorySid

The default integrity level of the subject is SeUntrustedMandatorySid, and the default integrity level of the object is SeMediumMandatorySid. This difference further strengthens this "hereditary System ".

0x05 process protection

Protected Process is a security mechanism established by the Windows operating system to protect some key processes and prevent them from being debugged, injected, or even read memory information by common processes.

The difference between a Protection process and other common processes is that the Protection Member of the Protection process is not 0.

#!cppkd> dt nt!_EPROCESS Protection   +0x6b2 Protection : _PS_PROTECTIONkd> dt nt!_PS_PROTECTION   +0x000 Level            : UChar   +0x000 Type             : Pos 0, 3 Bits   +0x000 Audit            : Pos 3, 1 Bit   +0x000 Signer           : Pos 4, 4 Bits

The Type member of the protection Process can represent two protection types: Protected Process (PP) and Protected Process Lite (PPL). The difference between the two is that PP protects the Process with higher permissions. The Signer Member of the protected process represents the type of the signature publisher of the process. For protection processes whose Signer is PsProtectedSignerWindows (5) and PsProtectedSignerTcb (6), the Type and Signer information are extracted and assembled into a Sid, representing the trustworthiness level of the process, save it to the TrustLevelSid member in the basic token. When the TrustLevelSid in a token is used, ensure that the Protection Information of the current process is synchronized, this is mainly to cope with the TrustLevelSid member expiration situation caused by token passing between different processes (for example, the sub-process inherits the token of the parent process.

When debugging or creating a process, the kernel function pspcheckforinvalidaccpolicyprotection is called for permission check, based on the Protection of the current process and the target process, this function determines whether the current operation must comply with the permission restrictions stipulated by the Protection process. The specific determination rules are as follows:

If the operation comes from the kernel-state code, no restrictions need to be observed. If the Protection Member of the target process is empty, the target process is not a Protection process and no restrictions need to be observed; if the current process is a PP-type protection process, this type of protection process has the highest permissions and does not need to comply with the restrictions. If the current process and the target process are both PPL-Type Protection processes, the RtlProtectedAccess table is used to determine whether the Signer of the current process takes precedence over the Signer of the (dominate) target process. If yes, no restrictions are required. Otherwise, the restrictions must be observed.

The RtlProtectedAccess table is as follows:

#!cppRTL_PROTECTED_ACCESS RtlProtectedAccess[] ={//   Domination,       Process,         Thread,//         Mask,  Restrictions,   Restrictions,    {         0,             0,             0}, //PsProtectedSignerNone               Subject To Restriction Type    {         2,    0x000fc7fe,    0x000fe3fd}, //PsProtectedSignerAuthenticode       0y00000010    {         4,    0x000fc7fe,    0x000fe3fd}, //PsProtectedSignerCodeGen            0y00000100    {         8,    0x000fc7ff,    0x000fe3ff}, //PsProtectedSignerAntimalware        0y00001000    {      0x10,    0x000fc7ff,    0x000fe3ff}, //PsProtectedSignerLsa                0y00010000    {      0x3e,    0x000fc7fe,    0x000fe3fd}, //PsProtectedSignerWindows            0y00111110    {      0x7e,    0x000fc7ff,    0x000fe3ff}, //PsProtectedSignerTcb                0y01111110};

Process Restrictions and Thread Restrictions represent the Process and Thread permission Restrictions. For details, see:

We can use the Demo code of NtDebugActiveProcess and NtCreateUserProcess to understand the logic to protect the process and its restrictions:

#!cppstaticNTSTATUSNtDebugActiveProcess(    __in HANDLE ProcessHandle,    __in HANDLE DebugObjectHandle    ){    PEPROCESS target_process = nullptr;    NTSTATUS result = ObReferenceObjectByHandleWithTag( ProcessHandle, &target_process);    if (! NT_SUCCESS(result))        return result;    PEPROCESS host_process = PsGetCurrentProcess();    if (host_process == target_process)        return 0xC0000022;    if (PsInitialSystemProcess == target_process)        return 0xC0000022;    if (PspCheckForInvalidAccessByProtection(PreviousMode, host_process->Protection, target_process->Protection))        return 0xC0000712;    // ......}staticNTSTATUSNtCreateUserProcess(    __out PHANDLE ProcessHandle,    __out PHANDLE ThreadHandle,    __in  ACCESS_MASK ProcessDesiredAccess ,    __in  ACCESS_MASK ThreadDesiredAccess ,    __in  POBJECT_ATTRIBUTES ProcessObjectAttributes OPTIONAL ,    __in  POBJECT_ATTRIBUTES ThreadObjectAttributes OPTIONAL ,    __in  ULONG CreateProcessFlags,    __in  ULONG CreateThreadFlags,    __in  PRTL_USER_PROCESS_PARAMETERS ProcessParameters ,    __in  PVOID Parameter9,    __in  PNT_PROC_THREAD_ATTRIBUTE_LIST AttributeList    ){    ACCESS_MASK allowed_process_access = ProcessDesiredAccess ;    ACCESS_MASK allowed_thread_access = ThreadDesiredAccess ;    PS_PROTECTION protection = ProcessContext.member_at_0x20;    if (PspCheckForInvalidAccessByProtection(PreviousMode, host_process->Protection, target_process->Protection))    {        // 1 << 0x19 = 0x80000,  WRITE_OWNER        if ( MAXIMUM_ALLOWED == ProcessDesiredAccess )            allowed_process_access = (((~RtlProtectedAccess[protection.Signer].DeniedProcessAccess) & 0x1FFFFF) | ProcessDesiredAccess) & (~(1 << 0x19));        if ( MAXIMUM_ALLOWED == ThreadDesiredAccess )            allowed_thread_access = (((~RtlProtectedAccess[protection.Signer].DeniedThreadAccess) & 0x1FFFFF) | ThreadDesiredAccess) & (~(1 << 0x19));    }    //PspInsertProcess(..., allowed_process_access, ...);    //PspInsertThread(..., allowed_thread_access, ...);}
0x06 conclusion

The permission check mechanism and Security System in Windows are constantly evolving. It is very interesting and beneficial to explore its implementation details and speculate on the design concept behind it, this article is just a Summary of the author's exploration. It is inevitable that there will be omissions or errors. For more details, refer to the following materials, or directly analyze and debug the Windows kernel to learn about the latest and most authentic Windows.

James Forshaw: The Windows Sandbox ParadoxJames Forshaw: A Link to the Past: Abusing Symbolic Links on WindowsAlex Ionescu: The Evolution of Protected Processes Part 1: pass-the-Hash Mitigations in Windows 8.1 Alex events: The Evolution of Protected Processes Part 2: Exploit/Jailbreak Mitigations, Unkillable Processes and Protected ServicesAlex events: Protected Processes Part 3: Windows PKI Inte Rnals (Signing Levels, Scenarios, Root Keys, EKUs & Runtime Signers) Daniel & Azure: Did You Get Your Token?

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.