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 #ifndef WIN32
11 #include <sys/types.h>
12 #include <sys/socket.h>
13 #include <sys/ioctl.h>
14 #include <net/if.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <unistd.h>
18 #include <string.h>
19
20 #ifdef SOLARIS
21 #include <stropts.h>
22 #include <sys/sockio.h>
23 #endif
24
25 #include "headers/debug_op.h"
26 #include "headers/defs.h"
27 #include "rootcheck.h"
28
29 #ifndef IFCONFIG
30 #define IFCONFIG "ifconfig %s | grep PROMISC > /dev/null 2>&1"
31 #endif
32
33 /* Prototypes */
34 static int run_ifconfig(const char *ifconfig);
35
36
37 /* Execute the ifconfig command
38 * Returns 1 if the interface is in promiscuous mode
39 */
run_ifconfig(const char * ifconfig)40 static int run_ifconfig(const char *ifconfig)
41 {
42 char nt[OS_SIZE_1024 + 1];
43
44 snprintf(nt, OS_SIZE_1024, IFCONFIG, ifconfig);
45 if (system(nt) == 0) {
46 return (1);
47 }
48
49 return (0);
50 }
51
52 /* Check all interfaces for promiscuous mode */
check_rc_if()53 void check_rc_if()
54 {
55 int _fd, _errors = 0, _total = 0;
56 struct ifreq tmp_str[16];
57
58 struct ifconf _if;
59 struct ifreq *_ir;
60 struct ifreq *_ifend;
61 struct ifreq _ifr;
62
63 _fd = socket(AF_INET, SOCK_DGRAM, 0);
64 if (_fd < 0) {
65 merror("%s: Error checking interfaces (socket)", ARGV0);
66 return;
67 }
68
69 memset(tmp_str, 0, sizeof(struct ifreq) * 16);
70 _if.ifc_len = sizeof(tmp_str);
71 _if.ifc_buf = (caddr_t)(tmp_str);
72
73 if (ioctl(_fd, SIOCGIFCONF, &_if) < 0) {
74 close(_fd);
75 merror("%s: Error checking interfaces (ioctl)", ARGV0);
76 return;
77 }
78
79 _ifend = (struct ifreq *) (void *) ((char *)tmp_str + _if.ifc_len);
80 _ir = tmp_str;
81
82 /* Loop over all interfaces */
83 for (; _ir < _ifend; _ir++) {
84 strncpy(_ifr.ifr_name, _ir->ifr_name, sizeof(_ifr.ifr_name));
85
86 /* Get information from each interface */
87 if (ioctl(_fd, SIOCGIFFLAGS, (char *)&_ifr) == -1) {
88 continue;
89 }
90
91 _total++;
92
93 if ((_ifr.ifr_flags & IFF_PROMISC) ) {
94 char op_msg[OS_SIZE_1024 + 1];
95 if (run_ifconfig(_ifr.ifr_name)) {
96 snprintf(op_msg, OS_SIZE_1024, "Interface '%s' in promiscuous"
97 " mode.", _ifr.ifr_name);
98 notify_rk(ALERT_SYSTEM_CRIT, op_msg);
99 } else {
100 snprintf(op_msg, OS_SIZE_1024, "Interface '%s' in promiscuous"
101 " mode, but ifconfig is not showing it"
102 "(probably trojaned).", _ifr.ifr_name);
103 notify_rk(ALERT_ROOTKIT_FOUND, op_msg);
104 }
105 _errors++;
106 }
107 }
108 close(_fd);
109
110 if (_errors == 0) {
111 char op_msg[OS_SIZE_1024 + 1];
112 snprintf(op_msg, OS_SIZE_1024, "No problem detected on ifconfig/ifs."
113 " Analyzed %d interfaces.", _total);
114 notify_rk(ALERT_OK, op_msg);
115 }
116
117 return;
118 }
119
120 #else /* WIN32 */
121
122 /* Not implemented on Windows */
check_rc_if()123 void check_rc_if()
124 {
125 return;
126 }
127
128 #endif /* WIN32 */
129
130