Ptrace と TOCTOU 攻撃

 帰国して、ようやく 404 Blog Not Found:perl - Shibuya.pm #11:The Catcher in the INT 80h が読めるようになった id:kazuhooku です。弾さんのスライドは、FreeBSD 特有の事情と、その問題をカバーしようとするための努力について解説していて、とてもおもしろく読ませていただきました。が、一点、気になったのが TOCTOU (Time-Of-Use Time-Of-Attack) 攻撃への対策についてです。TOCTOU 攻撃とは何か、端的に言うと、

You can't stop the invocation but you can still poke the argument on the stack.

Shibuya.pm #11:The Catcher in the INT 80h

とのことですが、同様のことを攻撃側から行う手法です。より具体的には、防御側のコードがスタック上の引数をチェックしてから、システムコールの実行が始まるまでの間に、別スレッド (あるいは別プロセス) からその値を書き換えることで、サンドボックスの防御機構を回避する攻撃になります*1

 タイミングに依存した成功確率の低い攻撃手法に見えるかもしれませんが、マルチプロセッサ環境であれば、別スレッドから本物と偽物の引数を交互に書き続けることで、1/4 の確率で攻撃が成功するように思われます。また、ユニプロセッサ環境においても ptrace トラップの際にコンテクストスイッチが発生するので、その際に引数書換用スレッドに制御がわたってしまうことも現実にありうると思います。

 スタックに使われるメモリ領域をプロセスで共有する方法としては mmap(2) と POSIX 共有メモリがあり、これらは lleval.cgi ではブロックされているようです。一方、スレッドを作成するためのシステムコール thr_new(2) ? は実行可能のようですので、こちらもブロックしたほうがいいのではないかな、と思いました。

 ひょっとしたら弾さんの環境においては TOCTOU 攻撃は不可能なのかもしれませんが、一般的には OS に関係なく対策が必要な攻撃手法だと思うので、ここで指摘させていただきます。

... まあ指摘するほうは楽なんですけどね。守るのはたいへん ...

*1:FreeBSD の場合、スタックのアクセス順序は逆になるかも