Relro

Tip

AWS ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ:HackTricks Training AWS Red Team Expert (ARTE)
GCP ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training GCP Red Team Expert (GRTE) Azure ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks ์ง€์›ํ•˜๊ธฐ

Relro

RELRO๋Š” Relocation Read-Only์˜ ์•ฝ์ž๋กœ, ๋ง์ปค(ld)์— ์˜ํ•ด ๊ตฌํ˜„๋œ ์™„ํ™” ์กฐ์น˜๋กœ, ELF์˜ ๋ฐ์ดํ„ฐ ์„ธ๊ทธ๋จผํŠธ์˜ ํ•˜์œ„ ์ง‘ํ•ฉ์„ ๋ชจ๋“  ์žฌ๋ฐฐ์น˜๊ฐ€ ์ ์šฉ๋œ ํ›„ ์ฝ๊ธฐ ์ „์šฉ์œผ๋กœ ์ „ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋ชฉํ‘œ๋Š” ๊ณต๊ฒฉ์ž๊ฐ€ ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰ ์ค‘์— ์—ญ์ฐธ์กฐ๋˜๋Š” GOT (Global Offset Table) ๋˜๋Š” ๊ธฐํƒ€ ์žฌ๋ฐฐ์น˜ ๊ด€๋ จ ํ…Œ์ด๋ธ”์˜ ํ•ญ๋ชฉ์„ ๋ฎ์–ด์“ฐ๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค (์˜ˆ: __fini_array).

ํ˜„๋Œ€ ๋ง์ปค๋Š” GOT (๋ฐ ๋ช‡ ๊ฐ€์ง€ ๋‹ค๋ฅธ ์„น์…˜)์„ .bss๋ณด๋‹ค ์•ž์„œ ์œ„์น˜์‹œํ‚ค๊ณ , ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ฒƒ์€ ๋™์  ๋กœ๋”๊ฐ€ ์žฌ๋ฐฐ์น˜๋ฅผ ์ ์šฉํ•œ ํ›„ Rโ€“X๋กœ ๋‹ค์‹œ ๋งคํ•‘๋˜๋Š” ์ „์šฉ PT_GNU_RELRO ์„ธ๊ทธ๋จผํŠธ๋ฅผ ์ƒ์„ฑํ•˜์—ฌ RELRO๋ฅผ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ .bss์—์„œ์˜ ์ „ํ˜•์ ์ธ ๋ฒ„ํผ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ๋Š” ๋” ์ด์ƒ GOT์— ๋„๋‹ฌํ•  ์ˆ˜ ์—†์œผ๋ฉฐ, ์ž„์˜ ์“ฐ๊ธฐ ์›์‹œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ RELRO๋กœ ๋ณดํ˜ธ๋œ ํŽ˜์ด์ง€ ๋‚ด์˜ ํ•จ์ˆ˜ ํฌ์ธํ„ฐ๋ฅผ ๋ฎ์–ด์“ธ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๋ง์ปค๊ฐ€ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋Š” ๋ณดํ˜ธ ์ˆ˜์ค€์€ ๋‘ ๊ฐ€์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค:

