new upstream release (3.3.0); modify package compatibility for Stretch
[ossec-hids.git] / src / rootcheck / run_rk_check.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 #include "shared.h"
11 #include "rootcheck.h"
12
13
14 /* Report a problem */
15 int notify_rk(int rk_type, const char *msg)
16 {
17     /* Non-queue notification */
18     if (rootcheck.notify != QUEUE) {
19         if (rk_type == ALERT_OK) {
20             printf("[OK]: %s\n", msg);
21         } else if (rk_type == ALERT_SYSTEM_ERR) {
22             printf("[ERR]: %s\n", msg);
23         } else if (rk_type == ALERT_POLICY_VIOLATION) {
24             printf("[INFO]: %s\n", msg);
25         } else {
26             printf("[FAILED]: %s\n", msg);
27         }
28
29         printf("\n");
30         return (0);
31     }
32
33     /* No need to alert on that to the server */
34     if (rk_type <= ALERT_SYSTEM_ERR) {
35         return (0);
36     }
37
38 #ifdef OSSECHIDS
39     /* When running in context of OSSEC-HIDS, send problem to the rootcheck queue */
40     if (SendMSG(rootcheck.queue, msg, ROOTCHECK, ROOTCHECK_MQ) < 0) {
41         merror(QUEUE_SEND, ARGV0);
42
43         if ((rootcheck.queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) {
44             ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH);
45         }
46
47         if (SendMSG(rootcheck.queue, msg, ROOTCHECK, ROOTCHECK_MQ) < 0) {
48             ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH);
49         }
50     }
51 #endif
52
53     return (0);
54 }
55
56 /* Execute the rootkit checks */
57 void run_rk_check()
58 {
59     time_t time1;
60     time_t time2;
61     FILE *fp;
62     OSList *plist;
63
64 #ifndef WIN32
65     /* On non-Windows, always start at / */
66     size_t i;
67     char basedir[] = "/";
68
69     /* Removing the last / from basedir */
70     i = strlen(basedir);
71     if (i > 0) {
72         if (basedir[i - 1] == '/') {
73             basedir[i - 1] = '\0';
74         }
75     }
76 #else
77     /* On Windows, always start at C:\ */
78     char basedir[] = "C:\\";
79
80 #endif
81
82     /* Set basedir */
83     if (rootcheck.basedir == NULL) {
84         rootcheck.basedir = basedir;
85     }
86
87     time1 = time(0);
88
89     /* Initial message */
90     if (rootcheck.notify != QUEUE) {
91         printf("\n");
92         printf("** Starting Rootcheck v0.9 by Daniel B. Cid        **\n");
93         printf("** http://www.ossec.net/en/about.html#dev-team     **\n");
94         printf("** http://www.ossec.net/rootcheck/                 **\n\n");
95         printf("Be patient, it may take a few minutes to complete...\n");
96         printf("\n");
97     }
98
99     /* Clean the global variables */
100     rk_sys_count = 0;
101     rk_sys_file[rk_sys_count] = NULL;
102     rk_sys_name[rk_sys_count] = NULL;
103
104     /* Send scan start message */
105     notify_rk(ALERT_POLICY_VIOLATION, "Starting rootcheck scan.");
106     if (rootcheck.notify == QUEUE) {
107         merror("%s: INFO: Starting rootcheck scan.", ARGV0);
108     }
109
110     /* Check for Rootkits */
111     /* Open rootkit_files and pass the pointer to check_rc_files */
112     if (rootcheck.checks.rc_files) {
113         if (!rootcheck.rootkit_files) {
114 #ifndef WIN32
115             merror("%s: No rootcheck_files file configured.", ARGV0);
116 #endif
117         } else {
118             fp = fopen(rootcheck.rootkit_files, "r");
119             if (!fp) {
120                 merror("%s: No rootcheck_files file: '%s'", ARGV0,
121                        rootcheck.rootkit_files);
122             }
123
124             else {
125                 check_rc_files(rootcheck.basedir, fp);
126
127                 fclose(fp);
128             }
129         }
130     }
131
132     /* Check for trojan entries in common binaries */
133     if (rootcheck.checks.rc_trojans) {
134         if (!rootcheck.rootkit_trojans) {
135 #ifndef WIN32
136             merror("%s: No rootcheck_trojans file configured.", ARGV0);
137 #endif
138         } else {
139             fp = fopen(rootcheck.rootkit_trojans, "r");
140             if (!fp) {
141                 merror("%s: No rootcheck_trojans file: '%s'", ARGV0,
142                        rootcheck.rootkit_trojans);
143             } else {
144 #ifndef HPUX
145                 check_rc_trojans(rootcheck.basedir, fp);
146 #endif
147                 fclose(fp);
148             }
149         }
150     }
151
152 #ifdef WIN32
153     /* Get process list */
154     plist = os_get_process_list();
155
156     /* Windows audit check */
157     if (rootcheck.checks.rc_winaudit) {
158         if (!rootcheck.winaudit) {
159             merror("%s: No winaudit file configured.", ARGV0);
160         } else {
161             fp = fopen(rootcheck.winaudit, "r");
162             if (!fp) {
163                 merror("%s: No winaudit file: '%s'", ARGV0,
164                        rootcheck.winaudit);
165             } else {
166                 check_rc_winaudit(fp, plist);
167                 fclose(fp);
168             }
169         }
170     }
171
172     /* Windows malware */
173     if (rootcheck.checks.rc_winmalware) {
174         if (!rootcheck.winmalware) {
175             merror("%s: No winmalware file configured.", ARGV0);
176         } else {
177             fp = fopen(rootcheck.winmalware, "r");
178             if (!fp) {
179                 merror("%s: No winmalware file: '%s'", ARGV0,
180                        rootcheck.winmalware);
181             } else {
182                 check_rc_winmalware(fp, plist);
183                 fclose(fp);
184             }
185         }
186     }
187
188     /* Windows Apps */
189     if (rootcheck.checks.rc_winapps) {
190         if (!rootcheck.winapps) {
191             merror("%s: No winapps file configured.", ARGV0);
192         } else {
193             fp = fopen(rootcheck.winapps, "r");
194             if (!fp) {
195                 merror("%s: No winapps file: '%s'", ARGV0,
196                        rootcheck.winapps);
197             } else {
198                 check_rc_winapps(fp, plist);
199                 fclose(fp);
200             }
201         }
202     }
203
204     /* Free the process list */
205     del_plist((void *)plist);
206
207 #else
208     /* Checks for other non-Windows */
209
210     /* Unix audit check ***/
211     if (rootcheck.checks.rc_unixaudit) {
212         if (rootcheck.unixaudit) {
213             /* Get process list */
214             plist = os_get_process_list();
215
216             i = 0;
217             while (rootcheck.unixaudit[i]) {
218                 fp = fopen(rootcheck.unixaudit[i], "r");
219                 if (!fp) {
220                     merror("%s: No unixaudit file: '%s'", ARGV0,
221                            rootcheck.unixaudit[i]);
222                 } else {
223                     /* Run unix audit */
224                     check_rc_unixaudit(fp, plist);
225                     fclose(fp);
226                 }
227
228                 i++;
229             }
230
231             /* Free list */
232             del_plist(plist);
233         }
234     }
235
236 #endif /* !WIN32 */
237
238     /* Check for files in the /dev filesystem */
239     if (rootcheck.checks.rc_dev) {
240         debug1("%s: DEBUG: Going into check_rc_dev", ARGV0);
241         check_rc_dev(rootcheck.basedir);
242         debug1("%s: DEBUG: Exiting check_rc_dev", ARGV0);
243     }
244
245     /* Scan the whole system for additional issues */
246     if (rootcheck.checks.rc_sys) {
247         debug1("%s: DEBUG: Going into check_rc_sys", ARGV0);
248         check_rc_sys(rootcheck.basedir);
249         debug1("%s: DEBUG: Exiting check_rc_sys", ARGV0);
250     }
251
252     /* Check processes */
253     if (rootcheck.checks.rc_pids) {
254         debug1("%s: DEBUG: Going into check_rc_pids", ARGV0);
255         check_rc_pids();
256         debug1("%s: DEBUG: Exiting check_rc_pids", ARGV0);
257     }
258
259     /* Check all ports */
260     if (rootcheck.checks.rc_ports) {
261         debug1("%s: DEBUG: Going into check_rc_ports", ARGV0);
262         check_rc_ports();
263         debug1("%s: DEBUG: Exiting check_rc_ports", ARGV0);
264
265         /* Check open ports */
266         debug1("%s: DEBUG: Going into check_open_ports", ARGV0);
267         check_open_ports();
268         debug1("%s: DEBUG: Exiting check_open_ports", ARGV0);
269     }
270
271     /* Check interfaces */
272     if (rootcheck.checks.rc_if) {
273         debug1("%s: DEBUG: Going into check_rc_if", ARGV0);
274         check_rc_if();
275         debug1("%s: DEBUG: Exiting check_rc_if", ARGV0);
276     }
277
278     debug1("%s: DEBUG: Completed with all checks.", ARGV0);
279
280     /* Clean the global memory */
281     {
282         int li;
283         for (li = 0; li <= rk_sys_count; li++) {
284             if (!rk_sys_file[li] ||
285                     !rk_sys_name[li]) {
286                 break;
287             }
288
289             free(rk_sys_file[li]);
290             free(rk_sys_name[li]);
291         }
292     }
293
294     /* Final message */
295     time2 = time(0);
296
297     if (rootcheck.notify != QUEUE) {
298         printf("\n");
299         printf("- Scan completed in %d seconds.\n\n", (int)(time2 - time1));
300     } else {
301         sleep(5);
302     }
303
304     /* Send scan ending message */
305     notify_rk(ALERT_POLICY_VIOLATION, "Ending rootcheck scan.");
306     if (rootcheck.notify == QUEUE) {
307         merror("%s: INFO: Ending rootcheck scan.", ARGV0);
308     }
309
310     debug1("%s: DEBUG: Leaving run_rk_check", ARGV0);
311     return;
312 }
313