PE-sieve
Scans all running processes. Recognizes and dumps a variety of potentially malicious implants (replaced/implanted PEs, shellcodes, hooks, in-memory patches).
Loading...
Searching...
No Matches
process_privilege.cpp
Go to the documentation of this file.
1#include "process_privilege.h"
2#include "process_util.h"
3
4#include <iostream>
5
6namespace pesieve {
7 namespace util {
8
9 inline HMODULE get_or_load_module(const char* name)
10 {
11 HMODULE hndl = GetModuleHandleA(name);
12 if (!hndl) {
13 hndl = LoadLibraryA(name);
14 }
15 return hndl;
16 }
17
18 /*
19 based on: https://support.microsoft.com/en-us/help/131065/how-to-obtain-a-handle-to-any-process-with-sedebugprivilege
20 */
22 HANDLE hToken, // token handle
23 LPCTSTR Privilege, // Privilege to enable/disable
24 BOOL bEnablePrivilege // TRUE to enable. FALSE to disable
25 )
26 {
27 TOKEN_PRIVILEGES tp;
28 LUID luid;
29 TOKEN_PRIVILEGES tpPrevious;
30 DWORD cbPrevious = sizeof(TOKEN_PRIVILEGES);
31
32 if (!LookupPrivilegeValueA(nullptr, Privilege, &luid)) {
33 return FALSE;
34 }
35 // get current privilege
36 tp.PrivilegeCount = 1;
37 tp.Privileges[0].Luid = luid;
38 tp.Privileges[0].Attributes = 0;
39
40 AdjustTokenPrivileges(
41 hToken,
42 FALSE,
43 &tp,
44 sizeof(TOKEN_PRIVILEGES),
45 &tpPrevious,
46 &cbPrevious
47 );
48
49 if (GetLastError() != ERROR_SUCCESS) {
50 return FALSE;
51 }
52 // set privilege based on previous setting
53 tpPrevious.PrivilegeCount = 1;
54 tpPrevious.Privileges[0].Luid = luid;
55
56 if (bEnablePrivilege) {
57 tpPrevious.Privileges[0].Attributes |= (SE_PRIVILEGE_ENABLED);
58 }
59 else {
60 tpPrevious.Privileges[0].Attributes ^= (SE_PRIVILEGE_ENABLED & tpPrevious.Privileges[0].Attributes);
61 }
62
63 AdjustTokenPrivileges(
64 hToken,
65 FALSE,
66 &tpPrevious,
67 cbPrevious,
68 NULL,
69 NULL
70 );
71
72 if (GetLastError() != ERROR_SUCCESS) {
73 return FALSE;
74 }
75 return TRUE;
76 }
77
78 BOOL _get_process_DEP_policy(HANDLE processHandle, DWORD &flags, BOOL &is_permanent)
79 {
80 //load the function GetProcessDEPPolicy dynamically, to provide backward compatibility with systems that don't have it
81 HMODULE kernelLib = get_or_load_module("kernel32.dll");
82 if (!kernelLib) return FALSE;
83
84 FARPROC procPtr = GetProcAddress(kernelLib, "GetProcessDEPPolicy");
85 if (!procPtr) return FALSE;
86
87 BOOL(WINAPI *_GetProcessDEPPolicy)(HANDLE, LPDWORD, PBOOL) = (BOOL(WINAPI *)(HANDLE, LPDWORD, PBOOL))procPtr;
88 return _GetProcessDEPPolicy(processHandle, &flags, &is_permanent);
89 }
90
91 DEP_SYSTEM_POLICY_TYPE _get_system_DEP_policy()
92 {
93 //load the function GetSystemDEPPolicy dynamically, to provide backward compatibility with systems that don't have it
94 HMODULE kernelLib = get_or_load_module("kernel32.dll");
95 if (!kernelLib) return DEPPolicyAlwaysOff;
96
97 FARPROC procPtr = GetProcAddress(kernelLib, "GetSystemDEPPolicy");
98 if (!procPtr) return DEPPolicyAlwaysOff; //in old systems where this function does not exist, DEP is Off
99
100 DEP_SYSTEM_POLICY_TYPE(WINAPI *_GetSystemDEPPolicy)(VOID) = (DEP_SYSTEM_POLICY_TYPE(WINAPI *)(VOID))procPtr;
101 return _GetSystemDEPPolicy();
102 }
103
104 };
105};
106
108{
109 HANDLE hToken;
110 if (!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &hToken)) {
111 if (GetLastError() == ERROR_NO_TOKEN) {
112 if (!ImpersonateSelf(SecurityImpersonation)) return false;
113 if(!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &hToken)){
114 std::cerr << "Error: cannot open the token" << std::endl;
115 return false;
116 }
117 }
118 }
119 bool is_ok = false;
120 // enable SeDebugPrivilege
121 if (set_privilege(hToken, SE_DEBUG_NAME, TRUE)) {
122 is_ok = true;
123 }
124 // close token handle
125 CloseHandle(hToken);
126 return is_ok;
127}
128
130{
131 DWORD dwIntegrityLevel = *GetSidSubAuthority(pTIL->Label.Sid,
132 (DWORD)(UCHAR)(*GetSidSubAuthorityCount(pTIL->Label.Sid) - 1));
133
134 if (dwIntegrityLevel == SECURITY_MANDATORY_LOW_RID)
135 {
136 // Low Integrity
138 }
139 if (dwIntegrityLevel >= SECURITY_MANDATORY_MEDIUM_RID &&
140 dwIntegrityLevel < SECURITY_MANDATORY_HIGH_RID)
141 {
142 // Medium Integrity
144 }
145 if (dwIntegrityLevel >= SECURITY_MANDATORY_HIGH_RID &&
146 dwIntegrityLevel < SECURITY_MANDATORY_SYSTEM_RID)
147 {
148 // High Integrity
150 }
151 if (dwIntegrityLevel >= SECURITY_MANDATORY_SYSTEM_RID)
152 {
153 // System Integrity
155 }
157}
158
160{
161 if (!hProcess) {
162 return INTEGRITY_UNKNOWN;
163 }
164
165 HANDLE hToken = NULL;
166 if (!OpenProcessToken(hProcess, TOKEN_QUERY, &hToken)) {
167 //std::cerr << "[-][Cannot Open the ProcessToken" << std::endl;
168 return INTEGRITY_UNKNOWN;
169 }
170 DWORD dwLength = sizeof(TOKEN_GROUPS);
171 TOKEN_MANDATORY_LABEL *ptg = (TOKEN_MANDATORY_LABEL*) calloc(1, dwLength);
172
173 if (!GetTokenInformation(
174 hToken, // handle to the access token
175 TokenIntegrityLevel, // get information about the token's groups
176 (LPVOID)ptg, // pointer to TOKEN_MANDATORY_LABEL buffer
177 0, // size of buffer
178 &dwLength // receives required buffer size
179 ))
180 {
181 free(ptg); ptg = nullptr;
182 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
183 CloseHandle(hToken);
184 return INTEGRITY_UNKNOWN;
185 }
186 ptg = (TOKEN_MANDATORY_LABEL*)calloc(1, dwLength);
187 if (!ptg) {
188 //failed allocating
189 CloseHandle(hToken);
190 return INTEGRITY_UNKNOWN;
191 }
192 }
194 if (GetTokenInformation(
195 hToken, // handle to the access token
196 TokenIntegrityLevel, // get information about the token's groups
197 (LPVOID)ptg, // pointer to TOKEN_MANDATORY_LABEL buffer
198 dwLength, // size of buffer
199 &dwLength // receives required buffer size
200 ))
201 {
202 level = translate_integrity_level(ptg);
203 }
204 //cleanup:
205 free(ptg); ptg = nullptr;
206 CloseHandle(hToken);
207 return level;
208}
209
210bool pesieve::util::is_DEP_enabled(HANDLE processHandle)
211{
212 DEP_SYSTEM_POLICY_TYPE global_dep = _get_system_DEP_policy();
213 if (global_dep == DEPPolicyAlwaysOff) {
214 return false;
215 }
216 if (global_dep == DEPPolicyAlwaysOn) {
217 return true;
218 }
219 //
220 DWORD flags = 0;
221 BOOL is_permanent = FALSE;
222 BOOL is_ok = _get_process_DEP_policy(processHandle, flags, is_permanent);
223 if (!is_ok) {
224#ifdef _WIN64
225 BOOL isRemoteWow64 = FALSE;
226 is_process_wow64(processHandle, &isRemoteWow64);
227 if (!isRemoteWow64) {
228 return true; // it is a 64 bit process, DEP is enabled
229 }
230#endif
231#ifdef _DEBUG
232 std::cerr << "Could not fetch the DEP status\n";
233#endif
234 return false;
235 }
236 const bool is_DEP = (flags & PROCESS_DEP_ENABLE) || (flags & PROCESS_DEP_DISABLE_ATL_THUNK_EMULATION);
237 return is_DEP;
238}
process_integrity_t get_integrity_level(HANDLE hProcess)
DEP_SYSTEM_POLICY_TYPE _get_system_DEP_policy()
BOOL is_process_wow64(IN HANDLE processHandle, OUT BOOL *isProcWow64)
bool is_DEP_enabled(HANDLE hProcess)
BOOL set_privilege(HANDLE hToken, LPCTSTR Privilege, BOOL bEnablePrivilege)
BOOL _get_process_DEP_policy(HANDLE processHandle, DWORD &flags, BOOL &is_permanent)
BOOL(CALLBACK *_MiniDumpWriteDump)(HANDLE hProcess
DWORD(__stdcall *_PssCaptureSnapshot)(HANDLE ProcessHandle
HMODULE get_or_load_module(const char *name)
pesieve::util::process_integrity_t translate_integrity_level(TOKEN_MANDATORY_LABEL *pTIL)