シェルスクリプト保護ツール比較:shc vs HimitsuShell(バイナリ化、暗号化、難読化)
shc(シェルスクリプトコンパイラ)は、シェルスクリプトをバイナリに変換してコード漏洩を防ぐツールだ。しかし、実際の運用には次のような限界がある。
- 難読化機能を提供しないため、リバースエンジニアリングに対して脆弱だ。
- システムのシェル(例: /bin/sh)に依存しているため、ロギング/フッキング攻撃に対して脆弱だ。
HimitsuShellは、これを補うために作られた。LLVMベースの様々な難読化技法が適用されており、システムのシェルにも依存しない。
それでは項目別に比較してみよう。
テスト環境
Ubuntu 24.04で以下のシェルスクリプトを使用する。

HimitsuShellはデフォルトオプションで、shcは以下のように最大セキュリティ強度でコンパイルする。
shc -Uf launcher.sh -o shc_binary
以下のように、HimitsuShellとshcで生成したバイナリはどちらも正常に動作する。

デバッグシンボルの削除

HimitsuShellとshcはどちらもデバッグシンボルが削除されている。
動的ライブラリフッキング防御

HimitsuShellは動的ライブラリに依存しないが、shcは依存する。
そのため、shcはフッキング攻撃に対して脆弱だ。
デバッガ検知


HimitsuShellとshcはどちらもデバッガ(例: gdb、strace等)を検知して遮断する。
文字列・定数の難読化


Ghidraで文字列一覧を抽出してみると、その差は明確だ。
HimitsuShellは文字列が難読化されているが、shcで作成したバイナリは機密性の高い文字列がそのまま露出する。
また、HimitsuShellは定数難読化を提供するが、shcは提供しない。
高度な難読化(制御フロー平坦化、ダミーコード挿入等)


Ghidraでmain関数の制御フローグラフを見ると、その差は明確だ。
HimitsuShellは制御フローの把握が事実上不可能なほど難読化されている。
一方、shcは制御フローが単純で解析しやすい。
OSレベルのロギング/フッキング防御

shcで生成したバイナリのシステムコール(例: execve)をauditdで監視すると、シェルスクリプトがそのままログに記録される。
システムのシェルに依存する構造のため、OSレベルのロギング/フッキング攻撃に対して脆弱だ。

一方、HimitsuShellで生成したバイナリは、同一条件下でもシェルスクリプトがログに記録されない。
システムのシェルに依存せず、バイナリに内蔵されたシェルを使用しているためだ。
結論
このように、shcとHimitsuShellはセキュリティ強度の差が明確であることが分かる。
| shc | HimitsuShell | |
|---|---|---|
| デバッグシンボルの削除 | ✓ | ✓ |
| 動的ライブラリフッキング防御 | ✓ | |
| デバッガ検知 | ✓ | ✓ |
| 文字列・定数の難読化 | ✓ | |
| 高度な難読化(制御フロー平坦化、ダミーコード挿入等) | ✓ | |
| OSレベルのロギング/フッキング防御 | ✓ |
追加の比較
shcを改良したsscも存在する。
一部の弱点(動的ライブラリフッキング防御、文字列難読化)は補強されているが、高度な難読化やOSレベルのロギング/フッキング防御には依然として限界がある。
特に、sscはシステムのシェルには依存しないが、実行時に/tmp/ssc/XXXXXXというパスにインタプリタ(例: /bin/sh等)を展開し、そこにシェルスクリプトを渡す。そのため、このパスをロギング/フッキングすればシェルスクリプトの奪取が可能だ。
一方、HimitsuShellはインタプリタをバイナリの外部に展開しないため安全だ。