Ads

Snortcheck Tool: Check If Snort Its Running PDF Print E-mail
Friday, 01 July 2005
Credit:
The information has been provided by fryxar.

Details
Snortcheck is a simple program that is useful for checking if snort (working as NIDS) is running correctly over a Linux box.

The program works by sending an ICMP echo-request packet (even if the sniffing interface is in stealth mode) specially prepared to generate a token alert by using a rule that identify the combination of Origin IP / Destination IP / ICMP echo-reply message.

By running the program periodically, its possible to check if the following items are running correctly:
- The snort process
- The output snort plugin (for example, the delivery of automatics mails of alerts)
- The SPAN (or mirroring) switching port.

Code:
/*
* snortcheck: Check if snort its running
* Based on etherpingtest.c
* by: Fryxar (fryxar at yahoo.com.ar)
*
*/

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <net/if.h>
#include <net/ethernet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/ip_icmp.h>
#include <netinet/if_ether.h>
#include <netpacket/packet.h>

struct addr {
uint32_t ip;
char mac[ETH_ALEN];
};

struct dev {
uint32_t index;
char name[IFNAMSIZ];
};

int send_echorequest(int, struct dev *, struct addr *, struct addr *);
int mac_aton(char *, char *);
int in_cksum(u_short *, int);
void usage(char *);

int main(int argc, char *argv[]) {
int sock = 0;
struct dev dev;
struct addr src, dst;

if (argc < 6) {
usage(argv[0]);
return -1;
}

/* device */
memset(&dev, 0, sizeof(dev));
strncpy(dev.name, argv[1], IFNAMSIZ-1);
if((dev.index = if_nametoindex(dev.name)) == 0) {
perror(argv[1]);
exit(-1);
}

/* source ip & mac */
memset(&src, 0, sizeof(src));
if (inet_aton(argv[2], (struct in_addr *)&src.ip) == 0) {
fprintf(stderr, "%s: invalid src ip address ", argv[2]);
exit(-1);
}

if (mac_aton(argv[3], src.mac) < 0) {
fprintf(stderr, "%s: invalid src hardware address ", argv[3]);
exit(-1);
}

/* destination ip & mac */
memset(&dst, 0, sizeof(dst));
if (inet_aton(argv[4], (struct in_addr *)&dst.ip) == 0) {
fprintf(stderr, "%s: invalid ip address ", argv[2]);
exit(-1);
}

if (mac_aton(argv[5], dst.mac) < 0) {
fprintf(stderr, "%s: invalid hardware address ", argv[3]);
exit(-1);
}

/* socket */
if ((sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0) {
perror("socket");
exit(-1);
}

/* send icmp echo request */
if (send_echorequest(sock, &dev, &src, &dst) < 0) {
perror("send");
exit(-1);
}

close(sock);

return 0;
}

int send_echorequest(int sock, struct dev *dev, struct addr *src, struct addr *dst) {
struct sockaddr_ll sll;
struct ether_header *eth;
struct iphdr *ip;
struct icmphdr *icmp;
char buf[sizeof(struct ether_header) + sizeof(struct iphdr) + sizeof(struct icmphdr)];

memset(&sll, 0, sizeof(sll));
sll.sll_family = PF_PACKET;
sll.sll_ifindex = dev->index;
sll.sll_halen = ETH_ALEN;
memcpy(&sll.sll_addr, dst->mac, ETH_ALEN);

memset(buf, 0, sizeof(buf));
eth = (struct ether_header *)buf;
ip = (struct iphdr *)((char *)eth + sizeof(struct ether_header));
icmp = (struct icmphdr *)((char *)ip + sizeof(struct iphdr));

/* icmp header */
icmp->type = ICMP_ECHO;
icmp->checksum = in_cksum((u_short *)icmp, sizeof(struct icmphdr));

/* ip header */
ip->version = 4;
ip->ihl = 5;
ip->tot_len = htons(sizeof(struct iphdr) + sizeof(struct icmphdr));
ip->id = rand() & 0xffff;
ip->ttl = 0;
ip->protocol = IPPROTO_ICMP;
ip->saddr = src->ip;
ip->daddr = dst->ip;
ip->check = in_cksum((u_short *)ip, sizeof(struct iphdr));

/* ether_header */
memcpy(eth->ether_shost, src->mac, ETH_ALEN);
memcpy(eth->ether_dhost, dst->mac, ETH_ALEN);
eth->ether_type = htons(ETH_P_IP);

/* send to icmp echo packet */
return sendto(sock, buf, sizeof(buf), 0, (struct sockaddr *)&sll, sizeof(sll));
}

int mac_aton(char *amac, char *nmac) {
char c;
int i;
unsigned int val;

i = 0;
while ((*amac != ) && (i < ETH_ALEN)) {
val = 0;
c = *amac++;
if (c >= 0 && c <= 9) {
val = c - 0;
}
else if (c >= a && c <= f) {
val = c - a + 10;
}
else if (c >= A && c <= F) {
val = c - A + 10;
}
else {
errno = EINVAL;
return -1;
}
val <<= 4;

c = *amac;
if (c >= 0 && c <= 9) {
val |= c - 0;
}
else if (c >= a && c <= f) {
val |= c - a + 10;
}
else if (c >= A && c <= F) {
val |= c - A + 10;
}
else if (c == : || c == ) {
val >>= 4;
}
else {
errno = EINVAL;
return -1;
}
if (c != 0) {
amac++;
}
*nmac++ = val & 0xff;
i++;

/* We might get a semicolon here - not required. */
if (*amac == :) {
amac++;
}
}
return 0;
}

int in_cksum(u_short *addr, int len) {
int nleft = len;
u_short *w = addr;
int sum = 0;
u_short answer = 0;

while (nleft > 1) {
sum += *w++;
nleft -= 2;
}

if (nleft == 1) {
*(u_char *)(&answer) = *(u_char *)w;
sum += answer;
}

sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
answer = ~sum;

return answer;
}

void usage(char *cmd) {
fprintf(stderr, "usage: %s dev srcip srcmac dstip dstmac ", cmd);
}

/* EOF */

 
< Prev