首页
社区
课程
招聘
[原创]某公司DLP产品通过驱动注入DLL分析
2016-2-27 17:22 21339

[原创]某公司DLP产品通过驱动注入DLL分析

2016-2-27 17:22
21339
最近在分析某公司DLP产品,里边文档控制相关功能,出于好奇分析了一下原理。
      应用层的权限控制一般通过全局Hook注入DLL进行权限控制,使用工具PCHunder发现,除了WH_KEYBOARD_LL消息Hook,没有其它消息Hook,最后通过PCHunder发现是通过驱动层进行设置PsSetCreateProcessNotifyRoutine回调注入Shellcode实现。
      具体IDA分析如下图:
bool __stdcall sub_15D40(HANDLE ProcessHandle, wchar_t *wzDllPath)
{
  int v3; // [sp+0h] [bp-488h]@21
  int v4; // [sp+4h] [bp-484h]@11
  char v5; // [sp+8h] [bp-480h]@11
  int v6; // [sp+14h] [bp-474h]@12
  int v7; // [sp+18h] [bp-470h]@13
  unsigned __int8 v8; // [sp+240h] [bp-248h]@2
  int v9; // [sp+241h] [bp-247h]@2
  unsigned __int8 v10; // [sp+245h] [bp-243h]@2
  int v11; // [sp+246h] [bp-242h]@2
  unsigned __int16 v12; // [sp+24Ah] [bp-23Eh]@2
  int v13; // [sp+24Ch] [bp-23Ch]@2
  int v14; // [sp+250h] [bp-238h]@2
  int v15; // [sp+254h] [bp-234h]@3
  __int16 v16; // [sp+25Dh] [bp-22Bh]@5
  __int16 v17; // [sp+25Fh] [bp-229h]@5
  int v18; // [sp+261h] [bp-227h]@5
  wchar_t v19; // [sp+265h] [bp-223h]@5
  int v20; // [sp+46Dh] [bp-1Bh]@5
  int v21; // [sp+471h] [bp-17h]@5
  unsigned __int8 v22; // [sp+478h] [bp-10h]@8
  int v23; // [sp+479h] [bp-Fh]@11
  bool v24; // [sp+483h] [bp-5h]@1
  int v25; // [sp+484h] [bp-4h]@1

  v24 = 0;
  v25 = (int)MyAllocateVirtualMemory(ProcessHandle, 0x2BBu, 0);
  if ( v25 )
  {
    v8 = 0xB8u;                                  // MOV EAX,XXXXXXXX
    v9 = v25;
    v10 = 0xB9u;                                // MOV ECX,XXXXXXXX
    v11 = v25 + 565;
    v12 = 0xD1FFu;                            // CALL ECX
    v13 = 0x4C69636D;                     // 特征码
    v14 = 0;
    v15 = pfnNtTestAlert ? pfnNtTestAlert : sub_15570(ProcessHandle);
    v16 = 2 * wcslen(wzDllPath);                // UNICODE_STRING ++0 Length
    v17 = v16 + 2;                                    // UNICODE_STRING ++2 MaxmumLength
    v18 = v25 + 0x25;                              // UNICODE_STRING ++4 Buffer
    wcscpy(&v19, wzDllPath);                    // 将wzDllPath拷贝进ShellCode
    v20 = pfnNtProtectVirtualMemory;
    v21 = pfnLdrLoadDll;
    if ( v15 )
    {
      if ( MyWriteVirtualMemory((int)ProcessHandle, v25, (int)&v8, 566)
        && MyWriteVirtualMemory((int)ProcessHandle, v25 + 0x235, (int)sub_10420, 133)
        && MyReadVirtualMemory((int)ProcessHandle, v15, (int)&v22, 5)// 读取pfnNtTestAlert函数前5个字节备份到ShellCode中
        && MyWriteVirtualMemory((int)ProcessHandle, v25 + 0x18, (int)&v22, 5) )
      {
        if ( v22 == 0xE9 )                      // 构造要插入dll的链表ShellCode
        {
          v4 = v15 + v23 + 5;
          if ( MyReadVirtualMemory((int)ProcessHandle, v4, (int)&v5, 566) && v6 == 0x4C69636D )
          {
            while ( v7 )
            {
              v4 = v7;
              if ( !MyReadVirtualMemory((int)ProcessHandle, v7, (int)&v5, 566) || v6 != 0x4C69636D )
              {
                v4 = 0;
                break;
              }
            }
            if ( v4 )
            {
              v7 = v25;
              v24 = MyWriteVirtualMemory((int)ProcessHandle, v4, (int)&v5, 566);
            }
          }
        }
        if ( !v24 && MyProtectVirutalMemory((int)ProcessHandle, v15, 5, 64, (int)&v3) )// 修改pfnNtTestAlert函数前面5个字节为jmp XXXX,其中XXXX为Shellcode入口地址
        {
          v22 = 0xE9u;
          v23 = v25 - v15 - 5;
          MyWriteVirtualMemory((int)ProcessHandle, v15, (int)&v22, 5);
          MyProtectVirutalMemory((int)ProcessHandle, v15, 5, v3, (int)&v3);
          v24 = 1;
        }
      }
    }
  }
  return v24;
}


     使用Windbg 启动notepad,反汇编发现ntdll!NtTestAlert函数前5个字节被修改为jmp指令,随后将jmp位置的内存进行转储分析如下:
     
