ソースコードを公開するわけじゃないしAWSの認証キーはハードコードしても良いよね。
という事で色々と調べました。
ビルドした実行ファイルは第三者に渡す可能性があるかも、というシチュエーション。
結果
ベタでハードコードした場合
- 中間言語だろうがネイティブコードだろうが即バレ
- 当然ですね。
- ただ、バイナリから抽出した文字列一覧から「コレ、AWSの認証情報だな??」と感じ取るセンスは必要。
難読化して .NET(C#) 中間言語にコンパイルした場合
- 難読化したところで実行ファイルからソースコードを復元出来る可能性が高いので、ちょっとした時間稼ぎ程度。
- とは言え、ソースコードを読む根気と「このアプリ、難読化された認証情報がハードコードされてそうだな」と感じ取るセンスが必要。
難読化してC++等ネイティブコードにコンパイルした場合
- ベタ書きだと実行ファイル内の文字列を抽出すればすぐに見つかる(要根気)
- 難読化しておけばプログラミングちょっと分かる、程度だと解析方法が分からないのでほぼ防げるんじゃ?
- (とりあえず自分には無理だった)
ハードコードを避けて認証キーを .json
ファイル等から読み込む場合
- そういう公式サンプルがあったりするけど、それはそれで難読化やハードコードを行うよりも認証キーが簡単に見つけられる。
- 外部と共有する際はファイルがどう扱われるか分からないので気を付けたい。
- 内々での利用、共有相手ごとに切り替え、またはAWSアカウントは自前で用意してね、を想定したものか。
仮想通貨マイニング用にAWSのアクセスキーを探しまわってるような人らは GitHub を周回しているだろうから、難読化してネイティブコードにしておけば自動化された攻撃の対象になることは回避できそう。
- GitHub に AWS キーペアを上げると抜かれるってほんと???試してみよー! - Qiita
- AWSで不正利用され80000ドルの請求が来た話 - Qiita
- AWSが不正利用され300万円の請求が届いてから免除までの一部始終 - Qiita
🧪 テスト内容
難読化
THE-KEY-MUST-BE-KEPT-IN-SECRET
を以下のツールで難読化。
こんな感じに 👇
#include <iostream>
int main()
{
std::string akqrsysg = "BKB4K0VO2O4oG3USFiHHcvPT-WV0E1";
std::string jelgafbu = "Hewg4Gu3IjgEBmX519rBuw+jZWJRMf";
std::string bbbdnvpg = "5rgmQbimSdy8+THE-kXTYOHcU5Ni7K";
std::string tpyftwhx = "3ooi-bC8mIUHKU9OP9EoIauizbT-V5";
std::string givmqxcq = "5IN-SECR7TFniNjtGDaapzw3ZGPxzW";
std::string bvrsavpv = "kd+lnf7YW-kfyRYc4ww2sH1oc+wEW1";
std::string orrhbnql = "uETqhaxpkMlm4905WDXHaq1PHVI2pi";
std::string mxknirgr = "Pg3crnvKXlcpHdW8Eab8AW7dibqQrF";
std::string pru_kdeu = "AZj12VKEY-MUShtCGfbOjLUPDAlgRE";
std::string mzhpjgcl = "JKEOtV0UxiuRpg4bXvvO-4GYV9uXgh";
std::string xkj_rnuw = "T-BE-KEnez382LWwZfbYELZ93n8on3";
std::string wwjkdzfr = "erxOrO6b-DpZ5fu0rhZPwxqOZrvyoY";
std::string secret = bbbdnvpg.substr(13, 4) + pru_kdeu.substr(6, 7) + xkj_rnuw.substr(0, 7) + akqrsysg.substr(22, 3) + givmqxcq.substr(1, 7) + orrhbnql.substr(1, 2);
std::cout << "Secret Key: " << secret << "\n";
}
ネイティブコード(C++)
ビルドした .exe
から難読化した文字列は見つかる。それぞれ単体では意味を成さないので使い道はない。
これらがどこでどのように使われているのかを .exe
から解析できればアクセスキーは復元されてしまう。
Unity+IL2CPP で C# をネイティブコード化
ゲームエンジンの Unity には C# を C++ に変換してビルドする IL2CPP という機能がある。
そちらを使った場合は、、、👇
コチラも文字列自体は見つかる。
IL2CPPによって Minified(?)されているので、C++の場合より見つけるのが難しい。というか探すべき対象を正確に知らないと見つけられない状態になっている。木を隠すなら森の中。
中間言語(.NET/C#)
文字列抽出
ネイティブコードにコンパイルした場合と同様バイナリデータから文字列を抽出できる。
※ リリースビルドなので未使用のものは消滅している
ソースコードの復元
難読化したところで所詮は中間言語(IL)、ビルドした実行ファイルからソースコードへの復元は容易い。
復元結果: C#コンソールアプリ
復元結果: C#コンソールアプリ(自己完結・単一ファイル)
自己完結(Self-Contained)かつ単一ファイルとしてビルドすれば復元は難しい? と思ったのも束の間、調べたらすぐ復元方法が分かった。
復元結果: Unity+Monoバックエンド
Unity+Mono でのビルドも特に問題なく復元可能。それはそう。
--
データもそうですが、金額的被害があるのが怖いですねー。
以上です。お疲れ様でした。