【问题标题】:How to minify/obfuscate a bash script [closed]如何缩小/混淆 bash 脚本 [关闭]
【发布时间】:2012-04-12 00:38:48
【问题描述】:

当然,bash 文件不能真正被混淆,并且始终是可读的。而且我不想将它们包装在一些二进制包中。 而且重命名局部变量也不值得麻烦。

但是是否有一个可靠的简单 bash 混淆器或压缩器,它至少可以删除所有缩进、所有空行和所有空格而不会破坏任何内容?尤其是 cmets 和脚本中可能包含敏感文档或信息的注释部分?

我害怕使用简单的 grep/sed-lines 来执行此操作,因为“HEREDOCs”当然不能被修改,因此需要进行一点真正的解析。

也许有一个工具可以做到这一点,那就太好了!

【问题讨论】:

  • 有很多这样的 css/javascript 文件工具,也许你可以根据你的需要调整其中的一个。有相当多的 bash 脚本可以完成这项任务。
  • 你会考虑一个现成的工具来加密脚本然后为你打包成二进制文件吗?
  • 我专门写了“而且我不想将它们包装在一些二进制包中”。但是,其他人当然可能对此感兴趣。请注意,任何加密都是毫无意义的,很容易被逆向工程。例如一个简单的 strace 将在将其传递给 bash 执行时显示已执行的脚本

标签: bash shell obfuscation minify


【解决方案1】:

基于 c00kiemon5ter 的想法,这里有脚本

你扭曲的递归思维会喜欢它,因为这不是原始脚本,而是混淆(obfuscated(original))

#!/bin/bash
#
# Usage:
#     obfuscate scrript.sh > script_obfuscated.sh
#
PIXIE=$(mktemp)
base64 -d  >${PIXIE}<<DIXIE
IyEvYmluL2Jhc2ggClBJWElFPSQobWt0ZW1wKQpiYXNlNjQgLWQgID4ke1BJWElFfTw8RElYSUUK
SXlFdlltbHVMMkpoYzJnS2FXWWdXeUFnTFdZZ0lpUXhJaUJkSUFwMGFHVnVDbU5oZENBOFBGQkpX
RWxGSUFvaklTOWlhVzR2WW1GegphQ0FLVUVsWVNVVTlYQ1FvYld0MFpXMXdLUXBpWVhObE5qUWdM
V1FnSUQ1Y0pIdFFTVmhKUlgwOFBFUkpXRWxGQ2lRb1ltRnpaVFkwCklDUXhLUXBFU1ZoSlJRcHpi
M1Z5WTJVZ1hDUjdVRWxZU1VWOUNuSnRJQzF5WmlCY0pIdFFTVmhKUlgwS1VFbFlTVVVLWlhocGRD
QXcKQ21acENtTmhkRHc4VGtWU1JBb2dJQ0IxYzJGblpUb2diMkoxYzJOaGRHVWdjMk55YVhCMENn
b2dJQ0JYYVd4c0lHZGxibVZ5WVhSbApJQ0p6WTNKcGNIUXViMkp6YUNJS1RrVlNSQW89CkRJWElF
CnNvdXJjZSAke1BJWElFfQpybSAtcmYgJHtQSVhJRX0K
DIXIE
source ${PIXIE}
rm -rf ${PIXIE}

【讨论】:

  • 去掉“rm -rf ....”查看原脚本
【解决方案2】:

这是我为缩小 bash 脚本创建的工具:https://github.com/precious/bash_minifier - 它会尝试删除所有 cmets 和尽可能多的空格/制表符/换行符。它也可以在 https://bash-minifier.appspot.com/ 处作为服务提供。

要缩小 bash 脚本,请运行以下命令:

python minifier.py /path/to/shell/script.sh

【讨论】:

  • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review
  • @hivert,添加了启动minification脚本的命令(脚本本身大到可以在这里插入,可以在github上找到)
  • 非常感谢!你是第一个真正考虑 heredocs 的人 :-) 看起来很有希望。
  • 干得好!!它看起来比我一起破解的更简单和健壮。继续加油!
  • 这样做的重点是使脚本不可读。如果用户仍然看到源代码,那么它就没有达到目的。
