shc(Shell Script Compiler)でスクリプトをバイナリ化(暗号化)する方法
前書き:Shell Scriptの中身を見せたくない
通常の開発業務では、Shell Scriptをバイナリ化(かつ暗号化)する利点はありません。自分しか解読できないShell Scriptは、他のチームメンバにとっては迷惑な存在(負債)になります。
が、Shell Scriptのバイナリ化に全く利点が無い訳ではありません。Shell Scriptのリリース後に発生する面倒事を避けるために、バイナリ化を検討する事もあります。
- 機密保持(顧客にShell Scriptを解読をさせない)
- Shell Scriptの改変防止
本記事では、shc(Shell Script Compiler)を用いてShell Scriptをバイナリ化する方法を紹介します。
検証環境
Ubuntu 21.04、Bash 5.1.4、shc 4.0.3を使用します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
./oydmMMMMMMmdyo/. nao@nao :smMMMMMMMMMMMhs+:++yhs: ------- `omMMMMMMMMMMMN+` `odo` OS: Ubuntu Budgie 21.04 x86_64 /NMMMMMMMMMMMMN- `sN/ Host: B450 I AORUS PRO WIFI `hMMMMmhhmMMMMMMh sMh` Kernel: 5.11.0-31-generic .mMmo- /yMMMMm` `MMm. Uptime: 12 hours, 45 mins mN/ yMMMMMMMd- MMMm Packages: 2830 (dpkg), 11 (snap) oN- oMMMMMMMMMms+//+o+: :MMMMo Shell: bash 5.1.4 m/ +NMMMMMMMMMMMMMMMMm. :NMMMMm Resolution: 2560x1080 M` .NMMMMMMMMMMMMMMMNodMMMMMMM DE: Budgie 10.5.2 M- sMMMMMMMMMMMMMMMMMMMMMMMMM WM: Mutter(Budgie) mm` mMMMMMMMMMNdhhdNMMMMMMMMMm Theme: Yaru-dark [GTK2/3] oMm/ .dMMMMMMMMh: :dMMMMMMMo Icons: ubuntu-mono-dark [GTK2/3] mMMNyo/:/sdMMMMMMMMM+ sMMMMMm Terminal: tilix .mMMMMMMMMMMMMMMMMMs `NMMMm. CPU: AMD Ryzen 5 3400G (8) @ 3.700GHz `hMMMMMMMMMMM.oo+. `MMMh` GPU: AMD ATI 09:00.0 Picasso /NMMMMMMMMMo sMN/ Memory: 10025MiB / 30099MiB `omMMMMMMMMy. :dmo` :smMMMMMMMh+-` `.:ohs: ./oydmMMMMMMdhyo/. |
shcコマンドの概要
shcコマンドは、C言語で実装されたシェルスクリプトコンパイラです(GPL v3)。ARC4で暗号化したShell ScriptをC言語にソースコード中に埋め込み、そのコードをコンパイルする事によってバイナリを生成しています。生成したバイナリの有効期限を設定する事もできます。
以下、「バイナリ化の流れ」と「バイナリ化されたShell Scriptを実行する流れ」です。
- “shc -f $SCRIPT”で指定された$SCRIPTを暗号化
- $SCRIPT.x.cという名称のC言語コード(暗号化された$SCRIPTをコード中に含む)を生成
- $SCRIPT.x.cをコンパイルし、$SCRIPT.xを生成
- $SCRIPT.xの実行時、暗号化された$SCRIPTを復号
- 手順4.の完了後、”sh -c $復号した文字列”を実行
上記の2.と5.の通り、途中でC言語ソースコードに変換されていますが、生成されるのはshellに依存したバイナリです(Shellの-cオプションは、指定した文字列を実行するオプション)
shcコマンドのインストール
Ubuntuの場合は、aptパッケージマネージャーでインストールできます。
1 |
$ sudo apt install shc |
最新版をビルドする場合は、以下の手順です。
1 2 3 4 5 6 7 |
$ sudo apt install git build-essential (注釈) ビルドに必要なツールのインストール $ git clone https://github.com/neurobin/shc.git $ cd shc $ ./configure (注釈) システム環境に合わせた設定 $ make (注釈) ビルド $ sudo make install (注釈) インストール |
shcコマンドのオプション
オプション | オプション引数 | 説明 |
-e | あり | 失効日をdd/mm/yyyy形式で指定 (デフォルト:無効) |
-m | あり | 失効した場合のメッセージ (デフォルト:”Please contact your provider”) |
-f | あり | コンパイル(暗号化)対象のスクリプト名 |
-i | あり | Shellインタプリタへのインラインオプション(例:-e) |
-x | あり | printfフォーマットでコマンドを実行(例:exec(‘%s’,@ARGV);) |
-l | あり | Last shellオプション(例:–) |
-o | あり | 出力ファイル名 (デフォルト:元ファイル名の末尾に”.x”を付与した名前) |
-r | なし | セキュリティを緩和する。再配布可能なバイナリを作る |
-v | なし | コンパイル時の出力を増やす |
-S | なし | rootユーザが実行するプログラムとしてuidをセットする |
-D | なし | デバッグ実行を有効化 |
-U | なし | untraceable(トレース不可な)バイナリを作成 |
-H | なし | 追加のセキュリティ保護(まだ未完成のオプション) |
-C | なし | ライセンスを表示して終了 |
-A | なし | shcコマンドの概要を表示して終了 |
-B | なし | Busybox向けにコンパイル |
-H | なし | ヘルプメッセージを表示して終了 |
shcコマンドによるバイナリ生成の例
今回の例では、ユーザが管理者権限を持つかどうかを表示するスクリプト(shell.sh)をバイナリ化します。shell.shの内容は、以下の通りです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#!/bin/bash function errMsg() { local message="$1" echo -n -e "\033[31m\c" # 文字色を赤に変更 echo "${message}" >&2 echo -n -e "\033[m\c" # 文字色を元に戻す } # isRoot()は、root権限を持つかどうかを確認する。 function isRoot() { if [ ${EUID:-${UID}} != 0 ]; then errMsg "${FUNCNAME[0]}: You are not root." exit 1 fi echo "You are root." } isRoot |
shcコマンドでshell.shをバイナリ化します。-oでバイナリの名前を指定できますが、今回は指定せずにデフォルトの挙動を確認します。
1 2 3 4 5 6 7 8 9 |
$ ls shell.sh (注釈) バイナリ化 $ shc -f shell.sh (注釈) *.xはバイナリ、*.cはバイナリ作成時に生成したC言語ソースコード $ ls shell.sh shell.sh.x shell.sh.x.c |
オリジナルスクリプトとバイナリの実行結果を比較します。同じ結果です。
1 2 3 4 5 6 7 8 9 |
$ ./shell.sh isRoot: You are not root. $ ./shell.sh.x isRoot: You are not root. $ sudo ./shell.sh You are root. $ sudo ./shell.sh.x You are root. |
ロシア人と国際結婚した地方エンジニア。
小学〜大学院、就職の全てが新潟。
大学の専攻は福祉工学だったのに、エンジニアとして就職。新卒入社した会社ではOS開発や半導体露光装置ソフトを開発。現在はサーバーサイドエンジニアとして修行中。HR/HM(メタル)とロシア妻が好き。サイトに関するお問い合わせやTwitterフォローは、お気軽にどうぞ。
1件の返信
[…] shc(Shell Script Compiler)でスクリプトをバイナリ化(暗号化)する方法 […]