seg000:00000000 seg000          segment byte public 'CODE' use32
seg000:00000000                 assume cs:seg000
seg000:00000000                 assume es:nothing, ss:nothing, ds:nothing, fs:nothing, gs:nothing
seg000:00000000                 mov     eax, 40000h
seg000:00000005
seg000:00000005 loc_5:
seg000:00000005                 mov     ecx, 40235h
seg000:0000000A                 call    ecx
seg000:0000000A ; ---------------------------------------------------------------------------
seg000:0000000C                 dd 4C69636Dh            ; 特征码
seg000:00000010                 dd 0                    ; 下一个ShellCode地址
seg000:00000014                 dd 76EC5D30h            ; pfnNtTestAlert
seg000:00000018 ; ---------------------------------------------------------------------------
seg000:00000018                 mov     eax, 174h
seg000:00000018 ; ---------------------------------------------------------------------------
seg000:0000001D                 UNICODE_STRING <5Eh, 60h, 40025h>
seg000:00000025 aCProgramFilesM:
seg000:00000025                 unicode 0, <C:\Program Files\XXXXX\DLP\Agent\fcagcbh32.dll>,0
....
seg000:0000022D                 dd 76EC5360h            ; pfnNtProtectVirtualMemory
seg000:00000231                 dd 76EDF585h            ; pfnLdrLoadDll
seg000:00000235
seg000:00000235 ; =============== S U B R O U T I N E =======================================
seg000:00000235
seg000:00000235 ; Attributes: bp-based frame
seg000:00000235
seg000:00000235 sub_235         proc near
seg000:00000235
seg000:00000235 var_C           = dword ptr -0Ch
seg000:00000235 var_8           = dword ptr -8
seg000:00000235 var_4           = dword ptr -4
seg000:00000235
seg000:00000235                 push    ebp
seg000:00000236                 mov     ebp, esp
seg000:00000238                 add     esp, 0FFFFFFF4h
seg000:0000023B                 push    ebx
seg000:0000023C                 mov     ebx, eax        ; 参数基址
seg000:0000023E                 mov     [ebp+var_4], ebp
seg000:00000241                 mov     eax, [ebp+var_4]
seg000:00000244                 add     eax, 4          ; 指向栈上函数返回地址
seg000:00000247                 mov     edx, [ebx+14h]
seg000:0000024A                 mov     [eax], edx      ; 修改函数返回地址为pfnNtTestAlert
seg000:0000024C                 mov     eax, [ebx+14h]
seg000:0000024F                 mov     [ebp+var_C], eax
seg000:00000252                 mov     [ebp+var_4], 5
seg000:00000259                 lea     eax, [ebp+var_8]
seg000:0000025C                 push    eax             ; OldProtect
seg000:0000025D                 push    40h ; '@'       ; PAGE_EXECUTE_READWRITE
seg000:0000025F                 lea     eax, [ebp+var_4]
seg000:00000262                 push    eax             ; RegionSize
seg000:00000263                 lea     eax, [ebp+var_C]
seg000:00000266                 push    eax             ; BaseAddress
seg000:00000267                 push    0FFFFFFFFh      ; ProcessHandle
seg000:00000269                 call    dword ptr [ebx+22Dh] ; NtProtectVirtualMemory
seg000:0000026F                 mov     eax, [ebx+14h]
seg000:00000272                 mov     edx, [ebx+18h]
seg000:00000275                 mov     [eax], edx
seg000:00000277                 mov     dl, [ebx+1Ch]   ; 修改NtTestAlert函数前5个字节为MOV EAX, 174h
seg000:0000027A                 mov     [eax+4], dl
seg000:0000027D                 mov     [ebp+var_4], 5
seg000:00000284                 lea     eax, [ebp+var_8]
seg000:00000287                 push    eax             ; OldProtect
seg000:00000288                 mov     eax, [ebp+var_8]
seg000:0000028B                 push    eax             ; NewProtectWin32
seg000:0000028C                 lea     eax, [ebp+var_4]
seg000:0000028F                 push    eax             ; RegionSize
seg000:00000290                 lea     eax, [ebp+var_C]
seg000:00000293                 push    eax             ; BaseAddress
seg000:00000294                 push    0FFFFFFFFh      ; ProcessHandle
seg000:00000296                 call    dword ptr [ebx+22Dh] ; NtProtectVirtualMemory
seg000:0000029C
seg000:0000029C loc_29C:                                ; CODE XREF: sub_235+7Ej
seg000:0000029C                 lea     eax, [ebp+var_4]
seg000:0000029F                 push    eax
seg000:000002A0                 lea     eax, [ebx+1Dh]
seg000:000002A3                 push    eax
seg000:000002A4                 push    0
seg000:000002A6                 push    0
seg000:000002A8                 call    dword ptr [ebx+231h] ; LdrLoadDll
seg000:000002AE                 mov     ebx, [ebx+10h]
seg000:000002B1                 test    ebx, ebx
seg000:000002B3                 jnz     short loc_29C
seg000:000002B5                 pop     ebx
seg000:000002B6                 mov     esp, ebp
seg000:000002B8                 pop     ebp
seg000:000002B9                 retn
seg000:000002B9 sub_235         endp
seg000:000002B9
seg000:000002B9 ; ---------------------------------------------------------------------------
seg000:000002BA                 align 1000h
seg000:000002BA seg000          ends
seg000:000002BA
seg000:000002BA
seg000:000002BA                 end

       最后总结一下原理:
       1、驱动通过函数PsSetCreateProcessNotifyRoutine对新启动的进程进行监控(Win8 以后机器需要额外调用PsSetLoadImageNotifyRoutine设置回调)。
       2、在ProcessCreate回调中对启动的进程插入ShellCode。
       3、修改启动进程ntdll函数NtTestAlert入口5字节为jmp指令跳转到ShellCode开始地址进行执行。
       4、进程的主线程开始执行调用ntdll!LdrInitializeThunk->ntdll!_LdrpInitialize->ntdll!NtTestAlert函数触发Shellcode执行。
       5、ShellCode执行通过调用ntdll!LdrLoadDll函数装入DLL并且修改ShellCode的返回地址为NtTestAlert,还原NtTestAlert函数的前5个字节内容,正式
           执行NtTestAlert函数。
       6、后续NtTestAlert函数的调用不再会触发ShellCode的执行。

