상세 컨텐츠

본문 제목

04. RELRO

Computer Science/Linux System

by RACC8N 2020. 3. 9. 09:34

본문

    • RELRO는 RELocation Read-Only의 줄임말이며, ELF 바이너리 / 프로세스의 데이터 섹션의 보안을 강화하는 일반적인 기술이다.
    • RELRO에는 Partial RELRO와 Full RELRO 두 가지 모드가 있다.
      • Partial RELRO
      • Full RELRO

다음과 같이 RELRO 적용시 "Program Header"와 "Dynamic Section"의 변화를 확인할 수 있다.

  • Partial RELRO를 적용하게되면 다음과 같은 변화가 발생한다.

    • 'Program Header'에 'RELRO' 영역이 생성된다.

      • 해당 영역의 권한은 Read only 이다.

    • 해당 영역에 포함되는 Section은 다음과 같다.

      • INIT_ARRAY, FINI_ARRAY

    • 즉, GOT영역을 덮어쓸수 있다.
  • Full RELRO를 적용하게되면 다음과 같은 변화가 발생한다.

    • 'Program Header'에 'RELRO' 영역이 생성된다.

      • 해당 영역의 권한은 Read only 이다.

    • 해당 영역에 포함되는 Section은 다음과 같다.

      • INIT_ARRAY, FINI_ARRAY, PLTGOT

    • 그리고 Section영역에서 PLTRELSZ, PLTREL, JMPREL가 제거되고, 'BIND_NOW', 'FLAGS_1' Section이 추가된다.

    • 즉, GOT영역을 덮어쓸수 없다.

No RELRO

다음과 같이 프로그램 헤더 정보와 메모리 맵을 통해 조금더 자세한 내용을 확인할 수 있다.

  • "__isoc99_scanf"의 주소값은 '.got.plt'영역에 저장되어 있다.
    • '.got.plt' 영역의 시작 주소는 0x600c20 이다.
  • 메모리 맵을 통해 해당 영역(0x00600000 ~ 0x00601000)에 'W' 쓰기 권한이 설정되어 있다.

Partial RELRO

다음과 같이 프로그램 헤더 정보와 메모리 맵을 통해 조금더 자세한 내용을 확인할 수 있다.

  • '.got.plt' 영역의 시작 주소는 0x601000 이다.
  • 메모리 맵에서 RELRO가 적용되지 않은 프로그램과 다른 부분을 확인할 수 있다.
    • 0x600000 ~ 0x601000 영역의 권한은 r--p 이다.
      • 해당 영역에는 .init_array, .fini_array, .jcr, .dynamic, .got 헤더가 포함된다.
    • 0x601000 ~ 0x602000 영역의 권한은 rw-p 이다.
      • 해당 영역에는 .got.plt,등의 헤더가 포함된다.
      • 즉, 이로 인해 .got.plt 영역에 값을 변경할 수 있다.

Full RELRO

  • 앞에서 테스트한 프로그램과 달리 GOT 영역에 값을 변경할 수 없다.
    • 디버거에서 '__isoc99_scanf'의 심볼 정보를 찾을 수 없다.

해당 프로그램의 헤더 구성이 No RELRO, Partial RELRO 와 다르다.

  • 해당 프로그램의 헤더 정보에 '.rela.plt', '.got.plt' 헤더가 존재하지 않는다.

 

 

 

Partial RELRO

  • 다음과 같이 동적 라이브러리의 주소가 호출 된다.

    • main 함수에서 printf 함수를 사용하기 위해 메모리 주소 0x4005b0을 호출한다.

      • 메모리 주소 0x4005b0는 ".plt" 영역이다.

      • ".plt" 영역은 0x400590 ~ 0x400610 이다.

    • 0x4005b0 영역의 코드는 "jmp QWORD PTR [rip+0x200a6a]" 이다.

      • 즉, 메모리 주소 0x601020에 저장된 주소로 JUMP 한다.

        • 메모리 주소 0x601020은 ".got.plt" 영역이다.

        • ".got.plt" 영역은 0x601000 ~ 0x601050 이다.

      • 메모리 주소 0x601020에 저장된 값은 동적 라이브러리의 주소가 아닌 '.plt' 영역이다.

        • 이는 해당 프로그램에서 printf 함수가 호출되지 않았기 때문에 Stub 코드("printf@plt+6") 주소 값이 저장되어 있다.

      • 프로그램을 실행하고 printf 함수가 호출되기 시작하면 메모리 주소 0x601020(".got.plt" 영역) 영역에 동적라이브러리의 printf 함수의 시작 주소 값이 저장된다.

    • 즉, Partial RELRO가 적용된 바이너리는 ".got.plt"영역이 Write가 가능하도록 설정되어 있기 때문에 ".got.plt" 영역에 저장된 값을 변경할 수 있다.

