如何在Windows上安全地转义cmd.exe Shell的命令行参数?

帕哈兹

好的,我有一些命令必须在shell=True模式下执行

os.system 要么 subprocess.Popen(..., shell=True)

并且此命令包含字符串替换,例如: cmd = "some_secret_command {0}".format(string_from_user)

我想要转义string_from_user变量以防止任何注入。

简单的错误答案:

  1. 使用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
  1. 使用转义^-不正确

例:

import os

CMD = '''string with spaces'''.replace('', '^').replace('^"', '')
os.system('python -c "import sys; print(sys.argv[1])" {0}'.format(CMD))

现在,我可以使用(空格)并注入多个参数。

  1. 使用^"'-错误

例:

import os

CMD = '''some arg with spaces'''.replace('', '^').replace('^"', '')
os.system('python -c "import sys; print(sys.argv[1])" "{0}"'.format(CMD))

打印 ^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))

打印 'some

我现在大约,shell=False但这对我来说是不正确的。

霍尔格·贾斯特

引用Windows命令行的问题在于,有两个受引用影响的分层解析引擎。首先,有cmd.exe解释某些特殊字符的Shell(例如)。然后,有一个调用程序解析命令行。CommandLineToArgvWWindows提供功能经常会发生这种情况,但并非总是如此。

就是说,对于一般情况,例如,使用cmd.exe与程序一起解析其命令行的程序CommandLineToArgvW,您可以使用Daniel Colascione在《每个人都用错误的方式引号命令行参数》中描述的技术我最初尝试将其适应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)

应用此代码,您应该能够成功转义cmd.exe Shell的参数。

print escape_argument('''some arg with spaces''')
# ^"some arg with spaces^"

请注意,该方法应引用单个完整参数。如果要从多个来源收集参数,例如,通过构建一串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!

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何使用动态命令行参数托管exe

记录cmd.exe的命令行

如何在Windows XP / 7上通过命令行cmd.exe更改键盘布局?

如何在AutoExec宏中获取WinWord.exe的命令行参数?

为什么cmd.exe命令行解释器不称为shell?

通过批处理脚本执行参数化的.exe文件(Windows命令行)

如何掌握在Visual Studio中将哪些命令行参数发送到cl.exe?

_progres.exe命令行参数

如何在Shell Sript中读取命令行参数

如何在 shell 脚本中转发命令行参数?

如何通过命令行传递jarsigner.exe密码?

如何从命令行获取exe实例数?

如何找到git-bash.exe的命令行选项?

code.exe忽略命令行参数

我无法获取.exe文件的命令行参数

如何将Shell命令行参数映射到READ命令

Shell脚本:如何将脚本的命令行参数传递给它调用的命令?

将参数从Shell脚本传递到Python脚本,而不必在命令行上指定参数

如何将Shell变量作为命令行参数传递给Shell脚本

如何在MSDeploy.exe命令行上设置目标网站

如何打开 .exe(不是 Windows 命令行)文件并向其发送命令?

Docker CMD的命令行参数

如何在shell脚本中将变量作为参数传递给Bigquery命令行

如何在shell脚本中将表名作为参数传递给Bigquery命令行

如何在shell脚本下面转换以获得更多数量的命令行输入参数。

如何在 Power Shell 中执行具有多个参数的命令行?

是什么导致EXE扩展名在命令行中是必需的,以及如何在当前Shell中解决它?

在Windows cmd.exe的同一命令行中设置和使用变量

HWUT:命令行上的参数