** Description changed: https://docs.python.org/2/library/mailcap.html mailcap.findmatch(caps, MIMEtype[, key[, filename[, plist]]]) Return a 2-tuple; the first element is a string containing the command line to be executed (which can be passed to os.system()), ... Security Bug in mailcap.findmatch() function : ==================================== 1) If the "filename" or path contains a shell command , it will be injected when you use os.system() to execute the resulting command line. As you can read in the docs above, the function is designed to run os.system(<string containing the command line>). (Have a look at the Exploit Example 1 below ) - 2) If you try to 'quote' the filename before using mailcap.findmatch() , the shell command can be injected too, because there may be another quoting inside the mailcaps strings witch allows the shell commands to escape. - (Have a look at the Exploit Example 2 below) + 2) If you try to 'quote' the filename before using mailcap.findmatch() , the shell command can be injected too, because there may be another quoting inside the mailcaps strings witch allows the shell commands to escape. + (Have a look at the Exploit Example 2 below) 3) There is no way to split the resulting command line in a correct way afterwards into a list object with a "command" and its "parameters" because after running the function you will never now if the characters for splitting the line where a part of the the filename or a part of the - the mailcap command in the first place. So even if you use subprocess - for executing the commandline instead of os.system , you can get in - trouble with unwanted parameters witch may make the viewer doing bad - things. - + mailcap command in the first place. So even if you use subprocess for + executing the commandline instead of os.system , you can get in trouble + with unwanted parameters witch may make the viewer doing bad things. Python Exploit Example 1 : import mailcap , os d=mailcap.getcaps() FILE="';ls;#';ls;#.mp4" cmd,m=mailcap.findmatch(d, "audio/mpeg4", filename=FILE) os.system(cmd) - ## this will lead to this in cmd : - ## vlc '';ls;#';ls;#.mp4' - ## Or it will lead us to this in cmd : + ## this will lead to this in cmd : + ## vlc '';ls;#';ls;#.mp4' + ## Or it will lead us to this in cmd : ## vlc ';ls;#';ls;#.mp4 ## No matter what, it will inject the ls command after you quit vlc - + -- Python Exploit Example 2 : import mailcap , os try: - from shlex import quote + from shlex import quote except ImportError: - from pipes import quote + from pipes import quote d=mailcap.getcaps() FILE=quote(";ls;#.txt") cmd,m=mailcap.findmatch(d, "text/plain", filename=FILE) - os.system(cmd) + os.system(cmd) ## this will lead to this in cmd : ## less '';ls;#.txt'' ## And it will inject the ls command after you quit less '' with the Q key - + -- TODO : a) The Return 2-tuple Command line should be quoted in this way to make shell commands stay inside the 'quotes' : - 1.] Remove the quotes from the caps string, for example make it - less %s and NOT less '%s' - 2.] Now quote the filename with quote(filename) , so we get for example - ';xmessage hello world;#.txt' in the filename variable. - 3.] Now we replace %s with the filename , so now we get - less ';xmessage hello world;#.txt' and NOT less '';xmessage hello world;#.txt'' - + 1.] Remove the quotes from the caps string, for example make it + less %s and NOT less '%s' + 2.] Now quote the filename with quote(filename) , so we get for example + ';xmessage hello world;#.txt' in the filename variable. + 3.] Now we replace %s with the filename , so now we get + less ';xmessage hello world;#.txt' and NOT less '';xmessage hello world;#.txt'' + b) The mailcap.py script itself is using "os.system()" witch is vulnerable for shell injections. - They should be all replaced with "subprocess.Popen()" or "subprocess.call()". + They should be all replaced with "subprocess.Popen()" or "subprocess.call()". c) The "MIMEtype" parameter is missing for test. - if there is %s in the 'test' entries key we get a "TypeError: cannot concatenate 'str' and 'list' objects" error. - Should be like this : - test = subst( e['test'], MIMEtype, filename, plist) + if there is %s in the 'test' entries key we get a "TypeError: cannot concatenate 'str' and 'list' objects" error. + Should be like this : + test = subst( e['test'], MIMEtype, filename, plist) - d) Think about replacing this scrip completely with the "run-mailcap" + d) Think about replacing this script completely with the "run-mailcap" program of the debian project. - -- You can find mailcap.py in this locations : libpython2.7-stdlib: /usr/lib/python2.7/mailcap.py libpython3.4-stdlib: /usr/lib/python3.4/mailcap.py libpython3.4-testsuite: /usr/lib/python3.4/test/test_mailcap.py libpython3.5-stdlib: /usr/lib/python3.5/mailcap.py libpython3.5-testsuite: /usr/lib/python3.5/test/test_mailcap.py pypy-lib: /usr/lib/pypy/lib-python/2.7/mailcap.py python-mailutils: /usr/lib/python2.7/dist-packages/mailutils/mailcap.py -- Weblinks : http://www.freiesmagazin.de/mobil/freiesMagazin-2015-10-bilder.html#fm_15_10_shell_command_injection http://bugs.python.org/issue24778 ProblemType: Bug DistroRelease: Ubuntu 15.10 Package: libpython3.5-stdlib 3.5.0-3 ProcVersionSignature: Ubuntu 4.2.0-16.19-generic 4.2.3 Uname: Linux 4.2.0-16-generic x86_64 ApportVersion: 2.19.1-0ubuntu3 Architecture: amd64 CurrentDesktop: XFCE Date: Mon Oct 26 22:48:55 2015 InstallationDate: Installed on 2015-10-09 (16 days ago) InstallationMedia: Ubuntu 15.10 "Wily Werewolf" - Alpha amd64 (20151009) SourcePackage: python3.5 UpgradeStatus: No upgrade log present (probably fresh install)
-- You received this bug notification because you are a member of Ubuntu Bugs, which is subscribed to Ubuntu. https://bugs.launchpad.net/bugs/1510317 Title: Shell Command Injection in "Mailcap" file handling To manage notifications about this bug go to: https://bugs.launchpad.net/ubuntu/+source/python3.5/+bug/1510317/+subscriptions -- ubuntu-bugs mailing list ubuntu-bugs@lists.ubuntu.com https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs