Headline
CVE-2021-25682: Bug #1912326 “Privilege escalation to root with core file dump” : Bugs : apport package : Ubuntu
It was discovered that the get_pid_info() function in data/apport did not properly parse the /proc/pid/status file from the kernel.
Vulnerabilities in Apport in ubuntu 20.04/18.04
================================================
Author information
------------------
Itai Greenhut(@Gr33nh4t)
Aleph Research by HCL Appscan
<email address hidden>
SUMMARY
-------
We found several vulnerabilities in apport program which work on default installations of ubuntu 20.04/18.04.
We were able to chain those vulnerabilities together to get local privilege escalation to root from an unprivileged user.
Issue 1: Bypass drop_privileges and set Uid and Gid to arbitrary value
--------------------------------------------------------------
real_uid and real_gid are set by reading /proc/pid/status file and parsing its content.
“get_pid_info” function will iterate through each line and if a line starts with “Uid:” or “Gid:” it takes the first argument in that line and puts it into real_uid and real_gid variables.
We were able to bypass this by crashing a process with a file name set to "a\rUid: 0\rGid: 0".
When the process crashed, we “injected” those values to /proc/pid/status file (in the Name field), causing apport to never really drop privileges in the function drop_privileges( real_uid now is 0 and real_gid is also 0).
By having full control over real_uid and real_gid we were able to bypass the suid check on “write_user_coredump” function.
Issue 2: Bypass get_process_startime check
---------------------------------------------------------
Apport checks if the process was replaced after the crash by comparing between apport_start and process_start.
process_start gets the start time of the process by parsing the content of /proc/pid/stat file.
The start time is extracted from the 22 column of the /proc/pid/stat file.
We were able to bypass this check by recycle the pid with a process with " "(space) in its filename, causing get_process_starttime to return the wrong value (which is smaller than apport_start).
Issue 3: delay apport get_pid_info by 30 seconds and recycle pid to suid process
---------------------------------------------------------------------------------
We were able to delay apport get_pid by 30 seconds from the process creation by acquiring the lock file of apport.
We were able to lock the file by creating a fifo file with a predictable name file crash in /var/log, and then create a new instance of apport.
Now when we create another apport instance it will then be locked for 30 seconds before getting a timeout.
We can release the lock file of the first instance by writing to the fifo file.
Exploitation:
---------------------------------------------------------
Our main goal in the exploitation is to write core file owned by root with our content to an arbitrary directory.
Apport creates a core file in the current directory of the crashed process.
As seen before on other apport exploits, we will create a core file in /etc/logrotate.d/ directory and execute a root shell.
In order to exploit those issues to gain local privilege escalation we need to perform the following steps:
1. Create unpackaged=true configuration in ~/.conf/apport/settings
2. mkfifo a predictable file of a decoy process.
3. Run the decoy process causing the first apport instance to "hang".
4. Create a symlink to /usr/bin/sudo with the name “a\rUid: 0\rGid: 0”
5. chdir to desired directory.
6. Create the crash program.
7. Fork lots of new processes to make the pid wrap to crash_program_pid - 1.
8. Send SIGSEGV to crash the program and trigger an additional apport instance.
9. Send SIGKILL to terminate the program and release crash_program_pid.
10. Create new process with fork and execve(“a/rUid: 0\rGid: 0”). (The crafted file name)
11. Release the first process by writing to the fifo file.
The second apport instance will continue with execution and create a core dump in the current directory of the new suid process.
Now we have a root owned core file in desired directory, we can exploit this by having a valid configuration for logrotate inside the core dump and place the core dump inside /etc/logrotate.d/ directory.
CREDITS
---------------------------------------------------------
Please credit “Itai Greenhut(@Gr33nh4t) from Aleph Research by HCL Appscan” for those issues.
Please note that we follow the community standard of 90 days before public disclosure please coordinate your patch release date with us.
Attaching poc of the exploit, run as follows:
1. tar zxvfm exploit.tar.gz
2. cd exploit
3. ./exploit.sh
Best regards,
Itai Greenhut
Aleph Research by HCL Appscan