
Sagemcom F@ST 3890 ケーブルモデム向けエクスプロイト。Cable Haunt 脆弱性を実装し、WebSocketベースのバッファオーバーフローとROPチェーンを介してリモートコード実行を実現します。
このエクスプロイトはCable Hauntの脆弱性を利用して、ローカルネットワークからSagemcom F@ST 3890(50.10.19*)ケーブルモデムにシェルを開きます。ファームウェアバージョン50.10.21以降はCable Hauntに対して安全であるはずです。このProof of conceptは、悪意のある目的に利用される可能性を制限するために、ローカルのみで動作するように特別に設計されています。Technicolor TC7230を対象として、外部接続へのリバースシェルを作成する別のPOCはこちらで入手できます。
既知の脆弱なモデムのリストは https://cablehaunt.com/#faq-am-i-affected にあります。
exploit.pyはWebサイトをホストし、そのサイトを訪問すると、ケーブルモデムへ悪意のあるWebSocketリクエストが送信されます。
このリクエストは、ケーブルモデムのスペクトラムアナライザ内のリターンアドレスと付随するレジスタをオーバーフローさせ、ROPチェーンを使用してポート1337でTCP接続の待受を開始します。
ROPチェーンは static/exploitSagemcom.js 内で構築され、コメントが付けられています。
その後、exploit.pyサーバーはこのTCP接続を介して exploit.raw ファイルを送信し、モデムによって実行されます。
exploit.raw ファイルは、MIPSアーキテクチャ用にコンパイルされた reverseshell.c です(方法は後述)。
Reverseshell.c は、このモデム専用に書かれたシェルです。このシェルは、ケーブルモデム上のeCosシェルで実行するコマンドを待ち受け、STDOUTをTCP接続にリダイレクトします。
このエクスプロイトを説明する動画はこちら: https://www.youtube.com/watch?v=5FM9mS5ck3Y
注: Windows 10は現在サポートされていません。LinuxベースのOSを使用する必要があります
python3用にpwntoolsとflaskをインストールし、python exploit.py を実行します。
次に、ブラウザで http://127.0.0.1:8080 にアクセスして、モデムを攻撃します。
使用されているWebSocketバージョンに互換性がないため、Firefoxでは動作しません。
これで、pythonスクリプトを実行しているターミナルにインタラクティブシェルが表示されるはずです。 シェルを終了した場合、新しいシェルを開始するにはモデムの再起動が必要です。
独自のペイロードをコンパイルしたい場合は、aeolus からツールチェーンを取得して、次のコマンドを実行します。
/<toolchain Path>/gnutools/mipsisa32-elf/bin/mipsisa32-elf-gcc -O3 -c ./reverseshell.c -o ./reverseshell.o && /<toolchain Path>/toolchains/gnutools/mipsisa32-elf/bin/mipsisa32-elf-objcopy -O binary reverseshell.o exploit.raw
この手法を使用して、Cable Hauntに対して脆弱な任意のモデムをビルドして攻撃できます。 独自のROPチェーンを記述する前に、技術レポートを読むことをお勧めします。 既知の脆弱なケーブルモデムのリストについては、Cable Haunt を参照してください。
まず、攻撃対象のケーブルモデム用のファームウェアが必要です。 次に、ファームウェアをリバースエンジニアリングして、シェル用のsocket()、bind()、accept()、listen()、recv()、connect() など、エクスプロイトの構築に関連する関数のアドレスを見つけます。 その後、Ropper を使用して、次のコマンドでガジェットを見つけることができます。
python Ropper.py --type all --all --badbytes 00c0c1f5f6f7f8f9fafbfcfdfeff2c -r -a MIPSBE -I 0x80004000 --console -f <firmware path>
すべてのガジェットに到達できるわけではありません。ガジェットは生のバイトとして送信される単なるアドレスであり、テキストフレームを持つWebSocketリクエストではすべてのバイトを送信できるわけではないためです。
たとえば、アドレス 0x8080a864 は有効なUTF-8文字ではないため、WebSocketテキストフレームに直接挿入することはできません。ただし、アドレス 0xf28080a864 は挿入できます。0xf2 は、0x8080a864 を後続バイトとする新しいUTF-8シンボルの開始を意味するためです。
UTF-8仕様により、どのアドレスにも次のバイトを含めることはできません: 0x00、0xc0、0xc1、0xf5、0xf6、0xf7、0xf8、0xf9、0xfa、0xfb、0xfc、0xfd、0xfe、0xff、0x2c。その他の制限もあり、これらはレポートで間もなく詳しく説明される予定です。
現時点では、utf8TestScript.py を読んで使用し、アドレスが到達可能かどうかをテストできます。
上記のプロセスを使用して、新しいケーブルモデム用の独自のペイロードをコンパイルできますが、ペイロードはリターンしてはならないことに注意してください! リターンした場合、プロセスは破壊されたスタック上のリターンアドレスを探し、クラッシュします。
ほとんどのモデムでは、ファームウェアを抽出するため、またはフラッシュチップから直接抽出するために、eCosシェルにアクセスする方法が必要になります。 これらのファームウェアは通常、ProgramStore と呼ばれる形式でパックされています。 シリアルコンソールが機能しない場合は、次のコマンドを実行してみてください(同軸ケーブルが切断されているか、プロビジョニングされていない場合にのみ機能する可能性があります):
snmpset -v2c -c private 192.168.0.1 1.3.6.1.4.1.4413.2.2.2.1.9.1.2.1.0 i 2
snmpset -v2c -c private 192.168.0.1 1.3.6.1.4.1.4413.2.2.2.1.9.1.2.1.0 i 0
snmpset -v2c -c private 192.168.0.1 1.3.6.1.4.1.4413.2.2.2.1.9.1.2.1.0 i 2
その後、シェルにアクセスできるようになり、bcm2-utils を使用すると、このシェルを使った抽出が簡単になります。 抽出したファームウェアをリバースするとき、ロード/ベースアドレスは(私たちが見た限りでは)常に 0x80004000 です。