在Win64环境启动64位程序,注入的ShellCode工作原理与32位的类似,上传ShellCode分析代码如下:
seg000:0000000000000000 seg000          segment byte public 'CODE' use64
seg000:0000000000000000                 assume cs:seg000
seg000:0000000000000000                 assume es:nothing, ss:nothing, ds:nothing, fs:nothing, gs:nothing
seg000:0000000000000000                 mov     rax, 77622B20h
seg000:000000000000000A                 push    rax             ; ShellCode执行完返回地址
seg000:000000000000000B                 push    rcx
seg000:000000000000000C                 push    rdx
seg000:000000000000000D                 push    r8
seg000:000000000000000F                 push    r9
seg000:0000000000000011                 sub     rsp, 28h
seg000:0000000000000015                 mov     rcx, 71B00000h  ; 该ShellCode加载基址
seg000:000000000000001F                 mov     rdx, 71B0026Ch
seg000:0000000000000029                 jmp     rdx
seg000:0000000000000029 ; ---------------------------------------------------------------------------
seg000:000000000000002B                 dd 4C69636Dh            ; 特征码
seg000:000000000000002F qword_2F        dq 0
seg000:0000000000000037                 dq 77622B20h            ; pfnNtTestAlert
seg000:000000000000003F                 db  4Ch ; L             ; NtTestAlert函数前5个字节备份
seg000:0000000000000040                 db  8Bh ; 
seg000:0000000000000041                 db 0D1h ; 
seg000:0000000000000042                 db 0B8h ; 
seg000:0000000000000043                 db  7Eh ; ~
seg000:0000000000000044                 dw 5Eh                  ; UNICODE_STRING ++0 Length
seg000:0000000000000046                 dw 60h                  ; UNICODE_STRING ++2 MaximumLength
seg000:0000000000000048                 dd 0                    ; UNICODE_STRING x64 align padding
seg000:000000000000004C                 dq 71B00054h            ; UNICODE_STRING ++8 Buffer
seg000:0000000000000054 aCProgramFilesM:
seg000:0000000000000054                 unicode 0, <C:\Program Files\XXXXXX\DLP\Agent\fcagcbh64.dll>,0
。。。。省略无效
seg000:000000000000025C                 dq 77621810h            ; pfnNtProtectVirtualMemory
seg000:0000000000000264                 dq 775F7A90h            ; pfnNtLdrLoadDll
seg000:000000000000026C
seg000:000000000000026C ; =============== S U B R O U T I N E =======================================
seg000:000000000000026C
seg000:000000000000026C
seg000:000000000000026C sub_26C         proc near
seg000:000000000000026C
seg000:000000000000026C var_18          = qword ptr -18h
seg000:000000000000026C arg_0           = dword ptr  8
seg000:000000000000026C arg_8           = qword ptr  10h
seg000:000000000000026C arg_10          = byte ptr  18h
seg000:000000000000026C
seg000:000000000000026C                 mov     r11, rsp
seg000:000000000000026F                 push    rbx
seg000:0000000000000270                 sub     rsp, 30h
seg000:0000000000000274                 mov     rax, [rcx+37h]  ; rax<-pfnNtTestAlert
seg000:0000000000000278                 mov     rbx, rcx
seg000:000000000000027B                 lea     r8, [r11+10h]   ; RegionSize
seg000:000000000000027F                 mov     [r11+18h], rax
seg000:0000000000000283                 lea     rax, [r11+8]
seg000:0000000000000287                 lea     rdx, [r11+18h]  ; BaseAddress
seg000:000000000000028B                 mov     r9d, 40h ; '@'  ; NewProtect
seg000:0000000000000291                 or      rcx, 0FFFFFFFFFFFFFFFFh ; ProcessHandle
seg000:0000000000000295                 mov     qword ptr [r11+10h], 5
seg000:000000000000029D                 mov     [r11-18h], rax
seg000:00000000000002A1                 call    qword ptr [rbx+25Ch] ; pfnNtProtectVirtualMemory
seg000:00000000000002A7                 test    eax, eax
seg000:00000000000002A9                 jnz     short loc_2E8
seg000:00000000000002AB                 mov     eax, [rbx+3Fh]  ; NtTestAlert前4个字节放到eax中
seg000:00000000000002AE                 mov     rdx, [rbx+37h]  ; rdx<-pfnNtTestAlert
seg000:00000000000002B2                 lea     r8, [rsp+38h+arg_8] ; RegionSize
seg000:00000000000002B7                 mov     [rdx], eax      ; 重写函数NtTestAlert前4个字节
seg000:00000000000002B9                 mov     al, [rbx+43h]   ; 获取备份的第5个字节
seg000:00000000000002BC                 or      rcx, 0FFFFFFFFFFFFFFFFh ; ProcessHandle
seg000:00000000000002C0                 mov     [rdx+4], al     ; 重写函数NtTestAlert第5个字节
seg000:00000000000002C3                 mov     r9d, [rsp+38h+arg_0]
seg000:00000000000002C8                 lea     rax, [rsp+38h+arg_0]
seg000:00000000000002CD                 lea     rdx, [rsp+38h+arg_10]
seg000:00000000000002D2                 mov     [rsp+38h+var_18], rax
seg000:00000000000002D7                 mov     [rsp+38h+arg_8], 5
seg000:00000000000002E0                 call    qword ptr [rbx+25Ch] ; pfnNtProtectVirtualMemory
seg000:00000000000002E6                 jmp     short loc_30F   ; ModuleFileName
seg000:00000000000002E8 ; ---------------------------------------------------------------------------
seg000:00000000000002E8
seg000:00000000000002E8 loc_2E8:                                ; CODE XREF: sub_26C+3Dj
seg000:00000000000002E8                 mov     rax, [rbx+37h]
seg000:00000000000002EC                 mov     rcx, [rax]      ; 将当前内存pfnNtTestAlert前8个字节放入rcx
seg000:00000000000002EF                 mov     eax, [rbx+3Fh]  ; 将备份的pfnNtTestAlert前4个字节放入eax
seg000:00000000000002F2                 mov     [rbx], rcx
seg000:00000000000002F5                 mov     [rbx], eax
seg000:00000000000002F7                 mov     al, [rbx+43h]
seg000:00000000000002FA                 mov     [rbx+4], al
seg000:00000000000002FD                 lea     rcx, [rbx+8]
seg000:0000000000000301                 mov     byte ptr [rcx], 0E9h ; ' ; 修改ShellCode入口代码,第一条语句为NtTestAlert函数第一条语句,第二条语句跳回NtTestAlert函数的第二条语句
seg000:0000000000000304                 mov     eax, [rbx+37h]
seg000:0000000000000307                 sub     eax, ecx
seg000:0000000000000309                 add     eax, 3
seg000:000000000000030C                 mov     [rcx+1], eax
seg000:000000000000030F
seg000:000000000000030F loc_30F:                                ; CODE XREF: sub_26C+7Aj
seg000:000000000000030F                                         ; sub_26C+BDj
seg000:000000000000030F                 lea     r8, [rbx+44h]   ; ModuleFileName
seg000:0000000000000313                 lea     r9, [rsp+38h+arg_8] ; ModuleHandle
seg000:0000000000000318                 xor     edx, edx        ; Flags
seg000:000000000000031A                 xor     ecx, ecx        ; PathToFile
seg000:000000000000031C                 call    qword ptr [rbx+264h] ; call NtTestAlert
seg000:0000000000000322                 mov     rbx, [rbx+2Fh]
seg000:0000000000000326                 test    rbx, rbx
seg000:0000000000000329                 jnz     short loc_30F   ; ModuleFileName
seg000:000000000000032B                 add     rsp, 30h
seg000:000000000000032F                 pop     rbx
seg000:0000000000000330                 add     rsp, 28h
seg000:0000000000000334                 pop     r9
seg000:0000000000000336                 pop     r8
seg000:0000000000000338                 pop     rdx
seg000:0000000000000339                 pop     rcx
seg000:000000000000033A                 retn


