システムコール引数の暗号化による コード注入攻撃の防止 大山 恵弘 米澤 明憲 (東京大学) 2004/11/16 第16回コンピュータシステム・シンポジウム コード注入攻撃 バッファ return address 悪意コードを 注入! 011100001011 バッファ 011101010010 110011000100 011011001101 return address 101010110110 … return address を上書き! スタック スタック 注入されるコードの例 unsigned char exploit[]= ... execveのシステムコール 番号11をeaxにセット "¥xb8\x1b\x11\x11\x11" /* movl $0x1111111b, %eax */ "\x2d\x10\x11\x11\x11" /* subl $0x11111110, %eax */ システムコール引数を ebx, ecx, edxにセット "¥x8b\x5d\x08" /* movl 0x8(%ebp), %ebx */ "\x8b\x4d\x0c" /* movl 0xc(%ebp), %ecx */ "\x8b\x55\x10" /* movl 0x10(%ebp), %edx */ "¥xcd\x80"; /* int $0x80 */ システムコール割り込み 提案方式 システムコール番号と引数を暗号化/復号 アプリケーション syscall(11, 12000, 800) 改造libc 暗号化 syscall(39406, 57614, 20881) カーネルモジュール syscall(11, 12000, 0) カーネル 復号 効果 悪意コードが発行するシステムコールは 異常な番号と引数に変わる 攻撃者によるexecveなどの実行が失敗する 悪意コードはエラーで終了する 実装 libcとカーネルモジュールで鍵を共有 プロセス生成時に暗号化の鍵を作成 プロセスごとに異なる鍵を使用 RC4などのストリーム暗号を利用 LD_PRELOADなどを用い、動的リンクする libcを変更する 鍵の生成と共有 アプリケーション fork() 改造libc ここに鍵を保持 p cfork(p) カーネルモジュール cfork(char *buf){ … } • 鍵を生成 • bufとqに鍵を書き込む fork() カーネル ここに鍵を保持 q 制限 return-into-libc攻撃を防止できない 元のlibcを静的リンクしたプログラムでは 暗号化が行われない 巧妙な攻撃コードは鍵を盗める システムコールフックを利用するシステム (デバッガ、トレーサなど)が使えなくなる 関連研究 システムコール表をかきまぜてカーネルを 再コンパイルする スタック上の制御情報(return address等)に 乱数をXORする [Chew & Song ’02] [StackGuard] CPU命令セットを乱数でかきまぜる [Barrantes et al ’03] [Kc et al. ’03] [大澤 et al. ’00] 今後の仕事 オーバヘッドの計測 実際の攻撃コードを用いた実証実験 マルチスレッド、SMPへの拡張
© Copyright 2024 ExpyDoc