hack主引导记录的乐趣

admin 2024年5月31日09:14:19评论112 views字数 10165阅读33分53秒阅读模式

攻击者已多次使用恶意软件来破坏计算机的主引导记录,使其无法运行。通过擦除 MBR,本机无法加载操作系统。没有操作系统,就没有简单的方法可以将主引导记录重写到位,并且计算机变得完全无用且无法恢复。此外,许多勒索软件通过用恶意代码覆盖主引导记录来感染主引导记录。然后,系统会自动重新启动以允许感染发生。当系统重新启动时,用户被锁定,勒索软件会显示要求付款的说明。

linux

hack主引导记录的乐趣

  • hack主引导记录的乐趣

  • hack主引导记录的乐趣

  • windows

  • hack主引导记录的乐趣

  • windows()

  • hack主引导记录的乐趣

  • USB()

  • hack主引导记录的乐趣

  • ()

  • hack主引导记录的乐趣

  • ios

  • hack主引导记录的乐趣

  • windbg

  • hack主引导记录的乐趣

  • ()

  • hack主引导记录的乐趣hack主引导记录的乐趣hack主引导记录的乐趣

  • hack主引导记录的乐趣

  • hack主引导记录的乐趣

  • hack主引导记录的乐趣

要了解所有这些是如何实现的,以及攻击者如何实现它,我们必须首先了解 MBR 及其执行过程。

启动过程

随着时间的推移,系统的启动过程变得越来越简单,但这并不总是意味着它更容易。每台计算机,无论大小,都要经历一个称为“启动”过程的启动过程。由于不同类型的硬件以不同的方式运行,因此启动过程受 CPU 体系结构和其他硬件组件类型的严重影响。

为了避免混淆,我不会详细介绍启动过程的每个阶段。但是,典型的 linux 引导过程涉及更高级别的以下阶段:

  1. 这是您按下电源按钮的步骤。这会触发主板闪存中的 BIOS ^wiki_bios 开始执行其功能。

  2. 开机自检

  3. BIOS 启动并运行后,它会启动快速自检,以了解所有必需的硬件组件是否处于工作状态。

  4. 查找启动设备

  5. 此步骤从先前检测到的硬盘驱动器中查找所有可启动设备。其工作方式是通过检查每个检测到的设备的 MBR(主引导记录)。MBR 是指任何可启动设备的前 512 个字节。

  6. 加载 MBR

  7. MBR 是前 512 个字节。这 512 个字节包含引导加载程序、分区表和幻数。它被加载到 ram 中,负责从驱动器读取数据并启动操作系统。

  8. 加载 GRUB

  9. 这是一个引导加载程序,分 2 个阶段工作。第一阶段是MBR上的小型机器代码二进制文件。它的唯一工作是找到第二阶段引导加载程序并将其加载到内存中。一旦第二阶段引导加载程序进入内存,它就会向用户显示一个图形屏幕,显示可供选择的不同操作系统。

  10. 内核

  11. 上面的操作系统选择决定了要加载到内存中的内核和可选的 initramfs。然后,内核初始化和配置计算机的内存,并配置连接到系统的各种硬件,包括所有 I/O 子系统。经过更多操作后,内核将完全加载到内存中并运行。是时候设置用户环境了。

  12. 初始化

  13. 这是第一个由内核启动的用户空间程序。现在,这将启动并管理所有用户空间进程,例如您的 Web 浏览器、文件管理器、Web 服务器等。

MBR和其他小东西

现在我们已经了解了引导过程的工作原理,我们可以继续讨论本文的主要目标,即主引导记录。(但不是此主引导记录)

如果您还不知道,这就是典型的硬盘驱动器从外部出现的方式。

hack主引导记录的乐趣

这个小的半金属盒子内有许多组件,有助于其正常操作。

但是我们不需要了解所有这些组件;取而代之的是,我们将专注于中心的圆盘状结构。这被称为拼盘。盘片是一张唱片。硬盘驱动器可能有一个或多个盘片。

hack主引导记录的乐趣

每个盘片被划分为几个圆形轨道,每个轨道又进一步分为几个区域。硬盘驱动器上的每个扇区通常存储 512 字节的用户可访问数据。

hack主引导记录的乐趣

硬盘驱动器的前 512 个字节(或第一个扇区)是 MBR 所在的位置。由于 Linux 中的所有内容都是一个“文件”,如果我们想提取 MBR 数据,我们所要做的就是读取可启动硬盘文件的前 512 个字节,然后将该内容写入另一个本地文件进行进一步分析。在大多数 linux 平台中,我们可以通过 ^man_dd 命令来做到这一点。dd