使用64位驱动注入ShellCode到32位应用程序Hook的是ntdll32!NtTestAlert函数,上传ShellCode分析代码。
seg000:00000000 seg000          segment byte public 'CODE' use32
seg000:00000000                 assume cs:seg000
seg000:00000000                 assume es:nothing, ss:nothing, ds:nothing, fs:nothing, gs:nothing
seg000:00000000                 mov     eax, 80000h     ; ShellCode加载基址
seg000:00000005
seg000:00000005 loc_5:
seg000:00000005                 mov     ecx, 80235h
seg000:0000000A                 call    ecx
seg000:0000000A ; ---------------------------------------------------------------------------
seg000:0000000C                 dd 4C69636Dh            ; 特征码
seg000:00000010                 dd 0
seg000:00000014                 dd 777D1DB0h            ; pfnNtTestAlert
seg000:00000018 ; ---------------------------------------------------------------------------
seg000:00000018                 mov     eax, 17Eh       ; 备份的NtTestAlert前5个字节
seg000:00000018 ; ---------------------------------------------------------------------------
seg000:0000001D                 dw 5Eh
seg000:0000001F                 dw 60h
seg000:00000021                 dd 80025h
seg000:00000025 aCProgramFilesM:                        ; DATA XREF: sub_235+Cr
seg000:00000025                 unicode 0, <C:\Program Files\XXXXX\DLP\Agent\fcagcbh32.dll>,0
。。。。
seg000:00000235 ; =============== S U B R O U T I N E =======================================
seg000:00000235
seg000:00000235 ; Attributes: bp-based frame
seg000:00000235
seg000:00000235 sub_235         proc near
seg000:00000235
seg000:00000235 var_54          = dword ptr -54h
seg000:00000235 var_44          = dword ptr -44h
seg000:00000235 var_34          = dword ptr -34h
seg000:00000235 var_30          = dword ptr -30h
seg000:00000235 var_2C          = dword ptr -2Ch
seg000:00000235 var_28          = dword ptr -28h
seg000:00000235 var_24          = dword ptr -24h
seg000:00000235 var_20          = dword ptr -20h
seg000:00000235 var_1C          = dword ptr -1Ch
seg000:00000235 var_18          = dword ptr -18h
seg000:00000235 var_14          = dword ptr -14h
seg000:00000235 var_10          = dword ptr -10h
seg000:00000235 var_C           = dword ptr -0Ch
seg000:00000235 var_8           = dword ptr -8
seg000:00000235 var_4           = dword ptr -4
seg000:00000235
seg000:00000235                 push    ebp
seg000:00000236                 mov     ebp, esp
seg000:00000238                 add     esp, 0FFFFFFACh ; sub esp, 84
seg000:0000023B                 push    ebx
seg000:0000023C                 push    esi
seg000:0000023D                 push    edi
seg000:0000023E                 mov     [ebp+var_C], eax ; [ebp+var_C]<-ShellCodeBase
seg000:00000241                 mov     ecx, dword ptr fs:aCProgramFilesM+0Bh
seg000:00000248                 mov     [ebp+var_4], ecx ; [ebp+var_4]<-_PEB地址
seg000:0000024B                 mov     [ebp+var_8], ebp
seg000:0000024E                 mov     eax, [ebp+var_C]
seg000:00000251                 mov     eax, [eax+14h]
seg000:00000254                 mov     edx, [ebp+var_8]
seg000:00000257                 add     edx, 4
seg000:0000025A                 mov     [edx], eax      ; 修改该函数返回地址为pfnNtTestAlert
seg000:0000025C                 xor     eax, eax
seg000:0000025E                 mov     [ebp+var_28], eax
seg000:00000261                 xor     eax, eax
seg000:00000263                 mov     [ebp+var_2C], eax
seg000:00000266                 mov     eax, [ebp+var_4]
seg000:00000269                 add     eax, 0Ch        ; Offset _PEB->Ldr
seg000:0000026C                 mov     eax, [eax]      ; eax指向_PEB_LDR_DATA
seg000:0000026E                 add     eax, 14h        ; eax 指向_PEB_LDR_DATA->InMemoryOrderModuleList
seg000:00000271                 mov     [ebp+var_18], eax
seg000:00000274                 mov     eax, [ebp+var_18]
seg000:00000277                 mov     esi, eax
seg000:00000279                 lea     edi, [ebp+var_54]
seg000:0000027C                 mov     ecx, 9
seg000:00000281                 rep movsd
seg000:00000283                 jmp     loc_48A
seg000:00000288 ; ---------------------------------------------------------------------------
seg000:00000288
seg000:00000288 loc_288:                                ; CODE XREF: sub_235+25Bj
seg000:00000288                 mov     eax, [ebp+var_54]
seg000:0000028B                 mov     esi, eax
seg000:0000028D                 lea     edi, [ebp+var_54]
seg000:00000290                 mov     ecx, 9
seg000:00000295                 rep movsd
seg000:00000297                 cmp     [ebp+var_34], 0
seg000:0000029B                 jz      loc_48A
seg000:000002A1                 xor     ebx, ebx
seg000:000002A3                 jmp     short loc_2A6   ; 从链表中查找ntdll.dll模块
seg000:000002A5 ; ---------------------------------------------------------------------------
seg000:000002A5
seg000:000002A5 loc_2A5:                                ; CODE XREF: sub_235+79j
seg000:000002A5                 inc     ebx
seg000:000002A6
seg000:000002A6 loc_2A6:                                ; CODE XREF: sub_235+6Ej
seg000:000002A6                 mov     eax, [ebp+var_34] ; 从链表中查找ntdll.dll模块
seg000:000002A9                 cmp     word ptr [eax+ebx*2], 0
seg000:000002AE                 jnz     short loc_2A5
seg000:000002B0                 mov     eax, [ebp+var_34]
seg000:000002B3                 lea     eax, [eax+ebx*2-12h]
seg000:000002B7                 cmp     dword ptr [eax+4], 6C0064h ; "ld"
seg000:000002BE                 jnz     loc_48A
seg000:000002C4                 cmp     dword ptr [eax], 74006Eh ; "tn"
seg000:000002CA                 jnz     loc_48A
seg000:000002D0                 mov     eax, [ebp+var_34]
seg000:000002D3                 lea     eax, [eax+ebx*2-0Ah]
seg000:000002D7                 cmp     dword ptr [eax+4], 6C0064h ; "ld"
seg000:000002DE                 jnz     loc_48A
seg000:000002E4                 cmp     dword ptr [eax], 2E006Ch ; ".l"
seg000:000002EA                 jnz     loc_48A
seg000:000002F0                 mov     esi, [ebp+var_44]
seg000:000002F3                 lea     eax, [esi+3Ch]
seg000:000002F6                 mov     eax, [eax]
seg000:000002F8                 add     eax, esi
seg000:000002FA                 mov     [ebp+var_1C], eax
seg000:000002FD                 mov     eax, [ebp+var_1C]
seg000:00000300                 mov     eax, [eax+78h]
seg000:00000303                 add     eax, esi
seg000:00000305                 mov     edi, eax
seg000:00000307                 mov     eax, [edi+18h]
seg000:0000030A                 dec     eax
seg000:0000030B                 test    eax, eax
seg000:0000030D                 jl      loc_496
seg000:00000313                 inc     eax
seg000:00000314                 mov     [ebp+var_30], eax
seg000:00000317                 mov     [ebp+var_20], 0
seg000:0000031E
seg000:0000031E loc_31E:                                ; CODE XREF: sub_235+24Dj
seg000:0000031E                 mov     eax, [edi+20h]  ; 查找函数"LdrLoadDll"
seg000:00000321                 add     eax, esi
seg000:00000323                 mov     edx, [ebp+var_20]
seg000:00000326                 mov     eax, [eax+edx*4]
seg000:00000329                 add     eax, esi
seg000:0000032B                 mov     [ebp+var_24], eax
seg000:0000032E                 cmp     [ebp+var_24], 0
seg000:00000332                 jz      loc_47C
seg000:00000338                 mov     eax, [ebp+var_24]
seg000:0000033B                 cmp     dword ptr [eax+4], 'Ddao'
seg000:00000342                 jnz     short loc_360   ; 查找函数"NtProtectVirtualMemory"
seg000:00000344                 cmp     dword ptr [eax], 'LrdL'
seg000:0000034A                 jnz     short loc_360   ; 查找函数"NtProtectVirtualMemory"
seg000:0000034C                 mov     eax, [ebp+var_24]
seg000:0000034F                 add     eax, 8
seg000:00000352                 mov     eax, [eax]
seg000:00000354                 and     eax, 0FFFFFFh
seg000:00000359                 cmp     eax, 'll'
seg000:0000035E                 jz      short loc_3C3
seg000:00000360
seg000:00000360 loc_360:                                ; CODE XREF: sub_235+10Dj
seg000:00000360                                         ; sub_235+115j
seg000:00000360                 mov     eax, [ebp+var_24] ; 查找函数"NtProtectVirtualMemory"
seg000:00000363                 cmp     dword ptr [eax+4], 6365746Fh
seg000:0000036A                 jnz     loc_47C
seg000:00000370                 cmp     dword ptr [eax], 7250744Eh
seg000:00000376                 jnz     loc_47C
seg000:0000037C                 mov     eax, [ebp+var_24]
seg000:0000037F                 add     eax, 8
seg000:00000382                 cmp     dword ptr [eax+4], 6C617574h
seg000:00000389                 jnz     loc_47C
seg000:0000038F                 cmp     dword ptr [eax], 72695674h
seg000:00000395                 jnz     loc_47C
seg000:0000039B                 mov     eax, [ebp+var_24]
seg000:0000039E                 add     eax, 10h
seg000:000003A1                 mov     edx, [eax+4]
seg000:000003A4                 mov     eax, [eax]
seg000:000003A6                 and     edx, 0FFFFFFh
seg000:000003AC                 cmp     edx, 7972h
seg000:000003B2                 jnz     loc_47C
seg000:000003B8                 cmp     eax, 6F6D654Dh
seg000:000003BD                 jnz     loc_47C
seg000:000003C3
seg000:000003C3 loc_3C3:                                ; CODE XREF: sub_235+129j
seg000:000003C3                 mov     eax, [edi+24h]
seg000:000003C6                 add     eax, esi
seg000:000003C8                 mov     edx, [ebp+var_20]
seg000:000003CB                 movzx   eax, word ptr [eax+edx*2]
seg000:000003CF                 mov     [ebp+var_8], eax
seg000:000003D2                 mov     eax, [edi+1Ch]
seg000:000003D5                 add     eax, esi
seg000:000003D7                 mov     edx, [ebp+var_8]
seg000:000003DA                 mov     eax, [eax+edx*4]
seg000:000003DD                 mov     [ebp+var_8], eax
seg000:000003E0                 mov     eax, [ebp+var_24]
seg000:000003E3                 cmp     byte ptr [eax], 4Ch ; 'L'
seg000:000003E6                 jnz     short loc_3F2
seg000:000003E8                 mov     eax, [ebp+var_8]
seg000:000003EB                 add     eax, esi
seg000:000003ED                 mov     [ebp+var_2C], eax
seg000:000003F0                 jmp     short loc_3FA   ; 修改函数NtTestAlert所在页面属性为PAGE_READWRITE_EXECUTE
seg000:000003F2 ; ---------------------------------------------------------------------------
seg000:000003F2
seg000:000003F2 loc_3F2:                                ; CODE XREF: sub_235+1B1j
seg000:000003F2                 mov     eax, [ebp+var_8]
seg000:000003F5                 add     eax, esi
seg000:000003F7                 mov     [ebp+var_28], eax
seg000:000003FA
seg000:000003FA loc_3FA:                                ; CODE XREF: sub_235+1BBj
seg000:000003FA                 cmp     [ebp+var_2C], 0 ; 修改函数NtTestAlert所在页面属性为PAGE_READWRITE_EXECUTE
seg000:000003FE                 jz      short loc_47C
seg000:00000400                 cmp     [ebp+var_28], 0
seg000:00000404                 jz      short loc_47C
seg000:00000406                 mov     eax, [ebp+var_C]
seg000:00000409                 mov     eax, [eax+14h]
seg000:0000040C                 mov     [ebp+var_14], eax
seg000:0000040F                 mov     [ebp+var_8], 5
seg000:00000416                 lea     eax, [ebp+var_10]
seg000:00000419                 push    eax
seg000:0000041A                 push    40h ; '@'
seg000:0000041C                 lea     eax, [ebp+var_8]
seg000:0000041F                 push    eax
seg000:00000420                 lea     eax, [ebp+var_14]
seg000:00000423                 push    eax
seg000:00000424                 push    0FFFFFFFFh
seg000:00000426                 call    [ebp+var_28]    ; pfnNtProtectVirutalMemory
seg000:00000429                 mov     eax, [ebp+var_C]
seg000:0000042C                 mov     eax, [eax+14h]  ; eax<-pfnNtTestAlert
seg000:0000042F                 mov     edx, [ebp+var_C]
seg000:00000432                 mov     ecx, [edx+18h]  ; ecx指向函数NtTestAlert备份的前4个字节
seg000:00000435                 mov     [eax], ecx
seg000:00000437                 mov     cl, [edx+1Ch]
seg000:0000043A                 mov     [eax+4], cl     ; 还原NtTestAlert前5个字节内容
seg000:0000043D                 mov     [ebp+var_8], 5
seg000:00000444                 lea     eax, [ebp+var_10]
seg000:00000447                 push    eax
seg000:00000448                 mov     eax, [ebp+var_10]
seg000:0000044B                 push    eax
seg000:0000044C                 lea     eax, [ebp+var_8]
seg000:0000044F                 push    eax
seg000:00000450                 lea     eax, [ebp+var_14]
seg000:00000453                 push    eax
seg000:00000454                 push    0FFFFFFFFh
seg000:00000456                 call    [ebp+var_28]    ; 还原NtTestAlert函数所在页面属性
seg000:00000459
seg000:00000459 loc_459:                                ; CODE XREF: sub_235+243j
seg000:00000459                 lea     eax, [ebp+var_8]
seg000:0000045C                 push    eax
seg000:0000045D                 mov     eax, [ebp+var_C]
seg000:00000460                 add     eax, 1Dh
seg000:00000463                 push    eax
seg000:00000464                 push    0
seg000:00000466                 push    0
seg000:00000468                 call    [ebp+var_2C]    ; 调用LdrLoadDll函数装入Dll
seg000:0000046B                 mov     eax, [ebp+var_C]
seg000:0000046E                 mov     eax, [eax+10h]
seg000:00000471                 mov     [ebp+var_C], eax
seg000:00000474                 cmp     [ebp+var_C], 0
seg000:00000478                 jnz     short loc_459
seg000:0000047A                 jmp     short loc_496
seg000:0000047C ; ---------------------------------------------------------------------------
seg000:0000047C
seg000:0000047C loc_47C:                                ; CODE XREF: sub_235+FDj
seg000:0000047C                                         ; sub_235+135j ...
seg000:0000047C                 inc     [ebp+var_20]
seg000:0000047F                 dec     [ebp+var_30]
seg000:00000482                 jnz     loc_31E         ; 查找函数"LdrLoadDll"
seg000:00000488                 jmp     short loc_496
seg000:0000048A ; ---------------------------------------------------------------------------
seg000:0000048A
seg000:0000048A loc_48A:                                ; CODE XREF: sub_235+4Ej
seg000:0000048A                                         ; sub_235+66j ...
seg000:0000048A                 mov     eax, [ebp+var_54]
seg000:0000048D                 cmp     eax, [ebp+var_18]
seg000:00000490                 jnz     loc_288
seg000:00000496
seg000:00000496 loc_496:                                ; CODE XREF: sub_235+D8j
seg000:00000496                                         ; sub_235+245j ...
seg000:00000496                 pop     edi
seg000:00000497                 pop     esi
seg000:00000498                 pop     ebx
seg000:00000499                 mov     esp, ebp
seg000:0000049B                 pop     ebp
seg000:0000049C                 retn
seg000:0000049C sub_235         endp
seg000:0000049C
seg000:0000049C ; ---------------------------------------------------------------------------
seg000:0000049D                 align 1000h
seg000:0000049D seg000          ends
seg000:0000049D
seg000:0000049D
seg000:0000049D                 end

