It's possible to invoke an application without interpreting any of its arguments as shell magic:
>>> print(subprocess.check_output(["C:/testapplication.exe", "foo", "&&", "echo", "%PROGRAMFILES%"]))
Hello world from application! 5 arguments:
Argument 0: 'C:/testapplication.exe'
Argument 1: 'foo'
Argument 2: '&&'
Argument 3: 'echo'
Argument 4: '%PROGRAMFILES%'
But not so for batch scripts:
>>> print(subprocess.check_output(["C:/testscript.bat", "foo", "&&", "echo", "%PROGRAMFILES%"]))
Hello world from script! 2 arguments:
Argument 0: 'C:/testscript.bat'
Argument 1: 'foo'
C:\Program Files
I don't know if this is a fundamental limitation of Windows' batch script processing, or of the Win32 CreateProcess API, but this looks exploitable, as it allows shell injection: the subprocess docs warn about shell injection in a big red box, and promise you'll be safe if you a list of arguments and the default shell=False.
Tested on Python 2.7.15 and Python 3.6.5. |