Logo Search packages:      
Sourcecode: yersinia version File versions

attack.c

/* attack.c
 * Attacks management core
 *
 * Yersinia
 * By David Barroso <tomac@wasahero.org> and Alfredo Andres <slay@wasahero.org>
 * Copyright 2005 Alfredo Andres and David Barroso
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

#ifndef lint
static const char rcsid[] =
       "$Id: attack.c,v 1.4 2005/07/28 19:29:24 t0mac Exp $";
#endif

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#define _REENTRANT

#include <stdio.h>
#include <errno.h>
#include <sys/types.h>

#ifdef HAVE_NETINET_IN_SYSTM_H
#include <netinet/in_systm.h>
#else
#ifdef HAVE_NETINET_IN_SYSTEM_H
#include <netinet/in_system.h>
#endif
#endif

#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>

#ifdef TIME_WITH_SYS_TIME
#include <sys/time.h>
#endif

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

#ifdef HAVE_STRING_H
#include <string.h>
#endif

#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif

#ifdef HAVE_BSTRING_H
#include <bstring.h>
#endif

#ifdef STDC_HEADERS
#include <stdlib.h>
#endif

#include "attack.h"


/* Launch choosed attack... */
int8_t
attack_launch(struct term_node *node, u_int16_t proto, u_int16_t attack, struct attack_param *attack_params, u_int8_t nparams)
{
    u_int16_t i = 0;

    while (i < MAX_THREAD_ATTACK) 
    {
        if (node->protocol[proto].attacks[i].up == 0) 
        {
            node->protocol[proto].attacks[i].up = 1;
            node->protocol[proto].attacks[i].mac_spoofing = node->mac_spoofing;
            node->protocol[proto].attacks[i].attack  = attack;
            node->protocol[proto].attacks[i].params  = attack_params;
            node->protocol[proto].attacks[i].nparams = nparams;
                    /* FIXME: temporal hasta ponerlo bien, pillamos para el ataque las interfaces del usuario */
            memcpy(node->protocol[proto].attacks[i].used_ints, node->used_ints, MAX_INTERFACES);

            if ((node->protocol[proto].attacks[i].data = calloc(1, protocols[proto].size )) == NULL)
            {
                thread_error("attack_launch calloc",errno);
                node->protocol[proto].attacks[i].params  = NULL;
                node->protocol[proto].attacks[i].nparams = 0;
                node->protocol[proto].attacks[i].up = 0;
                return -1;
            }
            memcpy(node->protocol[proto].attacks[i].data, 
                   node->protocol[proto].tmp_data, protocols[proto].size );

            if (pthread_mutex_init(&node->protocol[proto].attacks[i].attack_th.finished, NULL) != 0)
            {
               thread_error("attack_launch pthread_mutex_init mutex", errno);
               free(node->protocol[proto].attacks[i].data);
               return -1;
            }

            if (pthread_mutex_init(&node->protocol[proto].attacks[i].helper_th.finished, NULL) != 0)
            {
               thread_error("attack_launch pthread_mutex_init mutex", errno);
               free(node->protocol[proto].attacks[i].data);
               return -1;
            }

            if (thread_create(&node->protocol[proto].attacks[i].attack_th.id, 
                             (*protocols[proto].attacks[attack].attack_th_launch), 
                             &node->protocol[proto].attacks[i]) < 0)
            {
                free(node->protocol[proto].attacks[i].data);
                node->protocol[proto].attacks[i].params  = NULL;
                node->protocol[proto].attacks[i].nparams = 0;
                node->protocol[proto].attacks[i].up      = 0;
                return -1;
            }
            write_log(0, " attack_launch: %d Attack thread %ld is born!!\n", (int)pthread_self(),
            (u_long) node->protocol[proto].attacks[i].attack_th.id);
            return 0;
        }
        i++;
    } /* while...*/

    return -1;
}


/* 
 * Kill attack thread pertaining to "node".
 * If "pid" == 0 then kill *ALL* node attack threads.
 * Return -1 on error. Return 0 if Ok.
 */
int8_t
attack_kill_th(struct term_node *node, pthread_t pid)
{
    u_int16_t i, j;

    i = 0;
    
    while (i < MAX_PROTOCOLS) 
    {
        j=0;
        while (j < MAX_THREAD_ATTACK) 
        {
            if (node->protocol[i].attacks[j].up == 1) 
            {
                if (!pid || (node->protocol[i].attacks[j].attack_th.id == pid) ) 
                {
                   thread_destroy(&node->protocol[i].attacks[j].attack_th);
                   pthread_mutex_destroy(&node->protocol[i].attacks[j].attack_th.finished);
                   if (pid)
                       return 0;
                }
            }
            j++;
        }
        i++;
    } /* while protocols...*/
    
    return -1;
}


int8_t 
attack_th_exit(struct attacks *attacks)
{
write_log(0," attack_th_exit -> attack_th.stop=%d   attack_th.id=%d....\n",attacks->attack_th.stop,
attacks->attack_th.id);

    if (attacks->attack_th.stop == 0)
       attacks->attack_th.id = 0;
    else
       attacks->attack_th.stop = 0;

    if (attacks->helper_th.id) 
    {
       write_log(0," attack_th_exit: %d thread_destroy helper %d...\n",
                 (int)pthread_self(), (int)attacks->helper_th.id);    
       thread_destroy(&attacks->helper_th);
    }    

    pthread_mutex_destroy(&attacks->helper_th.finished);

    if (attacks->data)
    {
        free(attacks->data);
    }
    
    if (attacks->params)
    {
       attack_free_params(attacks->params, attacks->nparams);
       free(attacks->params);
    }
    
    attacks->data   = NULL;
    attacks->params = NULL;
    attacks->up     = 0;

    write_log(0, " attack_th_exit: %d finished\n", (int) pthread_self());
    
    return 0;
}


