कैसे परीक्षण करें कि क्या स्थिति के रूप में एक लिनक्स बाइनरी संकलित किया गया था?


38

मुझे हाल ही में पता चला है कि (कम से कम फेडोरा और रेड हेट एंटरप्राइज लिनक्स पर), निष्पादन योग्य कार्यक्रम जो स्थिति स्वतंत्र निष्पादनकर्ता (पीआईई) के रूप में संकलित किए जाते हैं, उन्हें मजबूत पता स्थान यादृच्छिकरण (एएसएलआर) संरक्षण प्राप्त होता है।

इसलिए: मैं कैसे परीक्षण करूं कि लिनक्स पर एक विशेष निष्पादन योग्य स्थिति के रूप में संकलित किया गया था या नहीं?


1
32-बिट के बारे में निश्चित नहीं है, लेकिन x86_64 कोड पर डिफ़ॉल्ट रूप से स्वतंत्र स्थिति है । और निश्चित रूप से सभी सिस्टम पैकेज इस तरह से आर्क पर संकलित किए जाते हैं।
माइकल हैम्पटन

1
@ मायकिल हैम्पटन, मुझे नहीं लगता कि यह सही है। (एक निष्पादन योग्य बाइनरी और एक साझा लाइब्रेरी के बीच अंतर के बारे में सावधान रहें; आपका बयान साझा पुस्तकालयों के लिए सही हो सकता है, लेकिन मुझे नहीं लगता कि यह निष्पादन योग्य के लिए सही है।) x86_64 पर भी, बायनेरिज़ डिफ़ॉल्ट रूप से PIE प्रतीत नहीं होते हैं। मैंने अभी एक छोटा परीक्षण कार्यक्रम लिखा था, और x86_64 पर, इसे PIE के रूप में संकलित नहीं किया गया था। मुझे लगता है कि आपको -pie -fpiePIE के रूप में एक कार्यक्रम संकलित करने के लिए विशेष संकलक झंडे को पास करना होगा । उस लिंक में अन्य रोचक जानकारी थी, हालांकि - धन्यवाद!
DW

1
: यह आदमी का पता लगाने के लिए एक bash स्क्रिप्ट है blog.fpmurphy.com/2008/06/position-independent-executables.html
CMCDragonkai

जवाबों:


32

आप पैकेज perlमें समाहित स्क्रिप्ट का उपयोग कर सकते हैं hardening-check, फेडोरा और डेबियन (एस hardening-includes) में उपलब्ध है। संकलित झंडों की जाँच के विवरण के लिए इस डेबियन विकी पृष्ठ को पढ़ें । यह डेबियन विशिष्ट है, लेकिन सिद्धांत रेड हैट पर भी लागू होता है।

उदाहरण:

$ 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 एलटीएस और संभवतः अन्य उबंटू संस्करणों पर भी लागू होता है। sudo apt-get install hardening-includesऔर फिर hardening-checkनिष्पादन योग्य पर्ल स्क्रिप्ट सामान्य रूप से उपलब्ध है PATH( /usr/bin/hardening-check); सिर्फ एक निट: ./उत्तर से हटाने के लिए सुझाव ;-)
Dilettant

