パスワードを忘れた? アカウント作成
5643 story

オーバフローを防げ:「exec-shield」 24

ストーリー by Oliver
多数の手段の積み重ね 部門より

Anonymous Coward曰く、 "exec-shieldのアナウンス文 (日本語訳)によるとLinux/x86向けにカーネル・ベースの新たなセキュリティ機構「exec-shield」のソースパッチが公開されました。公開されいるパッチは、カーネルは2.4.21-rc1を対象にしていますが、他のバージョンの対応も簡単にできるのではないかと思われます。
概略:根本的な考え方として、スタック(メモリ―)だけでなく仮想メモリも含め幅広くチェック機能をカーネルレベルで実現しようというもののようです。効率を第一に考えられているようで、システム・コール(PROT_MMAP)ごとの監視のためのオーバーヘッド(2サイクル)、コンテキスト・スイッチングごとに 2, 3サイクルが消費されるという設計になっているようです。また、あらゆるタイプの攻撃に対応しているものでは無いようなで、過信は禁物でしょう"

実行可能/不可能がページ単位で設定できないのはIA32(x86)の大きな弱点だ。そこで、それが設定可能なセグメントの管理を動的に行って、アプリケーションの再コンパイルなしに、スタックを実行不可にする、というパッチだ。さらにライブラリがロードされる仮想アドレスを工夫して、(0x00が表現できない)ASCII文字を使ったバッファオーバフローではライブラリのルーチンへジャンプが難しくなっている。

この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。
  • exec-shield (スコア:1, 参考になる)

    by Anonymous Coward on 2003年05月07日 20時59分 (#311331)
    テックスタイル [techstyle.jp]で配信されてきた。「最新号のハイライト」にも書いてある。
  • trampoline code (スコア:1, 参考になる)

    by Anonymous Coward on 2003年05月07日 23時05分 (#311381)
    スタック領域が実行可能になっているのは、IA32の制限の他にも、スタック上にtrampoline code(シグナルハンドラから復帰する際に実行されるコード)を作る必要があるからという理由もあります。

    そのあたりがこのパッチでどう解決しているのかと思ったら、特定アドレスで起こしたsegmentation faultがsigreturnとして機能するなんて仕組みになってるんですね。豪快というか泥臭いというか…。
  • by yosshy (3545) on 2003年05月07日 23時18分 (#311387) 日記
    文字列で '\0' が表現できない(文字列終端を示す)から不可能、という部分ですが、URL のエスケープ文字で %00 とした場合にどうなるんでしょうね?
    レアケースになるでしょうが、デコード後に '\0' になり、その時点でバッファオーバーフローが起き得る Webサーバであればアウトではないでしょうか。

    ただ、外部からのバッファオーバーフローの大半のケースにおいて効果が期待できるし、Oracle みたいな商用アプリケーションも恩恵を受けられるので、この実装は大歓迎です。
  • まあ、しょうがないか。
    --
    まつもと ゆきひろ /;|)
    • by Anonymous Coward on 2003年05月08日 3時33分 (#311468)

      トランポリンコードに対しては、Solar Designer(OpenWall) と同じ ELF拡張ビット があって、バイナリごとに制限を無視 させられるんですが、それではダメですか?

      OpenWallでは、そもそも JAVA自体が、これを設定しないと動かない はずなんですが…

      --
      大外しかもしれないのでAC~って最初からアカウントないやん

      親コメント
  • by Anonymous Coward on 2003年05月07日 20時59分 (#311330)
    > ライブラリがロードされる仮想アドレスを工夫して、
    > (0x00が表現できない)ASCII文字を使ったバッファオーバフローでは
    > ライブラリのルーチンへジャンプが難しくなっている。

    わたしゃix86のアセンブラ知らないのですが、間接ジャンプ命令だけで、回避できませんか?この対策。
    • by Anonymous Coward on 2003年05月08日 20時33分 (#311828)
      間接ジャンプで何とかなりそうな感じはしますね。
      あと、コードを持ち込むのではなく、コードの一部をスキップさせたりは簡単にできそうな気がします。

      たとえば、何らかの認証をするプログラムでバッファオーバーフローがあったとします。

      0x00123456 : 認証関数をコールしてる所のアドレス
      0x00123478 : 認証OKの場合の処理のアドレス

      という形で、認証関数で次のようにバッファが取られている場合

      char buf[10];

      スタックは

      低位←  →高位
      buf[10] 0x00123456

      となっているはず。(かなり省略してますが)
      ここで、buf[10]に14byte書き込んで直後の0x00123456を0x00123478に書換えできれば認証をスルーする事ができる(事にする)

      この書換えが本当にできるかどうかですが、x86というかリトルエンディアンの場合、0x00123456は0x56 0x34 0x12 0x00という順番でメモリ上にあるので、0x78 0x34 0x12 0x00 が書ければ良い訳ですが、0x00が明示的に書けなくてもASCIIZ文字列(文字列の終端が\0)である、たとえばC言語などでは、0x78 0x34 0x12まで書いたら、勝手にその後に0x00を補ってくれてしまいます。
      ですから、それ程難しい話ではないような予感。

      親コメント
      • by Anonymous Coward
        あ、ちなみにこれは、元記事の「制限」の所に
        しかし、スタック内のリターン・アドレスやヒープ内の関数 ポインタを狙った純粋なオーバーフロー攻撃はすべて阻止できると思う。
        とあったので、「そうでもないんじゃない?」という事で書いてみました。
        元ACさんの「間接ジャンプで・・・」というのとは別の話ね。
    • by Anonymous Coward
      > 間接ジャンプ命令だけで、回避できませんか?この対策。

      常にオーバーフローが起こるスタック上のアドレスが固定ならね。
    • by Anonymous Coward
      不正コードがどこにロードされるか(また実行されるか)というと
      スタック・ヒープのどちらかです。
      このどちらかがくだんのASCII-armor領域になければ、セグメンテーションを利用してジャンプ命令を実行させないことはできるのでは。
typodupeerror

Stay hungry, Stay foolish. -- Steven Paul Jobs

読み込み中...