Partial RELRO

  • ํ”Œ๋ž˜๊ทธ -Wl,-z,relro (๋˜๋Š” ld๋ฅผ ์ง์ ‘ ํ˜ธ์ถœํ•  ๋•Œ -z relro)๋กœ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.
  • GOT์˜ ๋น„-PLT ๋ถ€๋ถ„(๋ฐ์ดํ„ฐ ์žฌ๋ฐฐ์น˜์— ์‚ฌ์šฉ๋˜๋Š” ๋ถ€๋ถ„)๋งŒ ์ฝ๊ธฐ ์ „์šฉ ์„ธ๊ทธ๋จผํŠธ์— ๋ฐฐ์น˜๋ฉ๋‹ˆ๋‹ค. ๋Ÿฐํƒ€์ž„์— ์ˆ˜์ •ํ•ด์•ผ ํ•˜๋Š” ์„น์…˜ โ€“ ๊ฐ€์žฅ ์ค‘์š”ํ•œ .got.plt๋Š” ์ง€์—ฐ ๋ฐ”์ธ๋”ฉ์„ ์ง€์›ํ•˜๋ฉฐ ์—ฌ์ „ํžˆ ์“ฐ๊ธฐ๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
  • ์ด๋กœ ์ธํ•ด ์ž„์˜ ์“ฐ๊ธฐ ์›์‹œ๊ฐ€ PLT ํ•ญ๋ชฉ์„ ๋ฎ์–ด์“ฐ๊ฑฐ๋‚˜ ret2dlresolve๋ฅผ ์ˆ˜ํ–‰ํ•˜์—ฌ ์‹คํ–‰ ํ๋ฆ„์„ ๋ฆฌ๋””๋ ‰์…˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์„ฑ๋Šฅ ์˜ํ–ฅ์€ ๋ฏธ๋ฏธํ•˜๋ฉฐ, ๋”ฐ๋ผ์„œ ๊ฑฐ์˜ ๋ชจ๋“  ๋ฐฐํฌํŒ์ด ์ˆ˜๋…„๊ฐ„ ์ตœ์†Œ Partial RELRO๋กœ ํŒจํ‚ค์ง€๋ฅผ ์ œ๊ณตํ•ด์™”์Šต๋‹ˆ๋‹ค (2016๋…„๋ถ€ํ„ฐ GCC/Binutils์˜ ๊ธฐ๋ณธ๊ฐ’์ž…๋‹ˆ๋‹ค).

Full RELRO

  • ๋‘ ๊ฐ€์ง€ ํ”Œ๋ž˜๊ทธ -Wl,-z,relro,-z,now (์ผ๋ช… -z relro -z now)๋กœ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. -z now๋Š” ๋™์  ๋กœ๋”๊ฐ€ ๋ชจ๋“  ๊ธฐํ˜ธ๋ฅผ ๋ฏธ๋ฆฌ ํ•ด๊ฒฐํ•˜๋„๋ก ๊ฐ•์ œํ•˜์—ฌ (์ฆ‰๊ฐ์  ๋ฐ”์ธ๋”ฉ) .got.plt๊ฐ€ ๋‹ค์‹œ ์“ฐ์ผ ํ•„์š”๊ฐ€ ์—†๊ณ  ์•ˆ์ „ํ•˜๊ฒŒ ์ฝ๊ธฐ ์ „์šฉ์œผ๋กœ ๋งคํ•‘๋  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.
  • ์ „์ฒด GOT, .got.plt, .fini_array, .init_array, .preinit_array ๋ฐ ๋ช‡ ๊ฐ€์ง€ ์ถ”๊ฐ€ ๋‚ด๋ถ€ glibc ํ…Œ์ด๋ธ”์ด ์ฝ๊ธฐ ์ „์šฉ PT_GNU_RELRO ์„ธ๊ทธ๋จผํŠธ์— ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.
  • ์ธก์ • ๊ฐ€๋Šฅํ•œ ์‹œ์ž‘ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜์ง€๋งŒ (๋ชจ๋“  ๋™์  ์žฌ๋ฐฐ์น˜๊ฐ€ ์‹œ์ž‘ ์‹œ ์ฒ˜๋ฆฌ๋จ) ๋Ÿฐํƒ€์ž„ ์˜ค๋ฒ„ํ—ค๋“œ๋Š” ์—†์Šต๋‹ˆ๋‹ค.

2023๋…„๋ถ€ํ„ฐ ์—ฌ๋Ÿฌ ์ฃผ์š” ๋ฐฐํฌํŒ์ด ๊ธฐ๋ณธ์ ์œผ๋กœ Full RELRO๋กœ ์‹œ์Šคํ…œ ํˆด ์ฒด์ธ (๋ฐ ๋Œ€๋ถ€๋ถ„์˜ ํŒจํ‚ค์ง€)์„ ์ปดํŒŒ์ผํ•˜๋Š” ๊ฒƒ์œผ๋กœ ์ „ํ™˜ํ–ˆ์Šต๋‹ˆ๋‹ค โ€“ ์˜ˆ: Debian 12 โ€œbookwormโ€ (dpkg-buildflags 13.0.0) ๋ฐ Fedora 35+. ๋”ฐ๋ผ์„œ ํŽœํ…Œ์Šคํ„ฐ๋กœ์„œ ๋ชจ๋“  GOT ํ•ญ๋ชฉ์ด ์ฝ๊ธฐ ์ „์šฉ์ธ ๋ฐ”์ด๋„ˆ๋ฆฌ๋ฅผ ๋งŒ๋‚  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.


