Hacking/Pwnable

[Mitigation] PIE | Position Independent Executable

min_zu 2025. 5. 12. 23:28
728x90
반응형

PIE : Position-Independent Executable

무작위 주소에 매필되도 실행 가능한 실행 파일을 의미함 
즉, 코드 영역이 무작위 주소에 배치되는 바이너리 

 

  • ASLR이 코드 영역에 적용되는 것
  • ALSR이 적용되지 않으면, PIE도 적용되지 않음

PIC

Position-Independent Code 

 

리눅스에는 ELF, 공유 오브젝트(Shared Object, so) 두 가지가 존재함

그 중 공유 오브젝트는 재배치(Relocation)이 가능하도록 설계되어있음

 

재배치가 가능하다는 것은, 메모리의 어느 주소에 코드가 배치되어도 코드의 의미가 훼손되지 않음을 의미한다.

이러한 코드를 PIC라고 함

 

 

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

 

PIC가 적용되어 있는 코드들은 상대 주소로 작동하게 된다. 

따라서 어디에 매핑되어도 코드를 실행할 수 있는 것이다. 

 

PIE

PIC가 적용되어 있는 무작위 주소에 매핑되어도 실행 가능한 실행 파일을 의미한다. 

ASLR이 도입되면서 실행 파일도 무작위 주소에 매핑될 수 있도록 하여 원래 재배치가 가능했던 공유 오브젝트를 실행 파일로 사용하고자 함

 

Window DLL

Call 명령과 DLL 로딩

  • Window의 DLL은 CALL E8 (상대주소 기반 근거리 호출)을 사용함
  • 이 방식은 DLL이 메모리에 어디에 로딩되든 CALL명령의 내부 상대 주소는 수정 없이 그대로 동작함

코드의 재배치 (relocation)없이도 실행 가능하여 효율적

 

전역 변수와 주소 재배치

  • DLL 내부 전역 변수들은 문자열, 가상 함수 테이블 등의 주소(포인터)를 포함할 수 있음
  • DLL이 로드되는 실제 주소는 매번 다를 수 있기 때문에 
    • 동적 로더가 이 포인터 값을 재계산하여 전역 변수에 저장함
    • 이 과정에서 해당 메모리 페이지는 Copy on write 처리됨 -> 다른 프로세스와 공유 불가
  • 반면 코드 자체나 포인터가 없는 전역 변수는 그대로 공유 가능함

Vista 이전 이후

이전 : 커널이 직접 재배치하면서 재배치된 DLL도 프로세스 간 공유 가능

이후 : DLL 충돌 방지 방식으로 DLL이 고정된 주소에 로드 되어야함 -> DLL은 프로세스마다 별도로 복사됨

728x90
반응형