通过 在CodeSOD中 关于编辑,今天的故事里有几个WTF。让我们先解决第一个问题:Jan S下载了一个shell脚本,并以root身份运行它,而不需要阅读它。现在,让我们公平地说,这真的是一个相当温和的做法,我们都做过类似的事情,流行的软件工具仍然会告诉你用卷曲的…来安装它们。|sh,然后在脚本中对自己执行sudo额外权限。
本例中安装的软件是用于从Linux访问Bitlocker加密驱动器的工具。这里真正的WTF是安装脚本,我们稍后将深入研究它。然而,这并不是一些业余爱好者拼凑起来的小规模开源项目,而是由Initech的数据恢复业务发布的。在这种情况下,这是一个更大的数据恢复产品的开源核心--如果你愿意胡乱使用低级命令和配置,你可以免费使用,但是如果你想要一个模糊可用的UI,准备好支付40美元吧。
考虑到这一点,让我们来看看剧本。我们将分批进行这项工作,因为几乎每件事都是错的。你可能会认为我夸张了,但这里是剧本的前两行:
这不是您查找用户主目录的方式。我们通常使用${home},或者既然Shebang告诉我们这绝对是bash,我们可以只使用~。Jan还指出,虽然用户名可能不应该有空格,但这是可能的,而且由于${user}没有用引号引起来,所以在这种情况下这一点会中断。
Echo${home_dir}install_dir=$1 if[!-d";${install_dir}";];theninstall_dir=${home_dir}if[!-d";${install_dir}";];则echo";create dir:";${install_dir}mkdir${install_dir}。
谁想要在他们的脚本中缩进呢?如果脚本支持参数,我们应该告诉用户吗?当然不是!。只需检查他们是否提供了参数,如果提供了,我们会将其视为安装目录。
另外,mkdir行可以保护像Jan这样以root身份运行此脚本的用户,至少在他们的主目录是/root的情况下是这样,这是很常见的。当它尝试mkdir/home/root/initech.bitlocker时,脚本在那里失败。
再一次,写这个脚本的人似乎不明白Bash中的双引号是用来做什么的,但真正的魔力是下一段:
ECHO";复制运行时环境...";sudo cp-f./libcrypt.so.1.0.0/usr/lib/sudo cp-f./libssl.so.1.0.0/usr/lib64sudo cp-f./libcrypt.so.1.0.0/usr/lib/sudo cp-f./libssl.so.1.0.0/usr/lib64。
您的系统中是否已经安装了libssl?好了,现在您有了这个版本!希望那对你没问题。我们非常喜欢我们的libssl和libcrypto版本,所以我们将它们复制到您的库目录中两次。他们可能打算将libcrypto和libssl同时复制到lib和lib64,但是搞砸了。
嗯,这是假设您已经有了一个lib64目录,因为如果没有,您现在就有了一个包含来自libssl.so.1.0.0的数据的lib64文件。
这是作为Initech想要销售的产品的一部分发布的一款软件的安装程序,但他们没有成功安装它。
Sudo ln-s${install_dir}/mount t.bitlocker/usr/bin/mount t.bitlockersudo ln-s${install_dir}/bitlocker.creator/usr/bin/create.bitlockersudo ln-s${install_dir}/actiate.sh/usr/bin/initech.bitlocker.actiesudo ln-s${install_dir}/initech.mount t.sh/usr。
嘿,这里是一个没有严重错误的安装步骤,假设没有其他软件包或工具尝试在/usr/bin中声明这些名称,这可能是真的(Jan实际上使用dpkg-S…检查了这一点。以查看是否有任何包想要使用该路径)。
Source/etc/os-release case$ID indebian|ubuntu|devuan)echo";正在安装相关软件包-curl...";sudo apt-get install curl-y echo";安装相关软件包-openssl...";sudo apt-get安装相关软件包-fuse...";sudo apt-get install fuse-y echo";安装相关软件包-gksu...";sudo apt-get安装相关软件包-gksu...";sudo apt-get install fuse-y echo";安装相关软件包-gksu...";sudo apt-get Install Dependent Package-gksu...";sudo apt。
这是我们案件的第一个分支。他们已经学会了缩进。他们已经选择在所有apt-get命令上打上-y标志,这意味着用户不能选择安装这些软件包,这有点烦人。还值得注意的是,来源/etc/os-release可以被认为是有害的,但显然不会造成危害,这并不是本脚本议程上的首要任务。
CentOS|fedora|rhl)yumdnf=";yum";如果测试";$(ECHO";$VERSION_ID>;=22";|BC)";-ne0;则yumdnf=";DNF";FI ECHO";INSTALING Dependent Package-curl...";sudo$yumdnf install-y curl ECHO";INSTALING Dependent Package-。Sudo$yumdnf install-y fuse3-libs.x86_64;
所以,也许他们只是不认为是否支持额外的缩进?他们把箱子缩进得很好。我不确定他们是怎么想的。
说到IF,请仔细查看版本检查:TEST";$(ECHO";$VERSION_ID&>t;=22";|bc)";-ne0。
现在,这几乎是聪明的。如果您的Linux版本号使用十进制值,如18.04.您不能执行简单的if[";$VERSION_ID";-ge22]…。:您将获得整数表达式预期错误。所以使用BC确实是有意义的…。伊什。最好检查一下BC是否真的安装了(很可能是这样,但您不知道),而实际考虑检查的目的可能会更好。
他们实际上并不关心您运行的是什么版本的Redhat Linux。他们重新检查的是您的版本是否使用yum或其后续DNF进行包管理。更可靠的检查是简单地查看dnf是否为有效命令,如果不是,则回退到yum。
因此,如果您的系统没有使用基于APT的包管理器或基于YUM/DNF的包管理器,那么在这一点上就会放弃。没有错误消息,只有一个错误号。你知道它失败了,但你不知道为什么,在你的系统里复制了一堆垃圾之后,它就失败了。
因此,它首先主要安装自己,然后检查是否可以成功安装所有依赖项。如果它失败了,它会清理它所做的更改吗?你最好相信它不会!
ECHO";ECHO";Initech BitLocker Loader已成功安装到";${install_dir}";。";ECHO";运行initech.bitlocker--帮助了解有关Initech BitLocker Loader";的更多信息。
这是一个相当乐观的说法,虽然是的,但理论上它已经安装到${install_dir},假设我们已经做到这一点,它实际上已经安装到您的/usr/bin目录中。
对我来说,真正特别之处在于它与您的包管理器交互来安装依赖项。但是它也安装了自己版本的libcrypto和libssl,它们不是您的包管理器提供的。忽略了这样一个事实,即它可能*将它们安装到了错误的位置*,这看起来很糟糕。可疑的,坏的,令人不安的。
Jan没有给我们发送卸载脚本,老实说,我认为没有脚本。但是如果有,您知道它可能试图在那里的某个地方执行rm-rf/${SOME_VAR_THE_PROSE_BE_EMPTY}。考虑到,这可能是卸载此软件的最安全方式。
[广告]让老百姓远离生产。使用ProGet限制NuGet订阅源权限。了解更多。
Eyalnesher(未注册)如果这只是安装脚本,想想实际的产品可能有多可怕。
Foo AKA Fooo(未注册)为每个命令调用sudo,而不是以root身份运行一组语句(或者,更确切地说,是整个脚本)。通常,sudo被配置为缓存凭据几分钟,但如果不是,这将多次询问您的密码和/或在您的日志中生成大量警告。
首先假定固定的发行版名称。现在存在着更多的发行版。就像DNF vs Yum一样,他们可以只检查apt-get是否在那里。
创建从/usr/bin到$install_dir的符号链接(它可能是用户的主目录,其他用户甚至无法读取)。这不是它该怎么做的。或者将可执行文件本身放在那里,或者如果您对该层次结构不满意,可以使用/opt。
这就是说,自由党的事情没有想象的那么糟糕(无论如何也不是说没关系!)。因为它们只(覆盖)完全版本化的名称(*.so.1.0.0),而不是*.so链接,所以它们不会真正破坏另一个已安装的版本。但可以肯定的是,没有理由不通过软件包管理器安装它们。