Security
Headlines
HeadlinesLatestCVEs

Headline

CVE-2019-7307: Bug #1830858 “TOCTOU vulnerability in _get_ignore_dom (report.py...” : Bugs : apport package : Ubuntu

Apport before versions 2.14.1-0ubuntu3.29+esm1, 2.20.1-0ubuntu2.19, 2.20.9-0ubuntu7.7, 2.20.10-0ubuntu27.1, 2.20.11-0ubuntu5 contained a TOCTTOU vulnerability when reading the users ~/.apport-ignore.xml file, which allows a local attacker to replace this file with a symlink to any other file on the system and so cause Apport to include the contents of this other file in the resulting crash report. The crash report could then be read by that user either by causing it to be uploaded and reported to Launchpad, or by leveraging some other vulnerability to read the resulting crash report, and so allow the user to read arbitrary files on the system.

CVE
#vulnerability#ubuntu#linux#git

Dear Ubuntu Security Team,

I would like to report a privilege escalation vulnerability in Apport. The vulnerability is a TOCTOU which enables me to trick Apport into reading any file on the system and including it in a crash report file.

I have attached a proof-of-concept which triggers the vulnerability. I have tested it on an up-to-date Ubuntu 18.04. Run it as follows:

bunzip2 PoC.tar.bz2
tar -xf PoC.tar
cd PoC
make
./gencrashreport /etc/shadow

At this point the following file has been created:

/var/crash/_usr_share_apport_apport.0.crash

You can use the apport-unpack tool to decompress this file. If you look at the contents of the CoreDump file then you will see that it contains the contents of /etc/shadow (or whichever other file you passed on the command line of gencrashreport).

The bug has a couple of mitigations:

1. My PoC does not work if a file named /var/crash/.lock already exists and is owned by root. This file will only exist if Apport has previously generated a crash report. Based on an informal survey of my own 4 computers (yes - maybe I don’t need that many), it usually does not exist (unless the computer is used for security research).

2. The generated crash report file, /var/crash/_usr_share_apport_apport.0.crash, is only readable by root and by the whoopsie user. It will be uploaded to daisy.ubuntu.com if you create a file named /var/crash/_usr_share_apport_apport.0.upload, but that is not a huge security concern because it wouldn’t be of much benefit to an attacker. However, I have found some integer overflow vulnerabilities in whoopsie (which I will report separately). If those overflows can be exploited to gain code execution in whoopsie, then this will enable an attacker to read the contents of the crash report file.

To improve the effectiveness of the first mitigation, I would recommend that you make sure that /var/crash/.lock is created (and owned by root) by the Ubuntu installer and/or whoopsie when it starts up. It does not fix the root cause though, which I will describe next.

This is the source location of the TOCTOU vulnerability:

https://git.launchpad.net/ubuntu/+source/apport/tree/apport/report.py?h=applied/ubuntu/bionic-devel&id=2fc8fb446c78e950d643bf49bb7d4a0dc3b05429#n962

Apport allows the user to place a file in their home directory named `~/.apport-ignore.xml`. The call to os.access() on line 962 is intended to check that this file belongs to the correct user. But on line 967, the file is read again using xml.dom.minidom.parse. This creates a window of opportunity for an attacker to replace the file with a symlink. The symlink does not need to point to a valid XML file, because there is a try-except around the call to the parser, so if the file is invalid then Apport just ignores it and continues. However, the contents of the file still ends up in Apport’s heap.

Here’s a summary of how the PoC works:

1. Start a /bin/sleep and kill it with a SIGSEGV.
2. Apport starts up to generate a crash report for /bin/sleep
3. Replace ~/.apport-ignore.xml with a symlink at exactly the right moment, so that Apport loads a forbidden file into memory.
4. Wait until Apport drops privileges so that we can kill it with a SIGTRAP.
5. A second Apport starts up to generate a crash report for the first Apport.
6. The second Apport writes out a crash report for the first, containing a copy of the forbidden file in the core dump.

Apport tries quite hard to not run recursively on itself, so I had to jump through a few hoops to make the PoC work:

1. Apport sets a lock on /var/crash/.lock, using lockf. But locks created by lockf are only "advisory". If I own the file, then I can replace it with a different file, thereby deactivating the lock. This is why my PoC only works if /var/crash/.lock doesn’t already exist. I need to create it before Apport does, so that I can maintain ownership of it.

2. Apport has signal handlers for most of the core-generating signals, like SIGSEGV. But it doesn’t have a handler for SIGTRAP, so that’s what my PoC uses.

3. Apport is started with an RLIMIT_CORE value of 1, which is another recursion detection mechanism (see https://bugs.launchpad.net/ubuntu/+source/linux/+bug/498525/comments/3). But it is possible for another process to change it to zero, using prlimit.

As I mentioned earlier, I have also found a few other vulnerabilities in whoopsie and Apport. I will file them as separate bugs and include a link to this issue.

Please let me know when you have fixed the vulnerability, so that I can coordinate my disclosure with yours. For reference, here is a link to Semmle’s vulnerability disclosure policy: https://lgtm.com/security#disclosure_policy

Thank you,

Kevin Backhouse

Semmle Security Research Team

CVE: Latest News

CVE-2023-50976: Transactions API Authorization by oleiman · Pull Request #14969 · redpanda-data/redpanda
CVE-2023-6905
CVE-2023-6903
CVE-2023-6904
CVE-2023-3907