Sudo Heap-based Buffer Overflow (CVE-2021-3156)
Common Vulnerabilities & Exposures, so-called CVE, is a dictionary of system vulnerabilities that has been disclosed to the public. Normally, it consists of CVE-ID, a description, and a list of references. Specifically speaking, the CVE-ID specifies the identity of a particular CVE, the description field explains the detail of this CVE, and the references list all reports from each department that found this CVE. In this presentation, we are going to explore the latest CVE, CVE-2021-3156. It reported that the command “sudoedit -s” and any command that ends with a single backslash character will mistakenly promote the user’s permission as well as the root.
2.1 Vulnerability abstract
According to what the report declared, if users who are not supposed to obtain the administrative-level permission find this vulnerability and successfully exploit it to elevate their privileges, they will be able to execute system commands which should only be executed by administrators or some particular users. take a one step further, it will then cause information leakage and malicious tampering.
2.2 Vulnerability analyzation
When applying sudo to run commands in “shell” mode, there are two options, which are -i and -s. sudo dash s option will set sudo’s MODE_SHELL flag, whereas sudo -i will set both MODE_SHELL and MODE_login_shell flag.
Here is the code segment from sudo.c’s main function, it invokes parse_args function, which parses command line input into appropriate data structures.
The next code segment determines whether Mode_shell with -s or -i is activated. If one of them is chosen, it will rewrite argv by adding a backslash to the meta-characters.
Then, as the next code segment shows, it will invoke set_cmnd() function. The set_cmnd function will first calculate the size of input via strlen() function, then invokes mallc() function to allocate a buffer which is named user_args, each has a size of size. last, it will determine whether Model_shell is activated, if yes, it will connect command line input and store it into user_args.
The next code segment is where it causes the problem. This is the code segment that set_cmnd() stores the command line input into user_args. For example, if we input sudo -s / 112233. According to the code, from will be the backslash character, and from is going to be the argument’s null terminator. The null terminator is not a space character and it is not visible here. null terminator has it’s all bits set to zero and it is used to represent the end of a string of characters. As it fulfills all requirements here, the array variable “from” is going to be incremented and point to the null terminator now. Then, as next from, this null terminator is going to be stored into the “user_args” buffer and array variable “from” is going to be incremented again and point to the next character after the null terminator, which will cause it to be out of the argument’s bounds and keeps doing it because it is inside a while loop. put it another way, since the size of the “user_args” buffer is calculated at the beginning of set_cmnd function and it has a limited size, but it keeps store out of bound characters into this buffer, it gives rise to a heap-based buffer overflow.
However, logically, if the Mode_shell or mode_login_shell is set, command line input cannot end with a backslash character because the set_cmnd function will determine whether model_shell, mode_edit, or mode_check is activated. If MODE_SHELL is activated, the parse-args function will then parse all command-line input, which will change single backslash to double backslash. Therefore, instead of sudo, attackers can execute sudo-edit. Sudo-edit will trigger sudo, but will not reset valid_flags and Mode_run. Therefore, attackers are able to skip the parsing part of the parse_args function, therefore, keep a single backslash, and finally trigger the heap_based overflow.
We’ll demo the CVE during the class, however, here’s what we find great demo on the Internet. You could take it as a reference as ours.
https://www.youtube.com/watch?v=2_ZaNBl6qNo This is a very detailed explanation about the CVE, recommend to watch it if you want to learn more
https://github.com/blasty/CVE-2021-3156 The exploit we’ll use in this video.
Other stuff you might find useful