ShellCode注入原理
2020-11-06 19:15:30 Author: www.secpulse.com(查看原文) 阅读量:296 收藏

我们直接写入可能无法执行

unsigned char data[130] = {
    0x55, 0x8B, 0xEC, 0x83, 0xEC, 0x0C, 0xC7, 0x45, 0xF8, 0x00, 0x00, 0x40, 0x00, 0x8B, 0x45, 0xF8,    
    0x0F, 0xB7, 0x08, 0x81, 0xF9, 0x4D, 0x5A, 0x00, 0x00, 0x74, 0x04, 0x33, 0xC0, 0xEB, 0x5F, 0x8B,    
    0x55, 0xF8, 0x8B, 0x45, 0xF8, 0x03, 0x42, 0x3C, 0x89, 0x45, 0xFC, 0x8B, 0x4D, 0xFC, 0x81, 0x39,    
    0x50, 0x45, 0x00, 0x00, 0x74, 0x04, 0x33, 0xC0, 0xEB, 0x44, 0x8B, 0x55, 0xFC, 0x0F, 0xB7, 0x42,    
    0x18, 0x3D, 0x0B, 0x01, 0x00, 0x00, 0x74, 0x04, 0x33, 0xC0, 0xEB, 0x32, 0x8B, 0x4D, 0xFC, 0x83,    
    0x79, 0x74, 0x0E, 0x77, 0x04, 0x33, 0xC0, 0xEB, 0x25, 0xBA, 0x08, 0x00, 0x00, 0x00, 0x6B, 0xC2,    
    0x0E, 0x8B, 0x4D, 0xFC, 0x83, 0x7C, 0x01, 0x78, 0x00, 0x74, 0x09, 0xC7, 0x45, 0xF4, 0x01, 0x00,    
    0x00, 0x00, 0xEB, 0x07, 0xC7, 0x45, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x45, 0xF4, 0x8B, 0xE5,    
    0x5D, 0xC3
};
typedef void(*PFN_FOO)();
int main()
{ 
   PFN_FOO f = (PFN_FOO)(void *)data;    
   f();

无法执行

可以看到可读可写不可执行,修改保存就行了 因为shellcode在程序的全局区,没有可执行权限,代码所在内存必须可读可执行,但是重新编译不行,因为重新编译了就变了,所以还可以在当前程序申请一块可写可读可执行的代码区

VirtualAlloc

LPVOID VirtualAlloc(  LPVOID lpAddress,        // region to reserve or commit 
 SIZE_T dwSize,           // size of region  
 DWORD flAllocationType,  // type of allocation  
 DWORD flProtect          // type of access protection);

这里来申请一块

LPVOID lpAddr = VirtualAlloc(
            NULL,    //表示任意地址,随机分配            
            1,    //内存通常是以分页为单位来给空间 1页=4k 4096字节            
            MEM_COMMIT,    //告诉操作系统给分配一块内存            
            PAGE_EXECUTE_READWRITE       
          );    
       if (lpAddr == NULL){        
           printf("Alloc error!");        
           return 0;    
   }

可以看到内存已经申请好了,接下来就把我们的数据拷贝过来,再执行,最后还要释放掉

memcpy(lpAddr, data, sizeof(data));
typedef void(*PFN_FOO)();
PFN_FOO f = (PFN_FOO)(void*)lpAddr;
f();
VirtualFree(lpAddr,1,MEM_DECOMMIT);

完整代码

unsigned char data[130] = {
    0x55, 0x8B, 0xEC, 0x83, 0xEC, 0x0C, 0xC7, 0x45, 0xF8, 0x00, 0x00, 0x40, 0x00, 0x8B, 0x45, 0xF8,   
     0x0F, 0xB7, 0x08, 0x81, 0xF9, 0x4D, 0x5A, 0x00, 0x00, 0x74, 0x04, 0x33, 0xC0, 0xEB, 0x5F, 0x8B,    
     0x55, 0xF8, 0x8B, 0x45, 0xF8, 0x03, 0x42, 0x3C, 0x89, 0x45, 0xFC, 0x8B, 0x4D, 0xFC, 0x81, 0x39,    
     0x50, 0x45, 0x00, 0x00, 0x74, 0x04, 0x33, 0xC0, 0xEB, 0x44, 0x8B, 0x55, 0xFC, 0x0F, 0xB7, 0x42,    
     0x18, 0x3D, 0x0B, 0x01, 0x00, 0x00, 0x74, 0x04, 0x33, 0xC0, 0xEB, 0x32, 0x8B, 0x4D, 0xFC, 0x83,    
     0x79, 0x74, 0x0E, 0x77, 0x04, 0x33, 0xC0, 0xEB, 0x25, 0xBA, 0x08, 0x00, 0x00, 0x00, 0x6B, 0xC2,    
     0x0E, 0x8B, 0x4D, 0xFC, 0x83, 0x7C, 0x01, 0x78, 0x00, 0x74, 0x09, 0xC7, 0x45, 0xF4, 0x01, 0x00,    
     0x00, 0x00, 0xEB, 0x07, 0xC7, 0x45, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x45, 0xF4, 0x8B, 0xE5,    
     0x5D, 0xC3
};
int main()
{  
   LPVOID lpAddr = VirtualAlloc(
               NULL,    //表示任意地址,随机分配            
               1,    //内存通常是以分页为单位来给空间 1页=4k 4096字节            
               MEM_COMMIT,    //告诉操作系统给分配一块内存            
               PAGE_EXECUTE_READWRITE        
            );    
      if (lpAddr == NULL){     
          printf("Alloc error!");        
          return 0;    
      }    
      //到这里表示能够成功分配内存    
      memcpy(lpAddr, data, sizeof(data));    
      typedef void(*PFN_FOO)();    
      PFN_FOO f = (PFN_FOO)(void*)lpAddr;    
      f();    
      VirtualFree(lpAddr,1,MEM_DECOMMIT);    
      return 0;

这里我们本地写个messagebox,可以看到helloworld是再常量区地址为0C65858h,但是函数的引用地址却在0C6916Ch,他们之间是有强烈的依赖关系,所以我们如果直接把代码抽出来是无法利用的

所以如果上面我们想要执行成功就要处理掉相关依赖,比如相关函数的地址,字符串地址 自己重定位了,shellcode:一段与地址无关的代码,只要把它放在任意32位程序中只要给他一个起点就能执行 所以我们要先开辟空间然后再写入,然是可以看到VirtualAlloc写了谁调用在谁哪里开辟空间

所以我们就用加强版VirtualAllocEx,它可以在指定进程去开辟 VirtualAllocEx

image.png

代码差不多,但是这里我们要先获取我们要注入的进程句柄,这里shellcode为32位所以我们需要获取的也是32位的

image.png

就是昨天的代码,然后再来开辟一个空间

image.png

然后我们就是要写入,这里就不能使用memcpy了因为这个是当前进程调用的 WriteProcessMemory

image.png

这里我们就写入进去

image.png

写进去了还要调用才能执行,创建远程线程 CreateRemoteThread

image.png

返回目标进程的线程

image.png

这里我们不要立马释放因为可能执行需要一段时间,所以要等待执行完毕再释放 完成代码为

image.png

image.png

点赞 转发 在看

原创投稿作者:一寸一叶

本文作者:HACK_Learn

本文为安全脉搏专栏作者发布,转载请注明:https://www.secpulse.com/archives/145415.html


文章来源: https://www.secpulse.com/archives/145415.html
如有侵权请联系:admin#unsafe.sh