如何隱藏 shell 腳本內容

從事 Linux 開發的同學,經常需要編寫 shell 腳本,有時腳本中會涉及到一些敏感內容,比如一些 IP 地址,用戶名以及密碼等,或者腳本中有一些關鍵的代碼, 所有這些內容你都不想別人閱讀或者修改,更進一步,你希望對腳本設置過期時間,超過指定時間時間之後,腳本就無法使用

在不改變腳本內容、功能以及執行方式的情況下,有沒有辦法實現上面的需求呢?

答案是:有的, 在 Linux 下,我們可以使用 shc 這個工具來實現隱藏 shell 腳本內容以及設置過期時間的目的

簡介

shc 是一個通用 shell 腳本編譯器,它將 shell 腳本編譯 可執行的二進制文件,它的功能以及執行方式和原始腳本沒有區別

和 gcc 編譯器不同的是,shc 並沒有把腳本源代碼轉化成機器碼,它只是生成了一份 C 語言代碼,這份 C 語言代碼中包含了加密的原始 shell 腳本,併爲它添加了過期功能,然後,通過gcc編譯器將C代碼編譯成可執行的二進制文件

安裝

目前,大多數的 Linux 發行版的倉庫中都已經包含了 shc, 只需要使用默認的包管理器就可以安裝,具體的安裝命令如下:

yum install shc

輸入 shc -v 命令,下面的輸出表示安裝成功

[root@ecs-centos-7 shc_test]# shc -v
shc parse(-f): No source file specified

shc Usage: shc [-e date] [-m addr] [-i iopt] [-x cmnd] [-l lopt] [-o outfile] [-rvDSUHCABh] -f script

常用選項

下面是 shc 常用的一些選項以及選項的描述

lxCkgP

編譯腳本

sehll 腳本編譯成可執行的二進制文件之後,只需要把二進制文件提供給執行者即可,這樣執行者就無法知道原始腳本代碼了,從而實現別人無法閱讀和修改代碼的目的

新建 func.sh 腳本,往其中添加如下內容:

#!/bin/bash

#是否是有效的密碼
valid_passwd()
{
   if [ "$1" == "123" ]; then
        echo 1
   else
        echo 0
   fi
}

#獲取最大數量
max_num()
{
  echo 100
}

#登錄到遠程機器
login()
{
  sshpass -p '123456' ssh test@192.168.70.20
}

#版本號
ver()
{
   echo "1.0"
}

if [ $# -ne 0 ]; then
        
        shift 1
        ${name} "$@"
fi

執行下面的命令,編譯 func.sh 腳本

shc -rf func.sh -o func.bin

編譯完之後,當前目錄下會出現三個文件

[root@ecs-centos-7 shc_test]# ll
-rwxrwxr-x 1 root root 11640 7月   1 00:24 func.bin
-rw-r--r-- 1 root root   373 7月   1 00:19 func.sh
-rw-r--r-- 1 root root 19811 7月   1 00:24 func.sh.x.c

func.sh 是原始的腳本文件,func.sh.x.c 是生成的 c語言代碼, func.bin 是生成可執行的二進制文件,它的使用方法和原始腳本是一樣的

注意: 編譯出來的二進制文件func.bin,如果想讓它在其他機器也能運行的話,一定要指定 -r 選項

使用 file 命令分別查看 func.bin 、func.sh.x.c,結果如下:

腳本對外提供 valid_passwd、 max_num、 login、 ver 這四個接口,腳本中已經註明了每個接口的作用,使用方法是 ./func.bin 接口名 接口參數列表,下面的兩個實例說明了如何使用腳本

分別執行 ./func.bin ver 和 ./func.sh ver 命令,結果如下

從上圖可以看出,無論是用腳本還是二進制,最終的結果都是一樣的

執行 ./func.bin login 命令,結果如下

當傳入 login 參數時,就會執行func.sh腳本中的 login 函數,該函數的作用是使用 SSH 登錄到遠程機器, 函數體中的 sshpass 是一個自動填充 SSH 登錄密碼的工具

從結果可以知道,執行 ./func.bin login 命令之後,就登錄到 ip 爲 192.168.70.20 機器的 /home/test 目錄,後面再輸入 exit 從遠程機器退回到當前機器的目錄

我們把 func.sh 腳本編譯成 func.bin 二進制文件的目的就是要隱藏腳本文件中一些敏感信息,比如:腳本中的 SSH 用戶 test , IP 地址 192.168.70.20 以及密碼 123456

設置過期時間

shc 除了將把腳本編譯成二進制,還能爲二進制設置過期時間,下面還是以 func.sh 腳本爲例來說明

執行 shc -e 25/6/2021 -m "The script is expired, Please contact test@qq.com" -rf func.sh -o func.bin 命令把腳本的過期時間設置爲 2021 年 6 月 25 日,執行過期後的腳本提示語設置爲 "The script is expired, Please contact test@qq.com"

然後,執行 ./func.bin ver 命令進行測試,結果如下

從上圖可以看出,腳本設置過期時間之後,再次執行腳本會提示已經過期了

如何引用二進制腳本

func.sh 編譯成了二進制後,其他腳本引用它的方式也要調整下,原來以 source ./func.sh 的使用方式都需要修改,因爲 fun.sh 已經由原來的 ASICII 文件變成了 二進制文件了,下面給出一個 shell 腳本引用二進制腳本 func.bin 的實例

新建 test_func.sh 腳本,腳本內容如下:

#!/bin/bash

#調用 valid_passwd 函數
ret=$(./func.bin valid_passwd 123)
if [ $ret -eq 1 ]; then
   echo "passwd ok"
fi

#調用 valid_passwd 函數
ret=$(./func.bin valid_passwd 124)
if [ $ret -eq 1 ]; then
   echo "passwd ok"
else
   echo "passwd fail"
fi

#調用 max_num 函數
ret=$(./func.bin max_num)
echo "max_num:"$ret

#調用 ver 函數
ret=$(./func.bin ver)
echo "version:"$ret

執行 ./test_func.sh 命令,結果如下

從上圖可以看出,test_func.sh 腳本分別調用了二進制文件 fun.bin 中的 valid_passwd、max_num、 ver 函數,根據 func.sh 腳本內容,可以確定結果輸出都是正確的

從這個實例可以得出,普通腳本也可以正常使用二進制的腳本

安全性

shc 使用的加密類型是叫做 RC4 流密碼的一個變體,目前它已經被證實存在弱點,存在被破解的可能, 尤其在 shc 中,密鑰被攜帶到加密腳本本身中,所以,是存在 通過反彙編破解出密鑰,進而通過密鑰還原原始腳本的可能性

因此,我們不應該依賴 shc 加密的安全性,而是更多的把它當作是 shell 腳本內容的隱藏或者混淆工具

小結

本文主要介紹了隱藏 shell 腳本內容的工具 shc, 雖然它加密的安全性不高,但是我們平常可以把它作爲一個 shell 腳本代碼隱藏和混淆工具來使用,也能達到我們的目的, 更多關於 shc 的相關知識請參考網上其他資料

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/Br6B6n6RNybkO-RYLq2-0A