Orthanc DICOM Server
Out-of-Bounds-Lesezugriff im DICOM-Bilddecoder (PMSCT_RLE1-Dekomprimierung)
Orthanc dekodiert das proprietäre Philips-PMSCT_RLE1-Bildformat in zwei Durchgängen (RLE und anschließend Delta). Beide Durchgänge lesen zwei Bytes voraus, wenn sie auf einen Escape-Marker (0xa5 / 0x5a) treffen, prüfen jedoch nicht, dass diese Bytes innerhalb des Eingabepuffers liegen. Marker nahe dem Pufferende lösen Out-of-Bounds-Lesezugriffe aus, deren Bytes in die gerenderte Vorschau einfließen.
Beschreibung
PMSCT_RLE1 ist ein proprietäres RLE-und-Delta-Kompressionsformat, das von bestimmten Philips-Bildgebungsmodalitäten verwendet wird. Orthanc erreicht den Decoder, wenn eine DICOM-Datei das Standard-Tag PixelData (7FE0,0010) weglässt, jedoch die Philips-Private-Tags (0x07a1,0x1011) = "PMSCT_RLE1" und (0x07a1,0x100a) mit dem komprimierten Payload mitliefert — ImageSource::Setup fällt dann auf DecodePsmctRle1() zurück.
Der erste Durchgang implementiert die Run-Length-Expansion. Trifft er auf das Escape-Byte 0xa5, liest er zwei Folge-Bytes — einen Wiederholungszähler (i+1) und einen zu wiederholenden Wert (i+2) — ohne zu prüfen, ob diese Offsets innerhalb des Eingabepuffers liegen:
OrthancFramework/Sources/DicomParsing/Internals/DicomImageDecoder.cpp:191-206 (RLE-Pass)
for (size_t i = 0; i < length; i++){ if (inbuffer[i] == 0xa5) { temp.push_back(inbuffer[i+2]); // OOB-Lesezugriff falls i >= length-2 for (uint8_t repeat = inbuffer[i + 1]; repeat != 0; repeat--) { temp.push_back(inbuffer[i+2]); // OOB-Lesezugriff bis zu 255-mal wiederholt } i += 2; } // ...}Der zweite Durchgang implementiert die Delta-Wert-Rekonstruktion. Trifft er auf 0x5a, liest er zwei Folge-Bytes (i+1, i+2) und kombiniert sie zu einem 16-Bit-Wert, ohne die Grenzen zu prüfen:
OrthancFramework/Sources/DicomParsing/Internals/DicomImageDecoder.cpp:212-231 (Delta-Pass)
for (size_t i = 0; i < temp.size(); i++){ if (temp[i] == 0x5a) { uint16_t v1 = temp[i + 1]; // OOB-Lesezugriff falls i >= temp.size()-1 uint16_t v2 = temp[i + 2]; // OOB-Lesezugriff falls i >= temp.size()-2 value = (v2 << 8) + v1; i += 2; } // ...}Der RLE-Durchgang ist die nutzbarere Primitive: Ein einzelnes 0xa5 nahe dem Pufferende mit einem Wiederholungszähler von 255 liest dasselbe Out-of-Bounds-Byte 256-mal in den Ausgabestrom und erzeugt eine kontrollierte Verstärkung eines einzelnen Heap-Bytes über hunderte Pixel im Vorschaubild.
Im Test wurde ein 24 Byte großer Payload (\x00*22 + \xa5\xff) verwendet, der einen glibc-32-Byte-Chunk füllt. Das 0xa5-Escape an Position 22 liest inbuffer[24] — die Metadaten des nächsten Heap-Chunks — und wiederholt es 256-mal. Der Delta-Durchgang akkumuliert diese Bytes anschließend zu aufsteigenden Pixel-Intensitäten:
Vorschau-Ausgabe (8x8, mode=L)
row 0: [ 0, 0, 0, 0, 0, 0, 0, 0]row 1: [ 0, 0, 0, 0, 0, 0, 0, 0]row 2: [ 0, 0, 0, 0, 0, 0, 6, 12]row 3: [ 18, 24, 30, 36, 43, 49, 55, 61]row 4: [ 67, 73, 79, 85, 91, 97, 103, 109]row 5: [115, 121, 128, 134, 140, 146, 152, 158]row 6: [164, 170, 176, 182, 188, 194, 200, 206]row 7: [213, 219, 225, 231, 237, 243, 249, 255]AddressSanitizer verortet den ersten Out-of-Bounds-Zugriff in DicomImageDecoder.cpp:195, unmittelbar hinter einer 24-Byte-Heap-Region:
AddressSanitizer-Trace
==1==ERROR: AddressSanitizer: heap-buffer-overflow on address 0xffffa5437348READ of size 1 at 0xffffa5437348 thread T18 #0 in std::vector<unsigned char>::push_back() stl_vector.h:1192 #1 in Orthanc::DicomImageDecoder::DecodePsmctRle1() DicomImageDecoder.cpp:195 #2 in Orthanc::DicomImageDecoder::ImageSource::Setup() DicomImageDecoder.cpp:275 #3 in Orthanc::DicomImageDecoder::DecodeUncompressedImage() DicomImageDecoder.cpp:558 #4 in Orthanc::DicomImageDecoder::Decode() DicomImageDecoder.cpp:827 #5 in Orthanc::ParsedDicomFile::DecodeFrame() ParsedDicomFile.cpp:1823 #6 in Orthanc::ServerContext::DecodeDicomFrame() ServerContext.cpp:1921
0xffffa5437348 is located 0 bytes to the right of 24-byte region [0xffffa5437330,0xffffa5437348)allocated by thread T18 here: #0 in operator new[] #1 in DcmElement::newValueField() dcelem.cc:788Die Schwachstelle ist über dieselben zwei Pfade erreichbar wie CVE-2026-5445 (DecodeLookupTable): authentisierter HTTP-Upload + Vorschau, oder unauthentifizierte C-STORE-Ablage auf Port 4242 unter der Default-Konfiguration DicomAlwaysAllowStore: true. Variation der Payload-Größe über mehrere Anfragen hinweg tastet unterschiedliche Heap-Offsets ab und baut so einen mehrere Bytes umfassenden Heap-Dump auf.
Auswirkung
- Offenlegung von Informationen aus beliebigem Heap-Speicher über gerenderte Vorschaubilder, mit kontrollierter Verstärkung (ein OOB-Byte wird in der Ausgabe bis zu 256-mal wiederholt) durch den RLE-Wiederholungszähler.
- Durch Variation der Eingabe-Payload-Größe tastet der Angreifer über mehrere manipulierte Dateien hinweg unterschiedliche Heap-Offsets ab und baut einen mehrere Bytes umfassenden Heap-Dump auf.
- In Orthancs Default-Konfiguration (
DicomAlwaysAllowStore: true) ist das Ablegen unauthentifiziert; das Auslösen erfordert Read-Level-Authentifizierung. - Auf Builds mit striktem Heap-Layout (z. B. AddressSanitizer oder gehärteter glibc) kann ein Out-of-Bounds-Lesezugriff den Prozess abbrechen lassen; auf Standard-Builds ist das typische Resultat ein stiller Datenabfluss.
Abhilfe
Aktualisieren Sie Orthanc auf Version 1.12.11 oder höher. Der Patch fügt vor jedem i+1/i+2-Zugriff in beiden Durchgängen Grenzüberprüfungen ein und bricht das Decodieren mit BadFileFormat ab, sobald ein Escape-Marker auf zu wenig Folge-Daten trifft. Als sofortige Defense-in-Depth-Maßnahme setzen Sie DicomAlwaysAllowStore: false in orthanc.json und konfigurieren eine AET-Allowlist, was den unauthentifizierten Ablegevektor schließt.
Checkliste für Betreiber
Version prüfen.
curl -u <user>:<pass> http://<orthanc>:8042/system | jq .Version— der gepatchte Bereich beginnt bei 1.12.11.Unauthentifizierten C-STORE-Ablegevektor schließen.
Setzen Sie
DicomAlwaysAllowStore: falseinorthanc.jsonund definieren Sie eine expliziteDicomModalities-Allowlist legitimer AETs. Andernfalls kann jeder Host, der Port 4242 erreicht, das manipulierte DICOM unauthentifiziert ablegen.Vorschau-Endpunkt einschränken.
Wenn Ihr Deployment keine Web-Vorschau benötigt, beschränken Sie
GET /instances/*/previewan Ihrem Reverse-Proxy. Der Out-of-Bounds-Lesezugriff wird erst beobachtbar, wenn das manipulierte Bild gerendert wird.Read-Access-Konten prüfen.
Ein Angreifer benötigt nur Read-Level-Credentials, um die ausgelesenen Heap-Daten zu sehen. Prüfen Sie
RegisteredUsersinorthanc.jsonund ein externes Authentifizierungsbackend auf veraltete oder niedrig privilegierte Konten, die keinen Lesezugriff auf beliebige Studien haben sollten.DICOM-Speicher auf PMSCT_RLE1-Payloads prüfen.
Durchsuchen Sie den Speicher nach Studien, die
(7FE0,0010)PixelData weglassen, jedoch(0x07a1,0x1011) = "PMSCT_RLE1"enthalten. Studien aus Quellen außerhalb Ihres Modalitäten-Inventars oder mit unerwarteter Payload-Größe sollten vor dem Patch in Quarantäne und zur Prüfung gegeben werden.
Bewertung im Detail
DicomAlwaysAllowStore: true unauthentifizierte Requests akzeptiert und die Vorschau-Wiedergabe ohne HTTP-Authentifizierung exponiert ist.UI:REin Aufrufer (derselbe oder ein anderer Viewer) muss die Vorschau anfordern, damit das manipulierte DICOM gerendert und der Out-of-Bounds-Lesezugriff ausgelöst wird.S:UNur der Orthanc-Prozess ist betroffen; über diese Primitive sind keine prozessübergreifenden Ressourcen erreichbar.C:HKontrollierte Offenlegung von Heap-Inhalten über viele Ausgabe-Pixel pro Anfrage, mit Payload-Größen-Variation als Sweep über Heap-Offsets.I:NReine Lese-Primitive; nichts wird modifiziert.A:HAuf Builds mit striktem Heap-Layout kann der Out-of-Bounds-Lesezugriff eine nicht gemappte Speicherseite treffen und den Orthanc-Prozess terminieren.Referenzen
So können wir helfen
Wer wir sind
Die Sicherheitsforscher hinter diesem Sicherheitshinweis.

Dr. rer. nat. Simon Weber
Senior Pentester & MedSec-Forscher
Ich evaluiere Ihr SaMD mit derselben branchenprägenden Sicherheitsexpertise, die ich dem BAK MV für die Überarbeitung des B3S-Standards beigetragen habe.
- Promotion über Krankenhaus-Cybersicherheit
- Kritische Schwachstellen in Krankenhaussystemen gefunden
- Alumni der THB MedSec-Forschungsgruppe
- gematik Security Hero

Dipl.-Inf. Volker Schönefeld
Senior Application Security Expert
Als ehemaliger CTO und Entwickler, der zum Pentester wurde, arbeite ich mit Ihrem Team zusammen, um Schwachstellen aufzudecken und Lösungen zu finden, die zu Ihrer Architektur passen.
- 20+ Jahre als CTO, 50+ Mio. App-Downloads
- Architektur und Absicherung großer IoT-Flotten
- Certified Web Exploitation Specialist
- gematik Security Hero
Penetrationstest gesucht?
Machine Spirits ist spezialisiert auf Sicherheitsbewertungen für Medizinprodukte und Gesundheits-IT. Von MDR-Penetrationstests bis C5-Cloud-Compliance helfen wir MedTech-Unternehmen, regulatorische Anforderungen zu erfüllen.
