是否有可能打破受限(自定义)shell?

时间:2014-09-30 02:16:22

标签: linux shell security go

不确定这是否是合适的地方。

假设我写了一个接受stdin输入的shell,过滤此输入所以让我们说只有某些命令,比如

  • ls(列出二进制目录和子目录的内容)
  • 更新(git clone)
  • build(go build)
  • test(go test)
  • start(systemctl start this.service only)
  • 停止(systemctl stop this.service only)
  • 正在运行(正在执行的二进制文件以及有多少GOMAXPROCS?)
  • 用法(内存,cpu使用)
  • gensvc(生成.service文件)
  • 退出(离开shell /注销)
工作,你猜对了,我试图通过ssh为用户提供非常有限的维护访问权限。

说我对\0小心(我还是用Bufio.Scanner在Go中写的)

有没有办法阻止正在运行的shell并执行/ bin / sh或类似方法或以任何方式绕过这个shell?

这个想法是用户应该通过git将他们的东西推送到一个裸仓库,这个仓库被克隆到文件系统到某个目录,然后调用build,并使用生成的systemd .service文件运行二进制文件先前。

从逻辑上思考,如果用户只能写一些被接受的字符串,那就没有办法了。但也许你知道一个,一些ctrl + z巫术;)或其他什么。

唯一的攻击面是输入字符串或字节。当然用户可以通过git推送构建自己的shell或运行某些命令的程序,但这超出了范围(我会删除systemd的功能并限制设备访问,并禁止除了与数据库服务器,私有tmp和所有连接之外的任何连接,名称空间和子名称空间(TODO)

我看到的唯一问题是git推送,但我确信我可以在git only模式argv中解决这个问题并将其添加到〜/ .ssh / authorized_keys。像lish gitmode之类的东西,如果它们以git或类似的东西开始,则执行stdin命令。

示例:

https://gist.github.com/dalu/ce2ef43a2ef5c390a819

3 个答案:

答案 0 :(得分:3)

如果你只允许某些命令,你的“shell”将读取命令,解析它然后执行它然后你应该没事,除非我误解了它。

Go“memory”无法执行,不管你是不是没有用装配做一些讨厌的黑客攻击,所以你不必担心shell注入。

这些方面的东西应该是安全的:

func getAction() (name string, args []string) {
    // read stdin to get the command of the user
}

func doAction() {
    for {
        action, args := getAction()
        switch action {
            case "update": //let's assume the full command is: update https://repo/path.git
                if len(args) != 1 {
                    //error
                }
                out, err := exec.Command("/usr/bin/git", "clone", "--recursive", args[0]).CombinedOutput()
                // do stuff with out and err
        }
    }
} 

答案 1 :(得分:3)

如果您自己实现shell并通过exec()直接执行命令或在内部实现它们,那么肯定可以生成安全的受限shell。如果您只是在将命令行传递给真正的shell之前表面上检查它,那么可能会出现您可能不期望的边缘情况。

话虽如此,我有点担心你列出的test命令。是否打算运行用户上传的Go包的测试套件?如果是这样,如果我是攻击者,我甚至不会尝试利用受限制的shell:我只是上传一个包含执行我想要的操作的测试的包。 build / start也可以这样说。

答案 2 :(得分:1)

由测试团队审核。

当打破任何类型的沙箱时,人们可以非常有创意。只有当您从未接受用户的输入时,您才能认为自己在内部非常安全(但此处任何命令都是输入) - 纸质安全假设被认为是评估软件的弱点。它们类似于“没有错误”。对纸上算法的假设:一旦实现它,99%的时间就会出现错误