[培训]《安卓高级研修班(网课)》月薪三万计划,掌 握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

上传的附件:
收藏
免费 3
打赏
分享
最新回复 (60)
雪    币: 17
活跃值: (298)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
叁毛 1 2016-2-27 18:05
2
0
这个方案存在同步问题吧?
进程监控通知到注入这个期间,应用程序和注入不是同步的吧
雪    币: 17
活跃值: (298)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
叁毛 1 2016-2-27 18:07
3
0
方便把安装包上传下嘛?
雪    币: 110
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
核心未拥有 2016-2-27 19:02
4
0
我也这样搞搞过,但是用 NtProtectVirtualMemory 就蓝屏  我是在这个操作 PsSetLoadImageNotifyRoutine
附加到程序
雪    币: 608
活跃值: (638)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
Morgion 1 2016-2-28 08:27
5
0
不要在ImageNotify里调用ZwProtectVirtualMemory
雪    币: 110
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
核心未拥有 2016-2-28 10:00
6
0
这兄弟怎么说,为什么会这样,要在ProcessNotify才行是吧
雪    币: 110
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
核心未拥有 2016-2-28 10:01
7
0
是要在ProcessNotify 才行是吧
雪    币: 14
活跃值: (271)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
flylinfan 2016-2-28 10:03
8
0
驱动在进程通知的时候注入的ShellCode,ShellCode是在应用层线程执行时调用,没有同步问题。
雪    币: 110
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
核心未拥有 2016-2-28 12:35
9
0
我想知道,那个驱动修改那个ntdll API为 e9 的时机是什么