How to Check the RELRO status of a binary

$ checksec --file ./vuln
[*] '/tmp/vuln'
Arch:     amd64-64-little
RELRO:    Full
Stack:    Canary found
NX:       NX enabled
PIE:      No PIE (0x400000)

checksec (๋ถ€๋ถ„ pwntools ๋ฐ ๋งŽ์€ ๋ฐฐํฌํŒ) ๋Š” ELF ํ—ค๋”๋ฅผ ํŒŒ์‹ฑํ•˜๊ณ  ๋ณดํ˜ธ ์ˆ˜์ค€์„ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค. checksec๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ, readelf์— ์˜์กดํ•˜์„ธ์š”:

# Partial RELRO โ†’ PT_GNU_RELRO is present but BIND_NOW is *absent*
$ readelf -l ./vuln | grep -E "GNU_RELRO|BIND_NOW"
GNU_RELRO      0x0000000000600e20 0x0000000000600e20
# Full RELRO โ†’ PT_GNU_RELRO *and* the DF_BIND_NOW flag
$ readelf -d ./vuln | grep BIND_NOW
0x0000000000000010 (FLAGS)              FLAGS: BIND_NOW

์ด์ง„ ํŒŒ์ผ์ด ์‹คํ–‰ ์ค‘์ธ ๊ฒฝ์šฐ(์˜ˆ: set-uid root ํ—ฌํผ), **/proc/$PID/exe**๋ฅผ ํ†ตํ•ด ์‹คํ–‰ ํŒŒ์ผ์„ ์—ฌ์ „ํžˆ ๊ฒ€์‚ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

readelf -l /proc/$(pgrep helper)/exe | grep GNU_RELRO

์ž์‹ ์˜ ์ฝ”๋“œ๋ฅผ ์ปดํŒŒ์ผํ•  ๋•Œ RELRO ํ™œ์„ฑํ™”ํ•˜๊ธฐ

# GCC example โ€“ create a PIE with Full RELRO and other common hardenings
$ gcc -fPIE -pie -z relro -z now -Wl,--as-needed -D_FORTIFY_SOURCE=2 main.c -o secure

-z relro -z now๋Š” GCC/clang( -Wl, ๋’ค์— ์ „๋‹ฌ๋จ)์™€ ld ๋ชจ๋‘์—์„œ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. **CMake 3.18+**๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ๋‚ด์žฅ ํ”„๋ฆฌ์…‹์„ ํ†ตํ•ด ์ „์ฒด RELRO๋ฅผ ์š”์ฒญํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON) # LTO
set(CMAKE_ENABLE_EXPORTS OFF)
set(CMAKE_BUILD_RPATH_USE_ORIGIN ON)
set(CMAKE_EXE_LINKER_FLAGS "-Wl,-z,relro,-z,now")

์šฐํšŒ ๊ธฐ์ˆ 

