Stack Canaries
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
StackGuard एक विशेष मान जिसे canary कहा जाता है, को EIP (Extended Instruction Pointer) से पहले डालता है, विशेष रूप से 0x000aff0d
(जो null, newline, EOF, carriage return का प्रतिनिधित्व करता है) बफर ओवरफ्लो से सुरक्षा के लिए। हालाँकि, recv()
, memcpy()
, read()
, और bcopy()
जैसी फ़ंक्शन कमजोर रहती हैं, और यह EBP (Base Pointer) की सुरक्षा नहीं करता है।
StackShield StackGuard की तुलना में एक अधिक परिष्कृत दृष्टिकोण अपनाता है, जो एक Global Return Stack बनाए रखता है, जो सभी रिटर्न पते (EIPs) को संग्रहीत करता है। यह सेटअप सुनिश्चित करता है कि कोई भी ओवरफ्लो नुकसान नहीं पहुँचाता है, क्योंकि यह संग्रहीत और वास्तविक रिटर्न पते के बीच तुलना की अनुमति देता है ताकि ओवरफ्लो की घटनाओं का पता लगाया जा सके। इसके अतिरिक्त, StackShield रिटर्न पते की जांच एक सीमा मान के खिलाफ कर सकता है ताकि यह पता लगाया जा सके कि क्या EIP अपेक्षित डेटा स्थान के बाहर इंगित करता है। हालाँकि, इस सुरक्षा को Return-to-libc, ROP (Return-Oriented Programming), या ret2ret जैसी तकनीकों के माध्यम से दरकिनार किया जा सकता है, यह इंगित करता है कि StackShield स्थानीय चर की भी सुरक्षा नहीं करता है।
-fstack-protector
:यह तंत्र EBP से पहले एक canary रखता है, और स्थानीय चर को पुनर्गठित करता है ताकि बफर को उच्च मेमोरी पते पर रखा जा सके, जिससे वे अन्य चर को ओवरराइट नहीं कर सकें। यह स्थानीय चर के ऊपर स्टैक पर पास किए गए तर्कों को सुरक्षित रूप से कॉपी करता है और इन कॉपियों का उपयोग तर्कों के रूप में करता है। हालाँकि, यह 8 तत्वों से कम वाले ऐरे या उपयोगकर्ता की संरचना के भीतर बफर की सुरक्षा नहीं करता है।
canary एक यादृच्छिक संख्या है जो /dev/urandom
से प्राप्त होती है या इसका डिफ़ॉल्ट मान 0xff0a0000
होता है। इसे TLS (Thread Local Storage) में संग्रहीत किया जाता है, जिससे थ्रेड्स के बीच साझा मेमोरी स्थानों में थ्रेड-विशिष्ट वैश्विक या स्थिर चर हो सकते हैं। ये चर प्रारंभ में माता-पिता प्रक्रिया से कॉपी किए जाते हैं, और बाल प्रक्रियाएँ अपने डेटा को माता-पिता या भाई-बहनों को प्रभावित किए बिना बदल सकती हैं। हालाँकि, यदि fork()
का उपयोग बिना नए canary बनाए किया जाता है, तो सभी प्रक्रियाएँ (माता-पिता और बच्चे) एक ही canary साझा करती हैं, जिससे यह कमजोर हो जाता है। i386 आर्किटेक्चर पर, canary gs:0x14
पर संग्रहीत होता है, और x86_64 पर, fs:0x28
पर।
यह स्थानीय सुरक्षा उन फ़ंक्शनों की पहचान करती है जिनमें बफर हमलों के प्रति संवेदनशील होते हैं और इन फ़ंक्शनों की शुरुआत में कोड इंजेक्ट करती है ताकि canary को रखा जा सके, और अंत में इसकी अखंडता की पुष्टि करने के लिए।
जब एक वेब सर्वर fork()
का उपयोग करता है, तो यह canary बाइट को बाइट द्वारा अनुमान लगाने के लिए एक ब्रूट-फोर्स हमले की अनुमति देता है। हालाँकि, fork()
के बाद execve()
का उपयोग मेमोरी स्थान को ओवरराइट करता है, जिससे हमले को नकारा जाता है। vfork()
बच्चे प्रक्रिया को डुप्लिकेशन के बिना निष्पादित करने की अनुमति देता है जब तक कि यह लिखने का प्रयास नहीं करता, जिस बिंदु पर एक डुप्लिकेट बनाया जाता है, जो प्रक्रिया निर्माण और मेमोरी प्रबंधन के लिए एक अलग दृष्टिकोण प्रदान करता है।
x64
बाइनरी में, canary कुकी एक 0x8
बाइट qword है। पहले सात बाइट यादृच्छिक हैं और अंतिम बाइट एक null byte है।
x86
बाइनरी में, canary कुकी एक 0x4
बाइट dword है। पहले तीन बाइट यादृच्छिक हैं और अंतिम बाइट एक null byte है।
दोनों canaries का सबसे कम महत्वपूर्ण बाइट एक null byte है क्योंकि यह स्टैक में सबसे पहले होगा जो निम्न पते से आता है और इसलिए जो फ़ंक्शन स्ट्रिंग पढ़ते हैं वे इसे पढ़ने से पहले रुक जाएंगे।
canary को लीक करना और फिर इसे अपने मान (जैसे बफर ओवरफ्लो) के साथ ओवरराइट करना।
यदि canary बच्चे प्रक्रियाओं में fork किया गया है तो इसे एक बाइट में brute-force करना संभव हो सकता है:
यदि बाइनरी में कुछ दिलचस्प लीक या मनमाना पढ़ने की कमजोरी है तो इसे लीक करना संभव हो सकता है:
स्टैक में संग्रहीत पॉइंटर्स को ओवरराइट करना
स्टैक जो स्टैक ओवरफ्लो के प्रति संवेदनशील है, स्ट्रिंग्स या फ़ंक्शंस के पते को शामिल कर सकता है जिन्हें ओवरराइट किया जा सकता है ताकि कमजोरी का लाभ उठाया जा सके बिना स्टैक canary तक पहुँचने की आवश्यकता के। जाँच करें:
मास्टर और थ्रेड canary दोनों को संशोधित करना
एक थ्रेडेड फ़ंक्शन में ओवरफ्लो का उपयोग करके थ्रेड के मास्टर canary को संशोधित किया जा सकता है। परिणामस्वरूप, यह शमन बेकार है क्योंकि जांच दो समान (हालांकि संशोधित) canaries के साथ की जाती है।
इसके अलावा, एक थ्रेडेड फ़ंक्शन में ओवरफ्लो का उपयोग करके TLS में संग्रहीत मास्टर canary को संशोधित किया जा सकता है। इसका कारण यह है कि, यह संभव हो सकता है कि थ्रेड के स्टैक में bof के माध्यम से TLS में संग्रहीत मेमोरी स्थिति तक पहुँचा जा सके (और इसलिए, canary)। इस परिणामस्वरूप, यह शमन बेकार है क्योंकि जांच दो समान (हालांकि संशोधित) canaries के साथ की जाती है। यह हमला लिखने में किया गया है: http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads
जाँच करें https://www.slideshare.net/codeblue_jp/master-canary-forging-by-yuki-koike-code-blue-2015 की प्रस्तुति जो बताती है कि आमतौर पर TLS को mmap
द्वारा संग्रहीत किया जाता है और जब एक थ्रेड का स्टैक बनाया जाता है तो यह भी mmap
द्वारा उत्पन्न होता है, जो पिछले लिखने में दिखाए गए ओवरफ्लो की अनुमति दे सकता है।
__stack_chk_fail
के GOT प्रविष्टि को संशोधित करना
यदि बाइनरी में Partial RELRO है, तो आप __stack_chk_fail
के GOT प्रविष्टि को एक डमी फ़ंक्शन में संशोधित करने के लिए एक मनमाना लेखन का उपयोग कर सकते हैं जो यदि canary संशोधित किया जाता है तो कार्यक्रम को अवरुद्ध नहीं करता है।
यह हमला लिखने में किया गया है: https://7rocky.github.io/en/ctf/other/securinets-ctf/scrambler/
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)