【解决方案3】:

原文件script.sh:

#!/usr/bin/env bash
echo "foo"

创建other.sh

$ echo '#!/usr/bin/env bash' > other.sh
$ echo "echo '$(base64 script.sh)' | base64 -d | sh" >> other.sh
$ chmod +x other.sh

结果(cat other.sh):

#!/usr/bin/env bash
echo 'IyEvdXNyL2Jpbi9lbnYgYmFzaAplY2hvICJmb28iCg==' | base64 -d | sh

试试:

$ ./other.sh
foo

【讨论】:

  • 简单明了,完美运行。感谢分享
  • 这有点太计划了,以至于任何人都可以在没有| sh 的情况下运行并获得脚本的完整代码。例如,echo 'IyEvdXNyL2Jpbi9lbnYgYmFzaAplY2hvICJmb28iCg==' | base64 -d。我认为如果后面的两个命令以某种方式被混淆,那将不那么明显
【解决方案4】:

shell 脚本的缩小和混淆是两个不同的东西。

缩小意味着通过从源代码中删除所有不必要的字符而不改变其功能来减小脚本的大小。另一方面,混淆意味着使脚本难以阅读,如果不是不可能的话。

缩小:

要缩小大脚本,您可以针对要缩小的实际脚本运行以下代码:

