Monday, March 15, 2021

ACCESS_MASK: Specific rights of NT objects


#define FILE_READ_DATA            ( 0x0001 )    // file & pipe
#define FILE_LIST_DIRECTORY       ( 0x0001 )    // directory
#define FILE_WRITE_DATA           ( 0x0002 )    // file & pipe
#define FILE_ADD_FILE             ( 0x0002 )    // directory
#define FILE_APPEND_DATA          ( 0x0004 )    // file
#define FILE_ADD_SUBDIRECTORY     ( 0x0004 )    // directory
#define FILE_CREATE_PIPE_INSTANCE ( 0x0004 )    // named pipe
#define FILE_READ_EA              ( 0x0008 )    // file & directory
#define FILE_WRITE_EA             ( 0x0010 )    // file & directory
#define FILE_EXECUTE              ( 0x0020 )    // file
#define FILE_TRAVERSE             ( 0x0020 )    // directory
#define FILE_DELETE_CHILD         ( 0x0040 )    // directory
#define FILE_READ_ATTRIBUTES      ( 0x0080 )    // all
#define FILE_WRITE_ATTRIBUTES     ( 0x0100 )    // all
#define FILE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF)
#define FILE_GENERIC_READ         (STANDARD_RIGHTS_READ     |\
                                   FILE_READ_DATA           |\
                                   FILE_READ_ATTRIBUTES     |\
                                   FILE_READ_EA             |\
                                   SYNCHRONIZE)
#define FILE_GENERIC_WRITE        (STANDARD_RIGHTS_WRITE    |\
                                   FILE_WRITE_DATA          |\
                                   FILE_WRITE_ATTRIBUTES    |\
                                   FILE_WRITE_EA            |\
                                   FILE_APPEND_DATA         |\
                                   SYNCHRONIZE)
#define FILE_GENERIC_EXECUTE      (STANDARD_RIGHTS_EXECUTE  |\
                                   FILE_READ_ATTRIBUTES     |\
                                   FILE_EXECUTE             |\
                                   SYNCHRONIZE)



#define PROCESS_TERMINATE                  (0x0001) 
#define PROCESS_CREATE_THREAD              (0x0002) 
#define PROCESS_SET_SESSIONID              (0x0004) 
#define PROCESS_VM_OPERATION               (0x0008) 
#define PROCESS_VM_READ                    (0x0010) 
#define PROCESS_VM_WRITE                   (0x0020) 
#define PROCESS_DUP_HANDLE                 (0x0040) 
#define PROCESS_CREATE_PROCESS             (0x0080) 
#define PROCESS_SET_QUOTA                  (0x0100) 
#define PROCESS_SET_INFORMATION            (0x0200) 
#define PROCESS_QUERY_INFORMATION          (0x0400) 
#define PROCESS_SUSPEND_RESUME             (0x0800) 
#define PROCESS_QUERY_LIMITED_INFORMATION  (0x1000) 
#define PROCESS_SET_LIMITED_INFORMATION    (0x2000)
#define PROCESS_ALL_ACCESS        (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | \
                                   0xFFFF)



#define THREAD_TERMINATE                 (0x0001) 
#define THREAD_SUSPEND_RESUME            (0x0002) 
#define THREAD_GET_CONTEXT               (0x0008) 
#define THREAD_SET_CONTEXT               (0x0010) 
#define THREAD_QUERY_INFORMATION         (0x0040) 
#define THREAD_SET_INFORMATION           (0x0020) 
#define THREAD_SET_THREAD_TOKEN          (0x0080)
#define THREAD_IMPERSONATE               (0x0100)
#define THREAD_DIRECT_IMPERSONATION      (0x0200)
#define THREAD_SET_LIMITED_INFORMATION   (0x0400)  // winnt
#define THREAD_QUERY_LIMITED_INFORMATION (0x0800)  // winnt
#define THREAD_RESUME                    (0x1000)  // winnt
#if (NTDDI_VERSION >= NTDDI_VISTA)
#define THREAD_ALL_ACCESS         (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | \
                                   0xFFFF)



#define JOB_OBJECT_ASSIGN_PROCESS           (0x0001)
#define JOB_OBJECT_SET_ATTRIBUTES           (0x0002)
#define JOB_OBJECT_QUERY                    (0x0004)
#define JOB_OBJECT_TERMINATE                (0x0008)
#define JOB_OBJECT_SET_SECURITY_ATTRIBUTES  (0x0010)
#define JOB_OBJECT_IMPERSONATE              (0x0020)
#define JOB_OBJECT_ALL_ACCESS       (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | \
                                        0x3F )


