FlawOpen

flawopen.com/Teardowns/cve-2023-6246-glibc-syslog-heap-buffer-overflow

● CVE-2023-6246 · CVSS 7.8 · उच्च
सुरक्षा अनुसंधान · FlawOpen

CVE-2023-6246: glibc syslog में heap overflow

CVE-2023-6246 लंबे log header से होने वाला glibc syslog heap overflow है। अपने डिस्ट्रिब्यूशन का patched glibc package लगाएँ।

💡 आसान भाषा में (ELI5)

एक कर्मचारी की कल्पना करें जो छोटे पैमाने से पार्सल और उसका लेबल मापता है। लेबल पैमाने में नहीं समाता, इसलिए गणना आवश्यक जगह दर्ज नहीं करती। कर्मचारी बहुत छोटा डिब्बा मँगाता है और उसमें पूरा लेबल व सामग्री छापने की कोशिश करता है। glibc में लंबा syslog header आवश्यक आकार को दर्ज होने से रोक सकता था, जिससे logger heap में बहुत कम memory allocate करता था।

इस पेज के मुख्य शब्द

glibc
GNU C Library अधिकांश Linux programs द्वारा उपयोग किए जाने वाले मूल C runtime functions देती है।
__vsyslog_internal()
glibc का internal implementation, जिसका उपयोग syslog() और vsyslog() message तथा SYSLOG_HEADER format करके system logger को भेजने के लिए करते हैं।
SYSLOG_HEADER
syslog message से पहले format होने वाला priority और पहचान prefix। इसमें program name या openlog() से दिया गया ident हो सकता है।
Heap-based buffer overflow (CWE-122)
Heap में allocate हुए buffer की सीमा से आगे write होना। यहाँ लंबा नाम वाला header शुरुआती fixed buffer में न समाने पर size calculation विफल हुई।

फ्रेमवर्क मैपिंग

  • इस गाइड में बताई गई कमजोरी के लिए CWE संदर्भ: CWE-122

मूल कारण विश्लेषण (Root Cause)

glibc advisory के अनुसार, लंबे program name वाला SYSLOG_HEADER format करते समय __vsyslog_internal() आवश्यक buffer size अपडेट नहीं करता था। असुरक्षित code में header length l 1,024-byte stack buffer के बराबर या उससे अधिक हो सकती थी, जिससे message body format करने और bufsize तय करने वाली branch छूट जाती थी। बाद का heap allocation path unset/zero size उपयोग करता और फिर छोटे allocation में header और message लिखता था। Qualys के अनुसार लंबा नाम caller-controlled argv[0] के basename या 1,024 bytes से बड़े openlog() ident से आ सकता है; इस path पर logging करने वाला vulnerable setuid program सुरक्षा प्रभाव पैदा कर सकता है। Qualys ने Fedora 38 पर su के जरिए local privilege escalation दिखाई। जोखिम local access, configuration और call path पर निर्भर है; यह सामान्य remote syslog exploit नहीं है।

हमले का चरण-दर-चरण प्रवाह

चरण 1

स्थानीय शर्त

स्थानीय प्रक्रिया को प्रभावित glibc वाले program के जरिए syslog() या vsyslog() तक पहुँचना होगा। सुरक्षा प्रभाव के लिए privileged caller और ऐसा path आवश्यक है जो program-name prefix को सुरक्षित, सीमित ident से न बदले।

चरण 2

लंबा header

Header शुरुआती buffer से बड़ा है|SYSLOG_HEADER में लंबा program name (argv[0] के basename से बना __progname) या लंबा openlog() ident शामिल होता है। Qualys के अनुसार trigger value 1,024 bytes से बड़ा होना चाहिए।

चरण 3

अधूरी गणना

Size calculation वाली branch छूटती है|जब header 1,024-byte stack buffer में नहीं समाता, vulnerable code bufsize निकालने वाली branch छोड़ देता है। बाद के heap allocation में header और formatted message के लिए पर्याप्त जगह नहीं रहती।

चरण 4

मेमोरी पर प्रभाव

Write allocation सीमा से आगे जाता है|Logger छोटे buffer में header और message लिखकर heap memory को corrupt करता है। Qualys ने Fedora 38 पर su के माध्यम से local privilege escalation दिखाई; हर app या distribution पर वही reachability न मानें।

सोर्स कोड: कमज़ोर बनाम सुरक्षित कार्यान्वयन

पुरानी branch header के stack buffer में न समाने पर bufsize को शून्य छोड़ देती थी, जिससे heap fallback बहुत कम memory ले सकता था। सुधार इस स्थिति में stack buffer को अनुपयोगी चिह्नित करता है, body length मापने के लिए उसमें format करता है, l + vl दर्ज करता है और आवश्यक size के साथ मौजूदा allocation path पर चलता है। ये upstream patch के केंद्रित अंश हैं, पूर्ण standalone functions नहीं।

सोर्स अंश: misc/syslog.c

कमज़ोर कार्यान्वयन
/* commit 6bd0e4efcc78 से पहले misc/syslog.c का संबंधित अंश। */
char bufs[1024];
char *buf = NULL;
size_t bufsize = 0;
...
if (0 <= l && l < sizeof bufs)
  {
    va_list apc;
    va_copy (apc, ap);
    int vl = __vsnprintf_internal (bufs + l, sizeof bufs - l, fmt, apc,
                                   mode_flags);
    if (0 <= vl && vl < sizeof bufs - l)
      buf = bufs;
    bufsize = l + vl;
    va_end (apc);
  }
/* लंबा header ऊपर वाली size सेट करने की branch को छोड़ देता है। */
सुरक्षित और सुदृढ़ फ़िक्स
/* commit 6bd0e4efcc78 के बाद misc/syslog.c का संबंधित अंश। */
char bufs[1024];
char *buf = bufs;
size_t bufsize;
...
if (0 <= l && l < sizeof bufs)
  {
    pos = bufs + l;
    len = sizeof (bufs) - l;
  }
else
  {
    buf = NULL;
    pos = bufs;
    len = sizeof (bufs);
  }
vl = __vsnprintf_internal (pos, len, fmt, apc, mode_flags);
if (!(0 <= vl && vl < len))
  buf = NULL;
bufsize = l + vl;

इंजीनियरिंग और सिस्टम सुरक्षा चेकलिस्ट

स्रोत