Relro

Support HackTricks

Relro

RELRORelocation Read-Only의 약자로, GOT (Global Offset Table) 오버라이트와 관련된 위험을 완화하기 위해 바이너리에서 사용되는 보안 기능입니다. RELRO 보호에는 두 가지 유형이 있습니다: (1) Partial RELRO와 (2) Full RELRO. 두 가지 모두 ELF 파일의 GOTBSS를 재배치하지만, 결과와 의미는 다릅니다. 구체적으로, GOT 섹션을 BSS보다 앞에 배치합니다. 즉, GOTBSS보다 낮은 주소에 위치하므로, BSS의 변수를 오버플로우하여 GOT 항목을 덮어쓰는 것이 불가능합니다 (메모리에 쓰는 것은 낮은 주소에서 높은 주소로 진행됩니다).

명확성을 위해 이 개념을 두 가지 유형으로 나누어 보겠습니다.

Partial RELRO

Partial RELRO는 바이너리의 성능에 큰 영향을 주지 않으면서 보안을 강화하는 간단한 접근 방식을 취합니다. Partial RELRO는 .got을 읽기 전용으로 만듭니다 (GOT 섹션의 비-PLT 부분). 나머지 섹션(예: .got.plt)은 여전히 쓰기가 가능하므로 공격의 대상이 될 수 있습니다. 이는 GOT임의 쓰기 취약점으로 악용되는 것을 방지하지 않습니다.

참고: 기본적으로 GCC는 Partial RELRO로 바이너리를 컴파일합니다.

Full RELRO

Full RELRO전체 GOT (both .got and .got.plt)와 .fini_array 섹션을 완전히 읽기 전용으로 만들어 보호를 강화합니다. 바이너리가 시작되면 모든 함수 주소가 해결되고 GOT에 로드된 후, GOT는 읽기 전용으로 표시되어 런타임 중에 수정이 효과적으로 방지됩니다.

그러나 Full RELRO의 단점은 성능과 시작 시간에 있습니다. GOT를 읽기 전용으로 표시하기 전에 모든 동적 심볼을 시작 시 해결해야 하므로, Full RELRO가 활성화된 바이너리는 로드 시간이 더 길어질 수 있습니다. 이 추가 시작 오버헤드 때문에 Full RELRO는 모든 바이너리에서 기본적으로 활성화되지 않습니다.

Full RELRO가 활성화되어 있는지 확인하는 방법은 다음과 같습니다:

readelf -l /proc/ID_PROC/exe | grep BIND_NOW

Bypass

Full RELRO가 활성화된 경우, 이를 우회하는 유일한 방법은 GOT 테이블에 쓰지 않고 임의 실행을 얻는 다른 방법을 찾는 것입니다.

LIBC의 GOT는 일반적으로 Partial RELRO이므로, 임의 쓰기로 수정할 수 있습니다. Targetting libc GOT entries에서 더 많은 정보를 확인하세요.

Support HackTricks

Last updated