Wednesday, November 13, 2019

Process Mitigations in 2019 (1)

ProcessImageLoadPolicy
In the recent years,Microsoft has add many mitigations in the Windows system. In this article i will show you the implementation of these mitigations.
The first question is how many mitigations have been added in Windows and what they are.
If you have even used a process manager tool which named Process Hacker, you can query each process's mitigation status.For example:
QQ图片20191109201759.png-106.3kB
In fact, there is a struct named PROCESS_MITIGATION_POLICY in the SDK header file.
  1. typedef enum _PROCESS_MITIGATION_POLICY {
  2. ProcessDEPPolicy,
  3. ProcessASLRPolicy,
  4. ProcessDynamicCodePolicy,
  5. ProcessStrictHandleCheckPolicy,
  6. ProcessSystemCallDisablePolicy,
  7. ProcessMitigationOptionsMask,
  8. ProcessExtensionPointDisablePolicy,
  9. ProcessControlFlowGuardPolicy,
  10. ProcessSignaturePolicy,
  11. ProcessFontDisablePolicy,
  12. ProcessImageLoadPolicy,
  13. ProcessSystemCallFilterPolicy,
  14. ProcessPayloadRestrictionPolicy,
  15. ProcessChildProcessPolicy,
  16. ProcessSideChannelIsolationPolicy,
  17. MaxProcessMitigationPolicy
  18. } PROCESS_MITIGATION_POLICY, *PPROCESS_MITIGATION_POLICY;
If you want to know the mitigation status of a process, you can use the Windows Native API NtQueryInformationProcess.
NtQueryInformationProcess declaration is following:
  1. NTSYSCALLAPI
  2. NTSTATUS
  3. NTAPI
  4. NtQueryInformationProcess(
  5. _In_ HANDLE ProcessHandle,
  6. _In_ PROCESSINFOCLASS ProcessInformationClass,
  7. _Out_writes_bytes_(ProcessInformationLength) PVOID ProcessInformation,
  8. _In_ ULONG ProcessInformationLength,
  9. _Out_opt_ PULONG ReturnLength
  10. );
ProcessInformationClass is an enumeration that indicate the function code. ProcessMitigationPolicy(52) is used for querying the process mitigation policy. When you assign ProcessInformationClass argument as ProcessMitigationPolicy,the ProcessInformationLength is a pointer to a PROCESS_MITIGATION_POLICY_INFORMATION.
  1. typedef struct _PROCESS_MITIGATION_POLICY_INFORMATION
  2. {
  3. PROCESS_MITIGATION_POLICY Policy;
  4. union
  5. {
  6. PROCESS_MITIGATION_ASLR_POLICY ASLRPolicy;
  7. PROCESS_MITIGATION_STRICT_HANDLE_CHECK_POLICY StrictHandleCheckPolicy;
  8. PROCESS_MITIGATION_SYSTEM_CALL_DISABLE_POLICY SystemCallDisablePolicy;
  9. PROCESS_MITIGATION_EXTENSION_POINT_DISABLE_POLICY ExtensionPointDisablePolicy;
  10. PROCESS_MITIGATION_DYNAMIC_CODE_POLICY DynamicCodePolicy;
  11. PROCESS_MITIGATION_CONTROL_FLOW_GUARD_POLICY ControlFlowGuardPolicy;
  12. PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY SignaturePolicy;
  13. PROCESS_MITIGATION_FONT_DISABLE_POLICY FontDisablePolicy;
  14. PROCESS_MITIGATION_IMAGE_LOAD_POLICY ImageLoadPolicy;
  15. PROCESS_MITIGATION_SYSTEM_CALL_FILTER_POLICY SystemCallFilterPolicy;
  16. PROCESS_MITIGATION_PAYLOAD_RESTRICTION_POLICY PayloadRestrictionPolicy;
  17. PROCESS_MITIGATION_CHILD_PROCESS_POLICY ChildProcessPolicy;
  18. PROCESS_MITIGATION_SIDE_CHANNEL_ISOLATION_POLICY SideChannelIsolationPolicy;
  19. };
  20. } PROCESS_MITIGATION_POLICY_INFORMATION, *PPROCESS_MITIGATION_POLICY_INFORMATION;
