補足: ld -z relro でどこがreadonlyになるのか (とelfutilsについて)
前に書いたrelro記事の補足です。ld -z relro すると (.got 以外は) どこがreadonlyになるのか、について。
これは、readelf -S でセクション一覧を表示して、/proc/
elfutilsには、eu-readelf, eu-strip など、eu- からはじまるバイナリ閲覧操作関係のコマンドが含まれています。binutilsのreplacementということで、コマンドラインオプションも eu- なしのものと殆ど一緒のようです。また eu-findtextrel など、ちょっと便利*1なコマンドもいくつか含まれています。
で、本題。どこがreadonlyになっているかですが、eu-readelf によるとこんな感じだそうです。
% g++ -O2 -Wall -W -Wl,-z,relro,-z,now -o relro test_relro.cpp % eu-readelf -l relro Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align PHDR 0x000034 0x08048034 0x08048034 0x000120 0x000120 R E 0x4 INTERP 0x000154 0x08048154 0x08048154 0x000013 0x000013 R 0x1 [Requesting program interpreter: /lib/ld-linux.so.2] LOAD 0x000000 0x08048000 0x08048000 0x002a21 0x002a21 R E 0x1000 LOAD 0x002e78 0x0804be78 0x0804be78 0x00024c 0x00240c RW 0x1000 DYNAMIC 0x002e90 0x0804be90 0x0804be90 0x0000f0 0x0000f0 RW 0x4 NOTE 0x000168 0x08048168 0x08048168 0x000020 0x000020 R 0x4 GNU_EH_FRAME 0x002640 0x0804a640 0x0804a640 0x00008c 0x00008c R 0x4 GNU_STACK 0x000000 0x00000000 0x00000000 0x000000 0x000000 RW 0x4 GNU_RELRO 0x002e78 0x0804be78 0x0804be78 0x000188 0x000188 R 0x1 Section to Segment mapping: Segment Sections... 00 01 [RO: .interp] 02 [RO: .interp .note.ABI-tag .hash .dynsym .dynstr .gnu.version .gnu.version_r .rel.dyn .rel.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame .gcc_except_table] 03 [RELRO: .ctors .dtors .jcr .dynamic .got] .data .bss 04 [RELRO: .dynamic] 05 [RO: .note.ABI-tag] 06 [RO: .eh_frame_hdr] 07 08 [RELRO: .ctors .dtors .jcr .dynamic .got]
"Section to Segment mapping" に注目してください。.data と .bss 以外はreadonlyになっているようですね*2。relroしないと次の出力になります。
% g++ -O2 -Wall -W -o no_relro test_relro.cpp % eu-readelf -l no_relro (略) Section to Segment mapping: Segment Sections... 00 01 [RO: .interp] 02 [RO: .interp .note.ABI-tag .hash .dynsym .dynstr .gnu.version .gnu.version_r .rel.dyn .rel.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame .gcc_except_table] 03 .ctors .dtors .jcr .dynamic .got .got.plt .data .bss 04 .dynamic 05 [RO: .note.ABI-tag] 06 [RO: .eh_frame_hdr] 07
.ctors .dtors .jcr .dynamic .got .got.plt .dynamic に書き込み可能です。そのため、前に書いた .got に書き込む攻撃の他、.dtorsをいじる攻撃も可能です。この、.dtors overwrite と呼ばれる(古典的)攻撃手法についても、リハビリの一環としてまとめておきます。こちら。