Linux 바이너리가 위치 독립적 코드로 컴파일되었는지 테스트하는 방법은 무엇입니까?


38

최근에는 (적어도 Fedora 및 Red Hat Enterprise Linux에서) PIE (Position Independent Executables)로 컴파일 된 실행 프로그램이 강력한 ASLR (Address Space Randomization) 보호를 받는다는 사실을 최근에 알게되었습니다.

Linux에서 특정 실행 파일이 위치 독립적 실행 파일로 컴파일되었는지 어떻게 테스트합니까?


1
32 비트는 확실하지 않지만 x86_64 코드는 기본적으로 위치 독립적 입니다. 물론 모든 시스템 패키지는 이러한 방식으로 어느 쪽 아치에도 컴파일됩니다.
Michael Hampton

1
@ MichaelHampton, 나는 그것이 옳지 않다고 생각합니다. (실행 파일 바이너리와 공유 라이브러리의 차이점에주의하십시오. 명령문은 공유 라이브러리에 적합하지만 실행 파일에 적합하다고 생각하지 않습니다.) x86_64에서도 바이너리는 기본적으로 PIE 인 것처럼 보이지 않습니다. 방금 작은 테스트 프로그램을 작성했으며 x86_64에서 PIE로 컴파일되지 않았습니다. -pie -fpie프로그램을 PIE로 컴파일 하려면 특수 컴파일러 플래그 를 전달해야한다고 생각합니다 . 이 링크에는 다른 흥미로운 정보가 있습니다. 감사합니다!
DW

1
이 녀석은 탐지를위한 bash 스크립트를 가지고있다 : blog.fpmurphy.com/2008/06/position-independent- executables.html
CMCDragonkai

답변:


32

당신은 사용할 수 있습니다 perl에 포함 된 스크립트 hardening-check패키지, 페도라에서 사용할 수데비안을 (같은 hardening-includes). 컴파일 플래그 확인에 대한 자세한 내용은 이 데비안 위키 페이지 를 참조하십시오. 데비안 특정이지만 이론은 Red Hat에도 적용됩니다.

예:

$ hardening-check $(which sshd)
/usr/sbin/sshd:
 Position Independent Executable: yes
 Stack protected: yes
 Fortify Source functions: yes (some protected functions found)
 Read-only relocations: yes
 Immediate binding: yes

좋은 답변. 우분투 16.04 LTS 및 기타 우분투 버전에도 적용됩니다. sudo apt-get install hardening-includes그리고 hardening-check실행 가능한 perl 스크립트는 평소에 사용할 수 있습니다 PATH( /usr/bin/hardening-check); 그냥 니트 : ./대답에서 제거를 제안 ;-)
Dilettant

