pah*_*haz 7 python windows cmd
好吧,我有一个必须在shell=True模式下执行的命令.
os.system 要么 subprocess.Popen(..., shell=True)
此命令包含字符串替换,如: cmd = "some_secret_command {0}".format(string_from_user)
我想要逃避string_from_user变量来防止任何注射.
简单的错误答案:
shlex.quote- 不正确print(shlex.quote('file.txxt; &ls . #'))- > 'file.txxt; &ls . #'(注射)
例:
> python -c "import sys; print(sys.argv[1])" 'file.txxt; &ls . #'
secret.txt
secret2.txt
Run Code Online (Sandbox Code Playgroud)
^- 不正确 例:
import os
CMD = '''string with spaces'''.replace('', '^').replace('^"', '')
os.system('python -c "import sys; print(sys.argv[1])" {0}'.format(CMD))
Run Code Online (Sandbox Code Playgroud)
现在我可以使用 (space) and inject more then one argument.
^和"或'- 不正确例:
import os
CMD = '''some arg with spaces'''.replace('', '^').replace('^"', '')
os.system('python -c "import sys; print(sys.argv[1])" "{0}"'.format(CMD))
Run Code Online (Sandbox Code Playgroud)
打印 ^s^o^m^e^ ^a^r^g^ ^w^i^t^h^ ^s^p^a^c^e^s^
而如果 '
import os
CMD = '''some spaces'''.replace('', '^').replace('^\'', '')
os.system('python -c "import sys; print(sys.argv[1])" \'{0}\''.format(CMD))
Run Code Online (Sandbox Code Playgroud)
打印 'some
我现在约,shell=False但这对我不正确.
Hol*_*ust 13
引用Windows命令行的问题在于有两个分层的解析引擎受到引号的影响.首先,有Shell(例如cmd.exe)解释一些特殊字符.然后,有一个被调用的程序解析命令行.这通常发生在CommandLineToArgvWWindows提供的功能上,但并非总是如此.
也就是说,对于一般情况,例如使用cmd.exe解析其命令行的程序CommandLineToArgvW,您可以使用Daniel Colascione所描述的技术在Everyone中以错误的方式引用命令行参数.我原本试图将其改编为Ruby,现在尝试将其转换为python.
import re
def escape_argument(arg):
# Escape the argument for the cmd.exe shell.
# See http://blogs.msdn.com/b/twistylittlepassagesallalike/archive/2011/04/23/everyone-quotes-arguments-the-wrong-way.aspx
#
# First we escape the quote chars to produce a argument suitable for
# CommandLineToArgvW. We don't need to do this for simple arguments.
if not arg or re.search(r'(["\s])', arg):
arg = '"' + arg.replace('"', r'\"') + '"'
return escape_for_cmd_exe(arg)
def escape_for_cmd_exe(arg):
# Escape an argument string to be suitable to be passed to
# cmd.exe on Windows
#
# This method takes an argument that is expected to already be properly
# escaped for the receiving program to be properly parsed. This argument
# will be further escaped to pass the interpolation performed by cmd.exe
# unchanged.
#
# Any meta-characters will be escaped, removing the ability to e.g. use
# redirects or variables.
#
# @param arg [String] a single command line argument to escape for cmd.exe
# @return [String] an escaped string suitable to be passed as a program
# argument to cmd.exe
meta_chars = '()%!^"<>&|'
meta_re = re.compile('(' + '|'.join(re.escape(char) for char in list(meta_chars)) + ')')
meta_map = { char: "^%s" % char for char in meta_chars }
def escape_meta_chars(m):
char = m.group(1)
return meta_map[char]
return meta_re.sub(escape_meta_chars, arg)
Run Code Online (Sandbox Code Playgroud)
应用此代码,您应该能够成功转义cmd.exe shell的参数.
print escape_argument('''some arg with spaces''')
# ^"some arg with spaces^"
Run Code Online (Sandbox Code Playgroud)
请注意,该方法应引用一个完整的参数.如果你从多个源收集你的参数,例如,通过构建一串python代码传递给python命令,你必须在传递它之前组装它escape_argument.
import os
CMD = '''string with spaces and &weird^ charcters!'''
os.system('python -c "import sys; print(sys.argv[1])" {0}'.format(escape_argument(CMD)))
# string with spaces and &weird^ charcters!
Run Code Online (Sandbox Code Playgroud)