This is a peach of NtQueryInformationProcess disassembly code in the ntoskrnl.By the reserve enginning we found that we must have the PROCESS_QUERY_INFORMATION permission with the process handle to invoke this function.
  1. case 52: // ProcessMitigationPolicy
  2. if (ProcessInformationLength != 8 )
  3. return 0xC0000004;
  4. MitigationCode = *(_DWORD *)ProcessInformation;
  5. if ( Handle == (HANDLE)-1i64 )
  6. {
  7. pObject = (PEPROCESS)PsGetCurrentProcess();
  8. }
  9. else
  10. {
  11. result = ObReferenceObjectByHandleWithTag(
  12. (ULONG_PTR)Handle,
  13. 0x400, //PROCESS_QUERY_INFORMATION
  14. PsProcessType,
  15. PreviousMode,
  16. 'yQsP',
  17. (__int64)&pObject,
  18. 0i64);
  19. if ( result < 0 )
  20. return result;
  21. }
So we can write a simple progarm to query the mitigation status of a process. It look like this:
  1. ClientId.UniqueProcess = PID;
  2. NtOpenProcess(
  3. &ProcHandle,
  4. PROCESS_QUERY_INFORMATION,
  5. &ObjAttr,
  6. &ClientId);
  7. NtQueryInformationProcess(
  8. ProcHandle,
  9. ProcessMitigationPolicy,
  10. RecvBuffer,
  11. RecvBufferSize,
  12. &RetSize);
Then i query the Microsoft Edge content process by this tool, and get the mitigation policy information as below.
  1. [*]ProcessDEPPolicy:
  2. MEM_EXECUTE_OPTION_DISABLE 1
  3. MEM_EXECUTE_OPTION_ENABLE 0
  4. MEM_EXECUTE_OPTION_DISABLE_THUNK_EMULATION 1
  5. MEM_EXECUTE_OPTION_PERMANENT 1
  6. MEM_EXECUTE_OPTION_EXECUTE_DISPATCH_ENABLE 0
  7. MEM_EXECUTE_OPTION_IMAGE_DISPATCH_ENABLE 0
  8. MEM_EXECUTE_OPTION_VALID_FLAGS 1
  9. [*]ProcessASLRPolicy:
  10. EnableBottomUpRandomization 1
  11. EnableForceRelocateImages 1
  12. EnableHighEntropy 1
  13. DisallowStrippedImages 1
  14. [*]ProcessDynamicCodePolicy:
  15. ProhibitDynamicCode 0
  16. AllowThreadOptOut 0
  17. AllowRemoteDowngrade 0
  18. AuditProhibitDynamicCode 0
  19. [*]StrictHandleCheckPolicy:
  20. RaiseExceptionOnInvalidHandleReference 1
  21. HandleExceptionsPermanentlyEnabled 1
  22. [*]SystemCallDisablePolicy:
  23. DisallowWin32kSystemCalls 0
  24. AuditDisallowWin32kSystemCalls 0
  25. ProcessExtensionPointDisablePolicy:
  26. DisableExtensionPoints 0
  27. [*]ProcessControlFlowGuardPolicy:
  28. EnableControlFlowGuard 1
  29. EnableExportSuppression 1
  30. StrictMode 0
  31. [*]ProcessSignaturePolicy:
  32. MicrosoftSignedOnly 0
  33. StoreSignedOnly 0
  34. MitigationOptIn 0
  35. AuditMicrosoftSignedOnly 0
  36. AuditStoreSignedOnly 0
  37. [*]ProcessFontDisablePolicy:
  38. DisableNonSystemFonts 0
  39. AuditNonSystemFontLoading 0
  40. [*]ProcessImageLoadPolicy:
  41. NoRemoteImages 1
  42. NoLowMandatoryLabelImages 1
  43. PreferSystem32Images 0
  44. AuditNoRemoteImages 0
  45. AuditNoLowMandatoryLabelImages 0
  46. [*]SystemCallFilterPolicy:
  47. FilterId 0
  48. [*]PayloadRestrictionPolicy:
  49. EnableExportAddressFilter 0
  50. AuditExportAddressFilter 0
  51. EnableExportAddressFilterPlus 0
  52. AuditExportAddressFilterPlus 0
  53. EnableImportAddressFilter 0
  54. AuditImportAddressFilter 0
  55. EnableRopStackPivot 0
  56. AuditRopStackPivot 0
  57. EnableRopCallerCheck 0
  58. AuditRopCallerCheck 0
  59. EnableRopSimExec 0
  60. AuditRopSimExec 0
  61. [*]ProcessChildProcessPolicy:
  62. NoChildProcessCreation 1
  63. AuditNoChildProcessCreation 0
  64. AllowSecureProcessCreation 0
  65. [*]ProcessSideChannelIsolationPolicy:
  66. SmtBranchTargetIsolation 0
  67. IsolateSecurityDomain 0
  68. DisablePageCombine 0
  69. SpeculativeStoreBypassDisable 0

