mbr利用原理,c++编程分析(简单剖析)重新上图

http://bbs.kafan.cn/thread-672479-1-1.html

 

前段时间网上有个感染mbr的病毒,听说很厉害,那么什么是mbr呢,这个可能大家已经有所了解了,我在说具体点:(百度的)


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


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


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



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


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


#include "stdafx.h"

#include"windows.h"               

#include"stdlib.h"

#include"TCHAR.h"


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


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


{


            LPTSTR errMSG="";


            HANDLE hDevice;


            TCHAR szDevicename[64];


            LPTSTR szBuff;


            DISK_GEOMETRY Geometry;


            BOOL bRet;


            DWORD bytes,bread,count;


            char drive;

      itoa(Num,&drive,10);  //获得硬盘名


           wsprintf(szDevicename,"\\\\.\\PHYSICALDRIVE%c",drive); //获得设备句柄,共享读写



            hDevice = CreateFile(szDevicename,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);

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

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

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

*******************************************************************/
        if(hDevice==INVALID_HANDLE_VALUE)


       {



            errMSG="the device open error";
             exit(1);
       }

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

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

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

不懂得大家可以访问:http://blog.sina.com.cn/s/blog_626a27090100gatu.html 这里面有底层解释   *****************************************************************************/



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

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


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


          if(szBuff==NULL)


           {



           errMSG="Allocate memory errors";


           exit(1);


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



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


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


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


        {



          errMSG="Reading mbr error";

    exit(1);


         }



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


       {



          pMBR[n]=szBuff[n];


       }

//解锁硬盘,释放句柄


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


      CloseHandle(hDevice);


      return errMSG;

}


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




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

{


          HANDLE hDevice;


          char drive;


          DWORD bread,count;


          TCHAR szDeviceName[64];


          DISK_GEOMETRY Geometry;


          itoa(Num,&drive,10);


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



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



         if(hDevice==INVALID_HANDLE_VALUE)


      {



         printf("the device open error\n");
        exit(1);
      }



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

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


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


       {
         printf("write ok\n");

        }
   else


  {


  printf("write error\n");


  }


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


         CloseHandle(hDevice);

}


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


//我们就来测试一下:

void main( )

{


      BYTE MBR[512];


      ReadMBR(MBR,512,0);


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


      FILE *fp;


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


    {


    fwrite(MBR,1,512,fp);

     fclose(fp);


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


     else


    {



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


     }

}  //主函数完成读mbr


-----------------------------------------------------------------------------------------------------------



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

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


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


首先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 ,删除自身所有文件和服务。但这部分我还没搞懂,大家能理解过程就行了,和一般的内核病毒差不多。


本文一些内容是在百度上查到的,但大体是自己设计的,谢谢卡饭这个交流平台,希望大家都能进步。


此外我在网上找到了一个用户层上简单的mbr感染代码,和一个内核操控mbr的代码。这里给出连接,也能帮大家理解这个过程:该代码填0了主引导扇区(保括MBR,磁盘标志位和分区表)及其后的512字节,可以说极其危险,大家千万不要在本机试验 (在虚拟机上跑跑就行了)  

   

http://dingchaoqun12.blog.163.com/blog/static/11606250420102193825481/    (非安全的朋友,感谢他吧)

http://www.7747.net/Article/200909/41626.html    (邪8的朋友)


之前图片挂了,我再次上传到网络图库,这样会稳定点,呵呵,感谢大家提醒。

顺便把我的源码提供出来,方便大家调试:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值