3 /* Copyright (C) 2009 Trend Micro Inc.
6 * This program is a free software; you can redistribute it
7 * and/or modify it under the terms of the GNU General Public
8 * License (version 2) as published by the FSF - Free Software
16 #include "rootcheck.h"
19 #if defined(sun) || defined(__sun__)
20 #define NETSTAT "netstat -an -P %s | "\
21 "grep \"[^0-9]%d \" > /dev/null 2>&1"
25 #define NETSTAT "netstat -an -p %s | "\
30 #define NETSTAT_LIST "netstat -an | grep \"^%s\" | "\
31 "cut -d ':' -f 2 | cut -d ' ' -f 1"
32 #define NETSTAT "netstat -an | grep \"^%s\" | " \
33 "grep \"[^0-9]%d \" > /dev/null 2>&1"
37 #define NETSTAT "netstat -an | grep \"^%s\" | " \
38 "grep \"[^0-9]%d \" > /dev/null 2>&1"
42 int run_netstat(int proto, int port)
44 char nt[OS_SIZE_1024 +1];
46 if(proto == IPPROTO_TCP)
47 snprintf(nt, OS_SIZE_1024, NETSTAT, "tcp", port);
48 else if(proto == IPPROTO_UDP)
49 snprintf(nt, OS_SIZE_1024, NETSTAT, "udp", port);
52 merror("%s: Netstat error (wrong protocol)", ARGV0);
63 int conn_port(int proto, int port)
67 struct sockaddr_in server;
69 if(proto == IPPROTO_UDP)
71 if((ossock = socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP)) < 0)
74 else if(proto == IPPROTO_TCP)
76 if((ossock = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP)) < 0)
81 memset(&server, 0, sizeof(server));
82 server.sin_family = AF_INET;
83 server.sin_port = htons( port );
84 server.sin_addr.s_addr = htonl(INADDR_ANY);
87 /* If we can't bind, it means the port is open */
88 if(bind(ossock, (struct sockaddr *) &server, sizeof(server)) < 0)
93 /* Setting if port is open or closed */
94 if(proto == IPPROTO_TCP)
96 total_ports_tcp[port] = rc;
100 total_ports_udp[port] = rc;
109 void test_ports(int proto, int *_errors, int *_total)
113 for(i = 0; i<= 65535; i++)
116 if(conn_port(proto, i))
118 /* Checking if we can find it using netstat, if not,
119 * check again to see if the port is still being used.
121 if(run_netstat(proto, i))
130 /* If we are being run by the ossec hids, sleep here (no rush) */
135 if(!run_netstat(proto, i) && conn_port(proto, i))
137 char op_msg[OS_SIZE_1024 +1];
141 snprintf(op_msg, OS_SIZE_1024, "Port '%d'(%s) hidden. "
142 "Kernel-level rootkit or trojaned "
143 "version of netstat.", i,
144 (proto == IPPROTO_UDP)? "udp" : "tcp");
146 notify_rk(ALERT_ROOTKIT_FOUND, op_msg);
152 char op_msg[OS_SIZE_1024 +1];
153 snprintf(op_msg, OS_SIZE_1024, "Excessive number of '%s' ports "
154 "hidden. It maybe a false-positive or "
155 "something really bad is going on.",
156 (proto == IPPROTO_UDP)? "udp" : "tcp" );
157 notify_rk(ALERT_SYSTEM_CRIT, op_msg);
165 /* check_rc_ports: v0.1
168 void check_rc_ports()
177 total_ports_tcp[i] = 0;
178 total_ports_udp[i] = 0;
182 /* Trsting TCP ports */
183 test_ports(IPPROTO_TCP, &_errors, &_total);
185 /* Testing UDP ports */
186 test_ports(IPPROTO_UDP, &_errors, &_total);
190 char op_msg[OS_SIZE_1024 +1];
191 snprintf(op_msg,OS_SIZE_1024,"No kernel-level rootkit hiding any port."
192 "\n Netstat is acting correctly."
193 " Analyzed %d ports.", _total);
194 notify_rk(ALERT_OK, op_msg);
202 void check_rc_ports()