
02364eff880ba62afac67bcceebafade2b40d21f से पहले SmallBASIC पर ग्लोबल बफ़र ओवरफ़्लो की रिपोर्ट और PoC
SmallBASIC एक तेज़ और सीखने में आसान BASIC भाषा इंटरप्रेटर है जो रोज़ाना की गणनाओं, स्क्रिप्ट और प्रोटोटाइप के लिए आदर्श है। SmallBASIC में त्रिकोणमितीय, मैट्रिक्स और बीजगणित फलन, एक अंतर्निहित IDE, एक शक्तिशाली स्ट्रिंग लाइब्रेरी, सिस्टम, ध्वनि और ग्राफ़िक कमांड के साथ संरचित प्रोग्रामिंग सिंटैक्स शामिल है।
src/platform/sdl/main.cpp की पंक्ति 277 में, strcpy को argv को ग्लोबल वेरिएबल opt_command में कॉपी करने के लिए बुलाया गया है, जो src/common/smbas.h में परिभाषित है। यह ग्लोबल वेरिएबल एक निश्चित आकार का सरणी है, उसी फ़ाइल में परिभाषित OPT_CMD_CZ मैक्रो के अनुसार।
// src/common/smbas.h:105
EXTERN char opt_command[OPT_CMD_CZ] //
// src/platform/sdl/main.cpp:263
while (1) {
int option_index = 0;
int c = getopt_long(argc, argv, "hvkc:f:r:x:n:m:e:d:p:", OPTIONS, &option_index);
if (c == -1) {
// no more options
if (!option_index) {
for (int i = 1; i < argc; i++) {
const char *s = argv[i];
int len = strlen(s);
if (runFile == NULL
&& ((strcasecmp(s + len - 4, ".bas") == 0 && access(s, 0) == 0)
|| (strstr(s, "://") != NULL))) {
runFile = strdup(s);
} else if (chdir(s) != 0) {
strcpy(opt_command, s); // VULNERABLE
}
}
}
break;
}
src/common/smbas.h के अनुसार, OPT_CMD_CZ को 1024 के रूप में परिभाषित किया गया है।
#define OPT_CMD_CZ 1024
strlcpy फ़ंक्शन के विपरीत, strcpy यह जाँच नहीं करता कि कितने बाइट कॉपी किए जाने हैं। इसलिए opt_command सरणी में 1024 से अधिक बाइट कॉपी किए जा सकते हैं। चूंकि कमांड लाइन तर्क 1024 बाइट से अधिक लंबा हो सकता है, इनपुट अन्य वस्तुओं को ओवरराइट कर सकता है। इससे प्रोग्राम sbasicg अप्रत्याशित व्यवहार कर सकता है।
ध्यान दें कि विंडोज़ में कमांड प्रॉम्प्ट पर आप जिस स्ट्रिंग का अधिकतम लंबाई उपयोग कर सकते हैं वह 8191 कैरेक्टर है। लिनक्स में, लंबाई ARG_MAX और MAX_ARG_STRINGS पर निर्भर करती है।
SmallBASIC प्रोजेक्ट बनाएँ, फिर चलाएँ
$ src/platform/sdl/sbasicg $(python -c 'print("a"*1024)')
यह main फ़ंक्शन में लागू कमांड लाइन तर्क को पार्स करते समय ग्लोबल बफ़र ओवरफ़्लो का कारण बनता है। नीचे Adress Sanitizer से आउटपुट है:
=================================================================
==5322==ERROR: AddressSanitizer: global-buffer-overflow on address 0x0000016c22a0 at pc 0x0000004ba2e4 bp 0x7ffeb3ebac70 sp 0x7ffeb3eba428
WRITE of size 1025 at 0x0000016c22a0 thread T0
#0 0x4ba2e3 in strcpy (/home/ch1keen/fuzz/SmallBASIC/src/platform/sdl/sbasicg+0x4ba2e3) (BuildId: 4a800899b4dac082870bb647e1d872811e8633ea)
#1 0x8759c6 in main /home/ch1keen/fuzz/SmallBASIC/src/platform/sdl/main.cpp:277:13
#2 0x79e3ca62a1c9 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#3 0x79e3ca62a28a in __libc_start_main csu/../csu/libc-start.c:360:3
#4 0x4378b4 in _start (/home/ch1keen/fuzz/SmallBASIC/src/platform/sdl/sbasicg+0x4378b4) (BuildId: 4a800899b4dac082870bb647e1d872811e8633ea)
0x0000016c22a0 is located 0 bytes after global variable 'opt_command' defined in '/home/ch1keen/fuzz/SmallBASIC/src/common/smbas.h:105' (0x16c1ea0) of size 1024
SUMMARY: AddressSanitizer: global-buffer-overflow (/home/ch1keen/fuzz/SmallBASIC/src/platform/sdl/sbasicg+0x4ba2e3) (BuildId: 4a800899b4dac082870bb647e1d872811e8633ea) in strcpy
Shadow bytes around the buggy address:
0x0000016c2000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0000016c2080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0000016c2100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0000016c2180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0000016c2200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0000016c2280: 00 00 00 00[f9]f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
0x0000016c2300: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
0x0000016c2380: f9 f9 f9 f9 00 00 00 00 00 00 00 00 00 00 00 00
0x0000016c2400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0000016c2480: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0000016c2500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==5322==ABORTING
भेद्यता का प्रभाव स्पष्ट नहीं है। लेकिन ग्लोबल बफ़र ओवरफ़्लो अन्य ग्लोबल वेरिएबल को ओवरराइट कर सकता है, इससे प्रोग्राम के फ़्लैग और सेटिंग्स ओवरराइट हो सकते हैं।
भेद्यता को लगभग सभी strcpy को strlcpy से बदलकर ठीक किया गया, जिसमें मेरी रिपोर्ट की गई समस्या भी शामिल है।
@@ -277,1 +277,1 @@ int main(int argc, char* argv[]) {
< strcpy(opt_command, command);
---
> strlcpy(opt_command, command, sizeof(opt_command));