提出 #880113: liftoff-sr CIPster master before e8e9dba (reproduced on 1802525be27d33e19a9a83c163e331a1d13b1892) Out-of-bounds Read情報

タイトルliftoff-sr CIPster master before e8e9dba (reproduced on 1802525be27d33e19a9a83c163e331a1d13b1892) Out-of-bounds Read
説明During a security audit of liftoff-sr/CIPster, I identified and reported a remotely reachable out-of-bounds read in the parsing of CIP symbolic application paths. I disclosed the issue as GitHub issue #53. The vulnerable state was reproduced on master commit 632336d414ef708a542377c1aa8d6fdb7c70a760, and the defective logic is located in CipAppPath::deserialize_symbolic(). This is not an artificial unit-test condition or misuse of an internal helper. The flaw is reachable through the project’s own EtherNet/IP request-processing path. For reproduction, I used the official examples/POSIX sample server from the repository. The trigger sequence starts with a normal RegisterSession exchange. After the session is established, I send a crafted SendRRData packet carrying an unconnected explicit Message Router request. The embedded application path contains a truncated symbolic segment. The outer request structure is sufficient to pass through normal encapsulation, Common Packet Format, and Message Router handling. However, inside the symbolic path element, the segment declares a symbol length larger than the actual remaining bytes available in the input stream. The parser trusts the attacker-controlled length and attempts to copy that amount of data before confirming that the requested number of bytes is still present. This causes the code to read past the valid request boundary. The execution path I observed follows the intended protocol-processing flow: TCP handling, encapsulation processing, CPF handling, Message Router request deserialization, application path parsing, and finally CipAppPath::deserialize_symbolic(). This matters because the flaw is not confined to an offline parser, a debug-only path, or a contrived harness. It is exposed through realistic protocol interaction using the publicly shipped sample server and standard EtherNet/IP explicit messaging logic. The core defect is an input-length validation failure during symbolic path deserialization. The code obtains a symbolic segment size from external input and then performs a memory copy based on that declared length without first verifying that the remaining bytes in the BufReader are sufficient. That creates an out-of-bounds read. In my report, I showed that the outer Message Router path length can still appear superficially valid and allow earlier checks to pass, while the nested symbolic segment length is inconsistent with the actual remaining input. The failure therefore occurs after deeper interpretation of nested path content, not merely because a top-level frame is obviously malformed. My proof of concept uses a minimal but protocol-reachable malformed path. The outer Message Router path length is encoded so that upstream path-size checks accept it. Inside that path, the symbolic segment encodes a symbol size of 31 bytes while only 1 byte of actual symbol data is present. A secure parser should reject the request before any copy occurs because the declared segment length exceeds the bytes still available. The affected implementation instead attempts the read using the attacker-controlled size value. Under AddressSanitizer, this produces a reliable memory error showing that the parser reads beyond the valid receive buffer. AddressSanitizer reports a global-buffer-overflow read of size 31 at source/src/cip/cipepath.cc around line 360 inside deserialize_symbolic(). The trace shows the invalid read adjacent to the global TCP receive buffer used by the server process. The stack trace also covers the full path from TCP packet handling through encapsulation and Message Router parsing into symbolic application path deserialization. This demonstrates a real memory-safety vulnerability in a network-facing protocol implementation. Based on what I verified, the confirmed security impact is at least remote denial of service against the server-side process. In an instrumented build, the process terminates when the malformed request reaches the vulnerable path. In a non-sanitized build, the exact manifestation may vary with compiler options, platform, optimization level, and memory layout. It may result in a crash, abnormal termination, or other undefined behavior during request processing. I describe the impact conservatively as a remotely reachable server-side out-of-bounds read that can destabilize the process and cause denial of service. I am not claiming proven information disclosure or code execution because those outcomes would require separate validation beyond the public evidence I provided. From a root-cause perspective, this is a parser trust error in symbolic path handling. The implementation relies on a length field embedded in attacker-controlled path data but does not ensure that the input source still contains that many bytes before consuming them. Outer structural checks may still succeed, yet a nested field can drive the decoder into treating incomplete data as complete. The issue is therefore an unsafe memory access caused by inadequate bounds enforcement in nested protocol parsing. My reproduction did not require private integration code, local privileges, non-default debug hooks, or direct invocation of internal parsing routines. I used the repository’s public POSIX target and interacted with it as a normal EtherNet/IP peer. That strengthens the vulnerability assessment because it shows the bug exists in a practical, network-reachable execution path. After I reported the issue, the upstream maintainer closed it as completed in commit 886a4d0, titled “Fixes #53”. The public fix is relevant because it shows the report was addressed through a source-level correction. The patch changes deserialize_symbolic() so it no longer performs raw memcpy() from in.data() based solely on attacker-controlled length values. Instead, the code uses bounded BufReader access via in.get_bytes(), and the request-deserialization path was updated to catch range and runtime exceptions so malformed application paths are rejected as parse failures rather than continuing into out-of-bounds access. This patch structure is consistent with the root cause I reported: missing bounds enforcement during symbolic path consumption. The fix is also significant for vulnerability scoping. In my report, I noted closely related parsing patterns in the same symbolic path handling area. The upstream patch corrected the unsafe read patterns in that area rather than only masking one crash signature. For vulnerability-management purposes, I therefore view this most appropriately as a single out-of-bounds read vulnerability in symbolic application path deserialization, potentially with closely related trigger variants derived from the same trust-in-length mistake. Regarding affected scope, the publicly demonstrated vulnerable state is master commit 632336d414ef708a542377c1aa8d6fdb7c70a760. The public remediation point is commit 886a4d0. In this case, commit-based versioning is the most precise way to express affected and fixed code because the report and the repository evidence are tied directly to those public revisions. At minimum, code prior to 886a4d0 in the affected master state should be considered vulnerable. CIPster is an EtherNet/IP protocol implementation that may be embedded into industrial communication software, adapters, gateways, test systems, or research targets. In such environments, memory-safety flaws in request parsing are security-significant even when the demonstrated outcome is denial of service. A remotely triggerable parser over-read that destabilizes the process can interrupt protocol services, engineering access, device communications, or supervisory workflows. The most accurate weakness classification is CWE-125, Out-of-bounds Read. The issue is server-side, remotely reachable, triggered through crafted network input delivered over a normal EtherNet/IP messaging sequence, and confirmed through sanitizer evidence. My role was the original discovery, technical analysis, proof-of-concept construction, and public issue reporting. The public disclosure and the upstream fix together provide a complete evidence chain: reachable network entry, clear root cause, sanitizer-confirmed memory violation, and source-level remediation. In summary, I discovered a remotely reachable out-of-bounds read in liftoff-sr/CIPster’s symbolic application path deserialization logic. After normal session establishment, a crafted SendRRData request containing a truncated symbolic segment in an unconnected explicit Message Router request can drive the parser into trusting attacker-controlled symbolic length information and reading beyond the available input in CipAppPath::deserialize_symbolic(). I reproduced the issue on the official POSIX sample server, documented it in issue #53, and the upstream maintainer later fixed it in commit 886a4d0. This is a real protocol-reachable memory-safety vulnerability with confirmed denial-of-service impact and is appropriate for vulnerability tracking and CVE a
ソース⚠️ https://github.com/liftoff-sr/CIPster/issues/53
ユーザー
 Carnegie (UID 98671)
送信2026年07月04日 15:47 (2 月 ago)
モデレーション2026年08月19日 22:01 (2 months later)
ステータス重複
VulDBエントリ379755 [liftoff-sr CIPster 迄 632336d414ef708a542377c1aa8d6fdb7c70a760 cipepath.cc deserialize_symbolic 情報漏えい]
ポイント0

Do you need the next level of professionalism?

Upgrade your account now!