flawopen.com/Teardowns/cve-2023-6246-glibc-syslog-heap-buffer-overflow
CVE-2023-6246: glibc syslog में heap overflow
CVE-2023-6246 लंबे log header से होने वाला glibc syslog heap overflow है। अपने डिस्ट्रिब्यूशन का patched glibc package लगाएँ।
एक कर्मचारी की कल्पना करें जो छोटे पैमाने से पार्सल और उसका लेबल मापता है। लेबल पैमाने में नहीं समाता, इसलिए गणना आवश्यक जगह दर्ज नहीं करती। कर्मचारी बहुत छोटा डिब्बा मँगाता है और उसमें पूरा लेबल व सामग्री छापने की कोशिश करता है। 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_HEADERformat करके 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 नहीं है।
हमले का चरण-दर-चरण प्रवाह
स्थानीय शर्त
स्थानीय प्रक्रिया को प्रभावित glibc वाले program के जरिए syslog() या vsyslog() तक पहुँचना होगा। सुरक्षा प्रभाव के लिए privileged caller और ऐसा path आवश्यक है जो program-name prefix को सुरक्षित, सीमित ident से न बदले।
लंबा header
Header शुरुआती buffer से बड़ा है|SYSLOG_HEADER में लंबा program name (argv[0] के basename से बना __progname) या लंबा openlog() ident शामिल होता है। Qualys के अनुसार trigger value 1,024 bytes से बड़ा होना चाहिए।
अधूरी गणना
Size calculation वाली branch छूटती है|जब header 1,024-byte stack buffer में नहीं समाता, vulnerable code bufsize निकालने वाली branch छोड़ देता है। बाद के heap allocation में header और formatted message के लिए पर्याप्त जगह नहीं रहती।
मेमोरी पर प्रभाव
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;
इंजीनियरिंग और सिस्टम सुरक्षा चेकलिस्ट
- ✓अपनी distribution और release के लिए प्रकाशित fixed glibc package install करें; केवल upstream version से package status न मानें।
- ✓Distribution advisory देखें: upstream fixes glibc 2.39, 2.38-42, 2.37-57 और 2.36-126 हैं।
- ✓
syslog()याvsyslog()call करने वाले privileged programs की सूची बनाएँ और देखें कि caller-controlled names याopenlog()idents header तक पहुँचते हैं या नहीं। - ✓Formatted logging में शुरुआती fixed buffer छोटा हो तब भी header और body का पूरा size track करें; लंबे program name का regression test जोड़ें और allocation arithmetic जाँचें।