鬱猫のつぶやき

鬱猫が日々思っていることをつづります

hope-RIPEを試してみる その1

Runtime Intrusion Prevention Evaluator (RIPE) という、脆弱性攻撃に対する防御のカバレッジを測定するためのツールがある。これを用いると種々のパラメータを変化させながら種々の脆弱性攻撃用コードを生成、そのコードを実行し脆弱性攻撃の成否をレポートしてくれる。 RIPEのもとの論文はここからダウンロードできる。

このRIPEだが、RISC-V向けにポートしたものが昨年リリースされていたので、試してみた。hope-RIPEと呼ぶらしい。

以下では、RISC-V toolsがインストールされており、パスが通してあることを前提として話をすすめる。

build & run

基本的に普通にmakeで問題なくビルドできた。

$ git clone https://github.com/draperlaboratory/hope-RIPE.git
$ cd hope-RIPE
$ make

すべてのテストケースを実行するためにpythonスクリプトが用意されている。pythonスクリプトの中身を見ると

for attack in attacks:
        for tech in techniques:
                for loc in locations:
                        for ptr in code_ptr:
                                for func in funcs:
                                        os.system('rm -f out/out.text')
                                        cmdargs = 'build/ripe_attack_generator ' + '-t ' + tech + ' -i ' + attack + ' -c ' + ptr + ' -l ' + loc + ' -f ' + func
                                        cmdline= run_cmd + ' ' + cmdargs + ' 1> out/out.text 2>/dev/null'

                                        if is_attack_possible (attack, tech, loc, ptr, func) == 0:
                                                total_np += 1

となっており、要はすべてのパラメータの組み合わせについてRIPEを実行するだけとなっている。

テストを実行した結果は以下の通り。

...

('build/ripe_attack_generator -t direct -i rop -c longjmpdata -l data -f memcpy', 0)
('build/ripe_attack_generator -t direct -i dataonly -c bof -l stack -f memcpy', 1)
('build/ripe_attack_generator -t direct -i dataonly -c iof -l stack -f memcpy', 1)
('build/ripe_attack_generator -t direct -i dataonly -c leak -l stack -f memcpy', 0)
('build/ripe_attack_generator -t direct -i dataonly -c bof -l heap -f memcpy', 1)
('build/ripe_attack_generator -t direct -i dataonly -c iof -l heap -f memcpy', 1)
('build/ripe_attack_generator -t direct -i dataonly -c leak -l heap -f memcpy', 0)
('build/ripe_attack_generator -t direct -i dataonly -c bof -l bss -f memcpy', 1)
('build/ripe_attack_generator -t direct -i dataonly -c iof -l bss -f memcpy', 1)
('build/ripe_attack_generator -t direct -i dataonly -c leak -l bss -f memcpy', 0)
('build/ripe_attack_generator -t direct -i dataonly -c bof -l data -f memcpy', 1)
('build/ripe_attack_generator -t direct -i dataonly -c iof -l data -f memcpy', 1)
('build/ripe_attack_generator -t direct -i dataonly -c leak -l data -f memcpy', 0)
('build/ripe_attack_generator -t indirect -i dataonly -c bof -l stack -f memcpy', 1)
('build/ripe_attack_generator -t indirect -i dataonly -c bof -l bss -f memcpy', 1)
('build/ripe_attack_generator -t indirect -i dataonly -c bof -l data -f memcpy', 1)
SUMMARY
----------------------------------------------------------------
Total OK: 123
Total FAIL: 57
Total Attacks Executed: 180

OKは攻撃に成功したことを示し、FAILは攻撃に失敗したことを示す。攻撃に成功した場合には、標準出力に success. **** function reached. というメッセージが表示される(****には攻撃の手法の名前が入る)。

57件FAILしているわけだが、どういうことなのか。。。SSPによって守られているとかかな?

気になってMakefileを見てみると、

# Makefile for RIPE
# @author John Wilander & Nick Nikiforakis
# Modified for RISC-V by John Merrill

#Depending on how you test your system you may want to comment, or uncomment
#the following
CFLAGS= -fno-stack-protector -z execstack
CC=riscv64-unknown-elf-gcc

all: ripe_attack_generator

clean:
        rm -rf build/ out/

ripe_attack_generator: ./source/ripe_attack_generator.c
        mkdir -p build/ out/
        $(CC) \
                ./source/ripe_attack_generator.c -o ./build/ripe_attack_generator

となっており、バッチリ-fno-stack-protectorが入っている。

FAILしている原因調査は後日行うこととするが、ひとまずFAILしていたテストケースとして何があったかだけ調べたので、以下に掲載しておく。

パット見、direct rop stack ret memcpyとかで失敗しているが、このケースでの失敗はちょっと考えにくい。RISC-Vのポーティングを間違えている可能性が高そう。

direct shellcode funcptrbss bss memcpy
direct shellcode structfuncptrbss bss memcpy
direct shellcode longjmpbss bss memcpy
direct shellcode funcptrdata data memcpy
direct shellcode structfuncptrdata data memcpy
direct shellcode longjmpdata data memcpy
indirect shellcode ret bss memcpy
indirect shellcode funcptrstackvar bss memcpy
indirect shellcode funcptrstackparam bss memcpy
indirect shellcode funcptrheap bss memcpy
indirect shellcode funcptrbss bss memcpy
indirect shellcode funcptrdata bss memcpy
indirect shellcode structfuncptrstack bss memcpy
indirect shellcode structfuncptrheap bss memcpy
indirect shellcode structfuncptrdata bss memcpy
indirect shellcode structfuncptrbss bss memcpy
indirect shellcode longjmpstackvar bss memcpy
indirect shellcode longjmpstackparam bss memcpy
indirect shellcode longjmpheap bss memcpy
indirect shellcode longjmpdata bss memcpy
indirect shellcode longjmpbss bss memcpy
indirect shellcode ret data memcpy
indirect shellcode funcptrstackvar data memcpy
indirect shellcode funcptrstackparam data memcpy
indirect shellcode funcptrheap data memcpy
indirect shellcode funcptrbss data memcpy
indirect shellcode funcptrdata data memcpy
indirect shellcode structfuncptrstack data memcpy
indirect shellcode structfuncptrheap data memcpy
indirect shellcode structfuncptrdata data memcpy
indirect shellcode structfuncptrbss data memcpy
indirect shellcode longjmpstackvar data memcpy
indirect shellcode longjmpstackparam data memcpy
indirect shellcode longjmpheap data memcpy
indirect shellcode longjmpdata data memcpy
indirect shellcode longjmpbss data memcpy
indirect returnintolibc structfuncptrbss bss memcpy
indirect returnintolibc structfuncptrdata data memcpy
direct rop ret stack memcpy
direct rop funcptrstackvar stack memcpy
direct rop funcptrstackparam stack memcpy
direct rop structfuncptrstack stack memcpy
direct rop longjmpstackvar stack memcpy
direct rop longjmpstackparam stack memcpy
direct rop funcptrheap heap memcpy
direct rop structfuncptrheap heap memcpy
direct rop longjmpheap heap memcpy
direct rop funcptrbss bss memcpy
direct rop structfuncptrbss bss memcpy
direct rop longjmpbss bss memcpy
direct rop funcptrdata data memcpy
direct rop structfuncptrdata data memcpy
direct rop longjmpdata data memcpy
direct dataonly leak stack memcpy
direct dataonly leak heap memcpy
direct dataonly leak bss memcpy
direct dataonly leak data memcpy