@ :-( 더 이상 17.10하지 a25bedc5-3d09-41b8-82fb-ea6c353d75ae
치로 틸리新疆改造中心法轮功六四事件

CentOS / RedHat에서이 패키지는 epel 저장소 에서 사용할 수 있습니다
vikas027

@ a25bedc5-3d09-41b8-82fb-ea6c353d75ae 더 이상 우분투에서 사용할 수없는 것 같습니다. 18.04
Vadim Kotov

2
이것을 포함하는 데비안 패키지는 이제이라고 devscripts합니다.
Tamás Szelei

15

내가 사용하는 readelf --relocs정적 또는 동적 라이브러리 x86-64에 다음과 같은 방법에 PIC 여부를 테스트 :

$ readelf --relocs /usr/lib/gcc/x86_64-linux-gnu/4.6/libstdc++.a |\
      awk '$3~/^R_/ && $5!~/^\.debug/{print $3}' |sort -u
R_X86_64_32
R_X86_64_32S
R_X86_64_64
R_X86_64_DTPOFF32
R_X86_64_GOTPCREL
R_X86_64_PC32
R_X86_64_PLT32
R_X86_64_TLSLD
R_X86_64_TPOFF32

우리는 여기를 참조 R_X86_64_32하고 R_X86_64_32S. 이것은 코드가 위치 독립적이지 않다는 것을 의미합니다. -fPIC으로 라이브러리를 다시 빌드하면 다음과 같은 결과가 나타납니다.

$ readelf --relocs libstdc++.a |\
      awk '$3~/^R_/ && $5!~/^\.debug/{print $3}' |sort -u
R_X86_64_64
R_X86_64_DTPOFF32
R_X86_64_GOTPCREL
R_X86_64_PC32
R_X86_64_PLT32
R_X86_64_TLSGD
R_X86_64_TLSLD

이 방법은 아마도 실행 파일에서 작동 할 수도 있지만 그렇게 사용하지는 않았습니다.


8
해당 단일 라이너의 출력을 해석하는 방법을 설명하고 싶습니까? 공유 라이브러리를 PIC와 비 PIC로 분류하는 데 사용하는 기준은 무엇입니까?
DW

로 실행 파일을 빌드 한 경우 PIE 실행 파일로 링크되었을 -fPIE -no-pie 있지만 항상 동일한 주소에로드됩니다 . 사용 및 대한 모습 ELF는 object` 공유 대 (비 PIE) (PIE) : 32 비트 절대 주소는 더 이상 x86-64의 리눅스에서 허용하지? file a.outELF executable
Peter Cordes

12

file바이너리에서 간단히 사용 하십시오 :

$ file ./pie-off
./pie-off: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=0dc3858e9f0334060bfebcbe3e854909191d8bdc, not stripped
$ file ./pie-on
./pie-on: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=962235df5bd188e1ec48c151ff61b6435d395f89, not stripped

LSB 정보 다음에 인쇄 된 다른 유형에 유의하십시오.


1
PIE / ASLR로 컴파일하면 어떻게 표시됩니까?
Baruch

3
pie-off와 pie.on의 출력 간의 유일한 차이점은 executableshared object입니다. 공유 객체를 재배치 할 수 있어야한다고 생각하므로 PIE로 컴파일되었습니다.
Richard Braganza

예, PIE 실행 파일은 ELF 공유 객체입니다. 실행 파일에 대해 ASLR을 구현하는 가장 쉬운 방법은 동적 링커의 기존 지원 및 공유 객체의 ELF 진입 점을 사용하는 것입니다. x86-64 Linux에서 더 이상 허용되지 않는 32 비트 절대 주소 도 참조하십시오 . PIE를 제어하는 ​​gcc 옵션에 대한 자세한 내용 gcc -fPIE -pie은 이제 많은 배포판의 기본값입니다.
Peter Cordes

최신 버전의 파일은 파이를 명시 적으로 언급합니다. 예 : GNU / Linux 용 ELF 64 비트 LSB 파이 실행 파일, x86-64, 버전 1 (SYSV), 동적으로 링크 된 인터프리터 /lib64/ld-linux-x86-64.so.2 3.2.0, BuildID [sha1] = 9b502fd78165cb04aec34c3f046c1ba808365a96, 제거
Brian Minton

1
@PeterCordes는 file5.36은 이제의 DT_1_PIE플래그를 기반으로 실제로 PIE-ness를 인식 DT_FLAGS_1하고 pie executable대신에 명확하게 말합니다 shared object.
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

8

file 5.36은 분명히 말한다

file5.36은 실행 파일이 PIE인지 아닌지 실제로 실제로 인쇄합니다. 예를 들어 PIE 실행 파일은 다음과 같이 표시됩니다.

main.out: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, not stripped

PIE 이외의 것 :

main.out: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped

이 기능은 5.33에 도입되었지만 간단하게 chmod +x확인했습니다. 그 전에는 shared objectPIE 용으로 인쇄 되었습니다.

5.34에서는 좀 더 전문화 된 DF_1_PIEELF 메타 데이터를 확인하기 시작 했지만 구현상의 버그로 인해 실제로 문제가 발생하여 GCC PIE 실행 파일을로 표시했습니다 shared objects.

file버그를 포함하여 소스 코드를 해석 했으며 정확한 ELF 형식의 바이트는 https://stackoverflow.com/questions/34519521/why-does-gcc-create-a-shared-object 에서 자세히 확인했습니다. 대신 실행 가능한 이진에 따라 / 55704865 # 55704865

파일 5.36 동작에 대한 요약은 다음과 같습니다.

  • 만약 Elf32_Ehdr.e_type == ET_EXEC
    • 인쇄 executable
  • 그렇지 않으면 Elf32_Ehdr.e_type == ET_DYN
    • 경우 DT_FLAGS_1동적 부 엔트리가 존재
      • DF_1_PIE에 설정된 경우 DT_FLAGS_1:
        • 인쇄 pie executable
      • 그밖에
        • 인쇄 shared object
    • 그밖에
      • 사용자, 그룹 또는 다른 사람이 파일을 실행할 수있는 경우
        • 인쇄 pie executable
      • 그밖에
        • 인쇄 shared object

GDB는 실행 파일을 두 번 실행하고 ASLR을 참조하십시오.

가장 직접적인 방법은 GDB를 통해 실행 파일을 두 번 실행하고 ASLR로 인해 실행에서 주소가 변경되는지 확인하는 것입니다.

https://stackoverflow.com/questions/2463150/what-is-the-fpie-option-for-position-independent- executables- in-gcc- and-ld / 51308031 에서 자세한 방법을 설명했습니다. # 51308031

이것이 반드시 가장 실용적인 해결책은 아니며 실행 파일을 신뢰하지 않는 경우 가능하지는 않지만, 재미 있고 실제로 관심을 갖는 최종 점검을 수행합니다. 즉 Linux 커널 / 동적 로더가 실행 파일 위치를 변경하거나 아니.


1
"실행 사이의 주요 변경 사항 주소"-순수한 PIE의 영향이 아니며 PIE이며 활성화 된 ASLR입니다. 예, 거의 모든 곳에서 활성화되지만 ASLR 주소가 비활성화 된 시스템의 경우 두 번 동일합니다. ASLR은 전역 적으로 활성화 될 수 있지만 setarch -R man7.org/linux/man-pages/man8/setarch.8.html " -R, --addr-no-randomize 가상 주소 공간의 무작위 화를 비활성화합니다. 설정 ADDR_NO_RANDOMIZE합니다."를 사용하여 비활성화 할 수 있습니다 . man7.org/linux/man-pages/man2/personality.2.html " ADDR_NO_RANDOMIZE(Linux 2.6.12부터)이 플래그가 설정되면 address-space-layout randomization을 비활성화하십시오."
osgx

2

Github 에는 bash 스크립트 checksec.sh가 있으며 실행 파일 완화 속성 (RELRO, Stack Canary, NX bit, PIE, RPATH, RUNPATH, Fortify Source 포함)을 확인합니다.

실행 checksec으로 -f(파일 입력) 인수 :

$ checksec -f /usr/bin/bash

RELRO           STACK CANARY      NX            PIE             RPATH     RUNPATH      FORTIFY Fortified Fortifiable
Full RELRO      Canary found      NX enabled    PIE enabled     No RPATH   No RUNPATH    YES      13        33
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.