
デバイスのファームウェアコードを調べたい場合があります。 ただし、暗号化されているファームウェア自体は別として、何もありません。 そして、これとリバーサーはどのように生きますか? この記事では、コンピューターサイエンスとロジックの基本的な知識を活用して、ほとんど見込みのない問題を解決することができた実際の状況について説明します。
モデムの製造元の名前は削除され、一部のファイル名は特別に変更されました。これは、問題自体と、それを解決するための興味深いアプローチに焦点を当てたいためです。 ところで、このメーカーのモデムの最新モデルでは、この方法は機能しません。 しかし、他の場合に使用できる可能性があります。
1.構造の定義
ファームウェアファイルの構造を定義することから始めましょう。 1つのモデムには異なるバージョンの3つの更新ファイルがあります。
- v2.8_image.bin
- v3.7_image.bin
- v3.7.4_image.bin
注意深く見ると、3つのファイルはすべて、TLV(Tag-Length-Value)スキームで記述された構造内にあります。 たとえば、
v3.7.4_image.bin
:

すべての値はリトルエンディアン、タグの長さは16ビット、長さ-32ビットです。
ネストの最初のレベルでは、ファイルには0x7240タグのみが存在し、そのデータがファイル全体を占有します。 ネストの2番目のレベル(0x7240タグのデータ内)には、0x0003タグ(0x0Aバイト)、次に0x0000(0x4BDE0Eバイト)、タグ0x0001および0x0002(スクリーンショットに収まりませんでした)があります。 ネストの3番目のレベル(0x0003タグのデータ内)で、0x0002タグがカプセル化され、ファイル030704FFの4バイトバージョン番号が格納されます(すべてのFFを破棄すると、3.7.4になります)。
ネストの第2レベルにある残りのタグ(タグ0x0000、0x0001、および0x0002)内には、個々のファイルの説明が1つのイメージに「パック」されて保存されます。
各ファイルについて、名前(タグ0x0001)、フラグ(タグ0x0002)、サイズ(タグ0x0003)、16バイト値(タグ0x0004)、および実際のファイルデータ(タグ0x0005)が示されます。
ネストの3つのレベルすべてでタグを解析すると、次のような構造になります。

したがって、すべてのコンポーネント(
CPUImage
、
AutoInstall
および
WebUI
)の暗号化されたデータをファームウェアファイルから抽出できます。 判明したように、3つのファームウェアバージョンすべての
AutoInstall
の内容は同じであり、
WebUI
の内部はv3.7とv3.7.4で同じですが、v2.8では異なり、
CPUImage
は各バージョンで一意です。
2.アルゴリズムの推測
3番目のネストレベルの0x0004タグには、エントロピーの高い16バイトのデータセットが含まれています。 このハッシュ値は非常に可能性が高く、最も一般的な128ビットハッシュはMD5です。
抽出されたファイルを見ると、同じオフセットで多くのバイトが一致していることに気付くでしょう。 ここで、たとえば、2つのファイルの始まり(強調された相違点):