@ a25bedc5-3d09-41b8-82fb-ea6c353d75ae 17.10 में अब और नहीं :-(
सिरो सेंटिल्ली 新疆 5 5 六四 事件

CentOS / RedHat में, यह पैकेज एपल रिपॉजिटरी में उपलब्ध है
vikas027

@ a25bedc5-3d09-41b8-82fb-ea6c353d75ae ऐसा लगता है कि अब उबंटू 18.04 में उपलब्ध नहीं है
वादिम कोटोव

2
इसमें शामिल डेबियन पैकेज को अब कहा जाता है devscripts
तमसे सजेलेई

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। इसका मतलब है कि कोड स्वतंत्र नहीं है। जब मैं एक पुस्तकालय का पुनर्निर्माण करता हूं, तो मुझे मिलता है:

$ 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

यदि आपने एक निष्पादन योग्य बनाया है -fPIE -no-pie, तो इसे हमेशा एक ही पते पर लोड किया जाएगा, भले ही इसे PIE निष्पादन योग्य के रूप में जोड़ा जा सकता है। (गैर-पाई) बनाम ईएलएफ साझा वस्तु का उपयोग करें file a.outऔर देखें ELF executable(पीआईई): 32-बिट पूर्ण पते अब x86-64 लिनक्स में अनुमति नहीं है?
पीटर कॉर्डेस

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

एलएसबी सूचना के बाद मुद्रित विभिन्न प्रकार पर ध्यान दें।


1
PIE / ASLR के साथ संकलित होने पर यह कैसे दिखाता है?
बरूच

3
पाई-ऑफ और पाई.ऑन से आउटपुट के बीच एकमात्र अंतर है executableऔर shared object। मुझे लगता है कि साझा किए गए ऑब्जेक्ट को स्थानांतरित करने की आवश्यकता है इसलिए मेरे दिमाग को PIE के साथ संकलित किया गया है।
रिचर्ड ब्रागांज़ा

हाँ, पीआईई निष्पादनयोग्य ईएलएफ साझा ऑब्जेक्ट हैं; निष्पादन योग्यताओं के लिए एएसएलआर को लागू करने का सबसे आसान तरीका एक साझा ऑब्जेक्ट में डायनेमिक लिंकर और ईएलएफ प्रवेश बिंदु में मौजूदा समर्थन का उपयोग करना था। यह भी देखें कि 32-बिट पूर्ण पते अब x86-64 लिनक्स में अनुमति नहीं हैं? पीसीसी को नियंत्रित करने वाले जीसीसी विकल्पों के बारे में अधिक जानकारी के लिए, और gcc -fPIE -pieअब कई डिस्ट्रो पर डिफ़ॉल्ट है।
पीटर कॉर्डेस

फ़ाइल के नए संस्करणों में स्पष्ट रूप से पाई का उल्लेख है: उदाहरण के लिए, ELF 64-बिट LSB पाई निष्पादन योग्य, x86-64, संस्करण 1 (SYSV), गतिशील रूप से जुड़ा हुआ, GNU / Linux के लिए दुभाषिया /lib64/ld-linux-x86-64.2 .so.2 3.2.0, बिल्डआईडी [sha1] = 9b502fd78165cb04aec34c3f046c1ba808365a96, छीन लिया गया
ब्रायन मिंटन

1
@PeterCordes ध्यान दें कि file5.36 अब वास्तव में PIE-ness को DT_1_PIEध्वज के आधार पर पहचान सकते हैं DT_FLAGS_1, और pie executableइसके बजाय स्पष्ट रूप से कहते हैं shared object
सिरो सेंटिल्ली 新疆 改造 iro 六四

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_PIEईएलएफ मेटाडेटा की जांच शुरू करने के लिए था , लेकिन कार्यान्वयन में एक बग के कारण यह वास्तव में चीजों को तोड़ दिया और जीसीसी पाई के निष्पादनयोग्य के रूप में दिखाया shared objects

मैंने fileबग सहित स्रोत कोड की व्याख्या की है , और ईएलएफ प्रारूप के बाइट्स जो इसे विस्तृत रूप में विस्तृत रूप से जांचते हैं: https://stackoverflow.com/questions/34519521/why-does-gcc.acreate-a-soded-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-fpie-option-for-position-independent-executables-in-gcc-and-ld/51308031 # 51308031

हालांकि यह सबसे व्यावहारिक समाधान नहीं है और संभव नहीं है यदि आप निष्पादन योग्य पर भरोसा नहीं करते हैं, तो यह मजेदार है और यह अंतिम जांच करता है कि हम वास्तव में किसके बारे में परवाह करते हैं, अगर लिनक्स कर्नेल / डायनेमिक लोडर निष्पादन योग्य स्थान को बदलता है या नहीं।


1
"रन के बीच मुख्य परिवर्तनों का पता" - यह शुद्ध PIE का प्रभाव नहीं है, यह PIE है और सक्षम 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(लिनक्स 2.6.12 के बाद से) इस ध्वज सेट के साथ, पता-स्थान-लेआउट यादृच्छिकरण अक्षम करें।"
21

2

Github पर बैश स्क्रिप्ट checkec.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
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.