shell Etcdctl以获取包含bash无效符号的密钥

htrmnn0y  于 2023-03-09  发布在  Shell
关注(0)|答案(1)|浏览(92)

我无法使用Go语言或Python etcd API来执行与etcd的交互。
我需要查询:

env ETCDCTL_API=3 etcdctl --endpoints=server:2379 --cert ca.pem --key ca.key --cacert cacert.pem --command-timeout=60s get $(echo L3ZvdGUvADHd0kmW58d9JqTD8whMYS9vY3Nw | base64 -d)

这将返回:

-bash: warning: command substitution: ignored null byte in input

但单独运行:

echo L3ZvdGUvADHd0kmW58d9JqTD8whMYS9vY3Nw | base64 -d

退货:

/vote/1��I���}&��La/ocsp

问题是什么,我怎么可能逃脱,但仍然保持有效的etcd和GET查询它的关键?

jgzswidk

jgzswidk1#

短篇小说

不幸的是,除非etcdctl扩展为显式支持接受转义内容,并取消转义该内容以获得要使用的键名(或接受通过命令行以外的方式传递的键名),否则传递包含文本NUL的键名是不可能的。
如果您需要这样做的话,可以考虑为etcd编写自己的命令行客户端来接受编码字符串。

背景:程序如何在UNIX上启动程序

当一个程序在UNIX上启动另一个程序时,该过程涉及一个名为execve()的系统调用(或等效程序:还有更高级别的工具,如POSIX spawn()系列,但它们的作用与我们这里的目的类似)。

pid = execve("/usr/bin/etcd", char[][]{
  "etcd",
  "--endpoints=server:2379",
  /* other content here elided */
  "get",
  keyname
}, environment)

因为这个API是用C语言定义的,所以所有字符串都是以NULL结尾的C字符串;它们从单个char*所指向的字符开始,并在该字符后的下一个NUL处结束(因此,当您在C中键入"get"时,它会创建一个类似{"g", "e", "t", NULL}的数组)。
因此,如果你有一个实际上看起来像{"g", "e", "t", NULL, "f", "o", "o", NULL}的东西,那么只有get是从g开始的字符串的一部分;foo中需要有另一个指向f的指针,foo才能被视为一个单独的参数,并且不可能将get\x00foo视为一个字符串,而\x00表示任何编写来与C样式字符串交互的单字节NUL文字。

相关问题