ただし、同じファイル内で同じシーケンスを見つけようとしても、長い繰り返しは発生しません。
非常に長い長さの一定のガンマを重ね合わせて暗号化を使用する場合にも、同様の効果が発生します。 そして、そのように機能する最も人気のある暗号化アルゴリズムはRC4です。
3.一定のキーを使用したストリーム暗号に対する攻撃
複数のメッセージが同じキー(したがってガンマ)を使用して暗号化されている場合、それらを一緒にXORすることで、これらのメッセージの断片を発見することができます。 そして、メッセージの1つに0バイトがあった場所では、プレーンテキストがもう1つに表示されます。
AutoInstall
および
WebUI
を取得
WebUI
、興味深い結果が得られます。
00000000:EB 3C 90 6D 6B 64 6F 73 66 73 00 00 02 04 01 00 L <ђmkdosfs☻ 00000010:02 00 02 F8 0F F8 03 00 20 00 40 00 00 00 00 00☻☻sh☼sh@ 00000020:00 00 00 00 00 00 29 29 6E 1F 3B 15 47 43 54 2D 4C)n▼;§GCT-L 00000030:54 45 20 20 20 20 46 41 54 31 32 20 20 20 0E 1F TE FAT12♫▼ 00000040:BE 5B 7C AC 22 C0 74 0B 56 B4 0E BB 07 00 CD 10 * [|¬ "At♂Vґ♫"•► 00000050:5E EB F0 32 E4 CD 16 CD 19 EB FE 54 68 69 73 20 ^lr2dN▬N↓LiuThis 00000060:69 73 20 6E 6F 74 20 61 20 62 6F 6F 74 61 62 6Cはbootablではありません 00000070:65 20 64 69 73 6B 2E 20 20 50 6C 65 61 73 65 20 eディスク お願いします 00000080:69 6E 73 65 72 74 20 61 20 62 6F 6F 74 61 62 6C bootablを挿入 00000090:65 20 66 6C 6F 70 70 79 20 61 6E 64 0D 0A 70 72 e floppy and♪◙pr 000000A0:65 73 73 20 61 6E 79 20 6B 65 79 20 74 6F 20 74 000000B0:72 79 20 61 67 61 69 6E 20 2E 2E 2E 2E 20 0D 0A 00 ry ...♪◙ 000000C0:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ... 00008800:02 43 44 30 30 31 01 00 00 20 00 20 00 20 00 20☻CD001 00008810:00 20 00 20 00 20 00 20 00 20 00 20 00 20 00 20
4.色域の始まりを取得する
現代のセルラーモデムは、接続時に仮想CD-ROMを作成し、そこからドライバーまたは関連ソフトウェアをインストールできます。 おそらく同じ考えがここで使用されました。
ただし、モデムが最新のオペレーティングシステム(Windows 7/8、Linux、MacOS X)に接続されている場合、このCD-ROMはまったく表示されないか、ほんの一瞬表示されてから消えます。 2002年にWindows XPを搭載したラップトップを見つけなければなりませんでした。モデムを接続すると、CD-ROMも表示後すぐに消えてしまいましたが、5秒もかかりました。 この間、論理ボリュームのすべてのセクターを読み取り、サイズ
606 208 == 0x94000
バイトのイメージを取得することができました。これは
AutoInstall
ファイルのサイズに対応します。 読み取られたイメージのMD5値は
897279F34B7629801D839A3E18DA0345
であることが判明しました。これは、このファイルの0x0004タグの値に対応しています。
これで、読み取ったイメージを
AutoInstall
の内容でXORITのままにして、最初の600キロバイトのガンマを取得します。 この色域を使用して、
CPUImage
WebUI
と
WebUI
(それぞれ
WebUI
バイトと
WebUI
バイトの長さ)の始まりを解読でき
WebUI
。
5. FDD画像の再構成
WebUIファイルの先頭(最初の606,208バイト)を解読し、残りをゼロで埋め、すべてをFATイメージとして解釈すると、ファイルシステム構造が表示され、一部のファイルのコンテンツにさえアクセスできるようになります。
名前| サイズ| 日付|時間 bru |フォルダー| 05.31.12 | 22:17 cgi-bin |フォルダー| 05.31.12 | 22:17 cors |フォルダー| 05.31.12 | 22:17 css |フォルダー| 05.31.12 | 22:17 eng |フォルダー| 05.31.12 | 22:17 img |フォルダー| 05.31.12 | 22:17 js |フォルダー| 05.31.12 | 22:17 ru |フォルダー| 05.31.12 | 22:17 name.html | 2248 | 05/31/12 | 22:17 easyXDM.js | 101924 | 05/31/12 | 22:17 easyXDM.debug.js | 113900 | 05.31.12 | 22:17 easyXDM.min.js | 19863 | 05.31.12 | 22:17 easyXDM.Widgets.js | 11134 | 05.31.12 | 22:17 easyXDM.Widgets.debug.js | 11134 | 05.31.12 | 22:17 easyXDM.Widgets.min.js | 3114 | 05/31/12 | 22:17 json2.js | 17382 | 05.31.12 | 22:17 easyxdm.swf | 1758 | 05/31/12 | 22:17 MIT-license.txt | 1102 | 05.31.12 | 22:17
モデムが接続されているときに、ブラウザが
http://< >/dir
のWebインターフェイスにアクセスすると、まったく同じファイルシステムが表示され、任意のファイルをダウンロードできます。
したがって、WebUIディスクイメージを復元するには、Webインターフェースを介してダウンロードしたファイルを、ブートセクタ、FATテーブル、およびディレクトリの説明に従って、必要な場所に分解する必要があります。 唯一の難しさは、ルートの「ru」フォルダーです。 このフォルダー内のファイルの説明を含むクラスターは、最初の606,208バイトに該当せず、その内容を手動で再作成する必要があります。
Webインターフェイスからの情報によると、次のファイルがruディレクトリにあるはずです。
名前| サイズ| 日付|時間 Manualupdate.html | 3981 | 05.31.12 | 22:17 Index.html | 5327 | 05/31/12 | 22:17 Network.html | 3328 | 05/31/12 | 22:17
幸いなことに、ルートには「eng」フォルダがあり、同じ名前と作成日を持つファイルが配置されています。 ruフォルダーの正しいデータを取得するには、修正するだけです。
- 現在のディレクトリの開始クラスタ番号、
- 各ファイルのサイズ
- 各ファイルのクラスター番号を開始します。
ruディレクトリのクラスター番号(0x213)はルートディレクトリにあります。
Webインターフェースからファイルサイズ(3981 == 0xF8D、5327 == 0x14CF、3328 == 0xD00)を知っています。
ファイルの開始クラスターの数を推測する必要がありますが、これはそれほど難しくありません。 ブートセクターの情報によると、各クラスターは4セクターまたは2048バイトを占有します。 「ru」ディレクトリには、1つのクラスターで十分です
Manualupdate.html
および
Manualupdate.html
Network.html
は2つ、
Index.html
3つのクラスターが必要です。 通常、クラスターは空のディスクに書き込むときに順番に割り当てられるため、ファイルはそれぞれクラスター0x214、0x216、0x219で開始されます。 ruディレクトリの復元データは次のようになります。
00000000:2E 20 20 20 20 20 20 20 20 20 20 20 10 00 00 2C AA。 ►へ 00000010:BF 40 BF 40 00 00 2C AA BF 40 13 02 00 00 00 00┐@┐@、┐@☻ 00000020:2E 2E 20 20 20 20 20 20 20 20 20 20 10 00 00 2C AA ..►、to 00000030:BF 40 BF 40 00 00 2C AA BF 40 00 00 00 00 00 00┐@┐@、┐@ 00000040:42 68 00 74 00 6D 00 6C 00 00 00 0F 00 56 FF FF Bh tml☼V 00000050:FF FF FF FF FF FF FF FF FF FF 00 00 FF FF FF FF 00000060:01 6D 00 61 00 6E 00 75 00 61 00 0F 00 56 6C 00 manua☼Vl 00000070:75 00 70 00 64 00 61 00 74 00 00 00 65 00 2E 00アップデート。 00000080:4D 41 4E 55 41 4C 7E 31 48 54 4D 20 00 00 2C AA MANUAL〜1HTM、k 00000090:BF 40 BF 40 00 00 2C AA BF 40 14 02 8D 0F 00 00┐@┐@、┐@¶☻☼ 000000A0:41 69 00 6E 00 64 00 65 00 78 00 0F 00 33 2E 00 Aindex☼3。 000000B0:68 00 74 00 6D 00 6C 00 00 00 00 00 FF FF FF FF html 000000C0:49 4E 44 45 58 7E 31 20 48 54 4D 20 00 00 2C AAインデックス〜1 HTM、k 000000D0:BF 40 BF 40 00 00 2C AA BF 40 16 02 CF 14 00 00┐@┐@、┐@▬☻╧¶ 000000E0:41 6E 00 65 00 74 00 77 00 6F 00 0F 00 98 72 00 An etwo☼Wr 000000F0:6B 00 2E 00 68 00 74 00 6D 00 00 00 6C 00 00 00 k。 html 00000100:4E 45 54 57 4F 52 7E 31 48 54 4D 20 00 00 2C AA NETWOR〜1HTM、k 00000110:BF 40 BF 40 00 00 2C AA BF 40 19 02 00 0D 00 00┐@┐@、┐@↓♪♪ 00000120:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
再構築されたruフォルダーとWebインターフェイスから受信したすべてのファイルのコンテンツをディスクイメージに慎重に収集します(最初のクラスターがセクター0x23に対応することを考慮して)。MD5値が一致するWebUIファイルのプレーンテキストバージョンを取得します。更新ヘッダーからの
48D1C3194E45472D28ABFBEB6BBF1CC6
。
これで、復号化されたAutoInstallファイルとWebUIファイルが作成され、ガンマの最初の2 093 056バイトがわかりました。
6. CPUImageを見てみましょう
CPUImageの最初の2メガバイトを解読した後、最終的に逆アセンブラを実行するのが理にかなっています。 プロセッサコマンドシステム(ARMリトルエンディアン)、ベースロードアドレス(ファイルの最初の0x34Cバイトを破棄する必要があります)を定義し、更新が復号化される場所をローカライズすると、次のコードを確認できます。
ROM:0008ADD0 loc_8ADD0 ROM:0008ADD0 LDR R1、= byte_2ADC60 ROM:0008ADD4 LDRB R2、[R1、R0] ROM:0008ADD8 LDRB R1 [R4] ROM:0008ADDC ADD R0、R0、#1 ROM:0008ADE0 ADD R2、R2、R1 ROM:0008ADE4 ADD R2、R2、R6 ROM:0008ADE8およびR6、R2、#0xFF ROM:0008ADEC LDRB R2、[R10、R6] ROM:0008ADF0 STRB R2、[R4]、#1 ROM:0008ADF4 STRB R1、[R10、R6] ROM:0008ADF8 MOV R1、#0x15 ROM:0008ADFC BL sub_27C0EC ROM:0008AE00 SUBS R11、R11、#1 ROM:0008AE04およびR0、R1、#0xFF ROM:0008AE08 BNE loc_8ADD0
これは、0x2ADC60に位置し、RC4アルゴリズムに0x15バイトの長さを持つ暗号化キーをロードすることに他なりません。 ただし、
0x2ADC60==2'808'928
、つまりキーは、ガンマがわかっている領域の外側にあります。
確かに、最大3つのバージョンの更新プログラムがあります。 突然v3.7またはv2.8で、キーはより良い場所にありますか?
0x2A852C
、以前のファームウェアでは、キーの場所のアドレスは
0x2AD70C
と
0x2A852C
、これも復号化された領域の外にあります:(
7.また、XOR
アップデートv3.7およびv3.7.4 XORからCPUImageを選択すると、アドレス
0x34C + 0x2AD70C == 0x2ADA58
で、「SungKook」James「Shin」という行が見つかります。これは、含まれているすべてのファイルが暗号化されているRC4キーですアップデートに。
このキーで初期化されたRC4出力のガンマが
AutoInstall
および
WebUI
から以前に受信した
CPUImage
一致し、復号化された
CPUImage
MD5が更新ヘッダーの値と一致することを確認する必要があります。
これで、ファームウェア自体の分析を開始できますが、これはまったく別の話です。
Posted by Dmitry Sklyarov、アプリケーションリサーチ責任者、Positive Technologies