[issue24778] mailcap.findmatch() ........ Shell Command Injection in filename
New submission from Bernd Dietzel: if the filename contains Shell Commands they will be executed if they are passed to os.system() as discribed in the docs. Filename should be quoted with quote(filename) to fix the bug. 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() *), .." Exploid Demo wich runs xterm but should not : = import mailcap d=mailcap.getcaps() commandline,MIMEtype=mailcap.findmatch(d, "text/*", filename="'$(xterm);#.txt") ## commandline = "less ''$(xterm);#.txt'" import os os.system(commandline) ## xterm starts = By the way ... please do not use os.system() in your code, makes it unsafe. Best regards Bernd Dietzel Germany -- components: Library (Lib) files: screenshot.png messages: 247857 nosy: TheRegRunner priority: normal severity: normal status: open title: mailcap.findmatch() Shell Command Injection in filename type: security versions: Python 2.7 Added file: http://bugs.python.org/file40099/screenshot.png ___ Python tracker <http://bugs.python.org/issue24778> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue24778] mailcap.findmatch() ........ Shell Command Injection in filename
Bernd Dietzel added the comment: Maybe it would be a good idea to do so as run-mailcap does : theregrunner@mint17 : ~ € run-mailcap --debug "';xterm;#'.txt" - parsing parameter "';xterm;#'.txt" - Reading mime.types file "/etc/mime.types"... - extension "txt" maps to mime-type "text/plain" - Reading mailcap file "/etc/mailcap"... Processing file "';xterm;#'.txt" of type "text/plain" (encoding=none)... - checking mailcap entry "text/plain; less '%s'; needsterminal" - program to execute: less '%s' - filename contains shell meta-characters; aliased to '/tmp/fileV7f2MZ' - executing: less '/tmp/fileV7f2MZ' theregrunner@mint17 : ~ € -- ___ Python tracker <http://bugs.python.org/issue24778> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue24778] mailcap.findmatch() ........ Shell Command Injection in filename
Bernd Dietzel added the comment: @David Thanks for the comment :-) I think if you read the Documentation https://docs.python.org/2/library/mailcap.html this may lead new programmers, wich may never heard of Shell Injections before, step by step directly to write insecure webbbrowsers and/or mail readers. At least there should be a warning in the docs ! You ask why run-mailcap do not use quotig, i believe because quoting is not an easy thing to do, i attached a demo ;-) Thank you. -- Added file: http://bugs.python.org/file40116/The Quote Problem.py ___ Python tracker <http://bugs.python.org/issue24778> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue24778] mailcap.findmatch() ........ Shell Command Injection in filename
Bernd Dietzel added the comment: Exploid Demo wich works with quote() : >>> commandline,MIMETYPE=mailcap.findmatch(d, 'text/*', >>> filename=quote(';xterm;#.txt')) >>> commandline "less '';xterm;#.txt''" >>> os.system(commandline) ### xterm starts -- ___ Python tracker <http://bugs.python.org/issue24778> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue24778] mailcap.findmatch() ........ Shell Command Injection in filename
Bernd Dietzel added the comment: Yes changing the docs is a good idea. I was thinking about a patch : import os ### patch import random try: from shlex import quote except ImportError: from pipes import quote ### ... and so on # Part 3: using the database. def findmatch(caps, MIMEtype, key='view', filename="/dev/null", plist=[]): """Find a match for a mailcap entry. Return a tuple containing the command line, and the mailcap entry used; (None, None) if no match is found. This may invoke the 'test' command of several matching entries before deciding which entry to use. """ entries = lookup(caps, MIMEtype, key) # XXX This code should somehow check for the needsterminal flag. for e in entries: if 'test' in e: test = subst(e['test'], filename, plist) if test and os.system(test) != 0: continue ### patch ps=''.join(random.choice('python') for i in range(100)) x=e[key] while '%s' in x: x=x.replace('%s',ps) command=subst(x, MIMEtype, filename, plist) while "'"+ps+"'" in command: command=command.replace("'"+ps+"'",quote(filename)) while ps in command: command=command.replace(ps,quote(filename)) ## command = subst(e[key], MIMEtype, filename, plist) return command, e return None, None -- ___ Python tracker <http://bugs.python.org/issue24778> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue24778] mailcap.findmatch() ........ Shell Command Injection in filename
Bernd Dietzel added the comment: # for the docs ... quoting of the filename when you call mailcap.findmatch() f=";xterm;#.txt" # Shell Command Demo ... xterm will run if quote() fails import mailcap import random try: from shlex import quote except ImportError: from pipes import quote d=mailcap.getcaps() PY=''.join(random.choice('PYTHON') for i in range(100)) cmd,MIMEtype=mailcap.findmatch(d, 'text/plain', filename=PY) while "'"+PY+"'" in cmd: cmd=cmd.replace("'"+PY+"'",quote(f)) while PY in cmd: cmd=cmd.replace(PY,quote(f)) print(cmd) # less ';xterm;#.txt' -- ___ Python tracker <http://bugs.python.org/issue24778> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue24778] mailcap.findmatch: document shell command Injection danger in filename parameter
Bernd Dietzel added the comment: What i do is the last doc is like this : 1) Replace the filename with a random name 2) Run mailcap.findmatch() with the random name 3) If exists, replace the quote characters ' before and behind the random name with nothing. 4) Now the random name has no quoting from mailcap itself 5) So now we can use our own quote() savely -- ___ Python tracker <http://bugs.python.org/issue24778> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue24778] mailcap.findmatch: document shell command Injection danger in filename parameter
Bernd Dietzel added the comment: Thanks :-) As you may noticed i now choosed to use a random name made of the chars of "PYTHON" in BIG letters instead of small letters i used before. Thats because i do not want to get in trouble with the little "t" in %t wich is replaced by the subst function too. -- ___ Python tracker <http://bugs.python.org/issue24778> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue24778] mailcap.findmatch: document shell command Injection danger in filename parameter
Bernd Dietzel added the comment: My patch for mailcap.py. Please check and apply my patch please. 1) I have removed the os.system() calls for security reasons. 2) New "findmtach_list()" function witch returns the commandline as a [list] witch can be passed to subprocess instead of passing it to os.system(). 3) New run() function to execute the cmd_list with subprocess. 4) The test() function now uses findmatch_list() and run() instead of the old findmatch() and os.system() calls. 5) The subst() function is now shorter an does a quote(filename) when its replacing %s with a filename. 6) The "old" findmatch() function is still there if the user still likes to have the commandline as a "string". Attention ! With this old findmatch() function it's still possible that a shell command in the filename like '$(ls).txt' will be executed when the users passes the string to os.system() outside the mailcap script. Use findmatch() only for backwards compatibility. 7) Use the new findmatch_list() an run() for future projects. 8) Add 1)-7) to the docs Thank you. -- Added file: http://bugs.python.org/file40897/mailcap patch.zip ___ Python tracker <http://bugs.python.org/issue24778> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue25627] distutils : file "bdist_rpm.py" allows Shell injection in "name
New submission from Bernd Dietzel: https://bugs.launchpad.net/ubuntu/+source/python2.7/+bug/1514183 File : /usr/lib/python2.7/distutils/command/bdist_rpm.py Line 358 : This line in the code uses the depreached os.popen command, should be replaced with subprocess.Popen() : out = os.popen(q_cmd) Exploit demo : 1) Download the setup.py script witch i attached 2) Create a test folder an put the setup.py script in this folder 3) cd to the test folder 4) python setup.py bdist_rpm 5) A xmessage window pops up as a proof of concept -- components: Distutils files: setup.py messages: 254670 nosy: TheRegRunner, dstufft, eric.araujo priority: normal severity: normal status: open title: distutils : file "bdist_rpm.py" allows Shell injection in "name type: security versions: Python 2.7 Added file: http://bugs.python.org/file41043/setup.py ___ Python tracker <http://bugs.python.org/issue25627> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue25627] distutils : file "bdist_rpm.py" allows Shell injection in "name"
Changes by Bernd Dietzel : -- title: distutils : file "bdist_rpm.py" allows Shell injection in "name -> distutils : file "bdist_rpm.py" allows Shell injection in "name" ___ Python tracker <http://bugs.python.org/issue25627> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue25751] ctypes.util , Shell Injection in find_library()
New submission from Bernd Dietzel: The find_library() function can execute code when special chars like ;|`<>$ are in the name. The "os.popen()" calls in the util.py script should be replaced with "subprocess.Popen()". Demo Exploits for Linux : >>> from ctypes.util import find_library >>> find_library(";xeyes") # runs xeyes >>> find_library("|xterm") # runs terminal >>> find_library("&gimp") # runs gimp >>> find_library("$(nautilus)") # runs filemanager >>> find_library(">test") # creates, and if exists, erases a file "test" Traceback >>> find_library("`xmessage hello`") # shows a message, press ctrl+c for >>> Traceback ^CTraceback (most recent call last): File "", line 1, in File "/usr/lib/python3.4/ctypes/util.py", line 244, in find_library return _findSoname_ldconfig(name) or _get_soname(_findLib_gcc(name)) File "/usr/lib/python3.4/ctypes/util.py", line 99, in _findLib_gcc trace = f.read() KeyboardInterrupt https://bugs.launchpad.net/ubuntu/+source/python2.7/+bug/1512068 -- components: ctypes files: workaround.diff keywords: patch messages: 255482 nosy: TheRegRunner priority: normal severity: normal status: open title: ctypes.util , Shell Injection in find_library() type: security versions: Python 2.7, Python 3.4 Added file: http://bugs.python.org/file41174/workaround.diff ___ Python tracker <http://bugs.python.org/issue25751> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue25751] ctypes.util , Shell Injection in find_library()
Bernd Dietzel added the comment: i made the ubuntu link readable for everyone. -- ___ Python tracker <http://bugs.python.org/issue25751> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com