
CVE-2014-0038 向け Linux ローカルルートエクスプロイト
X86_X32 recvmmsg システムコールは、ユーザー空間から渡されるタイムアウトポインタを適切にサニタイズしません。
recvmmsg のタイムアウトとしてカーネルアドレスへのポインタを渡します。そのアドレスにある元のバイトが既知であれば、既知のデータで上書きできます。最下位バイトが 0xff の場合、255 秒待つと 0x00 になります。
渡されたアドレスの最初の long (tv_sec) は正の値で、2 番目の long (tv_nsec) は 1000000000 未満でなければなりません。
非初期化(そのため書き込み可能な)カーネルメモリにある ptmx_fops 構造体の release 関数ポインタをターゲットにします。最上位 3 バイトをゼロにして、ユーザー空間でマッピング可能なアドレスへのポインタに変換します。release ポインタはその後ろに 16 バイトの 0x00 が続くため使用されます(そのため tv_nsec が有効になります)。/dev/ptmx を開き、閉じて、完了です。
あまり美しくはありませんが、シンボルが解決できればかなり信頼できるはずです。
Ubuntu 13.10 でテスト済み
参照: http://blog.includesecurity.com/2014/03/exploit-CVE-2014-0038-x32-recvmmsg-kernel-vulnerablity.html
/proc/kallsyms からアドレスを取得し、エクスプロイトを実行します:
./build.sh && ./timeoutpwn
リモートサーバー用にバイナリをビルドしたい場合は、次のようにします:
ssh user@host 'cat /proc/kallsyms' > syms.txt
CFLAGS=-static ./build.sh syms.txt
scp timeoutpwn user@host:
...
kallsyms に ptmx_fops が見つからない場合は、ヘッダーパッケージ(Arch Linux の linux-headers)に付属する vmlinux から抽出してみてください:
nm /lib/modules/$(uname -r)/build/vmlinux > syms.txt