【问题标题】:Execute any command-line shell like into execve执行任何命令行 shell,例如进入 execve
【发布时间】:2015-11-04 02:13:56
【问题描述】:

如果这有帮助,这是我的环境:debian 8,gcc(使用 std = gnu99)。

我面临以下情况: 在我的 C 程序中,我得到一个字符串(通过套接字的 char*)。 此字符串表示要执行的 bash 命令(如“ls ls”)。 该命令可以是任何 bash,因为它可能很复杂(管道、列表、复合命令、协同进程、shell 函数定义......)。 我不能使用system或popen来执行这个命令,所以我使用current execve。

我担心我必须“过滤”某些命令。 例如,对于 rm 命令,我只能将其应用于“/home/test/”目录。禁止所有其他目的地。

所以我必须阻止命令“rm -r /”但也阻止“ls ls && rm -r /”。 所以我必须解析给我的命令行,找到所有的命令并对它们应用过滤器。

那是我开始真正迷失的时候。

命令可以是任何复杂的,所以如果我想创建管道(一次执行一个命令)或者如果我想找到所有命令来应用我的过滤器,我将不得不开发与之相同的解析器嘘。

我不喜欢再造轮子,尤其是当我把它做成方形的时候。 所以我想知道 C 库(或 gnu 的库)中是否有一个特性。

我听说过 wordexp,但我不知道如何管理管道、重定向或其他(事实上,这似乎不是为此而设计的),我不知道如何检索命令中的所有命令。

我读了 sh(1) 的 man 看看我是否可以用它来“解析”但不能执行命令,但到目前为止,我什么也没找到。

我需要从头开始编写解析器吗?

感谢您的阅读,我为我糟糕的英语道歉:这不是我的母语(感谢谷歌翻译...)。

【问题讨论】:

  • 为什么不为您的目录创建一个具有有限权限的用户并使用该用户执行命令?
  • rm 只是一个例子。这个想法是我必须对任何命令应用任何过滤器。过滤器的规则不由我决定,所以如果有一天过滤器说“不能在包含字母'a'的路径上执行ls”,那么我必须应用这个规则。
  • @RemiThomas 我的建议是您下载Source code of Bash 并从中获取您需要的部分(词法分析器、解析器、分叉器、吹笛者),然后在其之上构建一个规则堆栈器(像 ipchains 之类的东西)。从头开始创建所有这些将花费您大量的时间和工作。当然,您始终可以通过将输入字符串拆分为;、|、&& 等然后通过规则堆栈器运行它来创建更简单的词法分析器/解析器版本。
  • 感谢您的提示。我认为分析和理解源代码需要很多时间,但它比从头开始编码要短得多。但是我很惊讶这还不可用……我不是第一个想要完整的 sh 解析器的人。我是吗?
  • @RemiThomas Bash 是完整的 SH 解析器。如果您想要 full bash 语法,则必须从中获取代码。否则,您最终只会得到其中的一小部分。我认为你真的应该重新考虑你的程序的设计......为什么不让它成为 bash 的包装器,用它自己的语法呢?换句话说,抽象 BASH。让你拥有自己的语法。喜欢list foo 或delete file.c。包装将使您可以很好地控制执行的内容和不执行的内容。这是学校项目还是个人/工作项目?

标签: c


【解决方案1】:

你的问题:

我面临以下情况:在我的 C 程序中,我得到一个字符串 (char* 通过套接字)。此字符串表示要执行的 bash 命令 (如“ls ls”)。此命令可以是任何 bash,因为它可能很复杂 (管道、列表、复合命令、协进程、shell 函数 定义...)。

您打算如何验证套接字连接的另一端是谁?

您需要实现一个命令解析器,并考虑安全性?显然要远程运行命令,正如“我得到一个字符串(通过套接字的 char*)”所暗示的那样?

真正的解决方案:

How to set up SSH without passwords

你的目标

您想使用 Linux 和 OpenSSH 来自动化您的任务。所以 您需要从主机 A / 用户 a 自动登录到主机 B / 用户 b。 你不想输入任何密码,因为你想调用 ssh 从一个 shell 脚本中。

说真的。

你就是这样解决这个问题的:

我在套接字上收到一个作为 shell 命令的字符串,我必须 执行它。但在执行之前,我必须确保没有 与所有规则冲突的命令(例如 'rm only inside this 目录等)。为了执行命令,我不能使用 system 或 popen(我使用 execve)。剩下的就看我了。

给定

那是我开始真正迷失的时候。

因为您被要求做的是实现安全功能和命令解析。去看看 SSH 和 bash 的代码量。

您的操作系统带有安全功能。 SSH 进行身份验证。

不要试图重新发明这些。你不会做得很好——没有人能做到。看看bash 和 SSH 花了多长时间才达到安全水平。 (提示:这是几十年,因为当 bash 和 SSH 首次编码时,实际上有几十年的历史和知识......)

【讨论】:

  • 套接字末尾的用户已经通过身份验证。我想我没有给出所有细节:这个命令中的一些将是完整的 bash 语法,而允许的其余命令将是“内部的”。 “内部”是指我保留所有命令的完整历史记录,“内部”命令可以修改此历史记录(如“显示”、“清理”等)。我知道我不能重新实现这样的事情,但我能做什么?解析命令行真的不可能吗?即使是 bash 本身?
  • @Tom 的 套接字末尾的用户已经通过身份验证?如何?密码?您不会以明文形式通过网络传递它,对吗?还是您只是希望允许您的套接字连接另一端的东西在那里? 真的不可能解析命令行吗?即使使用 bash 本身? 鉴于 bash 不这样做我必须阻止命令“rm -r /”但也阻止命令“ls ls && rm -r /”,是的,它是不可能的。诸如 bash 之类的任何 shell 都依赖 OS 来防止未经授权的用户执行“rm -r /”。你打算怎么做?
  • 例如,即使假设您阻止rm -r /,您将如何阻止ln -s /bin/rm /tmp/asdf; /tmp/asdf -r /?你将如何阻止某人执行调用rm -r / 的脚本?鉴于您的连接显然具有root 访问权限,您将如何防止他们从/etc/shadow 转储您的散列密码以进行离线破解?或者安装键盘记录器或其他恶意软件?你知道你需要阻止哪些命令来防止这种情况发生吗?
  • 好吧,我没看到我必须说我认为的细节,真的很抱歉。套接字连接在 openvpn 连接上。给我这个任务的人暂时不在,但他要求他可以执行任何 shell 命令。据我所知,我想会有人和程序可以在套接字上发送命令。因此,对命令进行“过滤”(或规则)的主要目的是防止人为错误。
  • 对于您的 rm 示例,这是一个很好的问题......我认为这个程序的目的不是为了安全,因为安全是在其他地方管理的,但是我的程序必须管理“命令"(可以是 shell 命令或“内部”命令)。这就是为什么我必须解析命令行。我真的很抱歉没有从一开始就给你所有的规范。
猜你喜欢
  • 1970-01-01
  • 2015-01-03
  • 1970-01-01
  • 1970-01-01
  • 2018-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-15
相关资源
最近更新 更多