BROP - Blind Return Oriented Programming

Reading time: 7 minutes

tip

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

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

Basic Information

इस हमले का लक्ष्य है बिना किसी जानकारी के कमजोर बाइनरी के माध्यम से ROP का दुरुपयोग करना
यह हमला निम्नलिखित परिदृश्य पर आधारित है:

  • एक स्टैक भेद्यता और इसे सक्रिय करने का ज्ञान।
  • एक सर्वर एप्लिकेशन जो क्रैश के बाद पुनः प्रारंभ होता है।

Attack

1. कमजोर ऑफसेट खोजें एक और चरित्र भेजकर जब तक सर्वर में खराबी का पता नहीं चलता

2. ब्रूट-फोर्स कैनरी इसे लीक करने के लिए

3. स्टोर किए गए RBP और RIP पते को लीक करने के लिए ब्रूट-फोर्स करें

आप इन प्रक्रियाओं के बारे में अधिक जानकारी यहाँ (BF Forked & Threaded Stack Canaries) और यहाँ (BF Addresses in the Stack) पा सकते हैं।

4. स्टॉप गैजेट खोजें

यह गैजेट मूल रूप से यह पुष्टि करने की अनुमति देता है कि ROP गैजेट द्वारा कुछ दिलचस्प निष्पादित किया गया था क्योंकि निष्पादन क्रैश नहीं हुआ। आमतौर पर, यह गैजेट कुछ ऐसा होगा जो निष्पादन को रोकता है और यह ROP श्रृंखला के अंत में स्थित होता है जब किसी विशिष्ट ROP गैजेट के निष्पादन की पुष्टि करने के लिए ROP गैजेट्स की खोज की जाती है।

5. BROP गैजेट खोजें

यह तकनीक ret2csu गैजेट का उपयोग करती है। और इसका कारण यह है कि यदि आप कुछ निर्देशों के बीच में इस गैजेट तक पहुँचते हैं, तो आपको rsi और rdi को नियंत्रित करने के लिए गैजेट मिलते हैं:

https://www.scs.stanford.edu/brop/bittau-brop.pdf

ये गैजेट होंगे:

  • pop rsi; pop r15; ret
  • pop rdi; ret

ध्यान दें कि इन गैजेट्स के साथ एक फ़ंक्शन को कॉल करने के लिए 2 तर्कों को नियंत्रित करना संभव है

इसके अलावा, ध्यान दें कि ret2csu गैजेट का बहुत अद्वितीय हस्ताक्षर है क्योंकि यह स्टैक से 6 रजिस्टर को पॉप करेगा। इसलिए एक श्रृंखला भेजना जैसे:

'A' * offset + canary + rbp + ADDR + 0xdead * 6 + STOP

यदि STOP निष्पादित होता है, तो इसका अर्थ है कि एक पता जो स्टैक से 6 रजिस्टर को पॉप कर रहा है का उपयोग किया गया था। या कि उपयोग किया गया पता भी एक STOP पता था।

इस अंतिम विकल्प को हटाने के लिए एक नई श्रृंखला जैसे निम्नलिखित निष्पादित की जाती है और इसे पिछले एक की पुष्टि करने के लिए STOP गैजेट को निष्पादित नहीं करना चाहिए:

'A' * offset + canary + rbp + ADDR

ret2csu गैजेट के पते को जानकर, यह संभव है कि rsi और rdi को नियंत्रित करने के लिए गैजेट्स के पते का अनुमान लगाया जा सके

6. PLT खोजें

PLT तालिका को 0x400000 से या स्टैक से लीक किए गए RIP पते से खोजा जा सकता है (यदि PIE का उपयोग किया जा रहा है)। तालिका के प्रविष्टियाँ 16B (0x10B) द्वारा अलग होती हैं, और जब एक फ़ंक्शन को कॉल किया जाता है तो सर्वर क्रैश नहीं होता है भले ही तर्क सही न हों। इसके अलावा, एक प्रविष्टि के पते की जाँच करना PLT + 6B भी क्रैश नहीं होता क्योंकि यह पहला कोड है जो निष्पादित होता है।

इसलिए, निम्नलिखित व्यवहारों की जाँच करके PLT तालिका को खोजना संभव है:

  • 'A' * offset + canary + rbp + ADDR + STOP -> कोई क्रैश नहीं
  • 'A' * offset + canary + rbp + (ADDR + 0x6) + STOP -> कोई क्रैश नहीं
  • 'A' * offset + canary + rbp + (ADDR + 0x10) + STOP -> कोई क्रैश नहीं

7. strcmp खोजें

