Bootkit Analysis

Hello! In connection with the launch of the reverse engineering course, we held a planned open lesson. It was disassembled bootkit algorithm at different stages of loading it.

Lecturer – Arthur Pakulov, a viral analyst at Kaspersky Lab.

The following article is introductory and is a text version of only part of the lesson, which is devoted to the bootkit installer. A detailed analysis of the bootkit itself, see the video.

A bootkit is a malicious program that modifies Master Boot Record, the first sector of the first physical disk or boot sector, VBR. Programs of this kind mainly have Trojan functionality and are used to carry out any hidden actions in the system. In our example, the bootkit carries out privilege escalation to the process level, the name of which begins with a sequence of letters: “inte”. In fact, a bootkit is a rootkit that starts working in the 0 protection ring, which starts before the operating system starts loading. It is because of this that he is of great interest for research.

To develop such a program, the usual reverse engineering skills are not enough. It’s not enough just to be able to read the listing, you also need to understand such things as processor architecture, memory addressing, etc. We looked at the key places of the bootkit in an open lesson.

For work, a special sample bootkit-xp.exe was prepared, working under Windows XP. Therefore, in addition to studying the bootkit, we were a little nostalgic for this operating system. But in general, the OS XP was chosen in order to make it easier to reverse, since XP is a good visualization and the absence of unnecessary complications. Well, the sample was written specifically for this OS, judging by its code.

Here's what the bootkit installer looks like:

Just looking at it, you can draw certain conclusions. For example, it is immediately evident that this file has a small weight. If you look at the entry point, you can see that the code is receiving a file descriptor with the name of a symbolic link to the first physical disk – “PhysicalDrive0”:

Further, for convenience of perception of the code, we switched to IDA. It becomes clear that for a typical trojan the available functionality is quite small. Even the import table is suspiciously small:

Such a picture usually emerges when analyzing packaged samples. But, in our case, the file does not look packed. It turns out that the sample is either covered by some protector / cryptor and in the process of its work receives the addresses of the functions in a dynamic way, after which it calls the desired functional, or everything is fine, and the sample is as it is.

We continue to explore the code.

As we saw in HIEW, a function is called CreateFileA with an interesting argument as the first parameter What exactly is being done here? It is appropriate to recall such a thing as kernel objects. They cannot be manipulated directly from user mode, they are controlled by the kernel of the operating system. From user mode, a program can only make a request to receive / change the state of any kernel object. In order to indicate to the system with which particular kernel object the program will work, it is required to get the handle of the desired kernel object. Upon request for receipt, if all checks are passed, the OS will return us handle requested OA. And already using handle, we can work with the associated OA.

Thus, in the above image, using CreateFile, a symbolic link is accessed to the first connected physical hard disk. If access is granted, then it will be possible to work with such a “file” as with any other simple file. That is, the entire hard disk will be presented as one large file.

So, let's continue. Handle is back, and we find ourselves here:

What happens next? And then the function ReadFile, reads the first 0x200 bytes. And we have there the very first sector of the first physical disk.

As you may have guessed, this is Master Boot Record (MBR). MBR consists of 3 parts: code part, partition table, and signature. In a typical situation, bios reads the MBR into memory at 0: 0x7c00h, passing control to it. So, the code portion of the MBR begins to execute. During execution, it parses the partition table, finds the boot sector, and loads it. In the case of a bootkit, if the MBR is overwritten, its code will now receive control.

Ok, MBR is read and what next? And then the bootkit opens PhysicalDrive0 again, but with write access mode.

Next, a pointer is set at the 600th offset. I.e the original sector is read and copied to the third sector.

Why backup a sector? Obviously, this is necessary for the fact that it will be needed in the future.

Then the cycle starts. Naturally, looking at the code, one cannot but pay attention to constants like var_1C, 1BEh and others. And, at the same time, the MBR structure located above should be freshened up in memory. In particular, we are interested in the “Offset” column.

See, the read buffer of the first sector is in lpBuffer. Further to it is added 1BEh, In fact, the pointer points to the beginning of the partition table. All data from the table to the end of the sector is inserted into _marked_bytesstarting from the same offset – 1BE.

That is, in _marked_bytes the second and third parts of the original MBR are inserted.

What happens next? What next Setfilepointer sets the pointer to the very beginning of our “file”, that is, to the MBR.

Then there is a write (WriteFile) formed _marked_bytes and freeing up memory. On this, the functionality of the bootkit installer ends.

But it would be nice to see what exactly is in the first part _marked_bytes. To do this, dump it to disk and analyze it. The first thing that catches your eye is a decrease by 2 of the contents of the variable at 0x413.

If you look at the technical documentation, you can find that the variable at 0X413 contains the amount of installed physical memory in kilobytes. Accordingly, the bootkit code “cuts off” two kilobytes of memory:

Now, in order not to be done further, it will be considered that there is 2 kilobytes of memory less than it was. Why – is not yet clear.

Next, the physical address is calculated to the “bit off” piece of memory using a bitwise left shift of 6 bits:

A shift of 6 does two actions at once – converts kilobytes to bytes (multiplying the value of the variable by 2 ^ 10), thereby obtaining the physical address of the bitten off piece of memory, and extracts the segment number from it, dividing the result by 0x10 (2 ^ 4).

After that, your body will be copied over this piece of memory, and, since the bootkit code is in the “bitten” piece, nobody will disturb him further. Moreover, no interruption will not change what is written in this memory area. We can say that the code becomes virtually invisible to the systemas if there is no memory there.

This is just the beginning of the bootkit. Then there will be interrupt interception, ntldr signature tracking, modification of the kernel module of the OS, etc.

Therefore, we will not spoil it, it is better to watch the webinar to the end so as not to miss anything.

Similar Posts

Leave a Reply