Description Recently, researchers found a Grub2 vulnerability, the version 1. 9 8 and 2 0 0 9 released in to 2. 0 2 to 2 0 1 5 year of release, are affected. A local user can through this vulnerability to bypass any forms of authentication plaintext password or a hash of the password, so the attacker then can access the computer's control. And most of the linux systems are Grub2 as the boot the boot program, including some embedded systems. Therefore there will be countless devices affected by this vulnerability. As shown below, our success in Debian 7.5 QEMU use this vulnerability to get the Grub rescue shell. ! Quickly determine if your system is the vulnerability? Want to quickly determine whether your system has this vulnerability, simply in the grub that appears enter the user name of the interface, continuously press 2 8 times Backspace（Backspace if system reboot or return to the rescue shell, then your grub will be affected by the vulnerability. Impact Successful exploitation of this vulnerability an attacker can get the Grub rescue shell, Grub rescue is a permission very high shell via this vulnerability can do the following things: 1. Elevation of Privilege: an attacker without valid user name and password in the case you can get the grub console of the ownership limit. 2. Information disclosure: an attacker can load a custom kernel and initramfs like USB loading, so as to obtain a more convenient environment, a copy of stealing the entire hard disk data or to the system to install a rootkit. 3. Denial of service: an attacker is able to destroy any of the data including the grub itself, even if the hard drive is encrypted the data can also be overwritten, resulting in a DOS system cannot be used. Details This vulnerability from the 1. 9 8 and 2 0 0 9 version there is grub code, b391bdb2f2c5ccf29da66cecdbfb7566656a704d is this vulnerability of the submission number, the problem exists in the grub_password_get()function. There are two functions there is an integer underflow problem grub_username_get()and grub_password_get (a). They are present in grub-core/normal/auth. c and lib/crypto. c file. The two function in addition to the printf()call in other places are the same, just as shown in the following grub_username_get()above. Herein, the POC is through the use of grub_username_get()vulnerability in get the Grub rescue shell. The following is grub_username_get()function in the vulnerability details code: ! grub_username_get()function code This problem is due to the decrement variables cur_len did not do a range check. Using（POC） This code, for cur_len variable usage there are two problems with off-by-two and Out of bounds overwrite code in the next two comments. The front of the error notes point, for storing the user name in the buffer there will be two bytes long, but there is no way to use, is the cover of the memory is used for fill. Behind that error comment points// Out of bounds overwrite here the comparison is interesting, because this code allows us to use 0×0 0 to cover for storing the username cache memory. This is because grub_memset()function will try the user name buffer unused byte set to 0×0 to 0. In order to achieve this purpose, this code calculates the first unused byte address and need to be filled to 0×0 0 the buffer size. The two the result of the calculation will be passed as a parameter to grub_memset()function: grub_memset (buf + cur_len, 0, buf_size - cur_len); For example, when the user name Enter“root”, cur_len value is 5, grub_memset()function of the user name buffer of the first 5 to 1 0 2 4 bytes user name and password buffer length is 1 0 2 4 bytes empty set to 0×0 0 in. So write code, its robustness is very good. For example, if the input user name is stored in a clean 1 0 2 4-byte array, you can direct the whole 1 0 2 4-byte memory with a valid user name for comparison rather than to compare two strings. This can be Defense some short of side-channels attacks such as timing attacks, such as the first time enter the username as aaaaaaaa, and then followed by the input bbbb, so that the coding can avoid the second result is bbbb[0x00]aaa. The most simple and fast verify this memory cover the cross-border approach is to constantly press backspace （Backspace let cur_len variable underflow, reaches a very large value, this value will immediately be used to calculate to be empty space of the starting address. memset destination address = buf + cur_len By this point, since the user name buffer address of the value beyond the 3 2-bit variable capable of storing a range, the second buffer overflow is triggered. Therefore, we need to carefully structure the first underflow of the second buffer overflow to calculate the grub_memset()function will use the destination address: cur_len--; // Integer Underflow grub_memset (buf + cur_len, 0, buf_size - cur_len); // Integer Overflow Following this example can help you to understand how we exploit this vulnerability. Assume that the user name buffer starting address for 0x7f674, and then the attacker press the Backspace key below the overflow value is 0xFFFFFFFF, then memset is the following: grub_memset (0x7f673, 0, 1 0 2 5); The first parameter: (buf+cur_len) = (0x7f674+0xFFFFFFFF)=(0x7f674-1) = 0x7f673; the second parameter: used to overwrite the memory for the constants, here A is 0; and the third parameter is to cover the size: (buf_size-cur_len)=(1 0 2 4-(-1))=1 0 2 5。 As a result, the entire user name of the buffer space 1 0 2 4）applied in front of one byte are all 0×0 0 coverage. Press the Backspace key The number of times that the user name buffer prior to the filling of 0×0 0 Number. Now, we have been able to cover the username buffer of any number of bytes. Next need to find 0×0 0 cover and can be used to implement malicious code execution memory address. In the stack frame looking for, you can quickly find grub_memset()function's return address can be overwritten. Below this map you can clearly demonstrate the stack memory layout: ! Grub2: redirect control flow As shown in the figure, the grub_memset()function's return address with the username buffer zone between a distance of 1 6 bytes. In other words, if we press 1 7 times the Backspace key, we can overwrite the return address of the highest byte. So, the function returns the address of the 0x07eb53e8 will be replaced, will eventually jump to 0x00eb53e8 it. When grub_memset()execution is ended, the control flow will be redirected to 0x00eb53e8, cause the system to restart. Similarly, press the Backspace key 1 8 and 1 9 and 2 0, will cause the system to restart.