2017-10-22 19 views
11

एक बफर ओवरफ्लो शोषण पर काम करते समय मुझे कुछ वास्तव में अजीब मिला। मैंने सफलतापूर्वक पाया है कि मुझे उचित पते से पहले 32 वर्ण प्रदान करने की आवश्यकता है, जिसे मैं कूदना चाहता हूं और उचित पता 0x08048a37 है। जब मैंनेपायथन 3 प्रिंट() बनाम पायथन 2 प्रिंट

python -c "print '-'*32+'\x37\x8a\x04\x08'" | ./MyExecutable 

शोषण के परिणामस्वरूप सफलता मिली। लेकिन, जब मैंने कोशिश की:

python3 -c "print('-'*32+'\x37\x8a\x04\x08')" | ./MyExecutable 

ऐसा नहीं हुआ। निष्पादन योग्य बस वांछित पते पर कूदने के बिना एक सेगमेंटेशन फॉल्ट में परिणाम हुआ। वास्तव में, कंसोल पर दो अलग-अलग उत्पादन में

python -c "print '-'*32+'\x37\x8a\x04\x08'" 

और

python3 -c "print('-'*32+'\x37\x8a\x04\x08')" 

परिणाम को क्रियान्वित। पात्र, निश्चित रूप से, पठनीय नहीं हैं लेकिन वे दृष्टि से अलग हैं।

मुझे आश्चर्य है कि यह क्यों हो रहा है?

उत्तर

19

अजगर 2 कोड बाइट्स, अजगर 3 कोड पाठ है कि तब बाइट्स एन्कोड किया गया है लिखते लिखते हैं। उत्तरार्द्ध इस प्रकार एक ही आउटपुट नहीं लिखेंगे; यह आपके पाइप के लिए कॉन्फ़िगर किए गए कोडेक पर निर्भर करता है।

अजगर 3 में, बजाय sys.stdout.buffer वस्तु बाइट्स लिखें:

python3 -c "import sys; sys.stdout.buffer.write(b'-'*32+b'\x37\x8a\x04\x08')" 

आप मैन्युअल \n न्यू लाइन कि print जोड़ना होगा जोड़ सकते हैं।

sys.stdout है एक io.TextIOBase object, एन्कोडिंग डेटा किसी निश्चित कोडेक के लिए यह करने के लिए लिखा है (आमतौर पर अपने स्थान के आधार पर है, लेकिन जब एक पाइप का उपयोग कर अक्सर ASCII करने के लिए दोषी,), अंतर्निहित बफर वस्तु के लिए उस पर पार करने से पहले। TextIOBase.buffer attribute आपको अंतर्निहित BufferedIOBase object पर सीधे पहुंच प्रदान करता है।

संबंधित मुद्दे