RELRO ์ˆ˜์ค€์ผ๋ฐ˜์ ์ธ ์›์‹œ๊ฐ€๋Šฅํ•œ ์•…์šฉ ๊ธฐ์ˆ 
์—†์Œ / ๋ถ€๋ถ„์ž„์˜ ์“ฐ๊ธฐ1. .got.plt ํ•ญ๋ชฉ์„ ๋ฎ์–ด์“ฐ๊ณ  ์‹คํ–‰์„ ์ „ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
2. ret2dlresolve โ€“ ์“ฐ๊ธฐ ๊ฐ€๋Šฅํ•œ ์„ธ๊ทธ๋จผํŠธ์—์„œ ๊ฐ€์งœ Elf64_Rela ๋ฐ Elf64_Sym์„ ์ž‘์„ฑํ•˜๊ณ  _dl_runtime_resolve๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.
3. .fini_array / atexit() ๋ชฉ๋ก์˜ ํ•จ์ˆ˜ ํฌ์ธํ„ฐ๋ฅผ ๋ฎ์–ด์”๋‹ˆ๋‹ค.
์ „์ฒดGOT๋Š” ์ฝ๊ธฐ ์ „์šฉ1. ๋‹ค๋ฅธ ์“ฐ๊ธฐ ๊ฐ€๋Šฅํ•œ ์ฝ”๋“œ ํฌ์ธํ„ฐ (C++ vtables, __malloc_hook < glibc 2.34, __free_hook, ์‚ฌ์šฉ์ž ์ •์˜ .data ์„น์…˜์˜ ์ฝœ๋ฐฑ, JIT ํŽ˜์ด์ง€)๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค.
2. ์ƒ๋Œ€ ์ฝ๊ธฐ ์›์‹œ๋ฅผ ์•…์šฉํ•˜์—ฌ libc๋ฅผ ์œ ์ถœํ•˜๊ณ  SROP/ROP into libc๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
3. DT_RPATH/LD_PRELOAD๋ฅผ ํ†ตํ•ด ์•…์„ฑ ๊ณต์œ  ๊ฐ์ฒด๋ฅผ ์ฃผ์ž…ํ•ฉ๋‹ˆ๋‹ค (ํ™˜๊ฒฝ์ด ๊ณต๊ฒฉ์ž ์ œ์–ด ํ•˜์— ์žˆ๋Š” ๊ฒฝ์šฐ) ๋˜๋Š” ld_audit.
4. ํ˜•์‹ ๋ฌธ์ž์—ด ๋˜๋Š” ๋ถ€๋ถ„ ํฌ์ธํ„ฐ ๋ฎ์–ด์“ฐ๊ธฐ๋ฅผ ์•…์šฉํ•˜์—ฌ GOT์— ์†๋Œ€์ง€ ์•Š๊ณ  ์ œ์–ด ํ๋ฆ„์„ ์ „ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ’ก ์ „์ฒด RELRO๊ฐ€ ์žˆ๋”๋ผ๋„ **๋กœ๋“œ๋œ ๊ณต์œ  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ GOT (์˜ˆ: libc ์ž์ฒด)**๋Š” ๋ถ€๋ถ„ RELRO๋งŒ ์žˆ์Šต๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ์ด๋Ÿฌํ•œ ๊ฐ์ฒด๋Š” ๋กœ๋”๊ฐ€ ์žฌ๋ฐฐ์น˜๋ฅผ ์ ์šฉํ•  ๋•Œ ์ด๋ฏธ ๋งคํ•‘๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ž„์˜ ์“ฐ๊ธฐ ์›์‹œ๋ฅผ ์–ป์œผ๋ฉด ๋‹ค๋ฅธ ๊ณต์œ  ๊ฐ์ฒด์˜ ํŽ˜์ด์ง€๋ฅผ ๋Œ€์ƒ์œผ๋กœ ํ•˜์—ฌ libc์˜ GOT ํ•ญ๋ชฉ์ด๋‚˜ __rtld_global ์Šคํƒ์„ ๋ฎ์–ด์จ์„œ ์‹คํ–‰์„ ์ „ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ํ˜„๋Œ€ CTF ์ฑŒ๋ฆฐ์ง€์—์„œ ์ •๊ธฐ์ ์œผ๋กœ ์•…์šฉ๋˜๋Š” ๊ธฐ์ˆ ์ž…๋‹ˆ๋‹ค.

์‹ค์ œ ์šฐํšŒ ์˜ˆ์‹œ (2024 CTF โ€“ pwn.college โ€œenlightenedโ€)

