จะทดสอบว่าไบนารีลินุกซ์ได้รับการรวบรวมเป็นรหัสอิสระหรือไม่?


38

เมื่อเร็ว ๆ นี้ฉันได้เรียนรู้ว่า (อย่างน้อยใน Fedora และ Red Hat Enterprise Linux) โปรแกรมปฏิบัติการที่คอมไพล์เป็น Position Independent Executables (PIE) ได้รับการปกป้องพื้นที่แอดเดรสแบบสุ่ม (ASLR) ที่แข็งแกร่งยิ่งขึ้น

ดังนั้น: ฉันจะทดสอบได้อย่างไรว่ามีการประมวลผลไฟล์ใดไฟล์หนึ่งที่เรียกว่า Position Independent Executable บน Linux หรือไม่?


1
ไม่แน่ใจเกี่ยวกับ 32 บิต แต่ใน x86_64 รหัสคือตำแหน่งที่เป็นอิสระโดยค่าเริ่มต้น และแน่นอนแพ็กเกจระบบทั้งหมดจะถูกรวบรวมด้วยวิธีนี้บน arch
Michael Hampton

1
@MichaelHampton ฉันไม่คิดว่าถูกต้อง (ระวังเกี่ยวกับความแตกต่างระหว่างไบนารีที่ปฏิบัติการได้และไลบรารีที่แชร์คำสั่งของคุณอาจถูกต้องสำหรับไลบรารีที่แชร์ แต่ฉันไม่คิดว่ามันเหมาะกับไฟล์ที่เรียกใช้งานได้) แม้ใน x86_64 ไบนารีจะไม่ปรากฏว่าเป็น PIE ฉันเพิ่งเขียนโปรแกรมทดสอบขนาดเล็กและใน x86_64 มันไม่ได้รวบรวมเป็น PIE ฉันคิดว่าคุณต้องส่ง-pie -fpieแฟล็กคอมไพเลอร์พิเศษเพื่อรวบรวมโปรแกรมเป็น PIE ลิงค์นั้นมีข้อมูลที่น่าสนใจอื่น ๆ ขอบคุณ -!
DW

1
ผู้ชายคนนี้มีสคริปต์ทุบตีเพื่อการตรวจหา: blog.fpmurphy.com/2008/06/position-indrants-executables.html
CMCDragonkai

คำตอบ:


32

คุณสามารถใช้perlสคริปต์ที่มีอยู่ในhardening-checkแพ็คเกจซึ่งมีอยู่ใน FedoraและDebian (as hardening-includes) อ่านหน้าวิกิพีเดีย Debian นี้เพื่อดูรายละเอียดเกี่ยวกับการตรวจสอบสถานะการคอมไพล์ มันเป็นเรื่องเฉพาะของเดเบียน แต่ทฤษฎีนี้ใช้กับเรดแฮทเช่นกัน

ตัวอย่าง:

$ 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

คำตอบที่ดียังใช้ได้กับ Ubuntu 16.04 LTS และ Ubuntu รุ่นอื่น ๆ sudo apt-get install hardening-includesและจากนั้นhardening-checkสคริปต์ perl ที่ปฏิบัติการได้จะพร้อมใช้งานตามปกติPATH( /usr/bin/hardening-check); แค่นิดหน่อย: แนะนำให้ลบออก./จากคำตอบ ;-)
Dilettant

