Baru-baru ini saya mengetahui bahwa (setidaknya pada Fedora dan Red Hat Enterprise Linux), program yang dapat dieksekusi yang dikompilasi sebagai Position Independent Executables (PIE) menerima perlindungan pengalamatan ruang alamat (ASLR) yang lebih kuat.
Jadi: Bagaimana saya menguji apakah executable tertentu dikompilasi sebagai Posisi Independen yang Dapat Dilakukan, di Linux?
-pie -fpie
flag kompiler khusus untuk mengkompilasi program sebagai PIE. Tautan itu memiliki informasi menarik lainnya - terima kasih!Jawaban:
Anda dapat menggunakan
perl
skrip yang terkandung dalamhardening-check
paket, tersedia di Fedora dan Debian (ashardening-includes
). Baca halaman wiki Debian ini untuk perincian tentang flag kompilasi yang diperiksa. Ini spesifik untuk Debian, tetapi teorinya juga berlaku untuk Red Hat.Contoh:
sumber
sudo apt-get install hardening-includes
dan kemudianhardening-check
skrip perl yang dapat dieksekusi tersedia di biasanyaPATH
(/usr/bin/hardening-check
); just a nit: Sarankan untuk menghapus./
dari jawaban ;-)devscripts
.Saya biasa
readelf --relocs
menguji apakah perpustakaan statis atau dinamis adalah PIC pada x86-64 dengan cara berikut:Kita lihat di sini
R_X86_64_32
danR_X86_64_32S
. Ini berarti bahwa kode tersebut tidak independen terhadap posisi. Ketika saya membangun kembali perpustakaan dengan -fPIC saya mendapatkan:Metode ini mungkin bekerja untuk executable, tetapi saya belum menggunakannya seperti itu.
sumber
-fPIE -no-pie
, itu akan selalu dimuat di alamat yang sama meskipun itu bisa ditautkan sebagai executable PIE. Gunakanfile a.out
dan cariELF executable
(non-PIE) vs. ELF shared object` (PIE): Alamat absolut 32-bit tidak lagi diizinkan di x86-64 Linux?Cukup gunakan
file
pada biner:Perhatikan jenis berbeda yang dicetak setelah informasi LSB.
sumber
executable
danshared object
. Saya kira benda yang dibagikan harus dipindahkan sehingga pikiran saya telah dikompilasi dengan PIE.gcc -fPIE -pie
sekarang menjadi default pada banyak distro.file
5.36 sekarang dapat benar-benar mengenali PIE-ness berdasarkanDT_1_PIE
benderaDT_FLAGS_1
, dan dengan jelas mengatakanpie executable
bukanshared object
.file
5.36 mengatakannya dengan jelasfile
5.36 sebenarnya mencetaknya dengan jelas jika executable adalah PIE atau tidak. Sebagai contoh, executable PIE ditampilkan sebagai:dan yang non-PIE sebagai:
Fitur ini diperkenalkan pada 5.33 tetapi hanya melakukan
chmod +x
pemeriksaan sederhana . Sebelumnya hanya dicetakshared object
untuk PIE.Pada 5.34, itu dimaksudkan untuk mulai memeriksa
DF_1_PIE
metadata ELF yang lebih terspesialisasi , tetapi karena bug dalam implementasi itu benar-benar memecahkan banyak hal dan menunjukkan executable GCC PIE sebagaishared objects
.Saya telah menafsirkan
file
kode sumber, termasuk bug, dan byte mana dari format ELF yang diperiksa dalam detail yang luar biasa di: https://stackoverflow.com/questions/34519521/why-does-gcc-create-a- Shared-object -bukan-of-an-executable-binary-sesuai-ke / 55704865 # 55704865Ringkasan singkat perilaku file 5,36 adalah:
Elf32_Ehdr.e_type == ET_EXEC
executable
Elf32_Ehdr.e_type == ET_DYN
DT_FLAGS_1
entri bagian dinamis hadirDF_1_PIE
diaturDT_FLAGS_1
:pie executable
shared object
pie executable
shared object
GDB menjalankan executable dua kali dan melihat ASLR
Satu hal yang sangat langsung yang dapat Anda lakukan adalah menjalankan executable dua kali melalui GDB dan melihat apakah alamat berubah di seluruh run karena ASLR.
Saya telah menjelaskan bagaimana melakukannya secara rinci di: https://stackoverflow.com/questions/2463150/what-is-the-fpie-option-for-position-independent-executables-in-gcc-and-ld/51308031 # 51308031
Walaupun ini tidak selalu merupakan solusi yang paling praktis dan tidak mungkin jika Anda tidak mempercayai yang dapat dieksekusi, itu menyenangkan dan melakukan pemeriksaan akhir yang benar-benar kami pedulikan, yaitu jika kernel Linux / dynamic loader mengubah lokasi yang dapat dieksekusi atau tidak.
sumber
setarch -R
man7.org/linux/man-pages/man8/setarch.8.html "-R, --addr-no-randomize
Nonaktifkan pengacakan ruang alamat virtual. NyalakanADDR_NO_RANDOMIZE
." man7.org/linux/man-pages/man2/personality.2.html "ADDR_NO_RANDOMIZE
(sejak Linux 2.6.12) Dengan flag ini disetel, nonaktifkan pengacakan tata letak-ruang-alamat."Ada bash script checksec.sh di Github untuk memeriksa properti mitigasi yang dapat dieksekusi (termasuk RELRO, Stack Canary, NX bit, PIE, RPATH, RUNPATH, Fortify Source).
Jalankan
checksec
dengan-f
argumen (input file):sumber