์ด ๋„์ „ ๊ณผ์ œ๋Š” ์ „์ฒด RELRO์™€ ํ•จ๊ป˜ ์ œ๊ณต๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด ์•…์šฉ์€ ์˜คํ”„ ๋ฐ”์ด ์›์„ ์‚ฌ์šฉํ•˜์—ฌ ํž™ ์ฒญํฌ์˜ ํฌ๊ธฐ๋ฅผ ์†์ƒ์‹œํ‚ค๊ณ , tcache poisoning์œผ๋กœ libc๋ฅผ ์œ ์ถœํ•œ ํ›„, __free_hook (RELRO ์„ธ๊ทธ๋จผํŠธ ์™ธ๋ถ€)์„ ์›๊ฐ€์ ฏ์œผ๋กœ ๋ฎ์–ด์จ์„œ ์ฝ”๋“œ ์‹คํ–‰์„ ์–ป์—ˆ์Šต๋‹ˆ๋‹ค. GOT ์“ฐ๊ธฐ๋Š” ํ•„์š”ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.


์ตœ๊ทผ ์—ฐ๊ตฌ ๋ฐ ์ทจ์•ฝ์  (2022-2025)

  • glibc 2.40์—์„œ __malloc_hook / __free_hook ๋น„๊ถŒ์žฅ (2025) โ€“ ์ด๋Ÿฌํ•œ ๊ธฐํ˜ธ๋ฅผ ์•…์šฉํ•œ ๋Œ€๋ถ€๋ถ„์˜ ํ˜„๋Œ€ ํž™ ์•…์šฉ์€ ์ด์ œ rtld_global._dl_load_jump ๋˜๋Š” C++ ์˜ˆ์™ธ ํ…Œ์ด๋ธ”๊ณผ ๊ฐ™์€ ๋Œ€์ฒด ๋ฒกํ„ฐ๋กœ ์ „ํ™˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ›„ํฌ๊ฐ€ RELRO ์™ธ๋ถ€์— ์กด์žฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๋“ค์˜ ์ œ๊ฑฐ๋Š” ์ „์ฒด RELRO ์šฐํšŒ ๋‚œ์ด๋„๋ฅผ ์ฆ๊ฐ€์‹œํ‚ต๋‹ˆ๋‹ค.
  • Binutils 2.41 โ€œ์ตœ๋Œ€ ํŽ˜์ด์ง€ ํฌ๊ธฐโ€ ์ˆ˜์ • (2024) โ€“ ๋ฒ„๊ทธ๋กœ ์ธํ•ด RELRO ์„ธ๊ทธ๋จผํŠธ์˜ ๋งˆ์ง€๋ง‰ ๋ช‡ ๋ฐ”์ดํŠธ๊ฐ€ ์ผ๋ถ€ ARM64 ๋นŒ๋“œ์—์„œ ์“ฐ๊ธฐ ๊ฐ€๋Šฅํ•œ ๋ฐ์ดํ„ฐ์™€ ํŽ˜์ด์ง€๋ฅผ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ์–ด mprotect ์ดํ›„์— ์“ธ ์ˆ˜ ์žˆ๋Š” ์ž‘์€ RELRO ๊ฐญ์ด ๋‚จ์•˜์Šต๋‹ˆ๋‹ค. ์—…์ŠคํŠธ๋ฆผ์€ ์ด์ œ PT_GNU_RELRO๋ฅผ ํŽ˜์ด์ง€ ๊ฒฝ๊ณ„์— ์ •๋ ฌํ•˜์—ฌ ํ•ด๋‹น ์—ฃ์ง€ ์ผ€์ด์Šค๋ฅผ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.

์ฐธ์กฐ

  • Binutils ๋ฌธ์„œ โ€“ -z relro, -z now ๋ฐ PT_GNU_RELRO
  • โ€œRELRO โ€“ ์ „์ฒด, ๋ถ€๋ถ„ ๋ฐ ์šฐํšŒ ๊ธฐ์ˆ โ€ โ€“ ๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๋ฌผ @ wolfslittlered 2023

Tip

AWS ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ:HackTricks Training AWS Red Team Expert (ARTE)
GCP ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training GCP Red Team Expert (GRTE) Azure ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks ์ง€์›ํ•˜๊ธฐ