为什么 binfmt_misc 不带标志“OC”,而它在没有任何标志的情况下工作?

为什么 binfmt_misc 不带标志“OC”,而它在没有任何标志的情况下工作?

我一直binfmt_misc在 Debian 10 上测试 Linux 的功能,发现将标志设置为“OC”(使用二进制文件而不是解释器的凭据)会导致执行无提示地失败。

下面的POC中,/tmp/test.sh是解释器,qux.go是二进制文件。为什么/tmp/test.sh在没有标志的情况下成功执行,而在带有标志“OC”的情况下却默默地失败?

POC:

$ touch qux.go
$ chmod +x qux.go
$ cat <<EOF >/tmp/test.sh                                                                                                                                                                                                          
> #!/bin/sh                                                                                                                                                                                                                                                                       
> echo Golang                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
> EOF      
$ chmod +x /tmp/test.sh 
$ echo ':golang:E::go::/tmp/test.sh:' | sudo tee /proc/sys/fs/binfmt_misc/register 
:golang:E::go::/tmp/test.sh:
$ ./qux.go 
Golang
$ echo -1 | sudo tee /proc/sys/fs/binfmt_misc/golang 
-1
$ echo ':golang:E::go::/tmp/test.sh:OC' | sudo tee /proc/sys/fs/binfmt_misc/register 
:golang:E::go::/tmp/test.sh:OC
$ ./qux.go # no output

还:

mount | grep binfmt_misc
systemd-1 on /proc/sys/fs/binfmt_misc type autofs (rw,relatime,fd=28,pgrp=1,timeout=0,minproto=5,maxproto=5,direct,pipe_ino=658)
binfmt_misc on /proc/sys/fs/binfmt_misc type binfmt_misc (rw,nosuid,nodev,noexec,relatime)

奖金:

一些资源声称binfmt_misc可用于容器到主机的转义。然而,正如我所见,解释器路径是在chroot容器的文件系统内评估的,并且解释器的执行发生在容器内,即ls -la /显示容器根(而不是主机根)。

资源:

https://www.kernel.org/doc/html/latest/admin-guide/binfmt-misc.html

答案1

您被两个功能绊倒了。

第一个是,当exec失败时,shell 将查看您尝试运行的文件的内容,如果它看起来像 shell 脚本,它会自行解释它。空文件看起来像 shell 脚本。您可以通过运行strace -f ./qux.go(显示失败exec)并通过更改来看到这一点qux.go

$ echo echo Failed Golang > qux.go
$ ./qux.go
Failed Golang

另一个特点是O标志不适用于级联解释器:在你的情况下,qux.go需要一个解释器,但该解释器本身需要一个解释器,/bin/sh因此有两个文件需要解释,test.sh并且qux.go- 但只有一个最终可执行文件可以在模式下处理O。以下作品:

$ cat <<EOF > /tmp/test.c
#include <stdio.h>

int main(int argc, char **argv) {
  puts("Golang");
  return 0;
}
EOF
$ make /tmp/test
cc     /tmp/test.c   -o /tmp/test
$ echo ':golang:E::go::/tmp/test:OC' | sudo tee /proc/sys/fs/binfmt_misc/register
:golang:E::go::/tmp/test:OC
$ ./qux.go
Golang

相关内容