Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save uchan-nos/cdfc3b920c3e2af883b3d033437a6000 to your computer and use it in GitHub Desktop.
Save uchan-nos/cdfc3b920c3e2af883b3d033437a6000 to your computer and use it in GitHub Desktop.
システムソフトウェアに対する攻撃の歴史と傾向の読書メモ

「システムソフトウェアに対する攻撃の歴史と傾向」の読書メモ

対象記事:システムソフトウェアに対する攻撃の歴史と傾向

サイバー攻撃の始まり

  • 1972 年:バッファオーバーフローのバグを利用した攻撃について公に言及された
  • 1988 年:Morris Worm がバッファオーバーフローバグを侵入のための手段として用いる事で,バッファオーバーフローのバグが実用的な攻撃として認知され始めた
  • 1991 年:Linux 初リリース
  • 1996 年:スタックにシェルコードを配置して任意コードを実行する方法がまとめられた
  • 1998 年:-f-stack-protector が開発される
  • 2001 年:PaX 初リリース

PaX

データ用とコード用のページを分けて,データ用ページからの命令フェッチを禁止するというのが主な機能.

x86_64 アーキテクチャの PAE Paging と 4-Level Paging のためのページテーブルには XD ビット(63 ビット目)がある. このビットを 1 にすると,そのページからの命令フェッチができなくなる.

PaX は ASLR(Address Space Layout Randomization)も提供する.

ページング

仮想アドレス空間を固定長の領域に分割し,それぞれの領域を物理アドレス空間にマッピングする CPU の機能. 仮想アドレスと物理アドレスの変換は CPU の中の MMU(Memory Management Unit)が担当する.

参考 https://www.tutorialspoint.com/operating_system/os_virtual_memory.htm

カーネルへの侵入

カーネルをハックする方法は主に 2 つ

  • カーネルモジュール等の正規の手段を悪用する
  • カーネル自体の脆弱性を利用する

前者の方法として Linux on-the-fly kernel patching without LKM がある. これは /dev/kmem や SIDT 命令を用いる事でユーザーの権限でリアルタイムにカーネルのメモリを書き換える手法.

Linux on-the-fly kernel patching without LKM

IDT はハードウェア,ソフトウェア割り込みに対応するハンドラ(関数)のアドレスが登録してある表.メモリ上に載っている.CPU が割り込みを受け付けると,割り込みベクタ番号に対応するハンドラを起動する.ハードウェア割り込みとしてはキーボード入力割込,タイマ割込,ネットワーク受信割込,などがある.

Linux のシステムコールは,レジスタに必要な値をセットした後 int 0x80 を発行する.これは割り込みベクタ 0x80 に対するソフトウェア割込を発生させる.すると CPU は IDT 0x80 に登録されたハンドラを起動する.このハンドラはシステムコールを受け付けるハンドラになっており,レジスタの値に基づいてシステムコールが実行される.

このハンドラ一つで全システムコールに対応するために,システムコール別の関数表が別途ある.例えば readwrite システムコールの関数アドレスが登録された表だ.この表を書き変えることで,攻撃者はシステムコールを乗っ取ることができる.

IDTR(IDT のあるアドレスを格納してあるレジスタ)の内容を指定した変数にコピー(Store)する命令.この命令を実行すると,IDT の場所が分かる.IDT の 0x80 番目を読めば int 0x80 に対応するハンドラの場所が分かる.後は,そのハンドラの機械語をちょこっと変更し,細工されたシステムコール表を参照させれば攻撃できる.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment