1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
|
/*
* emunids
*
* emulation based network intrusion system
*
* Markus Koetter 2007
*
* gcc -Wall -I/opt/libemu/include/ -L/opt/libemu/lib/libemu -o printall printall.c -lnids -lemu
*
*
*/
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
#include "nids.h"
#include <pcap.h>
#include <emu/emu.h>
#include <emu/emu_shellcode.h>
#include <emu/emu_memory.h>
#define int_ntoa(x) inet_ntoa(*((struct in_addr *)&x))
struct emu *emu;
struct ip;
char *adres (struct tuple4 addr)
{
static char buf[256];
strcpy (buf, int_ntoa (addr.saddr));
sprintf (buf + strlen (buf), ":%i <-> ", addr.source);
strcat (buf, int_ntoa (addr.daddr));
sprintf (buf + strlen (buf), ":%i", addr.dest);
return buf;
}
void tcp_callback (struct tcp_stream *a_tcp, void ** this_time_not_needed)
{
// char buf[1024];
// strcpy (buf, adres (a_tcp->addr)); // we put conn params into buf
if ( a_tcp->nids_state == NIDS_JUST_EST )
{
a_tcp->client.collect++;
a_tcp->client.collect_urg++;
a_tcp->server.collect++;
a_tcp->server.collect_urg++;
// fprintf (stderr, "%s established\n", buf);
}/* else
if ( a_tcp->nids_state == NIDS_CLOSE )
{
fprintf (stderr, "%s closing\n", buf);
}else
if ( a_tcp->nids_state == NIDS_RESET )
{
fprintf (stderr, "%s reset\n", buf);
} */ else
if ( a_tcp->nids_state == NIDS_DATA )
{
struct half_stream *hlf;
char *data;
int size;
if ( a_tcp->server.count_new_urg || a_tcp->server.count_new )
{
hlf = &a_tcp->server;
}else
if ( a_tcp->client.count_new_urg || a_tcp->client.count_new )
{
hlf = &a_tcp->client;
}else
{
return;
}
size = hlf->count - hlf->offset;
data = hlf->data;
// printf("size is %i\n", size);
// printf("count %i offset %i size %i\n",hlf->count, hlf->offset, size);
if ( emu_shellcode_test(emu, (uint8_t *)data, size) >= 0 )
{
fprintf(stderr, "suspecting shellcode in connection %s\n", adres(a_tcp->addr));
}
if (size > 2048)
nids_discard(a_tcp, abs(2048-size));
emu_memory_clear(emu_memory_get(emu));
}
return ;
}
void xlog(int type, int err, struct ip *iph, void *data)
{
char *nids_warnings[] = {
"Murphy - you never should see this message !",
"Oversized IP packet",
"Invalid IP fragment list: fragment over size",
"Overlapping IP fragments",
"Invalid IP header",
"Source routed IP frame",
"Max number of TCP streams reached",
"Invalid TCP header",
"Too much data in TCP receive queue",
"Invalid TCP flags"
};
if (type != NIDS_WARN_SCAN)
{
printf("%s\n", nids_warnings[err]);
}
}
int main (int argc, const char *argv[])
{
if (argc == 1)
{
printf("useage %s <device>\n", argv[0]);
return -1;
}else
{
printf("listening on device %s\n", argv[1]);
}
emu = emu_new();
nids_params.device = strdup(argv[1]);;
nids_params.syslog = xlog;
if ( !nids_init () )
{
fprintf(stderr,"%s\n",nids_errbuf);
exit(1);
}
// disable checksumming as host may calculate the checksum on the nic in hardware
struct nids_chksum_ctl disable_checksums;
disable_checksums.netaddr = 0;
disable_checksums.mask = 0;
disable_checksums.action = NIDS_DONT_CHKSUM;
nids_register_chksum_ctl(&disable_checksums,1);
nids_register_tcp (tcp_callback);
nids_run ();
emu_free(emu);
return 0;
}
|