Skip to content
KitploitKITPLOIT
उपकरणएक्सप्लॉइटब्लॉग
Log in
जमा करें
उपकरणएक्सप्लॉइटब्लॉग
जमा करें

हैकिंग, पेनटेस्ट और साइबर सुरक्षा उपकरण आपके सुरक्षा शस्त्रागार के लिए!

Kitploit हैकिंग, साइबर सुरक्षा और पेंटेस्टिंग टूल्स की एक निर्देशिका है। कमजोरियों को खोजने, सिस्टम का विश्लेषण करने, परीक्षण को स्वचालित करने और अपनी सुरक्षा को मजबूत करने के लिए नवीनतम प्रोजेक्ट अपडेट खोजें।

फ़ीडसंपर्कगोपनीयता© 2026 Kitploit

टूल निर्देशिका

श्रेणियाँ

सभी श्रेणियाँ देखें
Loading categories
CVE-2020-28018 — Exim Use-After-Free (CVE-2020-28018) के लिए एक्सप्लॉइट, जो मेमोरी भ्रष्टाचार प्रिमिटिव के माध्यम से रिमोट कोड निष्पादन प्राप्त करता है, जिसमें मनमाना रीड/राइट और हीप लीक शामिल हैं, साथ ही वैकल्पिक लोकल प्रिविलेज एस्केलेशन चेन भी। | Kitploit
उपकरण/GitHubGitHub/dorkerdevil/cve-2020-28018
विशेषाधिकार वृद्धिमेमोरी फोरेंसिकभेद्यता विश्लेषणशोषणरिमोट एक्सेस टूलपेलोड डेवलपमेंटबाइनरी शोषण
GitHubdorkerdevil/cve-2020-28018

CVE-2020-28018

Exim Use-After-Free (CVE-2020-28018) के लिए एक्सप्लॉइट, जो मेमोरी भ्रष्टाचार प्रिमिटिव के माध्यम से रिमोट कोड निष्पादन प्राप्त करता है, जिसमें मनमाना रीड/राइट और हीप लीक शामिल हैं, साथ ही वैकल्पिक लोकल प्रिविलेज एस्केलेशन चेन भी।

रिपॉजिटरी देखें
71235 साल पहलेअभी तक समीक्षित नहीं

सबसे लोकप्रिय

सभी देखें →

हमारे समुदाय द्वारा सबसे अधिक उपयोग किए जाने वाले उपकरण खोजें।

सभी उपकरण खोजें

हमारे उपकरणों का संग्रह ब्राउज़ करें

सभी उपकरण देखें →
साझा करें

CVE-2020-28018: Exim Use-after-free (UAF) जो RCE की ओर ले जाता है

परिचय

tls-openssl.c में एक Use-after-free (UAF) भेद्यता मौजूद है जो दूरस्थ अनधिकृत हमलावरों को आंतरिक मेमोरी डेटा को दूषित करने की अनुमति देती है, इस प्रकार अंततः रिमोट कोड एक्सेक्यूशन प्राप्त होता है।

प्रिमिटिव्स:

  • मेमोरी लीकेज
  • आर्बिट्रेरी रीड प्रिमिटिव
  • राइट-व्हाट-व्हेयर प्रिमिटिव

इन सभी प्रिमिटिव्स को एक साथ श्रृंखलाबद्ध करके उपयोग करने पर सभी उपलब्ध एक्सप्लॉइट मिटिगेशन्स को पूरी तरह से बायपास करना संभव है, अंततः exim यूज़र के रूप में रिमोट कोड एक्सेक्यूशन तक पहुँचते हुए।

यह भेद्यता भेद्यताओं की एक विशाल सूची के बीच जारी की गई है, आधिकारिक Qualys रिपोर्ट RCE प्राप्त होने के बाद Local Privilege Escalation (LPE) करने के लिए Use-After-Free को CVE-2020-28008 के साथ श्रृंखलाबद्ध करती है।

पूर्व-आवश्यकताएँ

exim को निम्नलिखित तरीके से कॉन्फ़िगर / संकलित किया जाना चाहिए:

  • TLS सक्षम है
  • OpenSSL उपयोग किया जाता है (GnuTLS के बजाय)
  • Exim भेद्य संस्करणों में से एक है
  • X_PIPE_CONNECT अक्षम है

आप checker.py स्क्रिप्ट का उपयोग कर सकते हैं यह जाँचने के लिए कि क्या कोई दूरस्थ सर्वर भेद्य संस्करण पर है और उसके पास शोषण के लिए आवश्यक कुछ आवश्यकताएँ हैं या नहीं।

