Privilege escalation through Python module imports

Bug #1507480 reported by Martin Pitt
258
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Apport
Fix Released
High
Martin Pitt
apport (Ubuntu)
Fix Released
High
Martin Pitt
Precise
Fix Released
High
Marc Deslauriers
Trusty
Fix Released
High
Marc Deslauriers
Vivid
Fix Released
High
Marc Deslauriers
Wily
Fix Released
High
Marc Deslauriers
Xenial
Fix Released
High
Martin Pitt

Bug Description

Gabriel Campana <email address hidden> reported a security vulnerability in Apport:

ummary
=======

A privilege escalation was discovered in apport.

Details
=======

The command line of the process triggering the coredump is checked to
determine if it's a script. If the interpreter is Python and the first
argument is ``-m``, the method ``_python_module_path`` is called to find
the path of the culprit module
(``/usr/lib/python3/dist-packages/apport/report.py``)::

    @classmethod
    def _python_module_path(klass, module):
        '''Determine path of given Python module'''

        module = module.replace('/', '.')

        try:
            m = __import__(module)
            m
        except:
            return None

        [...]

Any Python module in ``sys.path`` can be imported because the variable
``module`` is under control of the attacker. It should be noted that
``_python_module_path`` is called with euid=0, and apport relies on the
process name to determine if the process is an interpreter. A crash of
Python isn't required to reach this function: any process name starting
with ``python`` and producing a core dump is enough. As an example, the
following bash script triggers the bug::

       #!/bin/bash

        cat <<EOF > python.c
        int main(void) { *(int *)0 = 0; return 0; }
        EOF
        gcc -o python python.c
        ./python -m venv.__main__

and results in the creation of a "lightweight virtual Python
environment" in the root directory::

        $ ./lol.sh
        ./lol.sh: line 8: 7665 Segmentation fault (core dumped)
        $ ls -l / | head -4
        total 100
        drw-rw---- 5 root root 4096 Sep 29 16:09 7665
        drwxr-xr-x 2 root root 4096 Sep 29 05:41 bin
        drwxr-xr-x 3 root root 4096 Sep 29 06:20 boot

Criticity
=========

Importing an arbitrary module is a security issue because a few standard
modules rely on files in the home directory associated to the uid of the
dumped process. A fully working exploit has been written (targetting
Python2 and Python3), giving an instant root shell to the attacker.
While the exploitation is straightforward for Python2, a bit more work
was required to find a suitable module for Python3.

The vulnerability seems to be limited to Ubuntu Dekstop because apport
is disabled on Ubuntu Server.

Tags: patch
Martin Pitt (pitti)
Changed in apport:
assignee: nobody → Martin Pitt (pitti)
importance: Undecided → High
status: New → In Progress
Changed in apport (Ubuntu Wily):
status: New → Triaged
Changed in apport (Ubuntu Vivid):
status: New → Triaged
Changed in apport (Ubuntu Trusty):
status: New → Triaged
Changed in apport (Ubuntu Precise):
status: New → Triaged
Revision history for this message
Martin Pitt (pitti) wrote :

