Security Camp2021
Z-VI
“Zipper Stack”をRISC-V上に実装する
2021/09
About Me
“Zipper Stack”
前提①
・アセンブラ(機械語)の命令フロー
・関数単位で命令が大きくジャンプしていく
・リターン先のアドレスはStackに保存される
・ret(return)命令がそれを拾う
・Return-Oriented-Programming(通称ROP)は
リターンアドレスを破壊し、攻撃してきた
ex) X86 architecture
push ebp
mov ebp, esp
sub esp, N
~
mov esp, ebp
pop ebp
ret ←ROP says Exploitable!
前提②
・Intel がShadow Stackの実装の発表
・隠しスタックを作成してリターンアドレスを2重に保存する
・ret時にその完全性を保証する
・つまりROPに対するハードウェアレイヤからの直接的対策
(link:Intel CETが、みんなの恋人ROPを殺す)
So What What
ZipperStackはShadow Stackを踏まえて、以下の特徴を持つ
・メモリ空間を必要とする隠しスタック領域を用いない
・リターンアドレスを入力したhash値を隠しレジスタに保存する
・さらに前回のhash値も連鎖的に混ぜていく
・Shadow Stackより大きい文脈単位の安全性をより小さいメモリ利用で実現する
謂わばShadow Stackの亜種的な機構
参照した論文:https://arxiv.org/abs/1902.00888
この論文の再現実装を行った、というのがつまるところ今回の発表
Architecture
RISC-V emulator
新たに2つの命令、2つのレジスタを追加
命令: zip,unzip …. hashを計算、照合
レジスタ: top, key …. hashとseedを保存
LLVM backend
関数のエピローグとプロローグに
追加した命令を挿入
RISC-V emulator
LLVM
C or Any Program
改造
改造
細かい話
・hashも積み上がるのだから結局余分なスタック領域が必要では?
→RISC-V64bitに関して言えばRV39に従ってreturn addressの上位25bitが空白なのでそこにhashを押し込める。
・hashの計算時間は関数呼び出しのたびに発生するが許容できるのか?
→emulatorにおいては不可能な策だが、hash計算を専用アクセラレータにまかせて命令のパイプラインを組み、照合を裏で行えばオーバーヘッドは十分少なくなる。(ref:論文)
また、プロセスの切り替えにはまだ命令追加やosのcontext switch改変が必要そうなため行っておらず、他にc++の例外処理にも未対応
Reference
Thank you.