[!] checker.py भेद्यता को ट्रिगर नहीं करती, केवल भेद्य संस्करण की जाँच करती है, जाँचती है कि PIPELINING और TLS सक्षम हैं या नहीं। इसका मतलब है कि यह चेकर पैच की जाँच नहीं करता, जिसका अर्थ है कि यह गलत सकारात्मक परिणाम उत्पन्न कर सकता है।

भेद्य कोड

जैसा कि हम पहले से जानते हैं, भेद्यता tls-openssl.c में स्थित है।

/*************************************************
*         Write bytes down TLS channel           *
*************************************************/

/*
Arguments:
  ct_ctx    client context pointer, or NULL for the one global server context
  buff      buffer of data
  len       number of bytes
  more	    further data expected soon

Returns:    the number of bytes after a successful write,
            -1 after a failed write

Used by both server-side and client-side TLS.
*/

int
tls_write(void * ct_ctx, const uschar *buff, size_t len, BOOL more)
{
int outbytes, error, left;
SSL * ssl = ct_ctx ? ((exim_openssl_client_tls_ctx *)ct_ctx)->ssl : server_ssl;
static gstring * corked = NULL;

DEBUG(D_tls) debug_printf("%s(%p, %lu%s)\n", __FUNCTION__,
  buff, (unsigned long)len, more ? ", more" : "");

/* Lacking a CORK or MSG_MORE facility (such as GnuTLS has) we copy data when
"more" is notified.  This hack is only ok if small amounts are involved AND only
one stream does it, in one context (i.e. no store reset).  Currently it is used
for the responses to the received SMTP MAIL , RCPT, DATA sequence, only. */
/*XXX + if PIPE_COMMAND, banner & ehlo-resp for smmtp-on-connect. Suspect there's
a store reset there. */

if (!ct_ctx && (more || corked))
  {
#ifdef EXPERIMENTAL_PIPE_CONNECT
  int save_pool = store_pool;
  store_pool = POOL_PERM;
#endif

  corked = string_catn(corked, buff, len);

#ifdef EXPERIMENTAL_PIPE_CONNECT
  store_pool = save_pool;
#endif

  if (more)
    return len;
  buff = CUS corked->s;
  len = corked->ptr;
  corked = NULL;
  }

for (left = len; left > 0;)
  {
  DEBUG(D_tls) debug_printf("SSL_write(%p, %p, %d)\n", ssl, buff, left);
  outbytes = SSL_write(ssl, CS buff, left);
  error = SSL_get_error(ssl, outbytes);
  DEBUG(D_tls) debug_printf("outbytes=%d error=%d\n", outbytes, error);
  switch (error)
    {
    case SSL_ERROR_SSL:
      ERR_error_string_n(ERR_get_error(), ssl_errstring, sizeof(ssl_errstring));
      log_write(0, LOG_MAIN, "TLS error (SSL_write): %s", ssl_errstring);
      return -1;

    case SSL_ERROR_NONE:
      left -= outbytes;
      buff += outbytes;
      break;

    case SSL_ERROR_ZERO_RETURN:
      log_write(0, LOG_MAIN, "SSL channel closed on write");
      return -1;

    case SSL_ERROR_SYSCALL:
      log_write(0, LOG_MAIN, "SSL_write: (from %s) syscall: %s",
	sender_fullhost ? sender_fullhost : US"<unknown>",
	strerror(errno));
      return -1;

    default:
      log_write(0, LOG_MAIN, "SSL_write error %d", error);
      return -1;
    }
  }
return len;
}

smtp_setup_msg() मुख्य फ़ंक्शन है जो क्लाइंट से संदेश पढ़ने का कार्य करता है।

विशिष्ट परिस्थितियों में, smtp_reset() को कॉल किया जाता है, जो सभी बफ़र्स और मानों की सफाई करता है।

यह निम्नलिखित स्थितियों में हो सकता है:

  • HELO/EHLO प्राप्त होता है
  • STARTTLS प्राप्त होता है
  • RSET प्राप्त होता है
  • smtp_setup_msg() की शुरुआत में

smtp_reset() के अंत में, store_reset() के लिए एक कॉल की जाती है।

store_reset एक मैक्रो है जो store_reset_3() फ़ंक्शन को रैप करता है।

स्टोर फ़ंक्शन केवल ऐसे फ़ंक्शन हैं जो डायनामिक मेमोरी का प्रबंधन करते हैं।

Exim malloc से प्राप्त ब्लॉक्स पर पूल आवंटक (pool allocator) का उपयोग करता है।

एक दिलचस्प कार्यक्षमता भी है जो एक ग्रोएबल स्ट्रिंग (growable string) कार्यान्वयन है।

gstring स्ट्रक्चर:

typedef struct gstring {
  int   size;           /* Current capacity of string memory */
  int   ptr;            /* Offset at which to append further chars */
  uschar * s;           /* The string memory */
} gstring;