#!/bin/sh
Script=${1}
if [ ! -z "${Script}" ] && [ -f ${Script} ] ; then
        CurrenTime=$(date | sed -e 's~ ~_~g' -e 's~:~~g')
        cp ${Script} ${Script}_${CurrenTime}
        #### Remove all empty lines
        #### Remove lines that begin with spaces and a comment sign #
        #### Remove all comment lines (meaning, lines that begin with a "#")
        awk '
                (/.*/ || /#!/) && (!/^#$/) &&
                (!/^#[[:blank:]]/) && (!/^#[a-z]/) && 
                (!/^#[A-Z]/) && (!/^##/) &&
                (!/^\t#/) && (!/^[[:space:]]*$/) &&
                ( /^#.*!/ || !/^[[:space:]]*#/)
        ' ${Script} | sed 's_^[[:space:]]*__g' > ${Script}.tmp 2>/dev/null
        #' ${Script} > ${Script}.tmp 2>/dev/null (comment out the above line and uncomment this line if your HEREDOCS are affected)
        ExitCode=$?
        if [ ${ExitCode} -eq 0 ] && [ -s ${Script}.tmp ] ; then
                echo
                echo "SUCCESS: Your newly [ minified ] script can be found here [ ${Script}.tmp ]."
                echo "Review the script [ ${Script}.tmp ] and if happy with it, replace your original script with it!"
                echo "NOTE: Your original script [ ${Script} ] was backed up as [ ${Script}_${CurrenTime} ]!"
                echo
                exit 0
        else
                echo
                echo "FAILURE: Unable to [ minify ] the specified script [ ${Script} ]!!!"
                echo
                exit 2
        fi
else
        echo
        echo "USAGE: ${0}  <your-script>"
        echo
        exit 3
fi

注意,只有当被缩小的脚本很大时,缩小才会产生影响……几百甚至几千行。我能够使用上面的代码从脚本中删除几兆字节。

混淆:

完成上述缩小后,如果您想要缩小尺寸,您可以直接停在那里。但是,如果在缩小之后,您还希望混淆您的脚本,您可以选择。

混淆脚本的最简单方法是使用 Openssl 等加密工具。

To encrypt your script using Openssl:

    1. cat <your-script> | openssl aes-128-cbc -a -salt -k "specify-a-password" > yourscript.enc

    OR

    2. openssl aes-128-cbc -a-salt -in <path-to-your-script> -k "yourpassword"

To decrypt a script using Openssl (notice the '-d'):

    1. cat yourscript.enc | openssl aes-128-cbc -a -d -salt -k "specify-a-password" > yourscript.dec

    OR

    2. openssl aes-128-cbc -a -d -salt -in <path-to-your-script> -k "yourpassword" > yourscript.dec

加密/混淆:

  1. 如果您的最终目标是让其他人难以阅读您的脚本,请尝试 pasting it here 为您生成加密副本。
  2. 如果您对 SHC 改变主意,最新版本可以是downloaded here

【讨论】:

    【解决方案5】:

    尽管这是一个老问题,但它似乎在 Google 上很受欢迎。我也在寻找一个 bash minifer/obfuscator,但不喜欢答案中的那个。

    我也不想添加乱码,也不想编译脚本。所以我写了一个在 Perl 中做我想做的事,并将它放在 GitHub 上 https://github.com/Aralhach/bashobfus/tree/master
    它可以:

    • 扁平缩进
    • 删除整行 cmets(除了最初的 hashbang (#!))和空行
    • 重命名基本声明中的所有 小写 变量(以避免重命名 PATH 等变量)、for 循环、数组访问和“读取”语句。

    在某些情况下它可能会失败,但我用一个相当大的 bash 脚本对其进行了测试,并弹出了列出的变量替换案例。它还将变量单独保留在单引号 (') 中 --在打印 AWK 脚本时会弹出此内容--但在单引号 (') 之间替换语句已经在双引号 (") 内 --在打印 MySQL 语句时弹出此语句

    这让我觉得我已经涵盖了所有重要的用例,但我之前错了。如果您发现任何错误,请随时报告(或修复它们!:D)。我也在考虑添加一个功能,用“;”将短线连接成一个。但是案件太多了,在我的截止日期前无法分析。

    我希望人们觉得它有用!

    【讨论】:

    • 干得好!我会尽快尝试的。到目前为止的一条评论:它看起来不支持 heredocs。您可以在 bash en.wikipedia.org/wiki/Here_document#Here_strings
    • 我不知道 heredocs!感谢您的链接!我确实尝试了这个 bash 代码:$ test='one' \n $ tr a-z A-Z &lt;&lt;&lt; $test \n ONE $ 所以看来应该进行变量替换。我没有考虑其他
    【解决方案6】:

    :P 这里有点搞笑。

    假设你的脚本被命名为origin,而被混淆的脚本被命名为obsf

    这里是origin:

    #!/bin/sh
    echo "fooo"
    

    这里是obsf

    $ echo "echo $(base64 origin)" > obsf
    $ cat obsf
    echo IyEvYmluL3NoCmVjaG8gImZvb28iCg==
    $ chmod +x obsf
    

    现在rm origin 并像这样运行obsf

    $ sh obsf | base64 -d | sh
    fooo
    

    嘿:3

    【讨论】:

    • 我不明白这应该是什么。 “base 64 encrypt”脚本是愚蠢的。我只是想摆脱原始脚本中的 cmets 和其他有用的东西。
    • 问得太晚了,我收到“非法变量名”。加密原始文件时出错,任何线索?????
    • 但这就像你“加密”了脚本,只是你没有使用密码? :>,确实很有趣xD
    • 问题在于您无法将参数传递给脚本。除非你使用 bash -s
    • @Christian 问题说“混淆”。这是这样做的。显然这不是真正的加密,但如果你只是想防止随意和不知情的窥探者......我喜欢这个!
    【解决方案7】:

    混淆shell脚本的工具: http://www.comp.eonworks.com/scripts/obfuscate_shell_script-20011012.html

    这样做有点傻,但这取决于你。还有一些方法可以将您的 shell 脚本“编译”成可执行文件。这个post's 接受的答案提供了几个链接,其中包含执行此操作的工具。

    【讨论】:

    • 感谢您找到这个。但我不想添加乱码,我只想剥离一些东西。这个下载的本质似乎是这样的: sed -e '2,$ {/^ *$/d ; /^ *#/d ; /^[ \t] *#/d ; /*^/d ; s/^[ \t]*// ; s/*[ \t]$// ; s/ $//}' $tmp_2 > $tmp_1 我认为这是坏的,因为它不处理 HEREDOCS。不过还是谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-23
    • 1970-01-01
    • 2020-07-04
    • 1970-01-01
    • 2017-09-19
    • 1970-01-01
    相关资源
    最近更新 更多