[Thanks to @ a young man with minor psychology for enthusiastic translation this time
OHM (Observe Hack Make) is an international outdoor camping festival dedicated to hackers, manufacturers, and those who have the spirit of inquiry. It lasts for 5 days. July 31 this year people attended the event in Geestmerambacht, Netherlands, 3000 from October 1 to 14.
This article has been published in OHM2013. The principle is to use some smart mechanisms of the hard disk to embed some information (such as login information) in a certain location, and then verify the user login in the operating system, the username and password reserved by the hacker are read independently.
Introduction
Hard Disk: If you are reading this article, I am sure you have used at least one or two hard disks. The hard disk is very simple. It basically refers to some 512-byte sectors. The address is indicated by an increasing number, which is called LBA, that is, "Logical Block Addressing ". The computer can read and write data to the sectors of the connected hard disk. Generally, a file system abstracts these slices into files or folders.
If you look at the hard disk from this naive perspective, you will think that the hardware should be very simple: What you need is something that can connect to the SATA interface, and then you can locate the read/write header, read and Write Data from a disk. But it may not be that simple: isn't the hard disk still capable of processing Bad blocks, S. M. A. R. T. attributes? Isn't there anything else to manage the cache?
The above means that some smart things in the hard disk can be hacked. I like black stuff, so I decided to see how hard drives work on a non-mechanical level. This research has previously been done on many hardware: From the PCI extension module of the notebook to the embedded controller, or even the Apple keyboard. These studies are usually used to prove that these hard disks can be cracked and affected by software, so I decided to achieve the same goal: in this attack, I would like to allow the hard disks to bypass the software security organization.
Components on PCB
I need to know whether the hard disk can be cracked. Like most of you, I also have a stack of bad or old hard disks to check whether:
Of course, we all know that the mechanical structure of the hard disk should be useful, and I am not interested in those parts. My interest lies in the Small PCB Board on the back of most hard disks with SATA and power interfaces. This PCB looks like this:
We can see that there are four chips on the PCB. Let's talk about these chips:
This is a DRAM (dynamic random memory ). This is very easy to handle, and the chip manual is very easy to find. The size of these chips is generally between 8 MB and 64 MB, corresponding to the nominal cache capacity of the hard disk.
This is the motor controller. This is not a standard device, and the Data Manual is hard to find, but these controllers generally have similar products that are easy to find. ST Smooth controller is probably the most commonly used one. In addition to the drive motor, it can also be used for power supply rectification, but also with some A/D conversion channels.
This is a serial flash. The processing capacity is usually between 64KB and 256KB. It seems that this is the boot program used to store the hard disk controller. Some hard disks do not use this chip, but have flash memory to store programs in the controller chip.
These little things are not chips, but piezoelectric vibration sensors. When a hard disk is hit, they can move the head to a safe place, but it is more likely that it marks a value somewhere, indicating that your warranty is invalid because it is your own hard disk.
Here is where the miracle is going to happen: hard disk controller. Mostly manufactured by Marvell, ST, or other LSI companies. Some hard drive manufacturers make their own controllers: I have seen Samsung and Western Digital have their own control chips. Because other parts are well handled, this part is my interest.
Unfortunately, these chips are not documented. The vendors that make these controllers do not disclose their documents. Some of them are not so cool: They don't even mention these chips on their own websites! Unfortunately, the entire Internet cannot help me: searching these chip manuals can only find manuals without manuals, and Chinese manufacturers selling chips ......
So without the most important chip manual, does it mean our plan is stranded?
Connect to JTAG
Fortunately, there are always some ways to find useful information except the chip manual. I found this one.
I am looking for a connection line from Dejan ON THE HDDGuru forum. Dejan does not know how to discard the Internal flash memory of his hard drive controller, and then wants to know whether there is a way to either start the controller from the external flash memory or rewrite the Internal flash memory. After five days, no one responded to him, but this guy was very creative: he posted another post saying that he found the JTAG Port Pin. This is really a major discovery: The JTAG interface can be used to control the controller. You can use it to start the controller, restart, modify the memory, and set breakpoints. Then Dejan finds out how to turn off the boot ROM of the controller, finds a serial port of the hard disk, and then tries to restore its Flash ROM. Later, he mentioned the flash update process and finally disappeared into the sea of people.
These are useful information: At least I know that the controller of Western data is of the ARM kernel and has a JTAG interface. These hard disks usually have serial ports, which are not used but can be used to debug programs. With this, I should have enough information to start cracking.
Well, these are my preparations:
The red one is a small FT2232H board, which is about 30 Euro and very cheap. It can be used for JTAG debugging, serial port, and SPI communication. Connect it to the JTAG port of the hard disk and the serial port. The hard disk is directly connected to the SATA port on the motherboard of my computer, and there is an external ATX power supply. I use OpenOCD to drive the JTAG interface.
Now the question is: can this thing really work? Dejan uses the 2.5 "GB hard drive of the 88i6745 controller and detects the arm9-kernel. I am looking for a 3.5 "2 TB hard drive of the 88i6745 controller, which has different format factors and is a bit new. Fortunately, OpenOCD can automatically detect devices connected to JTAG. As follows:
I don't understand this ...... I guess there will be a single tap, which is a separate ARM Kernel ...... But there are actually three taps ...... Does this film have three ARM kernels?
After some research, I found that this chip really has three kernels. Two are Feroceon kernel, is more awesome like the kernel of arm9-, There Is A Crotex-M3 kernel, relatively small, more like the core of the microcontroller. After a while (and later studies), these controllers have different functions:
- Feroceon 1 processes physical read/write operations on the disk
- Feroceon 2 Processing SATA interface
- Feroceon 2 simultaneously caches and translates logic Block Addressing into cylindrical/head/sector
- What does Cortex-M3 look like? It's okay if I turn off the hard drive for him.
Which core does it start to crack? My goal is to influence the system security by using the modified hard disk firmware. The simplest and most difficult way to detect is to directly modify data. In this method, you do not need to modify the data on the disk. The firmware can make itself invisible. To this end, I need to find a suitable core for listening: I need a core that can be accessed during transmission from the hard disk to the SATA line, data can be modified between the disk and the SATA cable.
How can data be sent from a hard disk to a SATA device? Based on the hacker's intuition, I guess:
If the processors work at 150 MHz and use standard memory replication, they can only reach a rate of 150*23/2 = 2.4Gbp, which is much less. The hard disk speed is 6 Gbps, so some accelerated hardware must be involved. The most likely acceleration hardware should be DMA (direct access to memory ). This means that the data is directly read from the head and put into the memory without the involvement of the processor. The same is true for SATA ports: The processor only specifies where the data is located, and the DMA will directly read the data from the memory.
If so, where will the memory directed by the DMA engine be? The hard disk cache is a good place: data is always stored in the cache when it is read from the disk, so it is okay to copy the data right away when reading the disk. I previously discovered that the second Feroceon was responsible for managing the cache, so it became my preferred target.
In this way, I infer that the data is read and written through DMA without any CPU action. Now the question is: Since the CPU will not be exposed to data in normal operations, can the CPU (abnormally) be exposed to data? To answer this question, I first used the JTAG connection and used some disassembly to check the memory of Feroceon2.
As you can see, the memory graph is fragmented. There are some small blocks in RAM, I/O space and IRQ space, and a ROM started internally. There is another 64 mb data segment. I guess this is the DRAM used as the cache. Let's see if this is the case. First, I load the hard disk to my computer and write "Hello world" in a file on the hard disk 」. Now let's see if I can find this string from 64 MB memory.
That's right! It seems that Feroceon2 can read the cache and map the 64 mb dram address.
Inject code
Of course, if I want to modify data in the cache, I cannot completely scan the entire 64 MB cache every time: I need to know how the cache works. For this reason, I need to disassemble and understand the firmware of the hard disk. At least I need to understand the cached functions.
Disassembly of firmware is not a simple task. First, the code is mixed with the ARM and Thumb commands. If you do not have the anti-assembler that automatically switches the two commands, it will be crazy. In addition, there is no information that can make disassembly easier: Generally, programs are written. When something goes wrong, a message similar to "Couldn't open logfile!" will pop up !」 . This information is helpful for understanding the code functions. This firmware does not have any information: You have to read the code to know what the code is doing. The code library seems a little old, and sometimes it feels like adding a lot of features to the code to make everything more complicated.
Of course, there are also several things that make the disassembly easier. First, the western data did not intentionally confuse the code: There were no jump moves in the middle of the command. Also, because of the existence of the JTAG interface, you can intervene in code execution, set breakpoints, or directly modify them so that you can easily know what the program is doing.
After reading the code for a long time, I tried to understand it. Sometimes I used a debugger to verify if I guessed it was correct. Finally I found the core code of the cache system: a table in RAM, I call it a cache Descriptor Table 」.
Each item in the cache description table describes a block in the cache. It contains the starting LBA of the disk sector in the cache, how much hard disk data is stored in the cache, and some status indicators that indicate the cache items, there is also an unknown number of cached data in the memory.
Currently, the secret of the cache descriptor table has not been uncovered. Can I truncate the disk read and retrieval code before the data is sent to the SATA port? Therefore, I need to execute my own code on the disk controller. In addition, I also need to determine whether the code can run at the right time: if it modifies the cache too early, the data has not been in; if it is too late, the data has been sent to the PC.
My method is to bind it to an existing task. I cracked Feroceon2. the CPU is responsible for all SATA transmissions, so there must be a service responsible for configuring SATA hardware to read data in the cache. If I find this service, I may run my code before it.
After reading a lot of code, setting a lot of breakpoints, and modifying it many times, I finally found a qualified service. I connected the service to run my code before execution. Here is the original code:
000167BE ; r0 - slot in sata_req000167BE sub_0_167BE:000167BE PUSH {R4-R7,LR}000167C0 MOVS R7, R0000167C2 LSLS R1, R0, #4000167C4 LDR R0, =sata_req000167C6 SUB SP, SP, #0x14000167C8 ADDS R6, R1, R0000167CA LDRB R1, [R6,#0xD]000167CC LDR R2, =stru_0_40028DC000167CE STR R1, [SP,#0x28+var_1C]000167D0 LDRB R0, [R6,#(off_0_FFE3F108+2 - 0xFFE3F0FC)] 000167D2 LDRB R5, [R6,#(off_0_FFE3F108 - 0xFFE3F0FC)]000167D4 LSLS R0, R0, #4
This is changed to connect to my code:
000167BE ; r0 - slot in sata_req000167BE sub_0_167BE:000167BE PUSH {R4-R7,LR}000167C0 MOVS R7, R0000167C2 LD R6, =hookedAddr000167C4 BX R6000167C6 .dw checksumFix000167C8 .dd hookedAddr000167CC LDR R2, =stru_0_40028DC000167CE STR R1, [SP,#0x28+var_1C]000167D0 LDRB R0, [R6,#(off_0_FFE3F108+2 - 0xFFE3F0FC)] 000167D2 LDRB R5, [R6,#(off_0_FFE3F108 - 0xFFE3F0FC)]000167D4 LSLS R0, R0, #4...FFE3F000 PUSH {R0-R12, LR}FFE3F004 BX changeThingsInCacheFFE3F008 POP {R0-R12, LR}FFE3F00C LSLS R1, R0, #4FFE3F010 LDR R0, =sata_reqFFE3F014 SUB SP, SP, #0x14FFE3F018 ADDS R6, R1, R0FFE3F01C LDRB R1, [R6,#0xD]FFE3F020 BX 0x167CC
As you can see, the original command is replaced by the new Code to be jumped to. The new Code is placed in the unused address 0xFFE3F000, and a sentence is added to ensure the validation of the code domain is effective. If this is not done, the hard disk will try to read the backup from the disk, which is not what I want. The redirected code executes a service called "changeThingsInCache" and then executes the command to modify the code. Finally, it seems that nothing has happened before to execute the original service.
Now I want to write about the service that modifies the cached data. First, I made a test and decided to use the following service written with pseudocode:
void hook() { foreach (cache_struct in cache_struct_table) { if (is_valid(cache_struct)) { foreach (sector in cache_struct.sectors) { sector[0]=0x12345678; } } }}
This code segment replaces the first four bytes of each slice in the cache with 0x12345678 each time it is called. Therefore, if I upload this code to the hard disk, this number is displayed in front of each slice I see. I uploaded code through JTAG ......
Then you can see:
Once and for all
Of course, I can completely crack the firmware, but every time the hard disk is started, I need to use JTAG to modify RAM, which is worth the candle. I have to keep it unchanged. That is to say, I want to save my modifications somewhere. This modification program will be included every time the hard disk is started.
I chose flash memory. I can probably put it on the reserved sector of the disk itself, but if I make a mistake, I will not be able to recover my hard disk. The flash memory chip is only a standard part with eight feet, so I can easily remove it, brush off the flash memory and install it back. Therefore, I soldered it and placed it on the universal board, so that I could easily switch between the programmer and the hard disk.
What should I write in flash? Fortunately, the storage format in the chip has been found: it contains multiple pieces of data, and a table described the data at the beginning. This table describes the position of the code block in flash memory, how to compress it (if it is compressed), where should the code block be placed in RAM, and what is an execution pointer in the last address, mark the place where the initiator should jump to execute the program.
Unfortunately, I cannot modify the code in the flash memory. The data in the place where I want to add Hooks is compressed by some unknown compression algorithm, so I cannot modify it. But what I can do is add an extra code block and modify the execution address so that the code block can be executed before others. This is much simpler. When my code block is executed, I can add my hook to the decompressed code.
Of course, I have to disassemble and re-compile the flash binary code. I made a small tool for this and named it fwtool 」. This tool can read a lot of data blocks in flash memory and translate them into text files to facilitate modification. Then you can modify, delete, or add code, and then recompile it into a firmware to be refreshed. I used it to add my code to the image, click it back to the chip, load the chip back to the hard disk, start the backup file, and then:
The results are not new: I did it before. The only change is that I can do it without using JTAG.
Brush Software
Although there has been a lot of progress on the flash memory side, I still cannot start my hacker Script: I believe no server company will accept these hard disks with disassembly and reassembly chips. I need to find a way to allow the chip to brush the firmware without being removed from the Board, preferably directly on the computer where the hard disk is installed.
The firmware upgrade tool for Western data provides the possibility of writing new firmware into the flash memory and service area in a DOS environment-that is, retaining the sector. According to online materials, this tool uses the so-called "Vendor Specific Commands" command. There are also some other tools that can modify the firmware: for example, there is a conceptual validation code that can use unused reserved sectors to hide data. Finally, there is a set of tools called idle3-tools that can modify the idle behavior of the hard disk by modifying the bytes in the firmware. This Code also uses VSC to modify the code through the Linux system SCSI (Small Computer System Interface) through IOCTLS (Input/Output Control System. I need to "borrow" its source code, modify it, and integrate it into my fwtool. After a random guess of the VSC parameter, fwtool suddenly can read and write the flash chip on the hard disk on the computer.
With this tool, my attack is almost complete. If a hacker with a black hat gets the highest permission of a server with such a hard drive, he can use fwtool to remotely obtain the hard drive flash, modify and then click back. In the end, the host owner will find that I am using his host as an alternative, and then may reinstall the system to cut the hacker's original access to the host.
However, with the cracked firmware, attackers can manipulate the hard disk to continue in the newly installed system. First, he needs to trigger the action, which requires writing a specific string required to crack the firmware in the hard disk in advance. This string can be in any file: the attacker can upload a .jpeg file with a code to the server. It can also be implemented by sending a file request to the server with a specific code appended to the URL. This will eventually end in the server's record file and trigger exploitation.
Next, the cracked hard disk firmware is starting to become messy. For example, he will wait for the host to read the files in/etc/shadow, store all the Unix/Linux passwords, and immediately change them to something that the attacker wrote before. When attackers attempt to log on to the system using their own password, the host will judge the password based on the modified/etc/shadow, and the attacker can easily log on again.
This is my demo. You can see the root user who failed to successfully log on to the host. Then I start the attack and give it a hash value that replaces the password, that is, the password "test123 」. Because the Linux system caches the shadow file (like all recently accessed files), I need to make a lot of hard drive activities to clear the cache; in this way, when I log on again, the Linux System reads the shadow file on the disk again. The cache is cleared. I can log on to the root user with a false "test123" password.
Other usage
Of course, restoring the secret login Methods cleared from the server is not the only method of my research results. This can also be used for defense purposes.
For example, you can create a hard disk that cannot be copied: If the Read mode of the sector is random, the hard disk will work normally like a normal operating system reading the file system. If the hard disk is read in an orderly manner, the hard disk will tamper with the data, and the original content cannot be copied.
As a general controller, the hard disk controller also has some advantages. You have three CPU cores with good performance and a large RAM. There is also a UART as the serial port, at least two SPI interfaces: one connected to the Flash ROM, one connected to the motor controller. You can upgrade the external flash memory chip to load code to the processor, or even load code on a serial port on the boot loader. To demonstrate the chip capabilities, I transplanted a fairly popular software on the hard disk. This demo is only conceptual verification. The serial port is the only peripheral device that works and has no user space. Even so, I am proud to claim that I have installed a Linux on my hard drive controller. At the top, there is a standard command line (hard disk loaded under/mnt), and the low end is my output on the hard disk serial port.
Here I will explain how this works: the kernel and startup are encapsulated into packages with each slice in size, with a special string and serial number in front of the package. By reading data from the disk, the kernel and startup will eventually enter the cache. Write the special string "HD, success !」 Finally, the modified firmware is triggered. Search for all sectors in the cache, recompile the kernel, and start it. However, a kernel without a memory control unit also requires a user space in a special format. I cannot compile this, so the kernel crashes because init cannot be found.
Conclusion
Yes, that's it. Although the hard disk controller is like a wild beast, it can still understand through reverse engineering and write code for it to execute. The unknown controller makes general-purpose cracking difficult, and I suspect that there will never be a Malicious firmware patch. Compared with reverse engineering cracking on each Hard Disk firmware of each server, it is easier to find a 0-day vulnerability.
I also want to confirm that a bad hard disk can still be used. When the mechanical part of the hard disk breaks down, the PCB still has an available embedded system, and its performance is quite good. In particular, the bad hard disk can be obtained without money.
The source code of the open security project is too bad. I want to open the code, but I don't want to be responsible for the resulting large number of "permanent cracking" servers ...... I decided to make a compromise: you can download the code here, But I removed the shadow replacement code. Note: I am not responsible for making the entire process fully operational. Hacker, come on by yourself.