dd if=/dev/sda of=mbr.sample bs=512 count=1

上面的命令将从中读取一个 512 字节的块(一次)并将其保存在文件中。然后,我们可以使用命令检查此文件的类型。/dev/sdambr.samplefile

file mbr.sample

## Output
# mbr.sample: x86 boot sector; partition 1: ID=0x83, active, starthead 32, startsector 2048, 2097152 sectors; partition 2: ID=0x8e, starthead 170, startsector 2099200, 41191424 sectors, code offset 0x63

此文件中可识别 x86 引导扇区。有趣的是,它还列出了所有分区的起始头、起始扇区、扇区总数、偏移量和 ID。这足以让我挖掘文件的十六进制转储并了解命令如何能够收集所有这些信息。file

hexdump -C mbr.sample

输出:-

00000000  eb 63 90 10 8e d0 bc 00  b0 b8 00 00 8e d8 8e c0  |.c..............|
00000010 fb be 00 7c bf 00 06 b9 00 02 f3 a4 ea 21 06 00 |...|.........!..|
00000020 00 be be 07 38 04 75 0b 83 c6 10 81 fe fe 07 75 |....8.u........u|
00000030 f3 eb 16 b4 02 b0 01 bb 00 7c b2 80 8a 74 01 8b |.........|...t..|
00000040 4c 02 cd 13 ea 00 7c 00 00 eb fe 00 00 00 00 00 |L.....|.........|
00000050 00 00 00 00 00 00 00 00 00 00 00 80 01 00 00 00 |................|
00000060 00 00 00 00 ff fa 90 90 f6 c2 80 74 05 f6 c2 70 |...........t...p|
00000070 74 02 b2 80 ea 79 7c 00 00 31 c0 8e d8 8e d0 bc |t....y|..1......|
00000080 00 20 fb a0 64 7c 3c ff 74 02 88 c2 52 be 05 7c |. ..d|<.t...R..||
00000090 b4 41 bb aa 55 cd 13 5a 52 72 3d 81 fb 55 aa 75 |.A..U..ZRr=..U.u|
000000a0 37 83 e1 01 74 32 31 c0 89 44 04 40 88 44 ff 89 |[email protected]..|
000000b0 44 02 c7 04 10 00 66 8b 1e 5c 7c 66 89 5c 08 66 |D.....f..|f..f|
000000c0 8b 1e 60 7c 66 89 5c 0c c7 44 06 00 70 b4 42 cd |..`|f...D..p.B.|
000000d0 13 72 05 bb 00 70 eb 76 b4 08 cd 13 73 0d 5a 84 |.r...p.v....s.Z.|
000000e0 d2 0f 83 de 00 be 85 7d e9 82 00 66 0f b6 c6 88 |.......}...f....|
000000f0 64 ff 40 66 89 44 04 0f b6 d1 c1 e2 02 88 e8 88 |[email protected]..........|
00000100 f4 40 89 44 08 0f b6 c2 c0 e8 02 66 89 04 66 a1 |[email protected].|
00000110 60 7c 66 09 c0 75 4e 66 a1 5c 7c 66 31 d2 66 f7 |`|f..uNf.|f1.f.|
00000120 34 88 d1 31 d2 66 f7 74 04 3b 44 08 7d 37 fe c1 |4..1.f.t.;D.}7..|
00000130 88 c5 30 c0 c1 e8 02 08 c1 88 d0 5a 88 c6 bb 00 |..0........Z....|
00000140 70 8e c3 31 db b8 01 02 cd 13 72 1e 8c c3 60 1e |p..1......r...`.|
00000150 b9 00 01 8e db 31 f6 bf 00 80 8e c6 fc f3 a5 1f |.....1..........|
00000160 61 ff 26 5a 7c be 80 7d eb 03 be 8f 7d e8 34 00 |a.&Z|..}....}.4.|
00000170 be 94 7d e8 2e 00 cd 18 eb fe 47 52 55 42 20 00 |..}.......GRUB .|
00000180 47 65 6f 6d 00 48 61 72 64 20 44 69 73 6b 00 52 |Geom.Hard Disk.R|
00000190 65 61 64 00 20 45 72 72 6f 72 0d 0a 00 bb 01 00 |ead. Error......|
000001a0 b4 0e cd 10 ac 3c 00 75 f4 c3 00 00 00 00 00 00 |.....<.u........|
000001b0 00 00 00 00 00 00 00 00 70 7e 04 00 00 00 80 20 |........p~..... |
000001c0 21 00 83 aa 28 82 00 08 00 00 00 00 20 00 00 aa |!...(....... ...|
000001d0 29 82 8e fe ff ff 00 08 20 00 00 88 74 02 00 00 |)....... ...t...|
000001e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa |..............U.|
00000200

剖析主引导记录

在没有任何布局知识的情况下,简单地查看输出并不是特别有用。因此,现在有必要了解MBR布局。hexdump

MBR 由 3 个部分组成:引导加载程序分区表幻数

幻数位于最后两个字节中,而不是常规用户空间文件。它位于文件中,但请注意处理器的字节序。由于我的 CPU 是小字节序,因此首先读取最左边的字节。结果,将成为神奇的数字。55AAAA55

减去后,我们剩下字节。其中,引导加载程序存储在第一个字节中,分区表存储在其余字节中。为了分别评估这些组件,让我们使用相同的旧命令将它们解压缩到不同的文件中。512-2 = 51044664dd

## Bootlaoder
dd if=mbr.sample of=mbr.bootloader bs=1 count=446

## Partition table (skip first 446 bytes)
dd if=mbr.sample of=mbr.partition_table bs=1 count=64 skip=446

## magic (skip first 510 bytes)
dd if=mbr.sample of=mbr.magic bs=1 count=2 skip=510

## Check file types
file *
## Output
# mbr.bootloader: data
# mbr.magic: BIOS (ia32) ROM Ext.
# mbr.partition_table: 8086 relocatable (Microsoft)
# mbr.sample: x86 boot sector; partition 1: ID=0x83, active, starthead 32, startsector 2048, 2097152 sectors; partition 2: ID=0x8e, starthead 170, startsector 2099200, 41191424 sectors, code offset 0x63

文件命令可以单独识别这些 MBR 组件中的每一个,这真是太棒了。现在有了单独的文件,我们可以仔细检查分区表并确定它可以为我们提供哪些数据。

hexdump -C -v  mbr.partition_table

输出:-

00000000  80 20 21 00 83 aa 28 82  00 08 00 00 00 00 20 00  |. !...(....... .|
00000010 00 aa 29 82 8e fe ff ff 00 08 20 00 00 88 74 02 |..)....... ...t.|
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|

MBR 系统仅支持 4 个主分区,因为分区表实际上只包含 4 条记录。如果我们想构造四个以上的分区,我们必须将主分区划分为更小的分区,并在该主分区内保留一个单独的分区表。术语“扩展分区”实际上用于描述这些扩展分区。从上面的结果中我们可以看到,总共有 64 个字节,每条记录的总字节数。让我们了解这 16 个字节的布局,然后我们可以使用 来分析分区表数据。64/4 = 16hexdump

|大小(以字节为单位) |目的| |— — — — — — — — |— — — — | |1 |启动指示器(0x80表示活动,0x00表示非活动) | |1 |分区开始:头 |1 |分区开始:扇区 |1 |分区启动:圆柱体 |1 |分区 ID |1 |隔断端:头 |1 |分区端:扇区 |1 |隔断端:圆柱体 |4 |此分区开始前的扇区数 (sectors_before) |4 |此分区中的扇区数 (number_of_sectors)

所有这些都有 16 个字节。现在我们知道命令之前显示的信息来自哪里。file

根据我们现在掌握的信息,我们可以自己弄清楚一些事情......

00000000  80 20 21 00 83 aa 28 82  00 08 00 00 00 00 20 00  |. !...(....... .|
00000010 00 aa 29 82 8e fe ff ff 00 08 20 00 00 88 74 02 |..)....... ...t.|
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|

例如,此磁盘只有 2 个分区,因为最后 2 条记录都是零。由于第一条记录中的“0x80”字节,第一个分区是可引导的。该分区的 ID 是 。而第二个分区是不可引导分区,并且该分区的 ID 是 。如果需要,您甚至可以借助这些记录中的其他信息来计算每个分区的大小。8382

我们现在只剩下第一个字节,其中包括引导加载程序。引导加载程序只是一个从可引导分区读取和加载其他应用程序的软件。GRUB 通常从磁盘加载自身的第二阶段,但这不是条件。有些引导加载程序可以将内核直接加载到内存中,或者更好的是,其中一些是可以正常工作的成熟应用程序。^osdev_512446

注意:- 虽然我今天不会讨论它,但您可以使用 反汇编程序来反汇编引导加载程序映像。这需要对 BIOS 中的中断和内存管理有一定的了解,这超出了本博客的讨论范围。ndisasm

这就解决了;既然我们已经知道了MBR中包含的内容,我们为什么不尝试构建一个呢?

创建自己的引导加载程序

首先,我们将制作一个简单的原始二进制文件并放入其中。请记住,这是属于 MBR 的幻数AA55

dw 0xAA55

将此文件另存为 。使用编译器编译后,结果应如下所示。custom bootloader.asmnasm

## Compile custom_bootloader.asm
nasm -fbin custom_bootloader.asm -o custom_bootloader.bin


## Check the file type
file rhel_magic_number custom_bootloader.bin

## Output
# rhel_magic_number: ISO-8859 text, with no line terminators
# custom_bootloader.bin: ISO-8859 text, with no line terminators


## Check hexdump
hexdump -C custom_bootloader.bin

## Ouput
# 00000000 55 aa |U.|
# 00000002

我们现在有一个包含幻数的 2 字节文件。但是,由于 MBR 的长度为 512 字节,因此我们必须再填充 510 个字节。目前,让我们用零填充它,看看它是否是一个有效的 MBR 文件。

times 510 db 0
dw 0xAA55

上面的代码会写 510 次,然后写 .0AA55

## Compile custom_bootloader.asm
nasm -fbin custom_bootloader.asm -o custom_bootloader.bin


## Check the file type
file rhel_mbr custom_bootloader.bin

## Ouput
# rhel_mbr: DOS/MBR boot sector
# custom_bootloader.bin: DOS/MBR boot sector


## Check hexdump
hexdump -C custom_bootloader.bin

## Ouput
# 00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
# *
# 000001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa |..............U.|
# 00000200

正如预期的那样,这是一个有效的 MBR 文件,没有关于分区表或引导加载程序的信息。但是,我们可以使用它来启动系统吗?

让我们试一试。

我首先尝试在没有任何 mbr 数据的情况下查看失败时会遇到什么错误。

qemu-system-x86_64

而且,正如我所料,它说“没有可启动的设备”。

hack主引导记录的乐趣

让我们再次运行测试,但这次使用我们制作的 MBR 文件。

hack主引导记录的乐趣

这次它没有给我错误。这必须意味着我们的 MBR 是有效的。由于它缺少引导加载程序代码,因此它不执行任何操作。但是,它不会返回相同的先前错误。

现在,我们可以将新指令添加到程序集文件中。但是,我们必须记住,我们不会超过文件的 512 字节限制。这意味着我们必须处理我们正在填充的零。因为这是一个非常简单的问题,所以有一些特殊字符可以帮助我们计算文件开头的内存地址和文件中的当前地址。

times 510-($-$$) db 0       ;$ - Start addr; $$ - current addr
dw 0xAA55

我们可以使用这些特殊字符计算填充所需的确切零数。让我们编译它并对其进行测试。

nasm -fbin custom_bootloader.asm -o custom_bootloader.bin

qemu-system-x86_64 custom_bootloader.bin

这将产生与以前相同的结果,并且输出文件大小仍为 512 字节。让我们添加更多说明来帮助我们在屏幕上编写一些文本。

与用户空间和内核空间程序不同,我们没有任何可以获取字符串并自动将其打印到屏幕上的辅助函数。我们必须告诉BIOS在这里做我们想做的事。我意识到的唯一方法是通过中断。它与操作系统和应用程序用于访问 BIOS 功能的工具相同。

以下是常见 BIOS 中断的列表。并非所有 BIOS(尤其是较旧的 BIOS)都支持所有这些中断。使用中断的基本思想是,我们在一些特定的寄存器中放置适当的值,然后触发中断。然后,中断例程将从这些寄存器中获取值,并基于此执行一些操作。

无论如何,使用上表,我确定我们需要在寄存器中使用中断向量(或0x10)和中断向量(或0x03)。将其视为调用参数值为 03h 的 10h 函数。这将返回光标的当前位置和形状。10h03hAH

mov ah, 0x03;
int 10h

times 510-($-$$) db 0
dw 0xAA55

我们可以看到,在编译和检查十六进制转储后,一些初始字节被写入二进制文件。而且,多亏了 和 ,文件大小仍然是 512 字节。$$$

# Compiling the binary
nasm -fbin custom_bootloader.asm -o custom_bootloader.bin

## Checking hexdump
hexdump -C custom_bootloader.bin

## Output
# 00000000 b8 03 00 cd 10 00 00 00 00 00 00 00 00 00 00 00 |................|
# 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
# *
# 000001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa |..............U.|
# 00000200

这会将 BIOS 切换到 TTY 模式,允许我使用相同的中断打印字符,但在寄存器中使用不同的值。10hah

mov ah, 0x03
int 10h

mov ah, 0xE
mov al, 'H'
int 0x10

mov al, 'E'
int 0x10

mov al, 'Y'
int 0x10

times 510-($-$$) db 0
dw 0xAA55

当我们使用 qemu 编译并运行它时,屏幕上会打印出消息“HEY”。

hack主引导记录的乐趣

现在我们知道了如何在屏幕上写字符,让我们制作一个字符串并循环它直到最后,使用相同的中断组合将每个字符一个接一个地打印在屏幕上。

; Setup TTY mode
mov ax, 0x03
int 10h


mov si, msg ; si register now points to msg
mov ah, 0Eh ; Use write function from 10h interrupt

.loop:
lodsb ; load first char from msg and point to next char
or al, al ; Check if end of string
jz halt ; if end of string, jump to halt
int 10h ; else, print char via interrupt
jmp .loop ; loop

halt:

msg: db "Hack the world", 0

times 510-($-$$) db 0
dw 0xAA55

不幸的是,测试上述代码不会产生所需的结果,而是会产生一些垃圾值。

hack主引导记录的乐趣

进一步的调查显示,内存中的引导加载程序没有正确对齐。这让我陷入了另一个兔子洞,这次是关于当 BIOS 跳转到我的引导加载程序代码时计算机物理内存的内容是什么样子的。这里有一个关于同一主题的专门页面,涵盖了很多关于它的细节。

对我们来说,我们需要在代码中添加更多指令以正确对齐它。最后,我们的代码将如下所示。

bits 16      ; BIOS works in 16 bit mode
org 0x7c00 ; MBR is loaded at 0x7c00 memory location

mov ax, 0x03
int 10h


mov si, msg
mov ah, 0Eh

.loop:
lodsb
or al, al
jz halt
int 10h
jmp .loop

halt:
cli ; disable further interrupts
hlt ; halt

msg: db "Hack the world!!", 0

times 510-($-$$) db 0
dw 0xAA55

这一次,我们在编译和测试上述内容后得到了所需的结果。

hack主引导记录的乐趣

我们成功地创建了一个引导加载程序,可以在屏幕上打印一些消息。

结论

我们知道,MBR行业由3个部分组成:

  • 引导加载程序(446 字节)

  • 分区表(64 字节)

  • 幻数(2 字节)

并且每个组件都可以单独提取并被视为常规的二进制文件。这意味着,如有必要,我们只能创建分区表的备份。或者,我们可以用另一个代码替换引导加载程序代码,而不会影响分区表。(明明是为了好玩,像个友好的玩笑,没什么恶意的) 😈 😈

hack主引导记录的乐趣

我们知道上面的“Hack the World!!”代码并没有使用所有 510 字节,那么为什么不将其缩小一点以适应 446 字节呢?这样我们就可以保护原来的分区表。

bits 16      
org 0x7c00

mov ax, 0x03
int 10h


mov si, msg
mov ah, 0Eh

.loop:
lodsb
or al, al
jz halt
int 10h
jmp .loop

halt:
cli
hlt

msg: db "Hack the world!!", 0

times 446-($-$$) db 0 ; Just change 510 to 446 :)
dw 0xAA55

这将生成包含引导加载程序的原始数据文件,我们可以在虚拟机中快速测试该文件。

Vagrant.configure("2") do |config|
config.vm.box = "archlinux/archlinux"
config.vm.box_check_update = true

config.vm.provider "virtualbox" do |vb|
vb.gui = true
vb.memory = "512"
end

config.vm.provision "shell", inline: <<-SHELL
# Backup the original bootloader
dd
if=/dev/sda
of=/vagrant/backedup_bootloader.bin
bs=1
count=446

# Copy the fun bootloader to first 446 bytes of sda
dd
if=/vagrant/custom_bootloader.bin
of=/dev/sda
bs=1
count=446

# Reboot the system to see the effect
reboot
SHELL
end

上面将启动一个快速测试 VM。我们只需要坐下来放松一下。Vagrantfile

成功启动和重新启动后,它显示预期的消息。

hack主引导记录的乐趣

原文始发于微信公众号(安全狗的自我修养):hack主引导记录的乐趣

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年5月31日09:14:19
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   hack主引导记录的乐趣https://cn-sec.com/archives/2790464.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息