我在 x64 老是蓝屏

这个方法比修改 OEP 感觉好点
雪    币: 13
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
比方 2016-3-1 16:12
10
0
你说的这个产品,怎么感觉和我的工程这么像,不会就是逆向我的吧,make!,
雪    币: 110
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
核心未拥有 2016-3-1 20:47
11
0
哈哈哈,兄弟开源注入吧,其他不要

我好想知道为什么我那个蓝
雪    币: 13
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
比方 2016-3-2 10:32
12
0
不行哦,这是公司商业代码,不方便
雪    币: 110
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
核心未拥有 2016-3-2 12:12
13
0
能不能解答下,为什么我用修改内存的那API在内核修改ring3内存,会蓝屏哦
雪    币: 14
活跃值: (271)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
flylinfan 2016-3-2 13:19
14
0
在64环境中看你启动的是32位程序还是64程序,如果启动的64位程序就在ProcessNotify中进行ShellCode插入,还有就是确认下你的ZwProtectVirtualMemory函数地址是否正确。如果你启动的是32位程序,需要在ImageNotify等待32位ntdll装入后插入ShellCode并修改E9。在ImageNotify再等待32位ntdll注入后启动一个WorkItem进行ShellCode插入。
雪    币: 110
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
核心未拥有 2016-3-2 23:21
15
0
是在 64注入到 32程序

