글쓴이 보관물: 소장 마

Linux 바이너리가 위치 독립적 코드로 컴파일되었는지 테스트하는 방법은 무엇입니까? 프로그램이 강력한 ASLR (Address Space Randomization) 보호를

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

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



답변

당신은 사용할 수 있습니다 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

답변

내가 사용하는 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

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


답변

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 정보 다음에 인쇄 된 다른 유형에 유의하십시오.


답변

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 커널 / 동적 로더가 실행 파일 위치를 변경하거나 아니.


답변

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

답변