/*
 *  macof.c
 *  gen_mac from Dug Song's macof-1.1 C port
 */
void
attack_gen_mac(u_int8_t *mac)
{
    *((in_addr_t *)mac) = libnet_get_prand(LIBNET_PRu32);
    *((u_int16_t *)(mac + 4)) = libnet_get_prand(LIBNET_PRu16);
}


int8_t
attack_init_params(struct term_node *node, struct attack_param *param, u_int8_t nparams)
{
   u_int8_t i, j, a;

   for (i=0; i < nparams; i++)
   {
       if ( (param[i].value = calloc(1, param[i].size) ) == NULL)
       {
           thread_error("attack_init_parameter calloc",errno);
           for (a=0; a<i; a++)
              free(param[a].value);
           return -1;
       }
   }
   
   if (node->type == TERM_CON)
   {
      for (j=0; j < nparams; j++)
      {
           if ( (param[j].print = calloc(1, param[j].size_print+1) ) == NULL)
           {
               thread_error("attack_init_parameter calloc",errno);
               for (a=0; a<j; a++)
                  free(param[a].print);
               for (a=0; a<i; a++)
                  free(param[a].value);
               return -1;
           }
       }
   }

   return 0;
}

void
attack_free_params(struct attack_param *param, u_int8_t nparams)
{
   u_int8_t i;

   for (i=0; i < nparams; i++)
   {
       if (param[i].value)
       {
          free(param[i].value);
       }
       if (param[i].print)
       {       
          free(param[i].print);
       }
   }
}


/*
 * Filter all attack parameters
 * On success Return 0.
 * On error Return -1 and error field number on "field".
 */
int8_t 
attack_filter_all_params(struct attack_param *attack_param, u_int8_t nparams, u_int8_t *field)
{
    u_int8_t j;

    for (j=0; j<nparams; j++)
    {
       if ( attack_filter_param(attack_param[j].type, 
                                attack_param[j].value,
                                attack_param[j].print,
                                attack_param[j].size_print,
                                attack_param[j].min,
                                attack_param[j].max
                                ) < 0 )
       {
          *field = j;
          return -1;
       }
    }

    return 0;
}


/*
 * Filter 1 attack parameter
 * Return -1 on error.
 * Return 0 on success.
 */
int8_t 
attack_filter_param(u_int8_t type, void *value, char *printable, u_int16_t size_print, int32_t min, int32_t max)
{
    u_int8_t i, *bytes, j;
    char tmp[3];
    char *temp;
    int8_t iface;
    u_int16_t end, len;
    u_int32_t aux_ip;
    struct in_addr addr;

    if (!printable || !value || !strlen(printable) || (strlen(printable) > size_print) )
       return -1;
       
    switch(type)
    {
        case FIELD_BRIDGEID:
            if (strlen(printable) != 17)
                return -1;
            if (parser_vrfy_bridge_id(printable,(u_int8_t *)value))
                return -1;
        break;

        case FIELD_MAC:
            if (parser_vrfy_mac(printable,(u_int8_t *)value))
                return -1;
        break;

        case FIELD_HEX:
        case FIELD_DEC:
            end = strlen(printable);
            for(i=0; i<end; i++)
            {
                if ( (type == FIELD_HEX) &&
                     !isxdigit(printable[i]) )
                   return -1;
                if ( (type == FIELD_DEC) &&
                     !isdigit(printable[i]) )
                   return -1;
            }
            if (type == FIELD_HEX)
               *((u_int32_t *)(value)) = strtoul(printable, (char **)NULL, 16);
            else
               *((u_int32_t *)(value)) = strtoul(printable, (char **)NULL, 10);

            if ( (*((u_int32_t *)value) < min) ||
                 (*((u_int32_t *)value) > max))
               return -1;
        break;

        case FIELD_IP:
            if (parser_get_inet_aton(printable, &addr) < 0) 
                return -1; 
/*            aux_ip = ntohl(addr.s_addr);*/
            aux_ip = addr.s_addr;
            memcpy(value, (void *)&aux_ip, 4);
        break;

        case FIELD_STR:
            end = strlen(printable);
            for(i=0; i<end; i++)
            {
                if ( !isascii(printable[i]) )
                   return -1;
            }
            memcpy((void *)value, (void *)printable, end);
        break;

        case FIELD_IFACE:
            end = strlen(printable);
            for(i=0; i<end; i++)
            {
                if ( !isascii(printable[i]) )
                   return -1;
            }
            iface = interfaces_get(printable);
            if (iface < 0)
               return -1;
            memcpy((void *)value, (void *)&iface, 1);
        break;

      case FIELD_BYTES:
            len = strlen(printable);
            bytes = (u_int8_t *)calloc(1, (len % 2) ? len/2 + 1 : len/2);
            temp = printable;
            for (j=0; j < len/2; j++) 
            {
                 memcpy((void *)tmp, (void *)temp, 2);
                 tmp[2] = '\0';
                 bytes[j] = strtol(tmp, NULL, 16);
                 temp+=2;
            }
            if (len % 2)
                bytes[j+1] = strtol(temp, NULL, 16);

            free(bytes);
      break;

    }

    return 0;
}


Generated by  Doxygen 1.6.0   Back to index