X-Git-Url: http://ftp.carnet.hr/carnet-debian/scm?p=ossec-hids.git;a=blobdiff_plain;f=src%2Frootcheck%2Fcheck_rc_ports.c;fp=src%2Frootcheck%2Fcheck_rc_ports.c;h=de4f8eecd1504523d8017f01ad06ffd9d89032ae;hp=94b1fae037e715862eb383fdfae94eed7b3d01ba;hb=3f728675941dc69d4e544d3a880a56240a6e394a;hpb=927951d1c1ad45ba9e7325f07d996154a91c911b diff --git a/src/rootcheck/check_rc_ports.c b/src/rootcheck/check_rc_ports.c old mode 100755 new mode 100644 index 94b1fae..de4f8ee --- a/src/rootcheck/check_rc_ports.c +++ b/src/rootcheck/check_rc_ports.c @@ -1,6 +1,3 @@ -/* @(#) $Id: ./src/rootcheck/check_rc_ports.c, 2011/09/08 dcid Exp $ - */ - /* Copyright (C) 2009 Trend Micro Inc. * All right reserved. * @@ -10,162 +7,164 @@ * Foundation */ - #ifndef WIN32 #include "shared.h" #include "rootcheck.h" -/* SunOS netstat */ #if defined(sun) || defined(__sun__) -#define NETSTAT "netstat -an -P %s | "\ - "grep \"[^0-9]%d \" > /dev/null 2>&1" - -/* -#elif WIN32 -#define NETSTAT "netstat -an -p %s | "\ - "find \":%d\"" -*/ - -#elif defined(Linux) -#define NETSTAT_LIST "netstat -an | grep \"^%s\" | "\ - "cut -d ':' -f 2 | cut -d ' ' -f 1" -#define NETSTAT "netstat -an | grep \"^%s\" | " \ - "grep \"[^0-9]%d \" > /dev/null 2>&1" +#define NETSTAT "netstat -an -P %s | "\ + "grep \"[^0-9]%d \" > /dev/null 2>&1" +#else +#define NETSTAT "netstat -an | grep \"^%s\" | " \ + "grep \"[^0-9]%d \" > /dev/null 2>&1" #endif -#ifndef NETSTAT -#define NETSTAT "netstat -an | grep \"^%s\" | " \ - "grep \"[^0-9]%d \" > /dev/null 2>&1" -#endif +/* Prototypes */ +static int run_netstat(int proto, int port); +static int conn_port(int proto, int port); +static void test_ports(int proto, int *_errors, int *_total); -int run_netstat(int proto, int port) +static int run_netstat(int proto, int port) { int ret; - char nt[OS_SIZE_1024 +1]; + char nt[OS_SIZE_1024 + 1]; - if(proto == IPPROTO_TCP) + if (proto == IPPROTO_TCP) { snprintf(nt, OS_SIZE_1024, NETSTAT, "tcp", port); - else if(proto == IPPROTO_UDP) + } else if (proto == IPPROTO_UDP) { snprintf(nt, OS_SIZE_1024, NETSTAT, "udp", port); - else - { + } else { merror("%s: Netstat error (wrong protocol)", ARGV0); - return(0); + return (0); } ret = system(nt); - if(ret == 0) - return(1); - - else if(ret == 1) - { - return(0); + if (ret == 0) { + return (1); + } else if (ret == 1) { + return (0); } - return(1); + return (1); } - -int conn_port(int proto, int port) +static int conn_port(int proto, int port) { int rc = 0; int ossock; struct sockaddr_in server; + struct sockaddr_in6 server6; - if(proto == IPPROTO_UDP) - { - if((ossock = socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP)) < 0) - return(0); - } - else if(proto == IPPROTO_TCP) - { - if((ossock = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP)) < 0) - return(0); - } - else - { - return (0); + if (proto == IPPROTO_UDP) { + if ((ossock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { + return (0); + } + } else if (proto == IPPROTO_TCP) { + if ((ossock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { + return (0); + } + } else { + return (0); } memset(&server, 0, sizeof(server)); server.sin_family = AF_INET; - server.sin_port = htons( port ); + server.sin_port = htons(port); server.sin_addr.s_addr = htonl(INADDR_ANY); + /* If we can't bind, it means the port is open */ + if (bind(ossock, (struct sockaddr *) &server, sizeof(server)) < 0) { + rc = 1; + } + + /* Setting if port is open or closed */ + if (proto == IPPROTO_TCP) { + total_ports_tcp[port] = (char) rc; + } else { + total_ports_udp[port] = (char) rc; + } + + close(ossock); + + /* repeat for IPv6 */ + if (proto == IPPROTO_UDP) { + if ((ossock = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP)) < 0) { + return(0); + } + } else if (proto == IPPROTO_TCP) { + if ((ossock = socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP)) < 0) { + return(0); + } + } + + + memset(&server6, 0, sizeof(server6)); + server6.sin6_family = AF_INET6; + server6.sin6_port = htons( port ); + memcpy(&server6.sin6_addr.s6_addr, &in6addr_any, sizeof in6addr_any); + /* If we can't bind, it means the port is open */ - if(bind(ossock, (struct sockaddr *) &server, sizeof(server)) < 0) - { + if(bind(ossock, (struct sockaddr *) &server6, sizeof(server6)) < 0) { rc = 1; } /* Setting if port is open or closed */ - if(proto == IPPROTO_TCP) - { + if(proto == IPPROTO_TCP) { total_ports_tcp[port] = rc; - } - else - { + } else { total_ports_udp[port] = rc; } close(ossock); - return(rc); + return (rc); } - -void test_ports(int proto, int *_errors, int *_total) +static void test_ports(int proto, int *_errors, int *_total) { int i; - for(i = 0; i<= 65535; i++) - { + for (i = 0; i <= 65535; i++) { (*_total)++; - if(conn_port(proto, i)) - { - /* Checking if we can find it using netstat, if not, + if (conn_port(proto, i)) { + /* Check if we can find it using netstat. If not, * check again to see if the port is still being used. */ - if(run_netstat(proto, i)) - { + if (run_netstat(proto, i)) { continue; - - #ifdef OSSECHIDS - sleep(2); - #endif } - /* If we are being run by the ossec hids, sleep here (no rush) */ - #ifdef OSSECHIDS - sleep(2); - #endif +#ifdef OSSECHIDS + /* If we are in the context of OSSEC-HIDS, sleep here (no rush) */ + debug1("%s: DEBUG: pause for %u", ARGV0, rootcheck.tsleep); + sleep(rootcheck.tsleep); +#endif - if(!run_netstat(proto, i) && conn_port(proto, i)) - { - char op_msg[OS_SIZE_1024 +1]; + if (!run_netstat(proto, i) && conn_port(proto, i)) { + char op_msg[OS_SIZE_1024 + 1]; (*_errors)++; snprintf(op_msg, OS_SIZE_1024, "Port '%d'(%s) hidden. " - "Kernel-level rootkit or trojaned " - "version of netstat.", i, - (proto == IPPROTO_UDP)? "udp" : "tcp"); + "Kernel-level rootkit or trojaned " + "version of netstat.", i, + (proto == IPPROTO_UDP) ? "udp" : "tcp"); notify_rk(ALERT_ROOTKIT_FOUND, op_msg); } } - if((*_errors) > 20) - { - char op_msg[OS_SIZE_1024 +1]; + if ((*_errors) > 20) { + char op_msg[OS_SIZE_1024 + 1]; + snprintf(op_msg, OS_SIZE_1024, "Excessive number of '%s' ports " - "hidden. It maybe a false-positive or " - "something really bad is going on.", - (proto == IPPROTO_UDP)? "udp" : "tcp" ); + "hidden. It maybe a false-positive or " + "something really bad is going on.", + (proto == IPPROTO_UDP) ? "udp" : "tcp" ); notify_rk(ALERT_SYSTEM_CRIT, op_msg); return; } @@ -173,10 +172,6 @@ void test_ports(int proto, int *_errors, int *_total) } - -/* check_rc_ports: v0.1 - * Check all ports - */ void check_rc_ports() { int _errors = 0; @@ -184,38 +179,35 @@ void check_rc_ports() int i = 0; - while(i<=65535) - { + while (i <= 65535) { total_ports_tcp[i] = 0; total_ports_udp[i] = 0; i++; } - /* Trsting TCP ports */ + /* Test both TCP and UDP ports */ test_ports(IPPROTO_TCP, &_errors, &_total); - - /* Testing UDP ports */ test_ports(IPPROTO_UDP, &_errors, &_total); - if(_errors == 0) - { - char op_msg[OS_SIZE_1024 +1]; - snprintf(op_msg,OS_SIZE_1024,"No kernel-level rootkit hiding any port." - "\n Netstat is acting correctly." - " Analyzed %d ports.", _total); + if (_errors == 0) { + char op_msg[OS_SIZE_1024 + 1]; + + snprintf(op_msg, OS_SIZE_1024, "No kernel-level rootkit hiding any port." + "\n Netstat is acting correctly." + " Analyzed %d ports.", _total); notify_rk(ALERT_OK, op_msg); } return; } +#else /* WIN32 */ -#else +/* Not implemented on Windows */ void check_rc_ports() { return; } -#endif +#endif /* WIN32 */ -/* EOF */