[分享] c++编程之MBR利用原理分析

[复制链接]
  • TA的每日心情
    开心
    2014-4-2 21:30
  • 签到天数: 3 天

    [LV.2]九品芝麻官

    534

    主题

    400

    回帖

    7742

    积分

    Intohard Team

    Rank: 7Rank: 7Rank: 7

    积分
    7742
    发表于 2012-4-20 09:09:45 | 显示全部楼层 |阅读模式
    前段时间网上有个感染mbr的病毒,听说很厉害,那么什么是mbr呢,这个可能大家已经有所了解了,我在说具体点:

    MBR(Master Boot Record)就是我们经常说的“硬盘主引导记录”,它是由FDISK等磁盘分区命令写在硬盘绝对0扇区的一段数据,它由主引导程序、硬盘分区表及扇区结束标志字(55AA)这3个部分组成。

    简单一点说就是你打开电源 先有主板上BIOS程序引导硬件初始化 然后交由系统(如XP/2000/LINUX等)引导 而系统的这块引导程序就在MBR—硬盘的第一分区第一扇区上的前512字节   这个可以用我生成的dat文件来证实,大家常见的命令就是FDISK/MBR 可以修复WIN引导,装完Linux的如果想卸载重装windows的同学可能就要用这个命令来修复引导区。

    最近找了些资料,结合简单的编程,实现了读mbr,不涉及ring0和内核,只为了让大家看懂和了解些知识。

    有人在谈rootkit,这里就大略的说一下mbr rootkit,MBR的rootkit又叫做Mebroot,最早产生于07年底,而不是某杀毒软件所谓的最新病毒,大家可以去搜索Trojan.Anserin,出于GMER之手,它利用了微软当时的内核漏洞,安装驱动到计算机,算是成功完成了一次攻击。 当然这不是我们菜鸟一天所能学会的,我下面就来介绍一下访问mbr的2种方式:

    1). 最简单的方式是我这次所重要介绍的,大家都能理解的,利用CreatFile()函数访问,在ring3下,用户是可以以用户态的方式访问mbr的,但在Vista和windows7下要使用管理员权限,这点大家在UAC机制中理解 ,我这里简单的实现了读mbr功能,程序在visual stdio 2008 调试,之前遇到了些问题,但也解决了,建议大家以后用stdio 2008,2010 来编译程序,不是因为美观,而是为了代码的安全。
    1. #include "stdafx.h"
    2. #include"windows.h"               
    3. #include"stdlib.h"
    4. #include"TCHAR.h"


    5. //头文件,在编译时别忘了审查代码


    6. LPTSTR ReadMBR(BYTE* pMBR,UINT nLen,int Num)


    7. {


    8.             LPTSTR errMSG="";
    9.             HANDLE hDevice;

    10.             TCHAR szDevicename[64];

    11.             LPTSTR szBuff;

    12.             DISK_GEOMETRY Geometry;

    13.             BOOL bRet;

    14.             DWORD bytes,bread,count;

    15.             char drive;
    16.       itoa(Num,&drive,10);  //获得硬盘名
    17.            wsprintf(szDevicename,"\\\\.\\PHYSICALDRIVE%c",drive); //获得设备句柄,共享读写
    18.             hDevice = CreateFile(szDevicename,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);

    19. /************************解释下createfile这个函数**********************

    20.       HANDLE CreateFile(
    21.        LPCTSTR lpFileName, //指向文件名的指针
    22.         DWORD dwDesiredAccess, //访问模式(写/读)
    23.         DWORD dwShareMode, //共享模式
    24.         LPSECURITY_ATTRIBUTES lpSecurityAttributes, //指向安全属性的指针
    25.         DWORD dwCreationDisposition, //如何创建
    26.         DWORD dwFlagsAndAttributes, //文件属性
    27.        HANDLE hTemplateFile //用于复制文件句柄
    28.   );

    29. 具体参数大家百度吧:http://baike.baidu.com/view/1288759.htm?fr=ala0_1_1

    30. *******************************************************************/

    31.         if(hDevice==INVALID_HANDLE_VALUE)


    32.        {



    33.             errMSG="the device open error";
    34.              exit(1);
    35.        }

    36. /****************************下面简单说明下deviceiocontrol这个函数******************************

    37. BOOL DeviceIoControl( HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize,  LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped );

    38. 参数表
    39.   参数 类型及说明
    40.   hDevice Long,设备句柄
    41.   dwIoControlCode Long,带有 FSCTL_ 前缀的常数。参考设备控制选项的部分列表
    42.   lpInBuffer Any,具体取决于dwIoControlCode参数。参考设备控制选项的部分列表
    43.   nInBufferSize Long,输入缓冲区的长度
    44.   lpOutBuffer Any,具体取决于dwIoControlCode参数。参考设备控制选项的部分列表
    45.   nOutBufferSize Long,输出缓冲区的长度
    46.   lpBytesReturned Long,实际装载到输出缓冲区的字节数量
    47.   lpOverlapped OVERLAPPED,这个结构用于重叠操作。针对同步操作,请用ByVal As Long传递零值

    48.   *****************************************************************************/

    49.           DeviceIoControl(hDevice,FSCTL_LOCK_VOLUME,NULL,0,NULL,0,&count,NULL); //锁定硬盘

    50.     DeviceIoControl(hDevice,IOCTL_DISK_GET_DRIVE_GEOMETRY,NULL,0,&Geometry,sizeof(DISK_GEOMETRY),&count,NULL);


    51.           szBuff = (LPSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,Geometry.BytesPerSector);


    52.           if(szBuff==NULL)


    53.            {

    54.            errMSG="Allocate memory errors";


    55.            exit(1);


    56.            }    //读取硬盘数据控制码

    57.           bytes=512;  //读硬盘头512字节,mbr所在位置

    58.           bRet = ReadFile(hDevice,szBuff,bytes,&bread,NULL);

    59.           if(bRet==FALSE||bread<512)

    60.         {

    61.           errMSG="Reading mbr error";

    62.     exit(1);


    63.          }

    64.         for(int n=0;n<512;n++)


    65.        {

    66.           pMBR[n]=szBuff[n];


    67.        }

    68. //解锁硬盘,释放句柄


    69.        DeviceIoControl(hDevice,FSCTL_UNLOCK_VOLUME,NULL,0,NULL,0,&count,NULL);

    70.       CloseHandle(hDevice);

    71.       return errMSG;

    72. }


    73. //以上完成了读mbr,通过对代码的分析,相信大家明白了读取mbr有多简单了吧。


    74. void WriteMBR(BYTE *pMBR,UINT nLen,int Num)

    75. {

    76.           HANDLE hDevice;

    77.           char drive;

    78.           DWORD bread,count;

    79.           TCHAR szDeviceName[64];

    80.           DISK_GEOMETRY Geometry;

    81.           itoa(Num,&drive,10);

    82.           wsprintf(szDeviceName,"\\\\.\\PHYSICALDRIVE%c",drive);

    83.           hDevice = CreateFile(szDeviceName,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);

    84.          if(hDevice==INVALID_HANDLE_VALUE)


    85.       {

    86.          printf("the device open error\n");
    87.         exit(1);
    88.       }


    89.           DeviceIoControl(hDevice,FSCTL_LOCK_VOLUME,NULL,0,NULL,0,&count,NULL);

    90.     DeviceIoControl(hDevice,IOCTL_DISK_GET_DRIVE_GEOMETRY,NULL,0,&Geometry,sizeof(DISK_GEOMETRY),&count,NULL);


    91.         if(WriteFile(hDevice,pMBR,512,&bread,NULL)==TRUE)


    92.        {
    93.          printf("write ok\n");

    94.         }
    95.    else

    96.   {

    97.   printf("write error\n");

    98.   }


    99.     DeviceIoControl(hDevice,FSCTL_UNLOCK_VOLUME,NULL,0,NULL,0,&count,NULL);

    100.          CloseHandle(hDevice);

    101. }


    102. //这是写mbr,和读mbr差不多,理解起来也不是那么难吧!

    103. //我们就来测试一下:

    104. void main( )

    105. {

    106.       BYTE MBR[512];

    107.       ReadMBR(MBR,512,0);

    108.       LPTSTR path="d:\\mbr.dat";

    109.       FILE *fp;

    110.      if((fp=fopen(path,"wb+"))!=NULL)

    111.     {

    112.     fwrite(MBR,1,512,fp);

    113.      fclose(fp);

    114.      printf(" 读取成功在mbr.dat\n");
    115.       }

    116.      else

    117.     {

    118.       printf("creat file false!\n");

    119.      }

    120. }  //主函数完成读mbr
    复制代码
    001.png
    002.png

    可以看到生成的文件为512kb,是符合我们的设计要求的,也就读出了mbr。

    2)第二种方法,也是最头疼,这次病毒用到的方法,个人在研究中,但貌似屁都不懂,还是拿出来随便说说吧:

    Disk.sys驱动封装和setwinEventhook()技术,它完全取代了刚才所使用的上层api createfile()函数,它们直接操纵了用户底层,可以随意穿透hips,它发送irp来执行读写操作

    003.png

    首先ld.exe 在系统重启后完场自删除,将可执行文件1.tmp文件放入我们熟悉的%temp%中然后运行,第二个程序在用户层下感染mbr组件,创建\readharddisk不存在设备,当安装1.Tmp时,文件ld.exe以参数cp 2.tmp运行,文件ld.exe 复制到2.tmp中,user32.dll 是被ld.exe 所读取的,并执行。同时检测setwineventHook()的前5个字节是否与磁盘相匹配,过滤api (在一些安全软件中,SetWinEventHook函数会被hips和安全程序hook掉),这个特殊的过滤API函数将DLL文件注入到explorer进程的文件中,此安装文件将会调用SetWinEventHook所需的3个重要传递参数:explorer.EXE id,2.mp,dll文件路径和导出例程wep()指针。这样rootkit就完全运行在explorer.exe中了。

    剩下的注册表和开启服务功能,然后感染mbr ,删除自身所有文件和服务。但这部分我还没搞懂,大家能理解过程就行了,和一般的内核病毒差不多。
  • TA的每日心情
    开心
    2012-5-17 17:02
  • 签到天数: 1 天

    [LV.1]布衣百姓

    1

    主题

    52

    回帖

    743

    积分

    [INTOHARD]连长

    www.w453.com

    Rank: 4

    积分
    743
    QQ
    发表于 2012-4-20 19:38:17 | 显示全部楼层
    (35: (35: (35:
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2014-5-10 18:39
  • 签到天数: 153 天

    [LV.7]四品道员

    6

    主题

    455

    回帖

    1393

    积分

    [INTOHARD]营长

    Rank: 6Rank: 6

    积分
    1393
    发表于 2012-6-1 16:55:30 | 显示全部楼层
    [s:190]授人与渔,怎能不顶一下呢。谢谢!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    2012-6-24 19:56
  • 签到天数: 2 天

    [LV.1]布衣百姓

    0

    主题

    5

    回帖

    50

    积分

    [INTOHARD]班长

    Rank: 2

    积分
    50
    发表于 2012-6-18 21:56:34 | 显示全部楼层
    怎么和winhex差别怎么大
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    2012-9-9 20:41
  • 签到天数: 3 天

    [LV.2]九品芝麻官

    6

    主题

    431

    回帖

    716

    积分

    [INTOHARD]连长

    Rank: 4

    积分
    716
    发表于 2012-6-26 20:21:01 | 显示全部楼层
    好东西哟!从这里入门
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    擦汗
    2016-6-15 19:50
  • 签到天数: 141 天

    [LV.7]四品道员

    6

    主题

    203

    回帖

    762

    积分

    [INTOHARD]连长

    Rank: 4

    积分
    762
    发表于 2012-6-26 21:08:39 | 显示全部楼层
    win7下比较难搞
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    擦汗
    2012-11-30 16:51
  • 签到天数: 12 天

    [LV.3]八品县丞

    2

    主题

    32

    回帖

    64

    积分

    [INTOHARD]班长

    Rank: 2

    积分
    64
    QQ
    发表于 2012-11-20 15:47:19 | 显示全部楼层
    好东西哟!从这里入门
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    12 小时前
  • 签到天数: 3751 天

    [LV.Master]三朝元老

    38

    主题

    6173

    回帖

    2万

    积分

    [INTOHARD]旅长

    Rank: 9Rank: 9Rank: 9

    积分
    21932
    发表于 2012-12-12 18:04:13 | 显示全部楼层
    学习研究学习(1:
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    0

    主题

    180

    回帖

    299

    积分

    [INTOHARD]排长

    Rank: 3Rank: 3

    积分
    299
    发表于 2012-12-12 18:57:03 | 显示全部楼层
    说的不错!











    暴力摩托中文版下载
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    0

    主题

    180

    回帖

    299

    积分

    [INTOHARD]排长

    Rank: 3Rank: 3

    积分
    299
    发表于 2012-12-12 21:11:58 | 显示全部楼层
    说的不错!











    暴力摩托中文版下载
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

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