Stack Canaries

Reading time: 7 minutes

tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE)

HackTricks का समर्थन करें

StackGuard और StackShield

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 स्थानीय चर की भी सुरक्षा नहीं करता है।

Stack Smash Protector (ProPolice) -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 बाइट क्यूवर्ड है। पहले सात बाइट यादृच्छिक हैं और अंतिम बाइट एक null byte है।

x86 बाइनरी में, canary कुकी एक 0x4 बाइट ड्वॉर्ड है। पहले तीन बाइट यादृच्छिक हैं और अंतिम बाइट एक null byte है।

caution

दोनों canaries का सबसे कम महत्वपूर्ण बाइट एक null byte है क्योंकि यह स्टैक में सबसे पहले होगा जो निम्न पते से आ रहा है और इसलिए जो फ़ंक्शन स्ट्रिंग पढ़ते हैं वे इसे पढ़ने से पहले रुक जाएंगे

बायपास

canary को लीक करना और फिर इसे अपने मान (जैसे बफर ओवरफ्लो) के साथ ओवरराइट करना।

  • यदि canary को बाल प्रक्रियाओं में fork किया गया है तो इसे एक बाइट में ब्रूट-फोर्स करना संभव हो सकता है:

BF Forked & Threaded Stack Canaries

  • यदि बाइनरी में कुछ दिलचस्प लीक या मनमाना पढ़ने की कमजोरी है तो इसे लीक करना संभव हो सकता है:

Print Stack Canary

  • स्टैक में संग्रहीत पॉइंटर्स को ओवरराइट करना

स्टैक जो स्टैक ओवरफ्लो के प्रति संवेदनशील है, स्ट्रिंग्स या फ़ंक्शंस के पते को शामिल कर सकता है जिन्हें ओवरराइट किया जा सकता है ताकि कमजोरी का लाभ उठाया जा सके बिना स्टैक canary तक पहुँचने की आवश्यकता के। जाँच करें:

Pointer Redirecting

  • मास्टर और थ्रेड canary दोनों को संशोधित करना

एक बफर ओवरफ्लो एक थ्रेडेड फ़ंक्शन में जो canary से सुरक्षित है, का उपयोग थ्रेड के मास्टर canary को संशोधित करने के लिए किया जा सकता है। परिणामस्वरूप, यह शमन बेकार है क्योंकि जाँच दो समान canaries के साथ की जाती है (हालाँकि संशोधित)।

इसके अलावा, एक बफर ओवरफ्लो एक थ्रेडेड फ़ंक्शन में जो canary से सुरक्षित है, का उपयोग 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/

संदर्भ

tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE)

HackTricks का समर्थन करें