libnids使用举例

—[[ libnids应用实例 ]]———————————-

1、nids_next)函数的应用

============================ cut here ============================

/*
This is an example how one can use nids_getfd) and nids_next) functions.
You can replace printall.c’s function main with this file.
*/

#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

int
main )
{
   // here we can alter libnids params, for instance:
   // nids_params.n_hosts=256;
   int fd;
   int time = 0;
   fd_set rset;
   struct timeval tv;

   if !nids_init ))
   {
         fprintfstderr,”%s
“,nids_errbuf);
         exit1);
   }
   nids_register_tcp tcp_callback);
   fd = nids_getfd );
   for ;;)
     {
       tv.tv_sec = 1;
       tv.tv_usec = 0;
       FD_ZERO &rset);
       FD_SET fd, &rset);
       // add any other fd we need to take care of
       if select fd + 1, &rset, 0, 0, &tv))
         {
                 if FD_ISSETfd,&rset)   // need to test it if there are other
                                         // fd in rset
                         if !nids_next )) break;
         }
       else
         fprintf stderr, “%i “, time++);
     }
   return 0;
}

============================ cut here ============================

2、Simple sniffer

============================ cut here ============================

/*
    Copyright c) 1999 Rafal Wojtczuk <nergal@avet.com.pl>. All rights reserved.
    See the file COPYING for license details.
*/

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <fcntl.h>
#include “nids.h”

#define LOG_MAX 100
#define SZLACZEK ”
————————————————–

#define int_ntoax)      inet_ntoa*struct in_addr *)&x))

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;
}

int logfd;
void
do_log char *adres_txt, char *data, int ile)
{
   write logfd, adres_txt, strlen adres_txt));
   write logfd, data, ile);
   write logfd, SZLACZEK, strlen SZLACZEK));
}

void
sniff_callback struct tcp_stream *a_tcp, void **this_time_not_needed)
{
   int dest;
   if a_tcp->nids_state == NIDS_JUST_EST)
     {
       dest = a_tcp->addr.dest;
       if dest == 21 || dest == 23 || dest == 110 || dest == 143 || dest == 513)
         a_tcp->server.collect++;
       return;
     }
   if a_tcp->nids_state != NIDS_DATA)
     {
       // seems the stream is closing, log as much as possible
       do_log adres a_tcp->addr), a_tcp->server.data,
               a_tcp->server.count – a_tcp->server.offset);
       return;
     }
   if a_tcp->server.count – a_tcp->server.offset < LOG_MAX)
     {
       // we haven’t got enough data yet; keep all of it
       nids_discard a_tcp, 0);
       return;
     }
    
   // enough data  
   do_log adres a_tcp->addr), a_tcp->server.data, LOG_MAX);

   // Now procedure sniff_callback doesn’t want to see this stream anymore.
   // So, we decrease all the “collect” fields we have previously increased.
   // If there were other callbacks following a_tcp stream, they would still
   // receive data
   a_tcp->server.collect–;
}

int
main )
{
   logfd = open “./logfile”, O_WRONLY | O_CREAT | O_TRUNC, 0600);
   if logfd < 0)
     {
       perror “opening ./logfile:”);
       exit 1);
     }
   if !nids_init ))
     {
       fprintf stderr, “%s
“, nids_errbuf);
       exit 1);
     }
   nids_register_tcp sniff_callback);
   nids_run );
   return 0;
}

============================ cut here ============================

3、Wu-FTPd overflow attack detector

============================ cut here ============================

/*
Copyright c) 1999 Rafal Wojtczuk <nergal@avet.com.pl>. All rights reserved.
See the file COPYING for license details.
*/

/*
This code attempts to detect attack against imapd AUTHENTICATE hole) and
wuftpd creation of deep directory). This code is to ilustrate use of libnids;
in order to improve readability, some simplifications were made, which enables
an attacker to bypass this code note, the below routines should be improved,
not libnids)
*/  

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include “nids.h”

#define int_ntoax)      inet_ntoa*struct in_addr *)&x))

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;
}

/*
if we find a pattern AUTHENTICATE {an_int} in data stream sent to an imap
server, where an_int >1024, it means an buffer overflow attempt. We kill the
connection.
*/

