new upstream release (3.3.0); modify package compatibility for Stretch
[ossec-hids.git] / src / rootcheck / win-process.c
1 /* Copyright (C) 2009 Trend Micro Inc.
2  * All right reserved.
3  *
4  * This program is a free software; you can redistribute it
5  * and/or modify it under the terms of the GNU General Public
6  * License (version 2) as published by the FSF - Free Software
7  * Foundation
8  */
9
10 #ifdef WIN32
11 #include "shared.h"
12 #include "rootcheck.h"
13
14 #include <tlhelp32.h>
15 #include <psapi.h>
16
17
18 /* Set Debug privilege
19  * See: "How to obtain a handle to any process with SeDebugPrivilege"
20  * http://support.microsoft.com/kb/131065/en-us
21  */
22 int os_win32_setdebugpriv(HANDLE h, int en)
23 {
24     TOKEN_PRIVILEGES tp;
25     TOKEN_PRIVILEGES tpPrevious;
26     LUID luid;
27     DWORD cbPrevious = sizeof(TOKEN_PRIVILEGES);
28
29     if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) {
30         return (0);
31     }
32
33     tp.PrivilegeCount = 1;
34     tp.Privileges[0].Luid = luid;
35     tp.Privileges[0].Attributes = 0;
36
37     AdjustTokenPrivileges(h, FALSE, &tp, sizeof(TOKEN_PRIVILEGES),
38                           &tpPrevious, &cbPrevious);
39
40     if (GetLastError() != ERROR_SUCCESS) {
41         return (0);
42     }
43
44     tpPrevious.PrivilegeCount = 1;
45     tpPrevious.Privileges[0].Luid = luid;
46
47     /* If en is set to true, we enable the privilege */
48     if (en) {
49         tpPrevious.Privileges[0].Attributes |= (SE_PRIVILEGE_ENABLED);
50     } else {
51         tpPrevious.Privileges[0].Attributes ^= (SE_PRIVILEGE_ENABLED &
52                                                 tpPrevious.Privileges[0].Attributes);
53     }
54
55     AdjustTokenPrivileges(h, FALSE, &tpPrevious, cbPrevious, NULL, NULL);
56     if (GetLastError() != ERROR_SUCCESS) {
57         return (0);
58     }
59
60     return (1);
61 }
62
63 /* Get list of win32 processes */
64 OSList *os_get_process_list()
65 {
66     OSList *p_list = NULL;
67     HANDLE hsnap;
68     HANDLE hpriv;
69     PROCESSENTRY32 p_entry;
70     p_entry.dwSize = sizeof(PROCESSENTRY32);
71
72     /* Get token to enable Debug privilege */
73     if (!OpenThreadToken(GetCurrentThread(),
74                          TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &hpriv)) {
75         if (GetLastError() == ERROR_NO_TOKEN) {
76             if (!ImpersonateSelf(SecurityImpersonation)) {
77                 merror("%s: ERROR: os_get_win32_process_list -> "
78                        "ImpersonateSelf", ARGV0);
79                 return (NULL);
80             }
81
82             if (!OpenThreadToken(GetCurrentThread(),
83                                  TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
84                                  FALSE, &hpriv)) {
85                 merror("%s: ERROR: os_get_win32_process_list -> "
86                        "OpenThread", ARGV0);
87                 return (NULL) ;
88             }
89         } else {
90             merror("%s: ERROR: os_get_win32_process_list -> OpenThread", ARGV0);
91             return (NULL);
92         }
93     }
94
95     /* Enable debug privilege */
96     if (!os_win32_setdebugpriv(hpriv, 1)) {
97         merror("%s: ERROR: os_win32_setdebugpriv", ARGV0);
98         CloseHandle(hpriv);
99         return (NULL);
100     }
101
102     /* Make a snapshot of every process */
103     hsnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
104     if (hsnap == INVALID_HANDLE_VALUE) {
105         merror("%s: ERROR: CreateToolhelp32Snapshot", ARGV0);
106         return (NULL);
107     }
108
109     /* Get first and second processes -- system entries */
110     if (!Process32First(hsnap, &p_entry) && !Process32Next(hsnap, &p_entry )) {
111         merror("%s: ERROR: Process32First", ARGV0);
112         CloseHandle(hsnap);
113         return (NULL);
114     }
115
116     /* Create process list */
117     p_list = OSList_Create();
118     if (!p_list) {
119         CloseHandle(hsnap);
120         merror(LIST_ERROR, ARGV0);
121         return (0);
122     }
123
124     /* Get each process name and path */
125     while (Process32Next( hsnap, &p_entry)) {
126         char *p_name;
127         char *p_path;
128         Proc_Info *p_info;
129
130         /* Set process name */
131         os_strdup(p_entry.szExeFile, p_name);
132
133         /* Get additional information from modules */
134         HANDLE hmod = INVALID_HANDLE_VALUE;
135         MODULEENTRY32 m_entry;
136         m_entry.dwSize = sizeof(MODULEENTRY32);
137
138         /* Snapshot of the process */
139         hmod = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, p_entry.th32ProcessID);
140
141         if (hmod == INVALID_HANDLE_VALUE) {
142             os_strdup(p_name, p_path);
143         } else if (!Module32First(hmod, &m_entry)) {
144             /* Get executable path (first entry in the module list) */
145             CloseHandle(hmod);
146             os_strdup(p_name, p_path);
147         } else {
148             os_strdup(m_entry.szExePath, p_path);
149             CloseHandle(hmod);
150         }
151
152         os_calloc(1, sizeof(Proc_Info), p_info);
153         p_info->p_name = p_name;
154         p_info->p_path = p_path;
155         OSList_AddData(p_list, p_info);
156     }
157
158     /* Remove debug privileges */
159     os_win32_setdebugpriv(hpriv, 0);
160
161     CloseHandle(hsnap);
162     return (p_list);
163 }
164
165 #endif /* WIN32 */
166