disabling cet

agenda

What_is_CET

Intel CETとは

Control-flow Enforcement Technology

Tiger Lake以降のCPUに実装されているROP対策機構

の2つのセキュリティ要素をまとめた呼称

詳しくはこちらなどを参照

shadow_stack

リターンアドレスの書き換えを防ぐ目的

実際のスタックとは別にshadow stackを用意し,

call命令ではshadow stackにもreturn addressをpushする

retの際shadow stackに積まれたアドレスと比較する

shadow stackの書き換えは?

call, ret以外での操作は不可能

indirect_branch_tracking

jmp, callの追跡を行う

簡潔に言うと

endbr32/64以外の命令がある所には遷移できない

endbrはCETが有効な環境以外ではNOPと同じで,余計な事はしない.


How_it_works

void win() {
    puts("ROPed!!");
    exit(1);
}

void vuln() {
    char buf[0x10];
    puts("I'm vuln function!");
    *(unsigned long*)(buf+0x28) = (unsigned long)((char*)&win);
}

int main() {
    vuln();
}

CETが無い環境では,普通にreturn addressの書き換えが可能

rop_without_cet

sdeで試してみる

sde_rop_demo

Disabling_CET

CETを無効化する

gccとclangでは,-fcf-protectionオプションで管理できる.

gccではデフォルトで有効化されており,-fcf-protection=noneで無効化できる.

では,デフォルトのclangはどうやってCETを無効化しているか,gdbでみてみると,prctlで設定しているらしい.

カーネルのコード等を参考に無効化の方法を調べてみると

以下の方法で呼び出し元のプロセスではCETによる保護が無効化される

int status;
arch_prctl(ARCH_CET_STATUS, &status)
arch_prctl(ARCH_CET_DISABLE, status)

では,この操作を行った上でsdeでROPをしてみる

sde_disable_cet

参考