
MikroTik remote jailbreak for v6.x.x
| / __ _ |/ | | | | | | | | | || | | ( | | ___ | | | || | | || | _ | / _ / _` | | | | || || | ) | || __/ (| | || _/|/ __|_,|
FOISted は、MikroTik の RouterOS における 2 つの認証後脆弱性を悪用するエクスプロイトです。6.34 (2016) から 6.49.6 (最新の v6 リリース) までを実行している RouterOS をリモートで脱獄するために使用できます。
このリポジトリには、x86 で動作するデバイス向けのエクスプロイトスクリプトが含まれています。この脆弱性は他のデバイスバージョンにも存在します。ropchain の作成は読者への演習として残されています :)
詳細については、RouterOS 内部構造に関するブログ記事を参照してください: https://margin.re/blog/pulling-mikrotik-into-the-limelight.aspx
自動実行:
$ python3 exploit.py -H <router_ip> -u <username> -p <password>
その後:
$ nc <router_ip> 1337
エクスプロイトスクリプトは RouterOS のバージョンを自動的に判別し、適切な ropchain を展開します。注: 現時点では x86 の RouterOS のみがサポートされています。
何らかの理由でバージョンが識別されない場合は、次のように明示的に指定できます:
-v <version> # e.g. 6.49.6
6.49.6 (公開時点での最新版) よりも新しい RouterOS バージョンでこれを実行する場合、その RouterOS バージョンはガジェットデータベース (./db) に含まれていない可能性があります。代わりに /nova/bin/www へのパスを渡すと、エクスプロイトスクリプトが ropchain 用の適切なガジェットを自動的に探します:
-f /path/to/nova/bin/www
FOISted は RouterOS v6 の 2 つの脆弱性を利用して、リモートコード実行を可能にします。このセクションでは、RouterOS IPC に関する背景知識を確認し、2 つの脆弱性について説明します。
注: このセクションは、完全なブログ記事 の大部分を省略したバージョンです。詳細はぜひそちらをご確認ください!
MikroTik の RouterOS 内部では、プログラム同士が独自の IPC プロトコルを使用して通信します。
実際のデータパケットは Nova Messages (内部では nv::message) です。これらは疑似 JSON 形式 (6.38 より前) とシリアライズされたバイナリ形式で存在します:

各プロセスは RouterOS システム内で固定アドレスを持ちます。たとえば、/nova/bin/user はアドレス 13、/nova/bin/www はアドレス 70 にあります。さらに、各プログラムは、サブ名前空間内で特定の機能を実装するハンドラを登録できます。たとえば、/nova/bin/user はアドレス 4 に "login" エンドポイントとして機能するハンドラを持ち、他のサービス向けの認証を実行します:

IPC 通信は RouterOS の動作に不可欠な部分です。使用目的は以下のとおりです:
リバースエンジニアリングの過程で、ルーターの動作中に交換されるすべてのメッセージを可視化できる内部メッセージトレーサーツールを作成しました。
次のデモでは、Web インターフェースをページ送りしたときに交換されるすべてのメッセージを確認できます: https://youtu.be/Em1hVWnbzQ4
RouterOS の Web インターフェースは /nova/bin/www バイナリによって実装されています。ただし、特定のページは個別の共有ライブラリに機能を実装する、別々の "Servlet" ライブラリによって処理される場合があります。
たとえば、jsproxy.p サーブレットは /jsproxy へのリクエストを処理し、winbox.p サーブレットは /winbox へのリクエストを処理します、など。
これらのサーブレットは、必要になった 最初の タイミングで /nova/bin/www に読み込まれるライブラリです。たとえば、最初に /jsproxy を読み込んだとき、jsproxy.p ライブラリがメモリ空間にロードされます。
このライブラリのロード処理中に、メッセージトレーサー内で興味深いトラフィックに気付きました:

具体的には、www バイナリ から www のハンドラ #2 に送信されているメッセージを発見しました。これは、RouterOS IPC が同一プロセス内の通信ではなく プロセス間通信 を目的としているため、すでに疑わしいものです...
さらに、2 つの引数が仮想ポインタ (32 ビット x86) であるように見えることに気付きました。これは非常に異例なため、興味をそそられました。
/nova/bin/www のハンドラ #2 内の実際の関数を調べると、これらの種類のメッセージを受信したときに実行される FoisHandler::cmdUnknown という関数が見つかります。
驚くべきことに、この関数はメッセージからパラメータ 0x11 を取り出し、他の 2 つのパラメータを引数として 関数として呼び出します!
つまり、このハンドラに到達する制御されたメッセージを送信できれば、任意の関数を呼び出せます。そしてそこから ropchain にピボットして、より高度なことを行うのはかなり簡単です。
RouterOS のユーザーとして内部 IPC メッセージを送信する方法はいくつかあります。実際、すべての外部クライアントは、認証後に任意のメッセージを送信できます:
8291 でアクセス) -- winbox.exe クライアントで使用これらのインターフェースは初期認証ハンドシェイクの方法が異なりますが、認証されると、ユーザーは任意の Nova Messages を内部システムにプロキシできます。Winbox と MAC Telnet の暗号プロトコルのリバースエンジニアリングについては、ブログ記事 と リポジトリ を参照してください!
このエクスプロイト実装では、通信の主要な手段として WebFig エンドポイントを使用します。リバースエンジニアリングされたクライアント実装については webfig.py を参照してください。
ただし、脆弱な FoisHandler エンドポイントを呼び出そうとすると問題があります:
RouterOS のすべてのハンドラは、どのユーザーがそれを呼び出せるかを指定する "ポリシー" ビットマスクを定義できます。FoisHandler のポリシーは 0x80000000 で、これは内部アクセスのみ (つまり、他のシステムプロセスから発信されたメッセージ) を許可することを示します。
管理者ユーザーとして GUI で設定できる最大権限ビットマスクは 0x7fffe のみであり、これでは不十分です。
これが 2 つ目のバグ、admin から "super-admin" への権限昇格です。
GUI では権限ビットマスクを 0x7fffe にしか設定できませんが、内部では実際には、ビットマスク値を含むフィールドの 1 つを持つ IPC メッセージを送信しているだけです:

つまり、権限ビットマスク値を 0xffffffff に設定した独自のメッセージを偽造するだけでよいのです!
これを行うと、システム内の任意のエンドポイントに無制限にアクセスできるようになります!
このエクスプロイトは、まず FTP 経由で 2 つのファイルをシステムにアップロードします:
stage2: ポート 1337 で待ち受けるリバースシェルスポナーを含むbusybox: 適切なシェル環境を提供する次に、エクスプロイトは権限昇格を実行して、FoisHandler エンドポイントにアクセスできるようにします。
最後に、メッセージに埋め込まれた ropchain にピボットするための細工したメッセージを送信します。ropchain は uClibc 内の chmod と execve のアドレスを計算し、以下を実行します:
chmod 0777 stage2execve stage2stage2 が実行されると、ポート 1337 に接続してシェルを取得できます!
いいえ、これらの脆弱性はどちらも悪用するために管理者資格情報を必要とします。
この脆弱性は、少なくとも 6.27 (ダウンロードできた最も古いソフトウェア) から、最新の v6 である 6.49.6 まで存在します。Web インターフェースは RouterOS v7 でリファクタリングされ、脆弱なハンドラは完全に削除されました。私たちの POC は x86 向けに書かれています。
エクスプロイトスクリプトは、6.34 から 6.49.6 までのすべての RouterOS バージョンに対して動作します (テスト済み!)。