नई स्ट्रिंग को जोड़ने के लिए अधिक स्थान की आवश्यकता होने पर, यह gstring_grow() को कॉल करता है।

वह फ़ंक्शन पहले store_extend_3() को कॉल करने का प्रयास करता है, वह फ़ंक्शन उसी पूल ब्लॉक के भीतर मेमोरी को बढ़ाने का प्रयास करता है।

यह तब उपयोगी हो सकता है जब इनपुट की लंबाई ज्ञात न हो, लेकिन यदि इसके बाद अधिक मेमोरी आवंटित की गई थी तो हम इसे बढ़ा नहीं पाएंगे।

फिर gstring_grow() store_newblock_3() को कॉल करता है जो केवल नई मेमोरी लौटाता है और पिछली मेमोरी में पहले से मौजूद बाइट्स को नई मेमोरी में कॉपी करता है।

फिर g->s पॉइंटर को gstring_catn() से पुनर्स्थापित किया जाता है।

फ़ंक्शन tls_write() में, हम देख सकते हैं कि more नामक एक BOOL है।

यह इंगित करता है कि डेटा को उपयोगकर्ता को वापस लौटाने से पहले स्ट्रिंग बफ़र में और अधिक सामग्री कॉपी की जानी है या नहीं।

यदि ऐसा है, तो पॉइंटर NULL नहीं किया जाता।

यदि नहीं, तो स्ट्रिंग बफ़र में निहित डेटा उपयोगकर्ता को लौटा दिया जाता है।

यह कार्यक्षमता Use-After-Free को ट्रिगर करने के कुछ दिलचस्प तरीके खोलती है।

पहले, gstring स्ट्रक्चर का पॉइंटर एक स्टैटिक वेरिएबल में संग्रहीत होता है, इसका मतलब है कि भविष्य में tls_write() के कॉल पर हम इसका उपयोग कर पाएंगे।

हम बफ़र को मुक्त (free) करके फिर उसका उपयोग कैसे कर सकते हैं?

हमें smtp_setup_msg() को smtp_reset() कॉल करवाना होगा जब हमारा एक बफ़र अभी भी server_corked पर हो (NULL नहीं किया गया)।

रीसेट के बाद, यदि हम किसी तरह tls_write() को कॉल करते हैं, तो पॉइंटर अभी भी वहाँ होगा, इस प्रकार मेमोरी मुक्त होने के बाद हमें इसका उपयोग करने की अनुमति मिलती है।

smtp_reset() POOL_MAIN की सभी मेमोरी मुक्त करता है, जिसमें हमारा बफ़र समाहित है।

Use-After-Free ट्रिगर करना

Use-After-Free को नियंत्रित करने के लिए हमें पहले एक नया कनेक्शन प्रारंभ करना होगा।

चूंकि हम tls_write() का शोषण करना चाहते हैं, हमें पहले एक नया TLS सत्र शुरू करना होगा।

इसलिए पहले हम EHLO कमांड भेजते हैं, उसके बाद TLS कनेक्शन शुरू करने के लिए STARTTLS भेजते हैं।

फिर more को 1 बनाने के लिए हम एक कमांड को पाइपलाइन करते हैं, और अंतिम कमांड एक NOOP का आधा होगा।

हम TLS कनेक्शन बंद कर देते हैं और NOOP कमांड का शेष भाग भेजते हैं।

अब हम फिर से EHLO भेजते हैं, जो smtp_reset को कॉल करवाएगा और हमारे बफ़र को मुक्त कर देगा।

अब हमें tls_write() का फिर से उपयोग करने में सक्षम होने के लिए एक और TLS कनेक्शन शुरू करना होगा।

हम STARTTLS भेजते हैं।

अब सर्वर को कोई भी कमांड भेजने पर प्रतिक्रिया लौटाने के लिए tls_write() कॉल होगा।

लेकिन... server_corked में अभी भी मुक्त मेमोरी में कहीं एक पॉइंटर है।

और वह डेटा अन्य फ़ंक्शन द्वारा उपयोग किया जा सकता है क्योंकि यह मुक्त है...इसलिए हमारा gstring स्ट्रक्चर यादृच्छिक बाइनरी डेटा से दूषित हो जाएगा।

UAF ट्रिगर करने का यह परिणाम है:

gef➤  p *corked
$1 = {
  size = 0x54595c9c, 
  ptr = 0xa7e800ba, 
  s = 0x7e35043433160bd3 <error: Cannot access memory at address 0x7e35043433160bd3>
}
gef➤  p corked
$2 = (gstring *) 0x555ad3be1b58
gef➤  

यह स्ट्रक्चर इसी तरह से होता है जब हम STARTTLS के बाद अपने कमांड के लिए tls_write() में प्रवेश करते हैं।

टूल डाउनलोड करें