ProcessImageLoadPolicy

When get or set ProcessImageLoadPolicy mitigation by PROCESS_MITIGATION_IMAGE_LOAD_POLICY struct. And this struct's declaration is below.We can see there are 5 levels restricted for image loading.
  1. typedef struct _PROCESS_MITIGATION_IMAGE_LOAD_POLICY {
  2. union {
  3. DWORD Flags;
  4. struct {
  5. DWORD NoRemoteImages : 1;
  6. DWORD NoLowMandatoryLabelImages : 1;
  7. DWORD PreferSystem32Images : 1;
  8. DWORD AuditNoRemoteImages : 1;
  9. DWORD AuditNoLowMandatoryLabelImages : 1;
  10. DWORD ReservedFlags : 27;
  11. } DUMMYSTRUCTNAME;
  12. } DUMMYUNIONNAME;
  13. } PROCESS_MITIGATION_IMAGE_LOAD_POLICY, *PPROCESS_MITIGATION_IMAGE_LOAD_POLICY;
In the Windows kernel section has three types.
  1. PhysicalSection
  2. ImageSection
  3. DataSection
NtCreateSection is the interface to create a section object in Windows.If we specify SEC_IMAGE flag when invoke NtCreateSection ,it will set a bit flag named MMSECTION_FLAGS in section.ControlArea after the section object has be created. Then it will execute into the MiMapViewOfImageSection when we call the NtMapViewOfSection function with this section handle.
  1. 1.NtMapViewOfSection
  2. 2.MiMapViewOfSection
  3. 3.MiMapViewOfImageSection
  4. 4.MiAllowImageMap
The ProcessImageLoadPolicy mitigation is implement in the MiAllowImageMap function.
MiAllowImageMap is splice into two piece.
Firstly, it check for remote image load.
  1. IsProhibitRemoteImageMapEnable = Process->MitigationFlags & 0x80000; // ProhibitRemoteImageMap
  2. IsAuditProhibitRemoteImageMap = Process->MitigationFlags & 0x100000; // AuditProhibitRemoteImageMap
  3. if ((IsProhibitRemoteImageMapEnable || IsAuditProhibitRemoteImageMap) &&
  4. (Section->u1.ControlArea & 3)) // AuditProhibitRemoteImageMap
  5. {
  6. if ( IsProhibitRemoteImageMapEnable )
  7. return STATUS_ACCESS_DENIED;
  8. }
Secondly, it checks for integrity level. It checks the source image file's integrity level by the image file's file object's security descripter.
  1. MitigationFlags = Process->MitigationFlags;
  2. IsAuditProhibitLowILImageMap = MitigationFlags & 0x400000; // AuditProhibitLowILImageMap
  3. IsProhibitLowILImageMap = MitigationFlags & 0x200000; // ProhibitLowILImageMap
  4. if ( IsProhibitLowILImageMap || IsAuditProhibitLowILImageMap )
  5. {
  6. MemoryAllocated = 0;
  7. FileObject = MiReferenceControlAreaFile(pControlArea);
  8. status = ObpGetObjectSecurity(FileObject, &SecurityDescriptor, &MemoryAllocated);
  9. if (!NT_SUCCESS(status))
  10. {
  11. status = STATUS_ACCESS_DENIED;
  12. }
  13. else
  14. {
  15. if (SeQueryMandatoryLabel(SecurityDescriptor) <= 0x1000 &&
  16. !SeGetTrustLabelAce(SecurityDescriptor) )
  17. status = STATUS_ACCESS_DENIED;
  18. ObReleaseObjectSecurity(SecurityDescriptor, MemoryAllocated);
  19. }
  20. MiDereferenceControlAreaFile(pControlArea, FileObject);
  21. }
