pwnmit/EPA-SWMM5-Global-Buffer-Overflow

GitHub: pwnmit/EPA-SWMM5-Global-Buffer-Overflow

针对 EPA SWMM5 计算引擎错误日志子系统中全局缓冲区溢出漏洞(CWE-787)的 PoC exploit,通过构造恶意 .inp 配置文件触发越界写入并导致拒绝服务。

Stars: 0 | Forks: 0

# EPA SWMM5 计算引擎全局缓冲区溢出 (CWE-787) 在 EPA Stormwater Management Model (SWMM5) 计算核心求解器架构中(影响至 v5.2.4 及以下版本)发现了一个越界内存写入漏洞(全局缓冲区溢出)。该缺陷位于求解器的错误日志记录子系统中,该系统通过无界内存复制例程处理未经校验的字符串编译 token。处理恶意构造的配置文件(`.inp`)会通过立即发生的段错误(`SIGSEGV`)引发拒绝服务条件。 ## 🔒 漏洞元数据 * **漏洞类型:** 越界写入 / 全局缓冲区溢出 ([CWE-787](https://cwe.mitre.org/data/definitions/787.html)) * **受影响组件:** `src/solver/error.c` -> `error_setInpError()` * **向量执行:** 本地文件摄取(`.inp` 解析配置) * **影响:** 可用性 / 进程故障 / 应用程序拒绝服务 * **发现者:** mit (pwnmit Security Research) ## 🔍 技术分析与根本原因 SWMM5 解析器架构使用严格结构化的数据分配来隔离空间和物理输入属性。然而,在 `src/solver/treatmnt.c` 内部评估应用程序配置期间进行语法异常处理时,会发生逻辑边界检查不匹配的问题。 ### 1. 数据聚合与校验失效 (`treatmnt.c`) 在处理序列评估期间,会读取配置参数并将其连接,直到达到允许的最大行边界(`MAXLINE`): ``` sstrncpy(s, tok[2], MAXLINE); for (i = 3; i < ntoks; i++) { sstrcat(s, " ", MAXLINE); sstrcat(s, tok[i], MAXLINE); } ... else return error_setInpError(ERR_KEYWORD, tok[2]); ## 如果 keyword 解析约束失败(例如,结构字符布局违反了验证标记),引擎会立即回退到 error propagation。它会通过 error_setInpError() 将原始的、未经校验的 configuration argument reference string (tok[2]) 路由到 central logging sub-tier。 2. Unbounded Memory Ingestion (error.c) The target exception logging module allocates a global tracking buffer, ErrString, with a fixed storage limit of 256 bytes in the uninitialized data segment (.bss): C char ErrString[256]; ... int error_setInpError(int errcode, char* s) { strcpy(ErrString, s); // Vulnerable Unbounded Memory Copy return errcode; } Because strcpy() performs byte serialization mapping sequentially until a null-terminator (\0) is found without validating variable lengths, incoming input sequences exceeding 256 bytes break bounds containment. This directly corrupts adjacent static registers in the .bss memory region, throwing an address violation trap (SIGSEGV) and causing an immediate application abort. 📊 Compilation Instrumentation & AddressSanitizer Logs Compiling the engine executable with AddressSanitizer (ASan) tracking directives exposes the exact memory offset collision when the bug is triggered: Plaintext ================================================================= ==3484==ERROR: AddressSanitizer: global-buffer-overflow on address 0x7f34a6df0fe0 at pc 0x7f34a6ea2681 bp 0x7ffdfa8c2a00 sp 0x7ffdfa8c21c0 WRITE of size 996 at 0x7f34a6df0fe0 thread T0 #0 0x7f34a6ea2680 in strcpy ../../../../src/libsanitizer/asan/asan_interceptors.cpp:563 #1 0x7f34a6c93452 in error_setInpError /src/solver/error.c:47 #2 0x7f34a6d87b50 in treatmnt_readExpression /src/solver/treatmnt.c:134 #3 0x7f34a6cc52af in parseLine /src/solver/input.c:596 0x7f34a6df0fe0 is located 0 bytes after global variable 'ErrString' defined in 'error.c:28:7' of size 256 SUMMARY: AddressSanitizer: global-buffer-overflow in strcpy ==3484==ABORTING ## 如果 keyword 解析约束失败(例如,结构字符布局违反了验证标记),引擎会立即回退到 error propagation。它会通过 error_setInpError() 将原始的、未经校验的 configuration argument reference string (tok[2]) 路由到 central logging sub-tier。 2. Unbounded Memory Ingestion (error.c) The target exception logging module allocates a global tracking buffer, ErrString, with a fixed storage limit of 256 bytes in the uninitialized data segment (.bss): C char ErrString[256]; ... int error_setInpError(int errcode, char* s) { strcpy(ErrString, s); // Vulnerable Unbounded Memory Copy return errcode; } Because strcpy() performs byte serialization mapping sequentially until a null-terminator (\0) is found without validating variable lengths, incoming input sequences exceeding 256 bytes break bounds containment. This directly corrupts adjacent static registers in the .bss memory region, throwing an address violation trap (SIGSEGV) and causing an immediate application abort. 📊 Compilation Instrumentation & AddressSanitizer Logs Compiling the engine executable with AddressSanitizer (ASan) tracking directives exposes the exact memory offset collision when the bug is triggered: Plaintext ================================================================= ==3484==ERROR: AddressSanitizer: global-buffer-overflow on address 0x7f34a6df0fe0 at pc 0x7f34a6ea2681 bp 0x7ffdfa8c2a00 sp 0x7ffdfa8c21c0 WRITE of size 996 at 0x7f34a6df0fe0 thread T0 #0 0x7f34a6ea2680 in strcpy ../../../../src/libsanitizer/asan/asan_interceptors.cpp:563 #1 0x7f34a6c93452 in error_setInpError /src/solver/error.c:47 #2 0x7f34a6d87b50 in treatmnt_readExpression /src/solver/treatmnt.c:134 #3 0x7f34a6cc52af in parseLine /src/solver/input.c:596 0x7f34a6df0fe0 is located 0 bytes after global variable 'ErrString' defined in 'error.c:28:7' of size 256 SUMMARY: AddressSanitizer: global-buffer-overflow in strcpy ==3484==ABORTING ```
标签:CWE-787, EPA SWMM5, PoC, 拒绝服务, 暴力破解, 缓冲区溢出, 配置错误