我是这样搞的 ProcessNotify 里设置有目标进程出现,就在全局设置为1

然后 ImageNotify 比较 unicode 的模块名字,是主进程的名字,就分配内存

修改OEP,如果加壳了的,没蓝屏过,因为没用修改属性那API

我想出现了主进程 ntdll早就加载了吧,不需要判断了吧
雪    币: 43
活跃值: (35)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
hbcld 2016-3-3 13:05
16
0
标记一下,未来看
雪    币: 3248
活跃值: (1566)
能力值: ( LV6,RANK:93 )
在线值:
发帖
回帖
粉丝
lynnux 2016-3-3 13:19
17
0
comodo,火绒都用过这个方式,不过火绒3.0稍微改了下反而没以前兼容好了
雪    币: 14
活跃值: (271)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
flylinfan 2016-3-7 09:09
18
0
已上传测试代码,共同学习下!
雪    币: 110
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
核心未拥有 2016-3-7 10:45
19
0
测试报告准备中,感谢楼主
雪    币: 110
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
核心未拥有 2016-3-7 10:52
20
0
看了下,没有对特定进程过滤吧

加载的DLL是也没看到,就看到shellcode
雪    币: 110
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
核心未拥有 2016-3-7 10:54
21
0
看了下,没有对特定进程过滤吧
雪    币: 14
活跃值: (271)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
flylinfan 2016-3-7 11:00
22
0
特定进程过滤是要走策略的。
雪    币: 110
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
核心未拥有 2016-3-7 11:53
23
0
x64 系统 注入到 x86 进程

只对某个进程注入

修改了dll路径

发现没注入成功

BOOLEAN InjectDll(HANDLE ProcessHandle, WCHAR *DllPath)

信息可以到这个地方,继续测试中

OEP 和 NT那个函数没发现 shellcode影子

我看默认开启时 oep的方法?
雪    币: 14
活跃值: (271)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
flylinfan 2016-3-7 12:21
24
0
OEP默认没开启,没住人成功看你的DLL编译方式是不是依赖其他非系统库了。
雪    币: 110
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
核心未拥有 2016-3-7 12:30
25
0
这个dll我经常用,其他驱动注入没问题的,加了upx壳

KERNEL32.DLL 就引用这个

但是在里面还有个memload另外的dll

有点诡异的是,我用OD调试,并没发现 shellcoe的影子
游客
登录 | 注册 方可回帖
返回