PIE, RELRO

์ปด์ปดํ•œํ•ด์ปคยท2025๋…„ 2์›” 16์ผ

์‹œ์Šคํ…œ ํ•ดํ‚น

๋ชฉ๋ก ๋ณด๊ธฐ
5/6

๐Ÿ“Œ PIC๋ž€?

PIC(Position-Independent Code) : ์žฌ๋ฐฐ์น˜๊ฐ€ ๊ฐ€๋Šฅํ•œ ์ฝ”๋“œ
= ๋ฉ”๋ชจ๋ฆฌ์˜ ์–ด๋А ์ฃผ์†Œ์— ์ ์žฌ๋˜์–ด๋„ ์ฝ”๋“œ์˜ ์˜๋ฏธ๊ฐ€ ํ›ผ์†๋˜์ง€ ์•Š๋Š” ์ฝ”๋“œ


๐Ÿ“Œ PIC ์ ์šฉ๊ณผ ๋ฏธ์ ์šฉ ์ฐจ์ด

PIC๋ฅผ ์ ์šฉํ•˜๋ฉด ๋ฌธ์ž์—ด ์ฃผ์†Œ๋ฅผ RIP + 0xa2์™€ ๊ฐ™์ด ์ƒ๋Œ€ ์ฃผ์†Œ๋กœ ์ฐธ์กฐํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ PIC๋ฅผ ์ ์šฉํ•˜์ง€ ์•Š์œผ๋ฉด 0x4005a1๊ณผ ๊ฐ™์ด ์ ˆ๋Œ€ ์ฃผ์†Œ๋กœ ๋ฌธ์ž์—ด์„ ์ฐธ์กฐํ•œ๋‹ค.

 push   rbp
 mov    rbp,rsp
-mov    rax,QWORD PTR [rip+0x200b3e]        # 0x601030 <data>
+mov    rax,QWORD PTR [rip+0x2009ab]        # 0x201010 <data>
 mov    rsi,rax
-mov    edi,0x4005a1
+lea    rdi,[rip+0xa2]        # 0x711
 mov    eax,0x0
-call   0x4003f0 <printf@plt>
+call   0x530 <printf@plt>
 mov    eax,0x0
 pop    rbp
 ret

- ๋ถ€๋ถ„์ด Pic ์—†๋Š” ์ฝ”๋“œ, + ๋ถ€๋ถ„์ด Pic ์žˆ๋Š” ์ฝ”๋“œ์ด๋‹ค.


๐Ÿ“Œ PIE๋ž€?

PIE(Position-Independent Executable) : ์žฌ๋ฐฐ์น˜๊ฐ€ ๊ฐ€๋Šฅํ•œ ์‹คํ–‰ ํŒŒ์ผ
= ๋ฌด์ž‘์œ„ ์ฃผ์†Œ์— ๋งคํ•‘๋ผ๋„ ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ ์‹คํ–‰ ํŒŒ์ผ

๋ฆฌ๋ˆ…์Šค์˜ ๊ธฐ๋ณธ ์‹คํ–‰ ํŒŒ์ผ์ธ /bin/ls์˜ ํŒŒ์ผ ํ—ค๋”๋ฅผ ๋ณด๋ฉด ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