Gabriel provided a fix for this, by rewriting _python_module_path() in a way to avoid actually importing the module. I created a test case for this which reproduces the issue with unittest.__main__ (which isn't an actual exploit, but sufficient to demonstrate the problem).

Security team, can you please assign a CVE and CRD? Once we agree to this fix, I'll provide backports for earlier Ubuntu stable releases.

Revision history for this message
Marc Deslauriers (mdeslaur) wrote :

Please use CVE-2015-1341 for this issue.

How about a CRD of 2015-10-27?

Revision history for this message
Martin Pitt (pitti) wrote :

Sounds good, thanks!

Martin Pitt (pitti)
Changed in apport (Ubuntu Xenial):
status: New → In Progress
Revision history for this message
Martin Pitt (pitti) wrote :

This is the debdiff for wily (the patch for trunk applies without issues).

This includes a tiny fix for the test suite from http://bazaar.launchpad.net/~apport-hackers/apport/trunk/revision/3020 . They started failing around October 15th (http://autopkgtest.ubuntu.com/packages/a/apport/wily/amd64/), presumably due to some side issues of the new apt/dpkg, but it would be really useful to have them passing again.

I'll backport that to the previous releases as well, as it also seems to affect e. g. http://autopkgtest.ubuntu.com/packages/a/apport/vivid/amd64/

I have the commits for this security fix and the release tag locally; I'll push them to lp:~ubuntu-core-dev/ubuntu/wily/apport/ubuntu when this gets published.

Changed in apport (Ubuntu Wily):
status: Triaged → Fix Committed
status: Fix Committed → In Progress
Revision history for this message
Martin Pitt (pitti) wrote :

debdiff for vivid, with same considerations as for wily. As for wily, local build, test, adt-run all pass.

Changed in apport (Ubuntu Vivid):
status: Triaged → In Progress
Revision history for this message
Martin Pitt (pitti) wrote :

debdiff for trusty. There are three test failures in adt-run, like in http://autopkgtest.ubuntu.com/packages/a/apport/trusty/amd64/, but the "report" tests (particularly the new one for this bug) succeed.

Revision history for this message
Martin Pitt (pitti) wrote :

Sorry, this is the right one for trusty.

Changed in apport (Ubuntu Trusty):
status: Triaged → In Progress
Revision history for this message
Martin Pitt (pitti) wrote :

And finally, debdiff for precise.

Changed in apport (Ubuntu Precise):
status: Triaged → In Progress
Revision history for this message
Marc Deslauriers (mdeslaur) wrote :

Thanks for the debdiffs!

Changed in apport (Ubuntu Precise):
assignee: nobody → Marc Deslauriers (mdeslaur)
Changed in apport (Ubuntu Trusty):
assignee: nobody → Marc Deslauriers (mdeslaur)
Changed in apport (Ubuntu Vivid):
assignee: nobody → Marc Deslauriers (mdeslaur)
Changed in apport (Ubuntu Wily):
assignee: nobody → Marc Deslauriers (mdeslaur)
Changed in apport (Ubuntu Xenial):
assignee: nobody → Martin Pitt (pitti)
Revision history for this message
Launchpad Janitor (janitor) wrote :

This bug was fixed in the package apport - 2.0.1-0ubuntu17.13

---------------
apport (2.0.1-0ubuntu17.13) precise-security; urgency=medium

  * SECURITY FIX: When determining the path of a Python module for a program
    like "python -m module_name", avoid actually importing and running the
    module; this could lead to local root privilege escalation. Thanks to
    Gabriel Campana for discovering this and the fix!
    (CVE-2015-1341, LP: #1507480)

 -- Martin Pitt <email address hidden> Thu, 22 Oct 2015 15:50:47 +0200

Changed in apport (Ubuntu Precise):
status: In Progress → Fix Released
Revision history for this message
Launchpad Janitor (janitor) wrote :

This bug was fixed in the package apport - 2.19.1-0ubuntu4

---------------
apport (2.19.1-0ubuntu4) wily-security; urgency=medium

  * test_backend_apt_dpkg.py: Reset internal apt caches between tests. Avoids
    random test failures due to leaking paths from previous test cases.
  * SECURITY FIX: When determining the path of a Python module for a program
    like "python -m module_name", avoid actually importing and running the
    module; this could lead to local root privilege escalation. Thanks to
    Gabriel Campana for discovering this and the fix!
    (CVE-2015-1341, LP: #1507480)

 -- Martin Pitt <email address hidden> Thu, 22 Oct 2015 14:46:22 +0200

Changed in apport (Ubuntu Wily):
status: In Progress → Fix Released
Revision history for this message
Launchpad Janitor (janitor) wrote :

This bug was fixed in the package apport - 2.17.2-0ubuntu1.7

---------------
apport (2.17.2-0ubuntu1.7) vivid-security; urgency=medium

  * test_backend_apt_dpkg.py: Reset internal apt caches between tests. Avoids
    random test failures due to leaking paths from previous test cases.
  * SECURITY FIX: When determining the path of a Python module for a program
    like "python -m module_name", avoid actually importing and running the
    module; this could lead to local root privilege escalation. Thanks to
    Gabriel Campana for discovering this and the fix!
    (CVE-2015-1341, LP: #1507480)

 -- Martin Pitt <email address hidden> Thu, 22 Oct 2015 15:05:43 +0200

Changed in apport (Ubuntu Vivid):
status: In Progress → Fix Released
information type: Private Security → Public Security
Changed in apport (Ubuntu Xenial):
assignee: Martin Pitt (pitti) → Marc Deslauriers (mdeslaur)
Revision history for this message
Launchpad Janitor (janitor) wrote :

This bug was fixed in the package apport - 2.14.1-0ubuntu3.18

---------------
apport (2.14.1-0ubuntu3.18) trusty-security; urgency=medium

  * test_backend_apt_dpkg.py: Reset internal apt caches between tests. Avoids
    random test failures due to leaking paths from previous test cases.
  * SECURITY FIX: When determining the path of a Python module for a program
    like "python -m module_name", avoid actually importing and running the
    module; this could lead to local root privilege escalation. Thanks to
    Gabriel Campana for discovering this and the fix!
    (CVE-2015-1341, LP: #1507480)

 -- Martin Pitt <email address hidden> Thu, 22 Oct 2015 15:15:37 +0200

Changed in apport (Ubuntu Trusty):
status: In Progress → Fix Released
Revision history for this message
Martin Pitt (pitti) wrote :

Published new upstream release https://launchpad.net/apport/trunk/2.19.2 which includes the fix.

Changed in apport:
status: In Progress → Fix Committed
status: Fix Committed → Fix Released
Martin Pitt (pitti)
Changed in apport (Ubuntu Xenial):
assignee: Marc Deslauriers (mdeslaur) → Martin Pitt (pitti)
status: In Progress → Fix Committed
tags: added: patch
Revision history for this message
Launchpad Janitor (janitor) wrote :

This bug was fixed in the package apport - 2.19.2-0ubuntu1

---------------
apport (2.19.2-0ubuntu1) xenial; urgency=medium

  * New upstream release. Changes since previous snapshot:
    - SECURITY FIX: When determining the path of a Python module for a program
      like "python -m module_name", avoid actually importing and running the
      module; this could lead to local root privilege escalation. Thanks to
      Gabriel Campana for discovering this and the fix!
      (CVE-2015-1341, LP: #1507480)
    - test_backend_apt_dpkg.py: Reset internal apt caches between tests.
      Avoids random test failures due to leaking paths from previous test
      cases.
  * debian/control: Adjust Vcs-Bzr: for xenial branch.
  * debian/control: Drop obsolete XS-Testsuite: header.

 -- Martin Pitt <email address hidden> Tue, 27 Oct 2015 14:33:28 +0100

Changed in apport (Ubuntu Xenial):
status: Fix Committed → Fix Released
Mathew Hodson (mhodson)
Changed in apport (Ubuntu Precise):
importance: Undecided → High
Changed in apport (Ubuntu Trusty):
importance: Undecided → High
Changed in apport (Ubuntu Vivid):
importance: Undecided → High
Changed in apport (Ubuntu Wily):
importance: Undecided → High
Changed in apport (Ubuntu Xenial):
importance: Undecided → High
To post a comment you must log in.
This report contains Public Security information  
Everyone can see this security related information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.