@ a25bedc5-3d09-41b8-82fb-ea6c353d75ae ไม่ได้อยู่ใน 17.10 อีกต่อไป :-(
Ciro Santilli 新疆改造中心中心法轮功六四事件

ใน CentOS / RedHat แพคเกจนี้สามารถใช้ได้ในEPELพื้นที่เก็บข้อมูล
vikas027

@ a25bedc5-3d09-41b8-82fb-ea6c353d75ae ดูเหมือนว่ามันจะไม่สามารถใช้งานได้ใน Ubuntu 18.04
Vadim Kotov

2
devscriptsแพคเกจเดเบียนที่มีนี้เรียกว่าตอนนี้
Tamás Szelei

15

ฉันใช้readelf --relocsเพื่อทดสอบว่าห้องสมุดแบบคงที่หรือแบบไดนามิกเป็น PIC ใน x86-64 ด้วยวิธีต่อไปนี้:

$ 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

วิธีนี้อาจใช้กับ executables ได้ แต่ฉันไม่ได้ใช้วิธีนี้


8
คุณสนใจที่จะอธิบายวิธีตีความผลลัพธ์ของสายการบินนั้นหรือไม่? เกณฑ์ในการจำแนกไลบรารีที่แบ่งใช้เป็น PIC เทียบกับที่ไม่ใช่ PIC คืออะไร
DW

หากคุณสร้างไฟล์เอ็กซีคิ้วท์ด้วยไฟล์-fPIE -no-pieนั้นจะถูกโหลดที่ที่อยู่เดียวกันเสมอแม้ว่ามันจะเชื่อมโยงกับไฟล์ PIE ได้ก็ตาม ใช้file a.outและมองหาELF executable(non-PIE) กับ ELF shared object `(PIE): ที่อยู่สัมบูรณ์แบบ 32 บิตไม่ได้รับอนุญาตใน x86-64 Linux อีกต่อไปหรือไม่
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
บารุค

3
ข้อแตกต่างระหว่างผลจากพายปิดและ pie.on มีและexecutable shared objectฉันคิดว่าวัตถุที่ใช้ร่วมกันจะต้องทำการเปลี่ยนตำแหน่งดังนั้นในใจของฉันจึงได้รับการรวบรวมด้วย PIE
Richard Braganza

Yup, PIE executables เป็นอ็อบเจ็กต์ที่แบ่งใช้ของ ELF วิธีที่ง่ายที่สุดในการติดตั้ง ASLR สำหรับโปรแกรมเรียกทำงานคือใช้การสนับสนุนที่มีอยู่ในตัวเชื่อมโยงแบบไดนามิกสำหรับและจุดเข้าใช้งาน ELF ในวัตถุที่ใช้ร่วมกัน ดูที่อยู่สัมบูรณ์แบบ 32 บิตใน x86-64 Linux ไม่ได้อีกต่อไป? สำหรับข้อมูลเพิ่มเติมเกี่ยวกับตัวเลือก gcc ที่ควบคุม PIE และgcc -fPIE -pieตอนนี้เป็นค่าเริ่มต้นสำหรับ distros หลายตัว
Peter Cordes

ไฟล์เวอร์ชันที่ใหม่กว่าพูดถึงวงกลมอย่างชัดเจน: เช่นปฏิบัติการ ELF 64- บิตของพาย LSB, x86-64, เวอร์ชัน 1 (SYSV), ลิงก์แบบไดนามิก, ล่าม /lib64/ld-linux-x86-64.so.2, สำหรับ GNU / Linux 3.2.0, BuildID [sha1] = 9b502fd78165cb04aec34c3f046c1ba808365a96 ที่ถูกปล้น
Brian Minton

1
@PeterCordes ทราบว่าfile5.36 ในขณะนี้สามารถรับรู้จริง PIE-Ness อยู่บนพื้นฐานของDT_1_PIEธงชาติ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

และไม่ใช่พาย - หนึ่ง:

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

ฟีเจอร์นี้เปิดตัวใน 5.33 แต่มันเป็นเพียงการchmod +xตรวจสอบง่าย ๆ ก่อนหน้านั้นเพิ่งพิมพ์shared objectสำหรับ PIE

ใน 5.34 มันก็หมายถึงการเริ่มต้นการตรวจสอบความเชี่ยวชาญมากขึ้นDF_1_PIEเอลฟ์เมตาดาต้า แต่เนื่องจากข้อผิดพลาดในการดำเนินการก็สิ่งที่ยากจนจริงและแสดงให้เห็น executables GCC shared objectsพายเป็น

ฉันได้ตีความfileซอร์สโค้ดรวมถึงข้อผิดพลาดและจำนวนไบต์ของรูปแบบเอลฟ์ที่ตรวจสอบในรายละเอียดที่ระรัวทุกข์ทรมานที่: https://stackoverflow.com/questions/34519521/why-does-gcc-create-a-shared-object -instead ของใช้ปฏิบัติการไบนารี-ตามไป / 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-the-fpie-option-for-position-indrants-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) ด้วยการตั้งค่าสถานะนี้ปิดการใช้งานการสุ่มที่อยู่พื้นที่รูปแบบ"
osgx

2

มีสคริปต์ทุบตีchecksec.sh บน Githubเพื่อตรวจสอบคุณสมบัติการลดการปฏิบัติการ (รวมถึง RELRO, Stack Canary, NX บิต, 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.