~$ readelf -h /bin/ls
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              DYN (Position-Independent Executable file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x6aa0
  Start of program headers:          64 (bytes into file)
  Start of section headers:          136232 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         13
  Size of section headers:           64 (bytes)
  Number of section headers:         31
  Section header string table index: 30

Type์„ ๋ณด๋ฉด DYN(Position-Independent Excutable File)์ด๋ผ๊ณ  ์ ํ˜€ ์žˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด PIE๊ฐ€ ์ ์šฉ ๋˜์–ด ์žˆ์Œ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

์•„๋‹ˆ๋ฉด checksec ๋ช…๋ น์–ด๋ฅผ ์ด์šฉํ•˜๋ฉด PIE๊ฐ€ ์ ์šฉ๋˜์—ˆ๋Š”์ง€ ์•ˆ๋˜์—ˆ๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ“ข PIE vs ASLR

PIE : ์ฝ”๋“œ ์˜์—ญ์— ๋ฌด์ž‘์œ„ ์ฃผ์†Œ์— ๋งคํ•‘๋˜๋Š” ๊ธฐ์ˆ 
ASLR : ์Šคํƒ, ํž™, ๊ณต์œ  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋“ฑ์ด ๋ฌด์ž‘์œ„ ์ฃผ์†Œ์— ๋งคํ•‘๋˜๋Š” ๊ธฐ์ˆ 


๐Ÿ“Œ PIE ์šฐํšŒ ๊ธฐ์ˆ 

ASLR์ฒ˜๋Ÿผ ์ฝ”๋“œ ์˜์—ญ์˜ ๊ฐ€์ ฏ์„ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜, ๋ฐ์ดํ„ฐ ์˜์—ญ์— ์ ‘๊ทผํ•˜๋ ค๋ฉด ๋ฐ”์ด๋„ˆ๋ฆฌ๊ฐ€ ์ ์žฌ๋œ ์ฃผ์†Œ๋ฅผ ์•Œ์•„์•ผ ํ•œ๋‹ค. ์ด ์ฃผ์†Œ๋ฅผ PIE ๋ฒ ์ด์Šค, ์ฆ‰ ์ฝ”๋“œ ๋ฒ ์ด์Šค๋ผ๊ณ  ๋ถ€๋ฅด๋Š”๋ฐ, ์ด ์ฃผ์†Œ๋ฅผ ์•Œ์•„์•ผ ์ฝ”๋“œ ์˜์—ญ์˜ ์ž„์˜ ์ฃผ์†Œ๋ฅผ ์ฝ๊ณ , ์˜คํ”„์…‹์œผ๋กœ ์ฃผ์†Œ๋ฅผ ๊ณ„์‚ฐํ•ด์•ผ ํ•œ๋‹ค.

  • Partial Overwrite : ASLR์˜ ํŠน์„ฑ ์ƒ, ์ฝ”๋“œ ์˜์—ญ์˜ ์ฃผ์†Œ๋„ ASLR๊ณผ ๋˜‘๊ฐ™์ด ํ•˜์œ„ 12๋น„ํŠธ ๊ฐ’์€ ํ•ญ์ƒ ๋™์ผํ•˜๋‹ค. ๋”ฐ๋ผ์„œ ์ผ๋ถ€๋ถ„(ํ•˜์œ„ ํ•œ ๋ฐ”์ดํŠธ)๋งŒ ๋‹ค๋ฅด๋ฉด ์ด ๊ฐ’์„ ๋ฎ์–ด์จ์„œ ์›ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ“Œ RELRO๋ž€?

RELRO(RELocation Read-Only) : ์“ฐ๊ธฐ ๊ถŒํ•œ์ด ๋ถˆํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ ์„ธ๊ทธ๋จผํŠธ ์˜์—ญ์˜ ์“ฐ๊ธฐ ๊ถŒํ•œ์„ ์ œ๊ฑฐํ•˜๋Š” ๊ธฐ์ˆ 

์ ์šฉ ๋ฒ”์œ„์— ๋”ฐ๋ผ Full RELRO์™€ Partial RELRO๋กœ ๋‚˜๋‰œ๋‹ค.

  • Partial RELRO = ๋ถ€๋ถ„์ ์œผ๋กœ ์ ์šฉํ•˜๋Š” ๊ธฐ์ˆ 
  • Full RELRO = ๊ฐ€์žฅ ๋„“์€ ์˜์—ญ์— ์ ์šฉํ•˜๋Š” ๊ธฐ์ˆ 

๐Ÿ“ข RELRO ๊ถŒํ•œ ํ™•์ธ ๋ฐฉ๋ฒ•

  1. gdb๋กœ ์‹คํ–‰ํŒŒ์ผ์„ ๋””๋ฒ„๊น…ํ•˜๊ณ  vmmap์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ์˜ ๊ถŒํ•œ์„ ํ™•์ธํ•˜๋ฉด ๋œ๋‹ค.
pwndbg> vmmap
LEGEND: STACK | HEAP | CODE | DATA | WX | RODATA
             Start                End Perm     Size Offset File
          0x400000           0x401000 r-xp     1000      0 /home/li-sh/Desktop/dreamhack/hookoverwrite/hook
          0x600000           0x601000 r--p     1000      0 /home/li-sh/Desktop/dreamhack/hookoverwrite/hook
          0x601000           0x602000 rw-p     1000   1000 /home/li-sh/Desktop/dreamhack/hookoverwrite/hook
          0x602000           0x623000 rw-p    21000      0 [heap]
    0x7ffff7c00000     0x7ffff7c28000 r--p    28000      0 /usr/lib/x86_64-linux-gnu/libc.so.6
    0x7ffff7c28000     0x7ffff7dbd000 r-xp   195000  28000 /usr/lib/x86_64-linux-gnu/libc.so.6
    0x7ffff7dbd000     0x7ffff7e15000 r--p    58000 1bd000 /usr/lib/x86_64-linux-gnu/libc.so.6
    0x7ffff7e15000     0x7ffff7e16000 ---p     1000 215000 /usr/lib/x86_64-linux-gnu/libc.so.6
    0x7ffff7e16000     0x7ffff7e1a000 r--p     4000 215000 /usr/lib/x86_64-linux-gnu/libc.so.6
    0x7ffff7e1a000     0x7ffff7e1c000 rw-p     2000 219000 /usr/lib/x86_64-linux-gnu/libc.so.6
    0x7ffff7e1c000     0x7ffff7e29000 rw-p     d000      0 [anon_7ffff7e1c]
    0x7ffff7fa8000     0x7ffff7fab000 rw-p     3000      0 [anon_7ffff7fa8]
    0x7ffff7fbb000     0x7ffff7fbd000 rw-p     2000      0 [anon_7ffff7fbb]
    0x7ffff7fbd000     0x7ffff7fc1000 r--p     4000      0 [vvar]
    0x7ffff7fc1000     0x7ffff7fc3000 r-xp     2000      0 [vdso]
    0x7ffff7fc3000     0x7ffff7fc5000 r--p     2000      0 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
    0x7ffff7fc5000     0x7ffff7fef000 r-xp    2a000   2000 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
    0x7ffff7fef000     0x7ffff7ffa000 r--p     b000  2c000 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
    0x7ffff7ffb000     0x7ffff7ffd000 r--p     2000  37000 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
    0x7ffff7ffd000     0x7ffff7fff000 rw-p     2000  39000 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
    0x7ffffffde000     0x7ffffffff000 rw-p    21000      0 [stack]
0xffffffffff600000 0xffffffffff601000 --xp     1000      0 [vsyscall]
  1. /proc/self/maps๋ฅผ ํ™•์ธํ•˜๋ฉด ๋ฉ”๋ชจ๋ฆฌ ๋งต์„ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ๋‹ค.

  2. objdump ๋ช…๋ น์–ด๋ฅผ ์ด์šฉํ•˜๋ฉด ๊ฐ ์„ธ๊ทธ๋จผํŠธ๊ฐ€ ์–ด๋А ๋ฉ”๋ชจ๋ฆฌ์— ํ• ๋‹น ๋˜์–ด์žˆ๋Š”์ง€ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ๋‹ค.

$ objdump -h ./hook

./hook:     file format elf64-x86-64

Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .interp       0000001c  0000000000400238  0000000000400238  00000238  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  1 .note.ABI-tag 00000020  0000000000400254  0000000000400254  00000254  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  2 .note.gnu.build-id 00000024  0000000000400274  0000000000400274  00000274  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 .gnu.hash     00000068  0000000000400298  0000000000400298  00000298  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .dynsym       00000198  0000000000400300  0000000000400300  00000300  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  5 .dynstr       000000b7  0000000000400498  0000000000400498  00000498  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  6 .gnu.version  00000022  0000000000400550  0000000000400550  00000550  2**1
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  7 .gnu.version_r 00000040  0000000000400578  0000000000400578  00000578  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  8 .rela.dyn     00000180  00000000004005b8  00000000004005b8  000005b8  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  9 .init         0000001a  0000000000400738  0000000000400738  00000738  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 10 .plt          00000010  0000000000400760  0000000000400760  00000760  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 11 .plt.got      00000070  0000000000400770  0000000000400770  00000770  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 12 .text         000002d2  00000000004007e0  00000000004007e0  000007e0  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 13 .fini         00000009  0000000000400ab4  0000000000400ab4  00000ab4  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 14 .rodata       00000033  0000000000400ac0  0000000000400ac0  00000ac0  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 15 .eh_frame_hdr 00000044  0000000000400af4  0000000000400af4  00000af4  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 16 .eh_frame     00000134  0000000000400b38  0000000000400b38  00000b38  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 17 .init_array   00000008  0000000000600da0  0000000000600da0  00000da0  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 18 .fini_array   00000008  0000000000600da8  0000000000600da8  00000da8  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 19 .jcr          00000008  0000000000600db0  0000000000600db0  00000db0  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 20 .dynamic      000001c0  0000000000600db8  0000000000600db8  00000db8  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 21 .got          00000088  0000000000600f78  0000000000600f78  00000f78  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 22 .data         00000010  0000000000601000  0000000000601000  00001000  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 23 .bss          00000020  0000000000601010  0000000000601010  00001010  2**4
                  ALLOC
 24 .comment      00000035  0000000000000000  0000000000000000  00001010  2**0
                  CONTENTS, READONLY

์ด ๋•Œ Partial RELRO๋Š” .got์™€ .got.plt๋กœ ์กด์žฌํ•˜๋Š”๋ฐ ๊ฐ๊ฐ์˜ ์ฐจ์ด์ ์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

  • .got๋Š” ์‹คํ–‰๋˜๋Š” ์‹œ์ ์— Lazy Binding๋˜๋Š” ๋ณ€์ˆ˜๊ฐ€ ์œ„์น˜ํ•˜๋Š” ๊ณณ์ด๋‹ค.
  • .got.plt๋Š” ์‹คํ–‰ ์ค‘์— Lazy Binding๋˜๋Š” ๋ณ€์ˆ˜๊ฐ€ ์œ„์น˜ํ•˜๋Š” ๊ณณ์ด๋‹ค.

๐Ÿ“Œ RELRO ์šฐํšŒ ๊ธฐ๋ฒ•

  1. Partial RELRO์ผ ๋•Œ
    .init_array์™€ .fini_array์— ๋Œ€ํ•œ ๊ถŒํ•œ์ด ์ œ๊ฑฐ๋˜์–ด ์žˆ์ง€๋งŒ, .got.plt ์˜์—ญ์— ๋Œ€ํ•œ ์“ฐ๊ธฐ ๊ถŒํ•œ์ด ์กด์žฌํ•˜๋ฏ€๋กœ GOT Overwrite ๊ณต๊ฒฉ์„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
  2. Full RELRO์ผ ๋•Œ
    .init_array,.fini_array,.got ์˜์—ญ ๋ชจ๋‘ ์“ฐ๊ธฐ ๊ถŒํ•œ์ด ์ œ๊ฑฐ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— hook ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•œ๋‹ค. __malloc_hook๊ณผ __free_hook์ด ๋Œ€ํ‘œ์ ์ธ hook ํ•จ์ˆ˜๋กœ ์ด๋Ÿฌํ•œ hook์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ณต๊ฒฉํ•˜๋Š” ๊ธฐ๋ฒ•์„ Hook Overwrite๋ผ๊ณ  ํ•œ๋‹ค.

์ถ”๊ฐ€์ ์œผ๋กœ ํ™•์ธํ•œ ์‚ฌํ•ญ
Hook Overwrite ๊ณต๊ฒฉ ๊ธฐ๋ฒ•์€ hook ๋ณ€์ˆ˜๋“ค์€ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ์˜ ์•ˆ์ „์„ฑ ๋ฌธ์ œ์™€ ๋ณด์•ˆ ์ทจ์•ฝ์ ์œผ๋กœ ์ธํ•ด glibc 2.32 ๋ฒ„์ „์—์„œ ์‚ฌ์šฉ์ด ๊ถŒ์žฅ๋˜์ง€ ์•Š๊ฒŒ ๋˜์—ˆ์œผ๋ฉฐ, glibc 2.34 ๋ฒ„์ „(2021๋…„ 8์›” ๋ฆด๋ฆฌ์Šค)๋ถ€ํ„ฐ๋Š” ์™„์ „ํžˆ ์ œ๊ฑฐ๋˜์—ˆ๋‹ค๊ณ  ํ•œ๋‹ค.

์ด๋Ÿฌํ•œ ๋ณ€ํ™”๋กœ ์ธํ•ด, ๊ธฐ์กด์— malloc hook์„ ์‚ฌ์šฉํ•˜๋˜ ๋””๋ฒ„๊น… ๊ธฐ๋Šฅ๋“ค์€ ๋ณ„๋„์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ธ libc_malloc_debug.so.0๋กœ ๋ถ„๋ฆฌ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ glibc 2.34 ๋ฒ„์ „ ์ดํ›„๋ถ€ํ„ฐ๋Š” ์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ๋กœ๋“œํ•˜์—ฌ์•ผ๋งŒ ์ด์ „์˜ ๋””๋ฒ„๊น… ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค.

0๊ฐœ์˜ ๋Œ“๊ธ€