SeQueryMandatoryLabel is a function for getting the integrity level, it's return value indicates the integrity level value.This is because of the mandatory label is a series of SID which have the same format. You can find them out in the MSDN document,And Microsoft named them as well-known SID.
  1. SID: S-1-16-0
  2. Name: Untrusted Mandatory Level
  3. Description: An untrusted integrity level. Note Added in Windows Vista and Windows Server 2008
  4. Note Added in Windows Vista and Windows Server 2008
  5. SID: S-1-16-4096
  6. Name: Low Mandatory Level
  7. Description: A low integrity level.
  8. Note Added in Windows Vista and Windows Server 2008
  9. SID: S-1-16-8192
  10. Name: Medium Mandatory Level
  11. Description: A medium integrity level.
  12. Note Added in Windows Vista and Windows Server 2008
  13. SID: S-1-16-8448
  14. Name: Medium Plus Mandatory Level
  15. Description: A medium plus integrity level.
  16. Note Added in Windows Vista and Windows Server 2008
  17. SID: S-1-16-12288
  18. Name: High Mandatory Level
  19. Description: A high integrity level.
  20. Note Added in Windows Vista and Windows Server 2008
  21. SID: S-1-16-16384
  22. Name: System Mandatory Level
  23. Description: A system integrity level.
  24. Note Added in Windows Vista and Windows Server 2008
  25. SID: S-1-16-20480
  26. Name: Protected Process Mandatory Level
  27. Description: A protected-process integrity level.
  28. Note Added in Windows Vista and Windows Server 2008
  29. SID: S-1-16-28672
  30. Name: Secure Process Mandatory Level
  31. Description: A secure process integrity level.
  32. Note Added in Windows Vista and Windows Server 2008
According to this, we known if the return value less than 0x1000 it indicate the security descripter's mandatory label is equal or less than Low Mandatory Level.

ProcessChildProcessPolicy

ProcessChildProcessPolicy has tree levels.
  1. typedef struct _PROCESS_MITIGATION_CHILD_PROCESS_POLICY {
  2. union {
  3. DWORD Flags;
  4. struct {
  5. DWORD NoChildProcessCreation : 1;
  6. DWORD AuditNoChildProcessCreation : 1;
  7. DWORD AllowSecureProcessCreation : 1;
  8. DWORD ReservedFlags : 29;
  9. } DUMMYSTRUCTNAME;
  10. } DUMMYUNIONNAME;
  11. } PROCESS_MITIGATION_CHILD_PROCESS_POLICY, *PPROCESS_MITIGATION_CHILD_PROCESS_POLICY;
At the branch that handles ProcessChildProcessPolicy logic, it invokes a function named PspGetNoChildProcessRestrictedPolicy for getting the current process's child process mitigation policy status.
  1. ChildPolicyLevel = PspGetNoChildProcessRestrictedPolicy(TargetProcess);
  2. if(ChildPolicyLevel == 1)
  3. {
  4. PolicyInfo.NoChildProcessCreation = 1;
  5. }
  6. else if(ChildPolicyLevel == 2)
  7. {
  8. PolicyInfo.NoChildProcessCreation = 1;
  9. PolicyInfo.AllowSecureProcessCreation = 1;
  10. }
  11. else if(ChildPolicyLevel == 3)
  12. {
  13. PolicyInfo.AuditNoChildProcessCreation = 1;
  14. }
Unusually, it does not get the policy status from the EPROCESS's MitigationFlags field.In fact, it get some bit flags from the process token's TokenFlags field.The fake code look like this.
  1. CurThread = KeGetCurrentThread();
  2. TokenFlags = PrimaryToken->TokenFlags;
  3. *NoChildProcessCreationFlag = (TokenFlags >> 19) & 1; // 20 bit
  4. *AllowSecureProcessCreationFlag = (TokenFlags >> 20) & 1; // 21 bit
  5. *AuditNoChildProcessCreationFlag = (TokenFlags >> 21) & 1; // 22 bit
There two ways to create a process.One is the NtCreateUserProcess function, and the other is the NtCreateProcess/NtCreateProcessEx.The NtCreateUserProcess is a newer native invoke that was introduced in Windows Vista. When we call CreateProcessW in user mode code, it will invoke NtCreateUserProcess function finally.
The ProcessChildProcessPolicy mitigation is implementation in the SeSubProcessToken.
  1. 1.NtCreateUserProcess
  2. 2.PspAllocateProcess
  3. 3.PspInitializeProcessSecurity
  4. 4.SeSubProcessToken
The SeSubProcessToken function is also invoke the PspGetNoChildProcessRestrictedPolicy to determine the the child can be created.If the creation desired is refused the NtCreateUserProcess will return the STATUS_CHILD_PROCESS_BLOCKED.

ACCESS_MASK: Specific rights of NT objects

#define FILE_READ_DATA            ( 0x0001 )    // file & pipe #define FILE_LIST_DIRECTORY       ( 0x0001 )    // directory #define FILE...