ブログとストーリー

SpiderLabsブログ

年間50万人以上の読者を魅了しているブログがセキュリティ コミュニティの主要目的地になっているのは、最新の脅威の技術的な分析、重要な脆弱性に関する開示、最先端の研究が掲載されているからです。

CVE-2018-2892 - Oracle Solaris におけるカーネルレベル 特権エスカレーション

最近発表した Trustwave アドバイザリー(勧告)で詳述していますが、Trustwave は、Oracle Solaris 10/11 のすべてのバージョンにおいてローカルで悪用可能な問題を発見しました。この問 題はカーネルに存在し、ローカルシステムに Sun StorageTek Availability Suite(AVS)が設定され ている場合、特権を持たないユーザーとしてローカルに悪用されます。

脆弱性

この脆弱性は、根本的な問題が最初に発見され悪用されたのが 2007 年という長い歴史を持つも のです。最初の問題は CanSec 2009 ( https://cansecwest.com/slides.html) のステージで公開さ れました。この問題の根本的な原因は、ユーザ制御の配列インデックスに対する境界チェックの欠 如による任意のメモリ参照の組み合わせと、 copyin() コール時の無制限のユーザ制御可能な長さ の組み合わせです。結合された結果は、 copyin() コール時の任意のメモリ書き込みとオーバーフ ローです。この脆弱性自体は '/dev/sdbc' デバイスの ioctl ハンドラに存在し、脆弱なコードパスは 'cmd' の値が 'SDBC_TEST_INIT' である次のコードを通過します。

common/avs/ns/sdbc/sd_misc.c:
922 static int 923 sdbcioctl(dev_t dev, int cmd, void *arg, int mode, cred_t *crp, int *rvp) 924 {
...
953 switch (cmd) {
...
966 case SDBC_TEST_INIT: 967 rc = _sd_test_init(&args); 968 break;

コードは、以下のように定義された _sd_testing_init(&args) コールを経由します。

common/avs/ns/sdbc/sd_tdaemon.c:
613 int 614 _sd_test_init(void *args) 615 { 616 register struct a { 617 caddr_t addr; 618 long ar; 619 long len; 620 long tsize; 621 long flag; 622 } *uap = (struct a *)args; 623 624 if (copyin(uap->addr, devarray[uap->ar]1, uap->len2)) { 625 return (EFAULT); 626 } 627 dev_tsize[uap->ar]3 = (uap->tsize < 48) ? 48 : uap->tsize; 628 dev_flag[uap->ar]4 = uap->flag; 629 return (0); 630 }

この小さなコードの断片には、少なくとも 4 つの異なる脆弱性が存在します。要約は以下の通りで す。

  1. 任意のメモリ逆参照の結果、任意の宛先ポインタが copyin() に渡される
  2. ユーザーが制御する任意の長さでの copyin() コールの結果、無制限のメモリ書込み
  3. 任意のメモリ逆参照、その結果のユーザ制御可能な書き込み
  4. 任意のメモリ逆参照、その結果のーザ制御可能な書き込み

しかし、この特定の脆弱性の歴史は終わりではありません。2009 年から 2017 年の間に、 Oracle/Sun は uap->ar の値についての境界チェックを追加して問題を修正しようとしました。以 下の逆アセンブリは、Oracle/Sun が適用されているかどうかを確認しています。

Screen Shot 2018-07-17 at 08.24.03

 

見ての通り、 uap->ar の値は 128 以上であってはなりません。しかし、 uap->ar の値が <0 の値 かチェックされていないため、我々は、Oracle/Sun が uap->ar の基本的な型を変更していないこ とも観察することができます。これは、signed long 型であり、このような signedness の問題が存在 するためです。このような攻撃者は、一番上のビットがセットされた(そして負の値を持つ)値を指 定し、境界チェックを渡すことで、任意のメモリを逆参照することができます。パッチの残りの部分 は、uap->len パラメータを 256 未満の符号付き値に制限します(ただし、潜在的に負の値)。

不正利用

この問題の不正利用は、x86(32 ビット)上で実行されている OpenSolaris と x86-64 上で実行され ている新しい Oracle Solaris 11 との間のアーキテクチャの変更を除いて、元の問題について 2007 年に開発されたエクスプロイトとほぼ同じです。ユーザ提供のインデックス uap->ar は負の値で なければなりません。

Image001

最終的な考え

Oracle Solaris の一般的な設定で明らかに悪用可能な問題がなぜ発生するのか疑問に思ってい た場合は、次のようなヒントを参考にしてください。

common/avs/ns/sdbc/sdbc_ioctl.h:
93 #define SDBC_TEST_INIT _SDBC_(5) /* TESTING - tdaemon parameters */ 94 /* 95 * char * device_name; 96 * int index; 97 * int len; 98 * int track_size; 99 * int flags; 100 */

問題のコードは、テストのためのものである可能性があります。

この脆弱性は CVE-2018-2892 で報告されています。
Oracle は、7 月の CPU パッチ・サイクルの一環として、この脆弱性にパッチを当てました。 http://www.oracle.com/technetwork/security-advisory/cpujul2018-4258247.html
さらに詳しい情報は、こちらのアドバイザリで入手可能です。 https://www.trustwave.com/Resources/Security-Advisories/Advisories/TWSL2018-007