我一直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