strcmp फ़ंक्शन रजिस्टर rdx को तुलना की जा रही स्ट्रिंग की लंबाई पर सेट करता है। ध्यान दें कि rdx तीसरा तर्क है और हमें इसे 0 से बड़ा होना चाहिए ताकि बाद में write का उपयोग करके प्रोग्राम को लीक किया जा सके।

हम अब फ़ंक्शनों के पहले 2 तर्कों को नियंत्रित कर सकते हैं, इस व्यवहार के आधार पर strcmp के स्थान को PLT में खोजना संभव है:

  • strcmp(<non read addr>, <non read addr>) -> क्रैश
  • strcmp(<non read addr>, <read addr>) -> क्रैश
  • strcmp(<read addr>, <non read addr>) -> क्रैश
  • strcmp(<read addr>, <read addr>) -> कोई क्रैश नहीं

इसकी जाँच करने के लिए PLT तालिका के प्रत्येक प्रविष्टि को कॉल करना या PLT धीमी पथ का उपयोग करना संभव है, जो मूल रूप से PLT तालिका में एक प्रविष्टि को कॉल करने पर आधारित है + 0xb (जो dlresolve को कॉल करता है) और स्टैक में प्रविष्टि संख्या जिसे आप जांचना चाहते हैं (शून्य से शुरू) को स्कैन करने के लिए:

  • strcmp(<non read addr>, <read addr>) -> क्रैश
  • b'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + p64(0x300) + p64(0x0) + (PLT + 0xb ) + p64(ENTRY) + STOP -> क्रैश होगा
  • strcmp(<read addr>, <non read addr>) -> क्रैश
  • b'A' * offset + canary + rbp + (BROP + 0x9) + p64(0x300) + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb ) + p64(ENTRY) + STOP
  • strcmp(<read addr>, <read addr>) -> कोई क्रैश नहीं
  • b'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb ) + p64(ENTRY) + STOP

याद रखें कि:

  • BROP + 0x7 pop RSI; pop R15; ret; की ओर इशारा करता है
  • BROP + 0x9 pop RDI; ret; की ओर इशारा करता है
  • PLT + 0xb dl_resolve को कॉल करने की ओर इशारा करता है।

strcmp को खोजने के बाद, rdx को 0 से बड़े मान पर सेट करना संभव है।

tip

ध्यान दें कि आमतौर पर rdx पहले से ही 0 से बड़ा मान रखेगा, इसलिए यह कदम आवश्यक नहीं हो सकता है।

8. Write या समकक्ष खोजें

अंत में, डेटा को एक्सफिल्ट्रेट करने के लिए एक गैजेट की आवश्यकता होती है ताकि बाइनरी को एक्सफिल्ट्रेट किया जा सके। और इस समय यह संभव है कि 2 तर्कों को नियंत्रित करें और rdx को 0 से बड़ा सेट करें।

इसके लिए 3 सामान्य फ़ंक्शन हैं जिनका दुरुपयोग किया जा सकता है:

  • puts(data)
  • dprintf(fd, data)
  • write(fd, data, len(data)

हालांकि, मूल पेपर केवल write का उल्लेख करता है, इसलिए आइए इसके बारे में बात करें:

वर्तमान समस्या यह है कि हमें नहीं पता write फ़ंक्शन PLT के अंदर कहाँ है और हमें नहीं पता डेटा को हमारे सॉकेट पर भेजने के लिए fd संख्या

हालांकि, हम जानते हैं PLT तालिका कहाँ है और इसके व्यवहार के आधार पर write को खोजना संभव है। और हम सर्वर के साथ कई कनेक्शन बना सकते हैं और एक उच्च FD का उपयोग कर सकते हैं यह उम्मीद करते हुए कि यह हमारे कुछ कनेक्शनों से मेल खाता है।

इन फ़ंक्शनों को खोजने के लिए व्यवहार हस्ताक्षर:

  • 'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + p64(0) + p64(0) + (PLT + 0xb) + p64(ENTRY) + STOP -> यदि डेटा प्रिंट होता है, तो इसका अर्थ है कि puts मिला
  • 'A' * offset + canary + rbp + (BROP + 0x9) + FD + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb) + p64(ENTRY) + STOP -> यदि डेटा प्रिंट होता है, तो इसका अर्थ है कि dprintf मिला
  • 'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + (RIP + 0x1) + p64(0x0) + (PLT + 0xb ) + p64(STRCMP ENTRY) + (BROP + 0x9) + FD + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb) + p64(ENTRY) + STOP -> यदि डेटा प्रिंट होता है, तो इसका अर्थ है कि write मिला

Automatic Exploitation

References

tip

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

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