다음과 같이 아직 호출되지 않은 함수들의 GOT 값은 어떤지 확인해보겠다.

  • main 함수에서 scanf 함수를 사용하기 위해 메모리 주소 0x400600(".plt")을 호출한다.

  • 0x400600 영역의 코드는 "jmp QWORD PTR [rip+0x200a42]" 이며, 0x601048 영역에 저장된 주소로 이동한다.

  • 0x601048 영역에 저장된 값은 0x400606 이며, 해당 영역은 Stub 코드가 저장되어 있다.
  • scanf 함수가 아직 호출된 적이 없기 때문에 0x601048(".got.plt") 영역에 동적라이브러리의 scanf 함수의 시작 주소 값이 저장되어 있지 않다.
  • Partial RELRO에 Lazy binding을 사용하기 때문에 함수를 호출하지 않으면 동적라이브러리의 주소 값을 ".got.plt" 영역에 저장되지 않는다.

Full RELRO

  • 다음과 같이 동적 라이브러리의 주소를 호출하게 된다.

    • main 함수에서 printf 함수를 사용하기 위해 메모리 주소 0x4005c8을 호출한다.

      • 메모리 주소 0x4005c8는 ".plt.got" 영역이다.

      • ".plt.got" 영역은 0x4005c0 ~ 0x400600 이다.

    • 0x4005c8 영역의 코드는 "jmp QWORD PTR [rip+0x2009fa]" 이다.

      • 즉, 메모리 주소 0x600fc8에 저장된 주소로 JUMP 한다.

        • 메모리 주소 0x600fc8은 ".got" 영역이다.

        • ".got.plt" 영역은 0x600fa8 ~ 0x601000이다.

      • 메모리 주소 0x600fc8에 아무런 값도 저장되어 있지 않다.

        • 이는 해당 프로그램에서 printf 함수가 호출되지 않았기 때문이다.

      • 프로그램을 실행하고 printf 함수가 호출되기 시작하면 메모리 주소 0x600fc8(".got" 영역) 영역에 동적라이브러리의 printf 함수의 시작 주소 값이 저장된다.

    • 즉, Full RELRO가 적용된 바이너리는 ".got"영역이 Read-only로 설정되지 때문에 ".got" 영역에 저장된 값을 변경할 수 없다.

다음과 같이 아직 호출되지 않은 함수들의 GOT 값은 어떤지 확인해보겠다.

  • main 함수에서 scanf 함수를 사용하기 위해 메모리 주소 0x4005f8(".plt.got")을 호출한다.

  • 0x4005f8 영역의 코드는 "jmp QWORD PTR [rip+0x2009fa]" 이며, 0x600ff8 영역에 저장된 주소로 이동한다.

  • 0x600ff8 영역에 저장된 값은 0x00007ffff7a784d0 이며, 해당 영역은 동적라이브러리의 scanf 함수의 시작 주소 값 이다.
  • Full RELRO에서는 Now binding을 사용하기 때문에 프로그램이 메모리에 로드 될때 해당 프로그램에서 사용되는 모든 동적 함수의 주소를 ".got" 영역에 저장된다.

LazyBinding : https://pwnkidh8n.tistory.com/76

'Computer Science > Linux System' 카테고리의 다른 글

Lazy binding (Feat. Now binding)  (0) 2020.03.09
03. Canaries  (0) 2020.03.08
02. ASLR  (0) 2020.03.08
01. NX Bit (MS : DEP)  (0) 2020.03.08

관련글 더보기

댓글 영역