0

我在 Python 中有一个服务器/客户端套接字对。服务器接收特定命令,然后准备响应并将其发送给客户端。

在这个问题中,我关心的只是代码中可能的注入:是否可以要求服务器使用第二个参数做一些奇怪的事情——如果对命令内容的控制不足以避免不希望的行为。

编辑:

  • 根据收到的建议
  • 在 windows 上shell=True调用时添加了参数。check_output不应该是危险的,因为该命令是一个简单的“目录”。

.

self.client, address = self.sock.accept()

...

cmd = bytes.decode(self.client.recv(4096))

ls: 执行系统命令但只读取目录的内容。

if cmd == 'ls':
    if self.linux:
        output = subprocess.check_output(['ls', '-l'])
    else:
        output = subprocess.check_output('dir', shell=True)
    self.client.send(output)

cd: 只是打电话os.chdir

elif cmd.startswith('cd '):
    path = cmd.split(' ')[1].strip()
    if not os.path.isdir(path):
        self.client.send(b'is not path')
    else:
        os.chdir(path)
        self.client.send( os.getcwd().encode() )

get: 将文件内容发送给客户端。

elif cmd.startswith('get '):
    file = cmd.split(' ')[1].strip()
    if not os.path.isfile(file):
        self.client.send(b'ERR: is not a file')
    else:
        try:
            with open(file) as f: contents = f.read()
        except IOError as er:
            res = "ERR: " + er.strerror
            self.client.send(res.encode())
            continue

        ... (send the file contents)
4

2 回答 2

3

除了实现细节之外,我看不到任何直接注入任意代码的可能性,因为您没有在您使用的唯一命令(ls -ldir)中使用接收到的参数。

但是您可能仍然存在一些安全问题:

  • 您通过路径而不是使用绝对位置来定位命令。如果有人可以更改路径环境变量会发生什么... =>我建议您直接使用os.listdir('.')可移植且风险较小的。

  • 您似乎无法控制允许的文件。如果我正确记得CON:旧 Windows 版本上的阅读或其他特殊文件会给出奇怪的结果。而且您永远不应该授予对敏感文件、配置、...的任何访问权限

  • 您可以控制请求文件的长度,以避免用户尝试使用异常长的文件名来破坏服务器。

于 2014-07-06T19:03:21.723 回答
2

客户端-服务器方案中的典型问题是:

  • 诱使服务器运行由客户端确定的命令。在最明显的形式中,如果服务器允许客户端运行命令(是的,愚蠢的),就会发生这种情况。但是,如果客户端只能提供命令参数但shell=True被使用,也会发生这种情况。例如,subprocess.check_output('dir %s' % dir, shell=True)与客户端提供的dir变量一起使用将是一个安全问题,dir可能具有类似的值c:\ && deltree c:\windows(由于 shell 命令行解释器的灵活性,添加了第二个命令)。这种攻击的一个相对罕见的变体是客户端能够影响环境变量,例如PATH欺骗服务器运行与预期不同的命令。
  • 使用内置编程语言函数的意外功能。例如,fopen()在 PHP 中不仅会打开文件,还会获取 URL。这允许将 URL 传递给期望文件名的功能,并使用服务器软件玩各种技巧。幸运的是,Python 是一种健全的语言——open()只处理文件而不是其他任何东西。尽管如此,如果 SQL 查询是使用客户端提供的信息( SQL 注入)动态生成的,例如数据库命令可能会出现问题。
  • 读取允许区域之外的数据。典型的场景是一个服务器,它应该只允许从特定目录读取文件,但通过../../../etc/passwd作为参数传入,您可以读取任何文件。另一个典型场景是服务器,它只允许读取具有特定文件扩展名(例如.png)的文件,但传入类似的东西passwords.txt\0harmless.png仍然允许读取其他类型的文件。

在这些问题中,只有最后一个问题出现在您的代码中。事实上,您的服务器根本不检查应该允许客户端读取哪些目录和文件 - 这是一个潜在的问题,客户端可能能够读取机密文件。

于 2014-07-06T19:20:53.050 回答