#define PATTERN “AUTHENTICATE {“
#define PATLEN strlenPATTERN)
void
detect_imap struct tcp_stream *a_tcp)
{
   char numbuf[30];
   int i, j, datalen, numberlen;
   struct half_stream *hlf;
   if a_tcp->nids_state == NIDS_JUST_EST)
     {
       if a_tcp->addr.dest == 143)
         {
           a_tcp->server.collect++;
           return;
         }
       else
         return;
     }
   if a_tcp->nids_state != NIDS_DATA)
     return;
   hlf = &a_tcp->server;
   datalen = hlf->count – hlf->offset;
   if datalen < PATLEN)
     {
       // we have too small amount of data to work on. Keep all data in buffer.
       nids_discard a_tcp, 0);
       return;
     }
   for i = 0; i <= datalen – PATLEN; i++)
     if !memcmp PATTERN, hlf->data + i, PATLEN)) //searching for a pattern
       break;
   if i > datalen – PATLEN)
     {
       // retain PATLEN bytes in buffer
       nids_discard a_tcp, datalen – PATLEN);
       return;
     }
   for j = i + PATLEN; j < datalen; j++) // searching for a closing ‘}’
     if *hlf->data + j) == ‘}’)
       break;
   if j > datalen)
     {
       if datalen > 20)
         {
           //number too long, perhaps we should log it, too
         }
       return;
     }
   numberlen = j – i – PATLEN;
   memcpy numbuf, hlf->data + i + PATLEN, numberlen); //numbuf contains
                                                       // AUTH argument
   numbuf[numberlen] = 0;
   if atoi numbuf) > 1024)
     {
       // notify admin
       syslognids_params.syslog_level,
       “Imapd exploit attempt, connection %s
“,adresa_tcp->addr));
       // kill the connection
       nids_killtcp a_tcp);
     }
   nids_discard a_tcp, datalen – PATLEN);
   return;
}

// auxiliary structure, needed to keep current dir of ftpd daemon
struct supp
{
   char *currdir;
   int last_newline;
};

// the below function adds “elem” string to “path” string, taking care of
// “..” and multiple ‘/’. If the resulting path is longer than 768,
// return value is 1, otherwise 0
int
add_to_path char *path, char *elem, int len)
{
int plen;
char * ptr;
   if len > 768)
     return 1;
   if len == 2 && elem[0] == ‘.’ && elem[1] == ‘.’)
     {
       ptr = rindex path, ‘/’);
       if ptr != path)
         *ptr = 0;
     }
   else if len > 0)
     {
       plen = strlen path);
       if plen + len + 1 > 768)
         return 1;
         if plen==1)
         {
         strncpypath+1,elem,len);
         path[1+len]=0;
         }
         else
         {
       path[plen] = ‘/’;
       strncpy path + plen + 1, elem, len);
       path[plen + 1 + len] = 0;
         }
     }
return 0;
}

void
do_detect_ftp struct tcp_stream *a_tcp, struct supp **param_ptr)
{
   struct supp *p = *param_ptr;
   int index = p->last_newline + 1;
   char *buf = a_tcp->server.data;
   int offset = a_tcp->server.offset;
   int n_bytes = a_tcp->server.count – offset;
   int path_index, pi2, index2, remcaret;
   for ;;)
     {
       index2 = index;
       while index2 – offset < n_bytes && buf[index2 – offset] != ‘
‘)
         index2++;
       if index2 – offset >= n_bytes)
         break;
       if !strncasecmp buf + index – offset, “cwd “, 4))
         {
           path_index = index + 4;
           if buf[path_index – offset] == ‘/’)
             {
               strcpy p->currdir, “/”);
               path_index++;
             }
           for ;;)
             {
               pi2 = path_index;
               while buf[pi2 – offset] != ‘
‘ && buf[pi2 – offset] != ‘/’)
                 pi2++;
                 if buf[pi2-offset]==’
‘ && buf[pi2-offset-1]==”)
                 remcaret=1;
                 else remcaret=0;
               if add_to_path p->currdir, buf + path_index-offset, pi2 – path_index-remcaret))
                 {
                   // notify admin
                   syslognids_params.syslog_level,
                   “Ftpd exploit attempt, connection %s
“,adresa_tcp->addr));
                   nids_killtcp a_tcp);
                   return;
                 }
               if buf[pi2 – offset] == ‘
‘)
                 break;
               path_index = pi2 + 1;
             }
         }
       index = index2 + 1;
     }
   p->last_newline = index – 1;
   nids_discard a_tcp, index – offset);
}

void
detect_ftpd struct tcp_stream *a_tcp, struct supp **param)
{
   if a_tcp->nids_state == NIDS_JUST_EST)
     {
       if a_tcp->addr.dest == 21)
         {
           struct supp *one_for_conn;
           a_tcp->server.collect++;
           one_for_conn = struct supp *) malloc sizeof struct supp));
           one_for_conn->currdir = malloc 1024);
           strcpy one_for_conn->currdir, “/”);
           one_for_conn->last_newline = 0;
           *param=one_for_conn;
         }
       return;
     }
   if a_tcp->nids_state != NIDS_DATA)
     {
       free *param)->currdir);
       free *param);
       return;
     }
   do_detect_ftp a_tcp, param);
}

int
main )
{
   if !nids_init ))
   {
         fprintfstderr,”%s
“,nids_errbuf);
         exit1);
   }
   nids_register_tcp detect_imap);
   nids_register_tcp detect_ftpd);
   nids_run );
   return 0;
}
#Net Programming

Published by

风君子

独自遨游何稽首 揭天掀地慰生平