← All hunts high TLP:CLEAR

Orthanc DICOM Server Vulnerability Exploitation

An intruder exploits CVE-2026-87020 by uploading a malformed image to an authenticated session on a vulnerable Orthanc server, causing a heap overflow and process crash.

Based on research by CISA 2026-09-20 12 steps · 5 queries T1090.003 T1133 T1190 T1499 T1566

Brief

Context: Orthanc DICOM Server (CVE-2026-87020)

CISA recently published an advisory regarding a high-severity heap overflow in the Orthanc DICOM Server (https://www.cisa.gov/news-events/ics-medical-advisories/icsma-26-253-02). Orthanc is a primary hub for storing and sharing medical imaging data in clinical environments. The vulnerability, designated CVE-2026-87020, allows authenticated users to trigger an integer overflow during the decoding of malformed images, resulting in an out-of-bounds write and service termination. Because Orthanc resides in sensitive healthcare networks, exploitation poses a significant risk to clinical workflows.

Phase 1: Scoping the Vulnerable Surface

The hunt begins by filtering the software inventory for Orthanc versions earlier than 1.13.0. We use a scoping query against the hb_software_inventory surface to capture hosts running affected packages. This step focuses the analysis on vulnerable assets and eliminates noise from systems that have already been remediated. We look for version strings like 1.12.x to ensure we capture legacy installations.

Phase 2: Assessing Exposure and Access

Once we identify vulnerable hosts, we analyze their risk profile. We check hb_exposed_assets for internet exposure by examining external scan data. We also use hb_http_activity to identify successful HTTP POST requests to authentication endpoints. Finding external exposure combined with active login traffic significantly increases the risk score for a specific server.

Phase 3: Identifying Malicious Uploads and Impact

The core of the hunt involves stacking HTTP upload activity to identify rare actors. We group source IPs that perform POST requests to known Orthanc upload paths like /instances/ using the hb_http_activity surface. Legitimate imaging tools typically perform high-volume uploads. We look for rare source IPs that have never interacted with the server. We then correlate these events with process termination logs in hb_process_activity. A match within a ten-minute window suggests a successful heap overflow and service crash.

Blind Spots and Limitations

This hunt cannot inspect the binary contents of the uploaded files. We see the upload event but cannot confirm if the image contains the malformed header without full HTTP body logging. Furthermore, process crashes occur during legitimate maintenance. An analyst must review application logs to confirm if a memory allocation error occurred at the time of the crash.

Steps

  1. Identify vulnerable Orthanc servers

    Query · scoping

    Filter software inventory for Orthanc versions earlier than 1.13.0 using explicit version patterns.

    reads hb_software_inventorysql
    SELECT device_hostname, package_name, package_version, install_path FROM hb_software_inventory WHERE (instr(',' || '{{orthanc_keywords}}' || ',', ',' || LOWER(package_name) || ',') > 0 OR LOWER(package_name) LIKE '%orthanc%') AND (package_version LIKE '1.12%' OR package_version LIKE '1.11%' OR package_version LIKE '1.10%' OR package_version LIKE '1.9%' OR package_version LIKE '0.%')

    What a hit looks like. A list of servers running affected versions. Silence confirms no vulnerable packages are registered.

  2. Examine internet exposure

    Query · enrichment

    Check external scanner data for Orthanc instances visible from the public internet.

    reads hb_exposed_assetssql
    SELECT domain_or_ip, port, product, version, discovered_at FROM hb_exposed_assets WHERE (LOWER(product) LIKE '%orthanc%' OR LOWER(source_product) LIKE '%orthanc%') AND discovered_at >= datetime('now', '-{{lookback_days}} days')

    What a hit looks like. Asset records for exposed servers. Silence means no public footprint was detected.

  3. Detect successful HTTP authentication

    Query · triage

    Identify successful authenticated POST requests to the Orthanc server.

    reads hb_http_activitysql
    SELECT device_hostname, src_endpoint_ip, url_full, status_code, time FROM hb_http_activity WHERE ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND http_method = 'POST' AND status_code = 200 AND (LOWER(url_path) LIKE '%auth%' OR LOWER(url_path) LIKE '%login%' OR LOWER(url_path) LIKE '%instances%') AND time >= datetime('now', '-{{lookback_days}} days')

    What a hit looks like. Successful authentication sessions. Authentication is a prerequisite for the CVE-2026-87020 exploit.

  4. Triage early evidence

    Agent triage

    Evaluate the risk of exploitation per host based on version and exposure evidence.

  5. Baseline rare image uploaders

    Query · baseline

    Stack-count source IPs uploading images to find rare actors that might be delivering exploits.

    reads hb_http_activitysql
    SELECT device_hostname, src_endpoint_ip, url_path, COUNT(*) AS request_count, MIN(time) AS first_upload FROM hb_http_activity WHERE ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND http_method = 'POST' AND instr(',' || '{{upload_endpoints}}' || ',', ',' || LOWER(url_path) || ',') > 0 AND time >= datetime('now', '-{{lookback_days}} days') GROUP BY device_hostname, src_endpoint_ip, url_path HAVING request_count < 20

    What a hit looks like. One-off or rare source IPs performing uploads. Frequent uploaders are likely legitimate clinical tools.

  6. Detect Orthanc service terminations

    Query · triage

    Find process termination events for Orthanc to identify potential DoS impact from exploitation.

    reads hb_process_activitysql
    SELECT device_hostname, process_name, process_cmd_line, activity_id, time FROM hb_process_activity WHERE ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND activity_id = 2 AND (instr(',' || '{{orthanc_keywords}}' || ',', ',' || LOWER(process_name) || ',') > 0 OR LOWER(process_name) LIKE '%orthanc%') AND time >= datetime('now', '-{{lookback_days}} days')

    What a hit looks like. Orthanc process terminations. Silence means the service has remained stable during the window.

  7. Final exploitation assessment

    Agent triage

    Link authenticated rare uploads to subsequent crashes within a short time window.

  8. Route on verdict

    Decision

    Determine the next action based on the exploitation correlation results.

  9. Isolate compromised server

    Response action

    Contain the server to prevent further exploitation or pivot.

  10. Forensic log review

    Analyst task

    Investigate the source of the malicious upload and the nature of the crash.

  11. Verify software upgrade

    Analyst task

    Ensure all systems are remediated to the patched version.

Coverage

Scenario coverage

StageCoveredHow, or why not
Identification of Vulnerable Orthanc Server
T1190
Yes find-vulnerable-orthanc
Initial Access & Credential Harvesting
T1566 · T1133
Yes exposed-orthanc-services, orthanc-authentication
Authenticated Malicious Image Upload
T1190
Yes rare-uploader-prevalence
Multi-hop Proxying
T1090.003
Existing rule Tor activity is covered by existing rule dns_query_tor_onion.
Process Crash and DoS
T1499
Yes orthanc-process-crashes

Blind spots

  • Needs Full HTTP body logging or DPI. We see the upload event but cannot confirm it is malicious without seeing the image data. It would answer Does the PNG/JPEG payload contain the specific malformed pitch header?.
  • Needs activity_id 2 for all processes or kernel crash logs. Legitimate maintenance could be flagged as a denial-of-service event. It would answer Was the process termination caused by the heap overflow or a manual service restart?.

Parameters & data

Parameters

ParameterTypeDefaultWhat it is
lookback_daysnumber14Days of history to examine.
orthanc_keywordslist[string]orthanc, dicomKeywords to identify Orthanc processes and packages.
scope_hostslist[host]List of hostnames to narrow the search; leave empty for all hosts.
upload_endpointslist[string]/instances/, /tools/preview/, /dicom-web/Known Orthanc image upload paths.

Telemetry

SourceCategoryTelemetry
Endpoint telemetry (hb_ surfaces)endpointendpoint
Web server / proxy logssiemnetwork

Source

Download hunt.md Definition (JSON) An open hunt.md file; it runs anywhere that reads the format.
---
analysis: Static rules for process crashes are too noisy for medical environments.
  This hunt uses a phased approach, building confidence from software versions, exposure,
  and rare authenticated upload patterns before correlating with impact.
blind_spots:
- id: http-body-inspection
  question: Does the PNG/JPEG payload contain the specific malformed pitch header?
  requires: Full HTTP body logging or DPI
  risk: We see the upload event but cannot confirm it is malicious without seeing
    the image data.
  stage: exploit-delivery-upload
- id: no-crash-telemetry
  question: Was the process termination caused by the heap overflow or a manual service
    restart?
  requires: activity_id 2 for all processes or kernel crash logs
  risk: Legitimate maintenance could be flagged as a denial-of-service event.
  stage: impact-denial-of-service
coverage:
- stage: vulnerability-inventory
  status: covered
  steps:
  - find-vulnerable-orthanc
- stage: initial-access-vectors
  status: covered
  steps:
  - exposed-orthanc-services
  - orthanc-authentication
- stage: exploit-delivery-upload
  status: covered
  steps:
  - rare-uploader-prevalence
- reason: Tor activity is covered by existing rule dns_query_tor_onion.
  stage: network-traffic-obfuscation
  status: existing_rule
- stage: impact-denial-of-service
  status: covered
  steps:
  - orthanc-process-crashes
guardrails:
  claims: no_unsupported
  evidence: citation_required
  missing_data: not_benign
  telemetry: untrusted
hunt:
  applicability: campaign-specific
  handoff: keep-as-periodic-hunt
  justification: Disruption to DICOM servers impacts clinical care. This hunt provides
    assurance that critical healthcare infrastructure is not being actively exploited
    via this high-severity heap overflow.
  methodology: model-assisted
  trigger: intel-report
hypothesis: An intruder exploits CVE-2026-87020 by uploading a malformed image to
  an authenticated session on a vulnerable Orthanc server, causing a heap overflow
  and process crash.
labels:
- hunt
- attack.t1190
- attack.t1090.003
- attack.t1133
- attack.t1566
- attack.t1499
name: Orthanc DICOM Server Vulnerability Exploitation
parameters:
  lookback_days:
    default: '14'
    description: Days of history to examine.
    from:
      kind: manual
      observed: '2026-09-10'
      ref: hunt-standard
    type: number
  orthanc_keywords:
    default:
    - orthanc
    - dicom
    description: Keywords to identify Orthanc processes and packages.
    from:
      kind: article
      observed: '2026-09-10'
      ref: cisa-advisory
    type: list[string]
  scope_hosts:
    default: []
    description: List of hostnames to narrow the search; leave empty for all hosts.
    from:
      kind: manual
      observed: '2026-09-10'
      ref: analyst-defined
    type: list[host]
  upload_endpoints:
    default:
    - /instances/
    - ' /tools/preview/'
    - ' /dicom-web/'
    description: Known Orthanc image upload paths.
    from:
      kind: article
      observed: '2026-09-10'
      ref: orthanc-documentation
    type: list[string]
provenance:
  authors:
  - name: Huntbase hunt generation
    org: huntbase.io
  generated:
    by: huntbase-hunt-generation
    from: https://www.cisa.gov/news-events/ics-medical-advisories/icsma-26-253-02
    gates:
    - dry-run
    - lint
    model: hb_google/gemini-3-flash-preview
rationale: Focus on medical imaging VLANs and servers running DICOM services. The
  scoping query uses LIKE patterns to capture vulnerable versions (e.g., 1.12.x) that
  string comparisons often miss.
references:
- name: 'CISA Advisory: Orthanc DICOM Server'
  url: https://www.cisa.gov/news-events/ics-medical-advisories/icsma-26-253-02
related:
- hunt: lateral-movement-from-clinical-assets
  reason: If an attacker crashes Orthanc, they may have already executed code and
    moved elsewhere.
  relation: follows
scenario:
  stages:
  - name: Initial Access & Credential Harvesting
    observables:
    - Unsolicited emails with malicious links or attachments
    - Remote access attempts via VPNs or exposed control systems
    slug: initial-access-vectors
    tactic: initial-access
    techniques:
    - T1566
    - T1133
  - name: Identification of Vulnerable Orthanc Server
    observables:
    - Orthanc DICOM Server versions < 1.13.0
    - CVE-2026-87020
    slug: vulnerability-inventory
    tactic: initial-access
    techniques:
    - T1190
  - name: Authenticated Malicious Image Upload
    observables:
    - Authenticated HTTP POST requests containing PNG or JPEG images
    - Communication with Orthanc DICOM service endpoints
    slug: exploit-delivery-upload
    tactic: initial-access
    techniques:
    - T1190
  - name: Multi-hop Proxying
    observables:
    - Traffic routed through multiple proxies or Tor to hide origin
    slug: network-traffic-obfuscation
    tactic: command-and-control
    techniques:
    - T1090.003
  - name: Process Crash and DoS
    observables:
    - Termination of Orthanc process
    - Heap out-of-bounds write leading to Orthanc service instability
    slug: impact-denial-of-service
    tactic: impact
    techniques:
    - T1499
  summary: Authenticated remote attackers exploit an integer overflow in Orthanc DICOM
    Server's image decoding logic (CVE-2026-87020) by providing malicious PNG or JPEG
    files. Successful exploitation triggers a heap out-of-bounds write that crashes
    the Orthanc process, resulting in a denial-of-service (DoS) condition.
severity: high
targets:
  analyst:
    name: Tier-2 analyst
    role: analyst
  endpoint:
    category: endpoint
    name: Endpoint telemetry (hb_ surfaces)
    telemetry:
    - endpoint
  hunter:
    agent: true
    name: Hunt agent
  web:
    category: siem
    name: Web server / proxy logs
    telemetry:
    - network
tlp: clear
type: investigation
---


# Orthanc DICOM Server Vulnerability Exploitation

This hunt identifies vulnerable Orthanc DICOM Server instances and correlates authenticated image uploads with subsequent process terminations. The vulnerability is a heap out-of-bounds write triggered by integer overflows during image decoding. Because the exploit requires authentication, the hunt first establishes the risk surface through exposure and successful HTTP authentication events. It then stacks upload activity to find rare origins that precede service crashes.

## find-vulnerable-orthanc
<!-- Identify vulnerable Orthanc servers -->
Filter software inventory for Orthanc versions earlier than 1.13.0 using explicit version patterns.

```sqlite target=endpoint role=scoping params=(orthanc_keywords=orthanc_keywords)
~~~yaml
expected: A list of servers running affected versions. Silence confirms no vulnerable
  packages are registered.
reads:
- device_hostname
- install_path
- package_name
- package_version
silence: not_evidence_of_absence
source: hb_software_inventory
verified: dry-run
verified_at: '2026-09-20'
~~~
SELECT device_hostname, package_name, package_version, install_path FROM hb_software_inventory WHERE (instr(',' || '{{orthanc_keywords}}' || ',', ',' || LOWER(package_name) || ',') > 0 OR LOWER(package_name) LIKE '%orthanc%') AND (package_version LIKE '1.12%' OR package_version LIKE '1.11%' OR package_version LIKE '1.10%' OR package_version LIKE '1.9%' OR package_version LIKE '0.%')
```

## early-risk-parallel
<!-- Exposure and access analysis -->
parallel:
- → exposed-orthanc-services
- → orthanc-authentication
join: → risk-assessment

## exposed-orthanc-services
<!-- Examine internet exposure -->
Check external scanner data for Orthanc instances visible from the public internet.

```sqlite target=endpoint role=enrichment params=(lookback_days=lookback_days)
~~~yaml
expected: Asset records for exposed servers. Silence means no public footprint was
  detected.
reads:
- discovered_at
- domain_or_ip
- port
- product
- source_product
- version
silence: not_evidence_of_absence
source: hb_exposed_assets
verified: dry-run
verified_at: '2026-09-20'
~~~
SELECT domain_or_ip, port, product, version, discovered_at FROM hb_exposed_assets WHERE (LOWER(product) LIKE '%orthanc%' OR LOWER(source_product) LIKE '%orthanc%') AND discovered_at >= datetime('now', '-{{lookback_days}} days')
```

## orthanc-authentication
<!-- Detect successful HTTP authentication -->
Identify successful authenticated POST requests to the Orthanc server.

```sqlite target=web role=triage params=(scope_hosts=scope_hosts, lookback_days=lookback_days)
~~~yaml
expected: Successful authentication sessions. Authentication is a prerequisite for
  the CVE-2026-87020 exploit.
reads:
- device_hostname
- http_method
- src_endpoint_ip
- status_code
- time
- url_full
- url_path
silence: not_evidence_of_absence
source: hb_http_activity
verified: dry-run
verified_at: '2026-09-20'
~~~
SELECT device_hostname, src_endpoint_ip, url_full, status_code, time FROM hb_http_activity WHERE ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND http_method = 'POST' AND status_code = 200 AND (LOWER(url_path) LIKE '%auth%' OR LOWER(url_path) LIKE '%login%' OR LOWER(url_path) LIKE '%instances%') AND time >= datetime('now', '-{{lookback_days}} days')
```

## risk-assessment
<!-- Triage early evidence -->
```agent target=hunter
cite: required
context:
- find-vulnerable-orthanc
- exposed-orthanc-services
- orthanc-authentication
max_iterations: 3
objective: Determine which vulnerable Orthanc servers are most at risk based on their
  version, exposure status, and the presence of authenticated traffic.
success_criteria: A summary per host citing vulnerable versions and evidence of external
  access.
tools:
- endpoint
- web
```

## exploitation-indicators-parallel
<!-- Correlate upload and crash activity -->
parallel:
- → rare-uploader-prevalence
- → orthanc-process-crashes
join: → exploitation-correlation

## rare-uploader-prevalence
<!-- Baseline rare image uploaders -->
Stack-count source IPs uploading images to find rare actors that might be delivering exploits.

```sqlite target=web role=baseline params=(scope_hosts=scope_hosts, upload_endpoints=upload_endpoints, lookback_days=lookback_days)
~~~yaml
baseline:
  compare: first_seen
  window: '{{lookback_days}}d'
expected: One-off or rare source IPs performing uploads. Frequent uploaders are likely
  legitimate clinical tools.
prevalence:
  by: device_hostname
  key:
  - src_endpoint_ip
  - url_path
  rare_below: 5
reads:
- device_hostname
- http_method
- src_endpoint_ip
- time
- url_path
silence: not_evidence_of_absence
source: hb_http_activity
verified: dry-run
verified_at: '2026-09-20'
~~~
SELECT device_hostname, src_endpoint_ip, url_path, COUNT(*) AS request_count, MIN(time) AS first_upload FROM hb_http_activity WHERE ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND http_method = 'POST' AND instr(',' || '{{upload_endpoints}}' || ',', ',' || LOWER(url_path) || ',') > 0 AND time >= datetime('now', '-{{lookback_days}} days') GROUP BY device_hostname, src_endpoint_ip, url_path HAVING request_count < 20
```

## orthanc-process-crashes
<!-- Detect Orthanc service terminations -->
Find process termination events for Orthanc to identify potential DoS impact from exploitation.

```sqlite target=endpoint role=triage params=(scope_hosts=scope_hosts, orthanc_keywords=orthanc_keywords, lookback_days=lookback_days)
~~~yaml
expected: Orthanc process terminations. Silence means the service has remained stable
  during the window.
reads:
- activity_id
- device_hostname
- process_cmd_line
- process_name
- time
silence: not_evidence_of_absence
source: hb_process_activity
verified: dry-run
verified_at: '2026-09-20'
~~~
SELECT device_hostname, process_name, process_cmd_line, activity_id, time FROM hb_process_activity WHERE ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND activity_id = 2 AND (instr(',' || '{{orthanc_keywords}}' || ',', ',' || LOWER(process_name) || ',') > 0 OR LOWER(process_name) LIKE '%orthanc%') AND time >= datetime('now', '-{{lookback_days}} days')
```

## exploitation-correlation
<!-- Final exploitation assessment -->
```agent target=hunter
cite: required
context:
- risk-assessment
- rare-uploader-prevalence
- orthanc-process-crashes
max_iterations: 5
objective: Correlate the risk assessment with rare upload events and process terminations
  on the same host within a 10-minute window to confirm exploitation of CVE-2026-87020.
success_criteria: A per-host verdict of malicious, suspicious, or benign with cited
  rows.
tools:
- endpoint
- web
```

## route-on-verdict
<!-- Route on verdict -->
if~: "the exploitation-correlation verdict is malicious for at least one host" (confidence: high, judge=hunter)
then: → isolate-affected-server
indeterminate: → analyst-manual-review
unavailable: → analyst-manual-review (blind_spot: no-crash-telemetry)
else: → patch-verification

## isolate-affected-server
<!-- Isolate compromised server -->
```action target=endpoint
~~~yaml
approval: required
~~~
Isolate the host and block port 8042 at the network perimeter until the software is patched.
```
→ analyst-manual-review

## analyst-manual-review
<!-- Forensic log review -->
```manual target=analyst
Review Orthanc application logs for memory allocation errors. Identify the authenticated user account linked to the suspicious POST request.
```
→ patch-verification

## patch-verification
<!-- Verify software upgrade -->
```manual target=analyst
Confirm that all servers identified in the scoping phase have been updated to Orthanc v1.13.0.
```
→ end

Run it

Take this hunt into your environment.

Open it in Huntbase to run every step against your own connections, with Scout weighing the evidence and your analysts in command. Or take the open hunt.md file anywhere that reads the format.

Machine-drafted by huntbase-hunt-generation using hb_google/gemini-3-flash-preview, gated by dry-run, lint, then reviewed by a person.