Skip to content

Threat Hunt Plan: Fortinet FortiProxy, FortiPAM and FortiSwitch Manager — HTTP/2 Memory Exhaustion Denial of Service

Date: August 17, 2026 | Revision 1.0

Hunt Objective and Scope

This hunt seeks evidence that an unauthenticated remote attacker has attempted or achieved a denial-of-service condition against Fortinet FortiProxy, FortiPAM, or FortiSwitch Manager appliances by exploiting CVE-2026-49975, the memory-exhaustion flaw in the Apache HTTP Server mod_http2 module publicly nicknamed the "HTTP/2 Bomb." The flaw permits a small number of crafted HTTP/2 header frames on a single connection to force a disproportionate memory allocation on the server, exhausting available memory and interrupting service. Fortinet published the issue as FG-IR-26-163 on August 12, 2026 with a vendor CVSS v3.1 score of 5.8; NIST scores the upstream Apache defect at CVSS v3.1 7.5. The hunt covers both the confirmed-affected Fortinet products and any standalone Apache HTTP Server instance in the estate running an affected version, because the same defect and the same exploitation technique apply to both.

Environment in scope: all internet-facing and internally reachable FortiProxy (7.2 all versions, 7.4.0–7.4.14, 7.6.0–7.6.6), FortiPAM (1.0–1.8 all versions, 1.9.0–1.9.1), and FortiSwitch Manager (7.2.0–7.2.9) instances; the network segments those appliances mediate, including any IT/OT boundary they enforce; all hosts running Apache HTTP Server 2.4.17 through 2.4.67; and the organization's public IP space and cloud asset inventory for the external-exposure leg. Where these appliances sit at an enterprise-to-control-network boundary, the OT segments behind them are in scope for availability-impact assessment.

Time window: 90 days back from execution, extended to cover June 8, 2026 — the upstream Apache disclosure date and the point at which public proof-of-concept exploit code first became available — through to the present. Any confirmed external exposure discovered in Hypothesis 1 expands the window for that specific asset to the full retention available, because continuous exposure across the disclosure window means the asset should be treated as presumptively enumerated by opportunistic scanners.

Scope note on sensor coverage: Fortinet appliances do not run a CrowdStrike Falcon sensor. All CrowdStrike Falcon LogScale (CQL) collection against the appliances themselves depends on Fortinet syslog being forwarded into NG-SIEM through a third-party data connector; the endpoint-telemetry queries below target hosts behind or adjacent to the appliances, not the appliances. Confirm the connector is present and populating before treating any zero-result appliance query as a negative.

Hypotheses and Hunt Procedures

Hypothesis 1: an external actor can reach an internet-facing FortiProxy, FortiPAM, or FortiSwitch Manager instance, observable as an exposed service in passive internet-scan indices. Execute FIRST; its output scopes the internal hypotheses.

MITRE ATT&CK: Reconnaissance | T1595 Active Scanning — defender-side passive discovery of what an actor would enumerate · Initial Access | T1133 External Remote Services — an exposed appliance management or proxy listener is the reachable surface · ICS | T0883 Internet Accessible Device — where the appliance fronts a control network.

Collection Queries — passive external indices (STRICTLY passive; never probe target infrastructure):

Run each recipe unscoped first to confirm the filter actually matches the product, then re-run scoped to your own estate. Fortinet product strings vary across the indices and FortiProxy and FortiPAM are less consistently fingerprinted than FortiGate, so read the returned banners before trusting a zero result.

Shodan:
product:"Fortinet"
http.title:"FortiProxy"
http.title:"FortiPAM"
http.title:"FortiSwitch Manager"
http.html:"fortinet" port:443,8443,10443
ssl.cert.subject.CN:"FortiProxy"

 

// scope with: net:<your_public_CIDR> org:"<Your Org Name>" asn:AS<your_ASN>

 

Censys (CenQL — current form; do NOT mix with legacy services.* CSL):
host.services.software.vendor: "Fortinet"
host.services.software.product: "FortiProxy"
host.services: (port = "443" and software.vendor: "Fortinet")
host.services.endpoints.http.html_title: "FortiPAM"

 

// scope with: and (host.autonomous_system.asn = <your_ASN> or host.ip: "<your_public_CIDR>")

 

Netlas (tie-breaker only):
http.title:"FortiProxy"
host:<your_public_CIDR> AND port:(443 OR 8443 OR 10443)
certificate.subject.common_name:"<your_domain>"

 

Cross-reference every exposed service and version banner against the CISA Known Exploited Vulnerabilities catalog (https://www.cisa.gov/known-exploited-vulnerabilities-catalog) and against CVE-2026-49975. CVE-2026-49975 is not KEV-listed as of this writing, but the Fortinet edge-appliance family carries multiple historical KEV entries; a KEV match on any other CVE against the same exposed instance is presumptive ransomware and actor-associated initial-access risk and outranks this advisory in remediation priority.

Analysis Queries:

Attribute every hit with at least two independent ownership signals — PTR record, ASN, TLS certificate CN or SAN, WHOIS/RDAP registration, and your own cloud asset inventory — before reporting it as your exposure. Shared hosting and CDN fronting break attribution in both directions; an unattributable hit is inconclusive, not negative.

Version-triage each banner against the affected ranges in Section 1 and record the index scan timestamp alongside the finding. A banner is stale in both directions: an in-range version is a prompt to verify current state on the device, and a fixed-version banner is not evidence of safety if the scan predates your patch window.

Corroborate in at least two of Shodan, Censys, and Netlas before escalating. Absence from an index is evidence only that the index did not observe the host.

Historical pivot: establish whether the exposure spans June 8, 2026 through the present. Continuous exposure across that window means the instance was reachable for the entire period in which public exploit code existed, and should be treated as presumptively enumerated.

Pivot into the internal hypotheses: feed every confirmed-owned, in-range instance into Hypotheses 2 and 3 as a priority target and hunt it exhaustively rather than by sampling. Where the instance fronts or reaches OT workloads, escalate to the OT analysis in Hypothesis 3 and document the blast radius — internet reachability of infrastructure serving a control environment is a finding in its own right under IEC 62443 and NERC CIP, independent of any confirmed exploitation.

Favicon-hash pivoting is available for stripped banners and non-standard ports, but derive the hash from an instance you own by reusing an index-computed value — never by fetching /favicon.ico from a target, and never by copying a hash from a third-party write-up.

API credentials are referenced by environment-variable name only: SHODAN_API_KEY, CENSYS_API_SECRET, CENSYS_ORG_ID, NETLAS_API_KEY. Never inline a key into a query, script, plan, or shell command. A missing key is non-blocking — skip that engine and record the coverage gap.

Hypothesis 2: an unauthenticated remote actor has sent crafted HTTP/2 header frames to an affected Fortinet appliance or Apache HTTP Server instance to force excessive memory allocation, observable as anomalous HTTP/2 connection patterns in network telemetry and as memory-pressure or process-restart events in appliance and host logs.

MITRE ATT&CK: Initial Access | T1190 Exploit Public-Facing Application — the vulnerable listener is reached directly over the network · Impact | T1499 Endpoint Denial of Service and T1499.004 Application or System Exploitation — the technique triggers a resource-exhaustion flaw rather than flooding bandwidth · ICS | T0814 Denial of Service — where the affected appliance mediates control-network traffic.

Collection Queries:

CrowdStrike Falcon LogScale (CQL) — enumerate which third-party data connectors are populating before writing any appliance query, so a zero result is interpretable:

*
| groupBy([#type], function=count(as=events), limit=max)
| sort(events, order=desc, limit=max)

 

#type=/fortinet/i
| groupBy([#type, observer.hostname], function=count(as=events), limit=max)
| sort(events, order=desc, limit=max)

 

CrowdStrike Falcon LogScale (CQL) — inbound sessions to appliance management and proxy listeners from non-RFC1918 sources. Fortinet syslog fields that have no ECS equivalent are preserved under the Vendor. prefix by the CrowdStrike Parsing Standard; probe one event with head(1) and fall back to Vendor.* wherever the ECS field comes back null:

#type=/fortinet/i
| in(destination.port, values=[443, 8443, 10443])
| !cidr(source.ip, subnet=["10.0.0.0/8","172.16.0.0/12","192.168.0.0/16","127.0.0.0/8"])
| groupBy([source.ip, destination.ip, destination.port, observer.hostname], function=count(as=sessions), limit=max)
| sort(sessions, order=desc, limit=max)

 

CrowdStrike Falcon LogScale (CQL) — endpoint-side view of client connections to the proxy and management listeners, bucketed hourly so an availability cliff is visible as a drop rather than as an absence:

#event_simpleName = "NetworkConnectIP4"
| in(RemotePort, values=[443, 8080, 8443, 3128])
| formatTime(format="%Y-%m-%dT%H:00", as=hourBucket)
| groupBy([hourBucket, RemoteAddressIP4, RemotePort], function=count(as=conns), limit=max)
| sort(hourBucket, order=asc, limit=max)

 

CrowdStrike Falcon LogScale (CQL) — external inbound connections accepted by Apache worker processes on managed Linux and Windows hosts. The join runs in reverse direction (ProcessRollup2 as the main query, the heavily filtered network event as the subquery) to stay under the 100,000-row subquery cap:

#event_simpleName = "ProcessRollup2"
| ImageFileName = /(\/httpd|\/apache2)$/i
| join({
#event_simpleName = "NetworkReceiveAcceptIP4"
| in(LocalPort, values=[80, 443, 8080, 8443])
| !cidr(RemoteAddressIP4, subnet=["10.0.0.0/8","172.16.0.0/12","192.168.0.0/16","127.0.0.0/8"])
},
field=[aid, TargetProcessId], key=[aid, ContextProcessId], mode=inner)
| groupBy([ComputerName, ImageFileName, UserName], function=count(as=hits), limit=max)
| sort(hits, order=desc, limit=max)

 

BPF packet capture — capture the HTTP/2 cleartext connection preface and TLS client hellos arriving at the appliance-facing interface. Note that -G requires a strftime format in the -w filename or each rotation overwrites the previous file:

tcpdump -i eth0 -s 0 -w /captures/http2_%Y%m%d_%H%M%S.pcap -G 3600 -C 500 \
'tcp and (port 80 or port 443 or port 8443 or port 10443 or port 8080)'

 

tcpdump -i eth0 -s 0 -w /captures/h2_preface_%Y%m%d_%H%M%S.pcap -G 900 \
'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x50524920'

 

tcpdump -i eth0 -nn -c 100000 -w /captures/h2_syn_rate_%Y%m%d_%H%M%S.pcap -G 300 \
'tcp[tcpflags] & tcp-syn != 0 and tcp[tcpflags] & tcp-ack = 0 and dst host <appliance_ip>'

 

Datadog Log Search — appliance syslog forwarded to Datadog, and the equivalent host-side view. Reserved attributes (source, host, service, status, message) are queried without the @ prefix; all others require it:

source:fortinet @destination.port:(443 OR 8443 OR 10443) -@source.ip:10.* -@source.ip:172.16.* -@source.ip:192.168.*
// time range: 2026-06-08T00:00Z to current

 

source:windows @evt.id:(7031 OR 7034 OR 1000 OR 2004)
// time range: 2026-06-08T00:00Z to current

 

source:kubernetes @kubernetes.container_name:"httpd" status:error message:"h2"
// time range: 2026-06-08T00:00Z to current

 

Datadog Live Process Monitoring — Infrastructure > Processes, not a log search; requires the Agent with process_config.process_collection.enabled set to true:

command:httpd user:www-data

 

command:apache2

 

// Fallback where Live Process Monitoring is not enabled:
// source:kubernetes @kubernetes.container_name:"httpd" — Analytics: Table view, group by @kubernetes.pod_name

 

Datadog CloudTrail — where the affected appliance or an Apache workload runs in AWS, capture the security-group and load-balancer changes that would have opened or closed the listener:

source:cloudtrail @evt.name:(AuthorizeSecurityGroupIngress OR RevokeSecurityGroupIngress OR ModifyListener OR CreateLoadBalancer) -@network.client.ip:10.*
// time range: 2026-06-08T00:00Z to current

 

Windows Event IDs to collect — for Windows hosts running Apache HTTP Server, and for management workstations that lost their brokered path through FortiPAM:

Event ID 7031 — Service Control Manager: service terminated unexpectedly and was restarted
Event ID 7034 — Service Control Manager: service terminated unexpectedly (no recovery action)
Event ID 7036 — Service Control Manager: service entered the running or stopped state
Event ID 1000 — Application Error: faulting application, module, and exception code
Event ID 1001 — Windows Error Reporting: fault bucket for the crashed process
Event ID 2004 — Resource-Exhaustion-Detector: Windows diagnosed low virtual memory and named the top consumers
Event ID 2019 — Srv: server unable to allocate from the system nonpaged pool

 

Get-WinEvent -FilterHashtable @{LogName='System'; Id=7031,7034,7036; StartTime=(Get-Date).AddDays(-90)} |
Where-Object { $_.Message -match 'Apache|httpd' } |
Select-Object TimeCreated, Id, MachineName, Message |
Export-Csv -NoTypeInformation -Path .\apache_service_terminations.csv

 

Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-Resource-Exhaustion-Detector/Operational'; Id=2004; StartTime=(Get-Date).AddDays(-90)} |
Select-Object TimeCreated, MachineName, Message |
Export-Csv -NoTypeInformation -Path .\resource_exhaustion_events.csv

 

Get-WinEvent -FilterHashtable @{LogName='Application'; Id=1000,1001; StartTime=(Get-Date).AddDays(-90)} |
Where-Object { $_.Message -match 'httpd\.exe|apache' } |
Select-Object TimeCreated, Id, MachineName, Message |
Export-Csv -NoTypeInformation -Path .\apache_application_faults.csv

 

YARA file-system scan — search staging hosts, jump servers, and any host that an actor may have used to launch the attack from inside the estate for HTTP/2 Bomb exploit tooling:

yara -r /opt/hunt/rules/http2_bomb.yar /home/ >> /opt/hunt/out/http2_disk_hits.txt

 

yara -r /opt/hunt/rules/http2_bomb.yar /tmp/ /var/tmp/ /opt/ >> /opt/hunt/out/http2_disk_hits.txt

 

Analysis Queries:

CrowdStrike Falcon LogScale (CQL) — rate analysis. A source producing a large number of short-lived sessions to a management listener within a single minute is the amplification signature; the technique does not require volumetric bandwidth, so look for connection count rather than byte count:

#type=/fortinet/i
| in(destination.port, values=[443, 8443, 10443])
| formatTime(format="%Y-%m-%dT%H:%M", as=minuteBucket)
| groupBy([minuteBucket, source.ip, destination.ip], function=count(as=sessions), limit=max)
| sessions > 200
| sort(sessions, order=desc, limit=max)

 

Wireshark display filters — isolate the HTTP/2 exchange and identify the amplification pattern. Wireshark dissects HTTP/2 over TLS only where a keylog file is supplied; over cleartext h2c the frames dissect directly:

http2
http2.type == 1
http2.type == 4
http2.headers.header.length > 1000
http2.flags.end_headers == 0
tcp.flags.syn == 1 && tcp.flags.ack == 0 && tcp.dstport in {443 8443 10443}
http.request.line contains "Upgrade: h2c"

 

tshark -r /captures/http2_capture.pcap -Y "http2.type == 1" -T fields \
-e frame.time -e ip.src -e ip.dst -e tcp.srcport -e http2.streamid -e http2.length

 

tshark -r /captures/http2_capture.pcap -q -z conv,tcp | sort -k7 -n -r | head -50

 

tshark -r /captures/http2_capture.pcap -Y "tcp.flags.syn == 1 && tcp.flags.ack == 0" -T fields \
-e ip.src | sort | uniq -c | sort -rn | head -50

 

Datadog Log Analytics — the same rate question expressed in Datadog. Log Analytics has no SQL ORDER BY or LIMIT; sort order is set in the UI:

source:fortinet @destination.port:(443 OR 8443 OR 10443)
// Use Timeseries view; group by @source.ip; rollup 1 minute; time range: last 90 days
// Equivalent to the CQL groupBy([minuteBucket, source.ip]) rate query above

 

source:fortinet @destination.port:(443 OR 8443 OR 10443)
// Use Top List view; group by @source.ip; time range: last 90 days

 

Datadog Audit Trail — confirm no Datadog-side monitor or log pipeline covering these appliances was disabled or modified during the window, which would explain a data gap rather than an absence of activity:

source:datadog @evt.name:Monitor
// Use Table view; group by @action, @usr.email; time range: last 90 days

 

source:datadog @evt.name:"Access Management"
// Use Table view; group by @action, @usr.email; time range: last 90 days

 

Datadog Monitor definition — one per hypothesis:

Type: Log Alert
Query: source:fortinet @destination.port:(443 OR 8443 OR 10443) -@source.ip:10.* -@source.ip:172.16.* -@source.ip:192.168.*
Evaluation window: last 5 minutes
Alert condition: count > 500 grouped by @source.ip
Message: "ALERT: high-rate external connection burst to a Fortinet management or proxy listener — possible HTTP/2 memory exhaustion attempt against CVE-2026-49975. Verify appliance memory utilization immediately @pagerduty-soc"
Prerequisites: Fortinet appliance syslog forwarded to Datadog with source:fortinet; destination.port and source.ip parsed as attributes
Create via: Monitors > New Monitor > Log Alert OR POST /api/v1/monitors

 

YARA memory scan — where an internal host is suspected of having launched the attack, scan the interpreter process holding the exploit tooling. Classic YARA 4.5 takes the PID as a positional target; there is no -p flag for process scanning, and YARA-X does not support process memory at all:

yara /opt/hunt/rules/http2_bomb.yar 4821

 

for pid in $(pgrep -f 'python|python3|node|go'); do yara /opt/hunt/rules/http2_bomb.yar $pid; done >> /opt/hunt/out/http2_mem_hits.txt

 

CrowdStrike Falcon can execute the same scan remotely — upload the rule file via Real Time Response (RTR) put, then run it with RTR runscript against the target host; alternatively convert the disk-side string set into a Custom IOA for standing coverage.

Hypothesis 3: an affected appliance has already suffered a memory-exhaustion availability failure, observable as memory-pressure and restart events on the device, as a measurable service interruption for the population behind it, and as a corresponding gap in OT visibility where the appliance mediates a control-network boundary.

MITRE ATT&CK: Impact | T1499 Endpoint Denial of Service — the observable is the outcome rather than the delivery · ICS | T0815 Denial of View — operators lose the traffic path that carries process visibility · ICS | T0826 Loss of Availability — the control-network boundary itself becomes unavailable.

Collection Queries:

CrowdStrike Falcon LogScale (CQL) — appliance-side memory, conserve-mode, restart, and watchdog events from forwarded Fortinet syslog:

#type=/fortinet/i
| Vendor.logdesc = /(memory|conserve|out of memory|restart|reboot|watchdog)/i
| groupBy([observer.hostname, Vendor.logid, Vendor.logdesc], function=count(as=hits), limit=max)
| sort(hits, order=desc, limit=max)

 

CrowdStrike Falcon LogScale (CQL) — Apache worker termination churn on managed hosts. EndOfProcess does not carry ImageFileName, so the image name is taken from ProcessRollup2 and the two are joined on the agent ID and process ID pair:

#event_simpleName = "ProcessRollup2"
| ImageFileName = /(\/httpd|\/apache2)$/i
| join({#event_simpleName = "EndOfProcess"},
field=[aid, TargetProcessId], key=[aid, TargetProcessId], mode=inner,
include=[ProcessEndTime])
| groupBy([ComputerName, ImageFileName], function=count(as=terminations), limit=max)
| sort(terminations, order=desc, limit=max)

 

CrowdStrike Falcon LogScale (CQL) — service restarts on Windows hosts running Apache or Fortinet management components:

#event_simpleName = "ServiceStarted"
| ServiceDisplayName = /(apache|httpd|forti)/i
| groupBy([ComputerName, ServiceDisplayName, ImageFileName], function=count(as=starts), limit=max)
| sort(starts, order=desc, limit=max)

 

SNMP polling — memory utilization and uptime are the two highest-value signals for this vulnerability, because a memory-exhaustion event that resolves via device restart leaves an uptime reset behind even when the log ring buffer has rolled. Poll at 60-second intervals across the hunt window and diff successive values:

snmpwalk -v2c -c <community> <appliance_ip> system

 

snmpget -v2c -c <community> <appliance_ip> SNMPv2-MIB::sysUpTime.0 SNMPv2-MIB::sysDescr.0

 

snmpget -v2c -c <community> <appliance_ip> .1.3.6.1.4.1.12356.101.4.1.4.0

 

snmpwalk -v2c -c <community> <appliance_ip> HOST-RESOURCES-MIB::hrStorageTable

 

snmpwalk -v2c -c <community> <switch_ip> IF-MIB::ifTable

 

snmpget -v2c -c <community> <switch_ip> IF-MIB::ifHCInOctets.<ifIndex> IF-MIB::ifHCOutOctets.<ifIndex> IF-MIB::ifInErrors.<ifIndex> IF-MIB::ifOutErrors.<ifIndex>

 

snmpwalk -v3 -l authPriv -u <snmp_user> -a SHA-256 -A <authpass> -x AES-256 -X <privpass> <appliance_ip> system

 

The Fortinet OID .1.3.6.1.4.1.12356.101.4.1.4.0 is fgSysMemUsage on FortiOS-family devices and returns memory utilization as a percentage; where it is unavailable, HOST-RESOURCES-MIB::hrStorageTable provides the vendor-neutral equivalent. SHA-2 authentication requires net-snmp 5.8 or later and AES-192/AES-256 require a build with Blumenthal AES support; where the device offers only stock cryptography, fall back to -a SHA -x AES. Provision SNMPv3 credentials through snmp.conf or createUser rather than inline arguments, which are visible in the process table. Treat any surviving v1 or v2c community-string access to an OT-adjacent appliance as a finding in its own right — those transit essentially in cleartext.

Collect SNMP trap logs from the trap receiver across the hunt window and filter for traps originating from the affected appliance addresses. Flag coldStart (1.3.6.1.6.3.1.1.5.1) and warmStart (1.3.6.1.6.3.1.1.5.2), which indicate a device restart consistent with recovery from memory exhaustion; linkDown and linkUp (1.3.6.1.6.3.1.1.5.3 and .4), which indicate port flaps on the device-facing switch port; and authenticationFailure (1.3.6.1.6.3.1.1.5.5), which indicates unauthorized access attempts against the management interface.

OT Data Collection: Claroty xDome — Devices > All Devices > Advanced Filters, set Manufacturer = Fortinet, and add the SW / FW Version column to the view to capture firmware per instance. Export the filtered table via the Export control, batching by site where the result set approaches the 100,000-row export ceiling. Then use Network > Communication > Communication Analysis with Side B filtered to Manufacturer = Fortinet to establish which OT assets depend on the appliance as a traffic path, and check the Vulnerabilities chip on each matched device for CVE correlation.

OT Data Collection: Claroty CTD — the same inventory question is answered from the on-prem console, but CTD retains continuous full PCAP where xDome does not. Where an availability event is suspected on a specific date, retrieve the packet capture for that window via the CTD-only per-event PCAP endpoint and analyze it with the Wireshark filters above. Do not treat CTD and xDome as interchangeable; only CTD can answer retrospective packet-level questions.

OT Data Collection: Dragos Platform — Assets, filtered by vendor to enumerate Fortinet devices and their firmware, then Notifications for the hunt window filtered to the asset set to surface any detection that fired against those devices. Use the Communications Hub to establish the traffic dependency between the appliance and the OT assets behind it, and check Vulnerability Management for the Now/Next/Never disposition on any Fortinet CVE already tracked for those assets.

OT Data Collection: Nozomi Guardian and Vantage — query the asset inventory and the traffic layer separately, because an asset with multiple interfaces is one assets row and several nodes rows:

assets | where vendor == "Fortinet" | select id name vendor product_name firmware_version ip

 

nodes | where vendor == "Fortinet" | select ip label type last_activity_time

 

links | where to_port == "443" or to_port == "8443" | join nodes to ip | join nodes from ip | select from_label to_label protocol

 

alerts | where time >= days_ago(90) | where name ~= "denial" | sort time desc | head 200

 

OT Data Collection: Tenable OT Security — the CVE-matching path is the strongest fit here because Tenable correlates firmware version to CVE through the same plugin pipeline as Nessus. Filter the asset inventory to Fortinet devices, review the Vulnerabilities view for CVE-2026-49975 and for any other open Fortinet CVE on the same assets, and export the asset-plus-vulnerability table. Do not aim a Nessus plugin scan at OT devices — restrict any active scanning to IT-class assets sitting in OT segments.

OT Data Collection: Forescout eyeInspect — use the asset inventory filtered to Fortinet to enumerate devices and firmware, review the vulnerability match results against the Forescout CPS vulnerability database and the Vedere Labs KEV list, and export the asset record set. eyeInspect's active-query depth is lighter than Tenable's, so treat its firmware inventory as passive-fingerprint quality and corroborate any version-based conclusion against the device itself.

Armis Centrix (ASQ) — inventory and connection queries. Set the time window in the UI time-picker rather than in the query body:

in:devices manufacturer:Fortinet

 

in:devices manufacturer:Fortinet category:"Network Equipment"

 

in:services port:443,8443,10443

 

in:ipConnections
serverPort:443,8443,10443
endpointA:(networkLocation:"External")
endpointB:(device:(manufacturer:Fortinet))

 

in:ipConnections
serverPort:443,8443,10443
endpointA:(networkLocation:"Internal")
endpointB:(device:(manufacturer:Fortinet))
orderBy:(bytesCount desc)

 

in:alerts affectedDevice:(manufacturer:Fortinet)

 

Analysis Queries:

Correlate the appliance restart timeline against the client-side connection cliff. A genuine memory-exhaustion event produces three signals within the same few minutes: a spike in inbound connection rate from one or a small number of sources, a memory utilization curve that rises steeply and does not recover, and a subsequent uptime reset or process restart. Two of the three without the third is more consistent with an operational fault than with exploitation.

Historian and SCADA alarm correlation: for every appliance restart timestamp identified above, pull the historian for the same window and check for data gaps, stale tag values, or quality-flag changes on tags whose data path crosses the appliance. Pull the SCADA alarm log for communication-loss and device-unreachable alarms in the same window. An availability event at the boundary that produced no historian gap and no communication alarm did not interrupt the control path; one that produced both defines the operational blast radius and belongs in the incident record regardless of whether exploitation is ultimately confirmed.

Baseline deviation: compare the connection-rate profile of each source address against its own 90-day baseline rather than against a fixed threshold. Vulnerability scanners, uptime monitors, and load balancers legitimately produce high connection counts against these listeners; what distinguishes exploitation is a source whose rate departs sharply from its own established pattern and whose sessions correlate in time with the memory curve.

Windows Event Log analysis:

$events = Get-WinEvent -FilterHashtable @{LogName='System'; Id=7031,7034; StartTime=(Get-Date).AddDays(-90)}
$events | Group-Object { $_.TimeCreated.ToString('yyyy-MM-dd HH:00') } |
Sort-Object Count -Descending |
Select-Object Name, Count |
Export-Csv -NoTypeInformation -Path .\service_termination_by_hour.csv

 

Get-WinEvent -FilterHashtable @{LogName='System'; Id=6005,6009} |
Select-Object TimeCreated, Id, MachineName |
Sort-Object TimeCreated |
Export-Csv -NoTypeInformation -Path .\host_boot_timeline.csv

 

Hypothesis 4: an affected version of FortiProxy, FortiPAM, FortiSwitch Manager, or standalone Apache HTTP Server remains deployed and unpatched in the estate, observable as an in-range version string in asset inventory and endpoint telemetry.

MITRE ATT&CK: Initial Access | T1190 Exploit Public-Facing Application — this hypothesis establishes the precondition rather than the activity; a confirmed in-range version is the exposure that Hypotheses 1 through 3 hunt for evidence against.

Collection Queries:

CrowdStrike Falcon LogScale (CQL) — enumerate Apache HTTP Server instances on managed hosts and capture the command line, which frequently carries the server root and configuration path needed to determine the compiled version:

#event_simpleName = "ProcessRollup2"
| ImageFileName = /(\/httpd|\/apache2|\\httpd\.exe)$/i
| groupBy([ComputerName, ImageFileName, CommandLine], function=count(as=execs), limit=max)
| sort(execs, order=desc, limit=max)

 

Falcon Exposure Management (Spotlight) provides the direct answer where the host is sensor-managed — filter the vulnerability view to CVE-2026-49975 and export the affected host list. For the Fortinet appliances themselves, which carry no sensor, the authoritative version source is the device management interface or the Fortinet support portal inventory, not any telemetry platform.

Datadog Log Search — surface Apache version strings from server banner and startup logging where those logs are forwarded:

source:kubernetes @kubernetes.container_name:"httpd" message:"Apache/2.4"
// Analytics: Table view, group by @kubernetes.pod_name; time range: last 30 days

 

source:windows message:"Apache/2.4"
// Analytics: Table view, group by host; time range: last 30 days

 

Analysis Queries:

Build a single reconciled inventory table with one row per instance carrying: hostname or appliance name, product, running version, affected-range determination, internet-reachable determination from Hypothesis 1, fixed build designated by Fortinet, and whether that fixed build was available at the time of the hunt. The last column matters operationally — at publication Fortinet described FortiPAM 1.9.2, FortiProxy 7.6.7 and 7.4.15, and FortiSwitch Manager 7.2.10 as upcoming releases rather than as builds already available for download, so an instance may be correctly identified as vulnerable with no patch yet obtainable. Those rows are the ones that require compensating network controls and a documented interim risk acceptance.

Flag separately every instance on FortiPAM 1.0 through 1.8 or FortiProxy 7.2. Fortinet is issuing no corrective build for those branches and directs a migration to a supported release, which is a project rather than a maintenance window and needs to enter the remediation plan on that basis.

Threat Actor Profile

Opportunistic and commodity actors are the most probable adversary for this vulnerability and should be the primary assumption. Sophistication required is low: working proof-of-concept code for the upstream Apache defect has been public since shortly after the June 2026 disclosure, exploitation requires no authentication and no prior access, and a single connection from a single host is sufficient. The access path is direct network reachability to any listener with HTTP/2 enabled. The characteristic TTP pattern is indiscriminate internet-wide scanning to enumerate vulnerable banners, followed by exploitation of whatever answers — meaning exposure, not targeting, determines who is affected. Because the outcome is availability loss rather than access, this class of actor gains no foothold; the damage is the outage itself.

Hacktivist and disruption-motivated actors are a credible secondary threat, and for critical infrastructure operators they are the more consequential one. Sophistication is low to moderate, the access path is identical, but target selection is deliberate rather than opportunistic and timing is chosen for effect — during a production peak, a public event, or a period of political attention. This class has repeatedly demonstrated a preference for internet-exposed OT-adjacent infrastructure precisely because a visible outage serves the objective better than a quiet compromise. An availability-only vulnerability on a device sitting at an IT/OT boundary is a close match to this actor's operating pattern.

Nation-state actors would not typically expend attention on an availability-only flaw as an objective, but the vulnerability is relevant to them in two narrower ways. First, as a diversion — a denial-of-service event against a security appliance draws responder attention and monitoring capacity toward the outage and away from concurrent activity elsewhere. Second, as a pre-positioning consideration: an actor already resident in an environment gains a reliable, low-attribution mechanism to disrupt a segmentation or privileged-access control point at a moment of its choosing. Sophistication is high, the access path may be internal rather than external, and the TTP of interest is the timing correlation between the availability event and other activity rather than the exploitation itself. This is the reason Hypothesis 3 asks the analyst to correlate every outage window against concurrent telemetry rather than closing it as an operational fault.

Insider and inadvertent causes must be excluded rather than assumed. A misconfigured internal scanner, an aggressive synthetic monitoring probe, or a load-test tool aimed at the wrong target can produce a memory-pressure and restart signature closely resembling exploitation. This is not a threat actor profile so much as the alternative hypothesis every confirmed availability event must be tested against before escalation.

Data Sources Required

Network: full packet capture or rolling PCAP at the appliance-facing interface with sufficient depth to retain HTTP/2 frame structure; NetFlow or IPFIX covering flows to the appliance management and proxy listeners; firewall and load-balancer session logs; TLS metadata where available. Packet capture is disproportionately valuable for this hunt because the distinguishing evidence is frame-level rather than volumetric.

Endpoint: CrowdStrike Falcon telemetry (ProcessRollup2, EndOfProcess, NetworkConnectIP4, NetworkReceiveAcceptIP4, ServiceStarted) for managed hosts running Apache HTTP Server; Windows Event Logs (System, Application, and Microsoft-Windows-Resource-Exhaustion-Detector/Operational) for Windows Apache hosts and for management workstations dependent on FortiPAM; Sysmon where deployed.

Vendor and device logs: Fortinet appliance syslog forwarded to the SIEM through a third-party data connector, including event, traffic, and system log categories; SNMP polling data and SNMP trap receiver logs for the appliances and their upstream switch ports; appliance configuration backups and firmware version records from the Fortinet support portal. This is the single most important collection dependency in the plan — without forwarded appliance syslog, the appliance-side legs of Hypotheses 2 and 3 cannot be executed and their absence must be reported as a coverage gap rather than as a negative finding.

OT and ICS: process historian for the tags whose data path crosses the affected appliances; SCADA alarm and event logs for communication-loss alarms; OT monitoring platform data from whichever of Claroty xDome or CTD, Dragos, Nozomi, Tenable OT, Forescout eyeInspect, and Armis Centrix are deployed, covering asset inventory, firmware version, traffic dependency, and vulnerability correlation.

External attack surface: the passive internet-scan indices queried read-only (Shodan, Censys, Netlas); the CISA Known Exploited Vulnerabilities catalog; and the organization's authoritative public IP address inventory and cloud asset inventory. The last of these is a hard requirement rather than a convenience — without an authoritative ownership record, an index hit cannot be attributed and the exposure determination cannot be made in either direction.

Detection Signatures

The SIGMA rules below span four distinct logsource categories so that a single missing log source does not silence the whole rule set. The first targets forwarded appliance syslog, the second webserver access logging, the third Linux process creation, and the fourth Windows network connection telemetry.

title: Fortinet Appliance Memory Pressure or Unexpected Restart
id: 7c4e1a92-3b6d-4f18-9a52-8d0c7e5b1f34
status: experimental
description: Detects memory conserve mode, out-of-memory conditions, watchdog resets, and unexpected process or device restarts on Fortinet appliances, which are the observable outcome of successful exploitation of CVE-2026-49975 against FortiProxy, FortiPAM, or FortiSwitch Manager.
references:
- https://fortiguard.fortinet.com/psirt/FG-IR-26-163
- https://nvd.nist.gov/vuln/detail/CVE-2026-49975
author: 1898 & Co.
date: 2026/08/17
logsource:
product: fortinet
service: event
detection:
selection_memory:
logdesc|contains:
- 'memory conserve'
- 'out of memory'
- 'memory usage'
selection_restart:
logdesc|contains:
- 'restart'
- 'reboot'
- 'watchdog'
condition: selection_memory or selection_restart
falsepositives:
- Planned firmware upgrades and scheduled maintenance reboots
- Memory conserve mode triggered by legitimate traffic peaks on an undersized appliance
- Configuration changes that require a service restart
level: high
tags:
- attack.impact
- attack.t1499
- attack.t1499.004

 

title: HTTP/2 Cleartext Upgrade Request Burst
id: 2f8b6d41-9c07-4e35-b1a8-6e93d2470c58
status: experimental
description: Detects a burst of HTTP/1.1 requests carrying an Upgrade to h2c header against a web server, which is the cleartext negotiation path into the vulnerable mod_http2 request handler and a common precursor to HTTP/2 Bomb exploitation attempts.
references:
- https://httpd.apache.org/security/vulnerabilities_24.html
- https://nvd.nist.gov/vuln/detail/CVE-2026-49975
author: 1898 & Co.
date: 2026/08/17
logsource:
category: webserver
detection:
selection:
cs-headers|contains: 'Upgrade: h2c'
condition: selection
falsepositives:
- Load balancers and reverse proxies that negotiate h2c to backend origins by design
- Application performance monitoring agents that probe protocol support
- Legitimate clients on networks where TLS is terminated upstream
level: medium
tags:
- attack.initial_access
- attack.t1190

 

title: Apache Worker Process Repeated Abnormal Termination on Linux
id: 5d1c9f38-4a26-4b70-8e93-1f7a0c62d845
status: experimental
description: Detects the process-creation pattern associated with Apache HTTP Server worker respawn churn and out-of-memory killer activity on Linux hosts, which follows a successful memory-exhaustion attack against mod_http2.
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-49975
author: 1898 & Co.
date: 2026/08/17
logsource:
category: process_creation
product: linux
detection:
selection_oom:
Image|endswith:
- '/dmesg'
- '/journalctl'
CommandLine|contains:
- 'oom'
- 'Out of memory'
selection_restart:
CommandLine|contains:
- 'systemctl restart httpd'
- 'systemctl restart apache2'
- 'apachectl restart'
- 'apachectl graceful'
condition: selection_oom or selection_restart
falsepositives:
- Scheduled configuration reloads and log-rotation graceful restarts
- Administrator troubleshooting during a maintenance window
- Configuration management tooling that restarts services on convergence
level: medium
tags:
- attack.impact
- attack.t1499

 

title: External Connection Burst to Appliance Management Port
id: 9a3e7b25-8f14-4c60-a7d9-3b5c81e64072
status: experimental
description: Detects a Windows host establishing repeated connections to appliance management ports from or toward an external address, used to identify both an internal host acting as the attack source and the client-side view of an appliance under exploitation.
references:
- https://fortiguard.fortinet.com/psirt/FG-IR-26-163
author: 1898 & Co.
date: 2026/08/17
logsource:
category: network_connection
product: windows
detection:
selection:
DestinationPort:
- 443
- 8443
- 10443
Initiated: 'true'
filter_internal:
DestinationIp|cidr:
- '10.0.0.0/8'
- '172.16.0.0/12'
- '192.168.0.0/16'
- '127.0.0.0/8'
condition: selection and not filter_internal
falsepositives:
- Browsers and business applications reaching external HTTPS services on 443
- Endpoint security and update agents polling vendor cloud services
- VPN clients establishing tunnels on 443 or 10443
level: low
tags:
- attack.impact
- attack.t1499

 

The Snort and Suricata rules below use local SIDs beginning at 1,000,000 per the Suricata local-rule reservation. Rule 1 matches the 24-byte HTTP/2 cleartext connection preface and fires only on a repetition threshold, so a single legitimate h2c client does not alert. Rule 2 matches the HTTP/1.1 upgrade path into the same handler. Rule 3 is a rate rule on new TCP sessions toward management ports, included because the TLS-wrapped case hides the HTTP/2 frames from inspection entirely and connection rate is the only signal left. Under Snort 3, convert the option lists to comma-separated form, move service out of metadata into its own option, and note that metadata is non-functional.

alert tcp any any -> $HOME_NET [80,8080,8000] (msg:"POLICY HTTP/2 cleartext connection preface burst - possible CVE-2026-49975 HTTP/2 Bomb probing"; flow:to_server,established; content:"PRI * HTTP/2.0|0d 0a 0d 0a|SM|0d 0a 0d 0a|"; depth:24; detection_filter:track by_src, count 20, seconds 60; classtype:attempted-dos; reference:cve,2026-49975; reference:url,httpd.apache.org/security/vulnerabilities_24.html; metadata:service http; sid:1000001; rev:1;)

 

alert http any any -> $HOME_NET any (msg:"POLICY HTTP/1.1 Upgrade to h2c requested at abnormal rate - CVE-2026-49975 negotiation path"; flow:to_server,established; http.header; content:"Upgrade|3a| h2c"; nocase; detection_filter:track by_src, count 10, seconds 60; classtype:attempted-dos; reference:cve,2026-49975; sid:1000002; rev:1;)

alert tcp any any -> $HOME_NET [443,8443,10443] (msg:"POLICY High rate of new TCP sessions to appliance management port - possible HTTP/2 memory exhaustion attempt"; flow:to_server; flags:S,12; threshold:type both, track by_src, count 200, seconds 60; classtype:attempted-dos; reference:cve,2026-49975; reference:url,fortiguard.fortinet.com/psirt/FG-IR-26-163; sid:1000003; rev:1;)

 

The first YARA rule targets exploit tooling at rest on disk. Because no attacker binary is published for this vulnerability and no hashes exist to pivot on, the rule matches the structural fingerprint that any HTTP/2 Bomb implementation must carry: the literal connection preface, HPACK and Huffman encoding references required to build the compressed header payload, and the CVE identifier that appears in nearly every public proof-of-concept. The condition requires the preface or an explicit CVE reference plus at least two supporting indicators, which prevents any single generic HTTP/2 library file from matching. The 400KB size ceiling further restricts matching to scripts and small tools rather than to the HTTP/2 libraries themselves.

rule HTTP2_Bomb_Exploit_Tooling_Disk
{
meta:
description = "Detects HTTP/2 Bomb (CVE-2026-49975) exploit scripts and tooling on disk by structural fingerprint rather than by hash"
author = "1898 & Co."
date = "2026-08-17"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2026-49975"
severity = "high"
strings:
$preface = "PRI * HTTP/2.0" ascii wide // mandatory HTTP/2 client connection preface
$cve1 = "CVE-2026-49975" ascii wide nocase // CVE identifier, present in most public PoCs
$cve2 = "HTTP/2 Bomb" ascii wide nocase // the public nickname for the technique
$h1 = "hpack" ascii wide nocase // HPACK header compression, required to build the payload
$h2 = "huffman" ascii wide nocase // Huffman coding used by HPACK to amplify header size
$h3 = "SETTINGS_MAX_HEADER_LIST_SIZE" ascii wide // the setting an exploit manipulates or ignores
$h4 = "CONTINUATION" ascii wide // frame type used to chain oversized header blocks
$h5 = "h2c" ascii wide // cleartext HTTP/2 negotiation token
$t1 = "mod_http2" ascii wide nocase // the vulnerable Apache module named as the target
condition:
filesize < 400KB and
(($preface or any of ($cve*)) and 2 of ($h*, $t1))
}

 

The second YARA rule targets the same tooling resident in process memory, for the case where the exploit was executed from a host inside the estate and the script itself was deleted or never written to disk. Scanning an interpreter process rather than a file changes the false-positive profile: an ordinary Python or Node process that merely imports an HTTP/2 library will hold the protocol constants, so the condition requires the connection preface together with at least three supporting indicators, and requires a target-specific string in the second branch. Scan interpreter and compiled-runtime processes only; a whole-system memory sweep with this rule is not productive.

rule HTTP2_Bomb_Exploit_Tooling_Memory
{
meta:
description = "Detects HTTP/2 Bomb (CVE-2026-49975) exploit tooling resident in process memory on a host used to launch the attack"
author = "1898 & Co."
date = "2026-08-17"
reference = "https://fortiguard.fortinet.com/psirt/FG-IR-26-163"
severity = "high"
scan_target = "interpreter and runtime process memory only - yara rules.yar <pid>"
strings:
$preface = "PRI * HTTP/2.0" ascii wide // the preface is written into the socket buffer at runtime
$m1 = "hpack" ascii wide nocase // HPACK encoder present in the running exploit
$m2 = "huffman" ascii wide nocase // Huffman table held in memory during payload construction
$m3 = "CONTINUATION" ascii wide // frame type assembled in the send path
$m4 = "SETTINGS_MAX_HEADER_LIST_SIZE" ascii wide // negotiated setting held in connection state
$m5 = "END_HEADERS" ascii wide // header block flag manipulated by the technique
$tgt1 = "FortiProxy" ascii wide nocase // target product named in the running tool
$tgt2 = "FortiPAM" ascii wide nocase // target product named in the running tool
$tgt3 = "mod_http2" ascii wide nocase // vulnerable module named in the running tool
$tgt4 = "CVE-2026-49975" ascii wide nocase // CVE identifier held in the process
condition:
($preface and 3 of ($m*)) or
($preface and any of ($tgt*) and 2 of ($m*))
}

 

Indicators of Compromise

Network indicators are behavioral rather than atomic for this vulnerability, because no attacker infrastructure has been published. Hunt for: a source address opening an abnormally high count of short-lived TCP sessions to ports 443, 8443, 10443, 80, or 8080 on an affected appliance within a single minute, where the byte volume per session is small relative to the session count; the 24-byte HTTP/2 cleartext connection preface appearing in a burst from a single source; HTTP/1.1 requests carrying an Upgrade to h2c header at a rate inconsistent with the client's own baseline; HTTP/2 HEADERS and CONTINUATION frames carrying header blocks whose decompressed size is disproportionate to their wire size; and TCP sessions to the appliance that are established and then abandoned without a completed request.

External-exposure indicators: any FortiProxy, FortiPAM, or FortiSwitch Manager management or proxy listener answering from an address in your public IP space or cloud estate; any such instance whose banner reports a version inside the affected ranges; any instance whose exposure is observable in the passive indices continuously across the June 8, 2026 to present window; and any host in your address space running Apache HTTP Server 2.4.17 through 2.4.67 with HTTP/2 enabled. Treat shadow infrastructure — an instance discovered in an index that does not appear in your asset inventory — as a finding in its own right independent of its version.

Host indicators: Apache httpd or apache2 worker processes terminating and respawning at a rate above their own baseline; Windows Event ID 7031 or 7034 naming an Apache service; Windows Event ID 2004 from the Resource-Exhaustion-Detector naming httpd.exe among the top memory consumers; Linux out-of-memory killer entries in dmesg or the journal naming an httpd or apache2 process; and any file or memory hit from the two YARA rules in Section 5.

Operational and OT indicators: an appliance memory utilization curve that rises steeply and does not recover; an appliance uptime reset with no corresponding change record; SNMP coldStart or warmStart traps from an affected appliance outside a maintenance window; linkDown and linkUp flaps on the switch port facing an affected appliance; historian data gaps or quality-flag changes on tags whose path crosses the appliance; SCADA communication-loss or device-unreachable alarms coincident with an appliance restart; and loss of brokered administrative access through FortiPAM reported by operators during the same window.

False Positive Baseline

Vulnerability scanners and compliance assessment tools produce high connection rates against exactly the listeners this hunt monitors, and frequently negotiate HTTP/2 to fingerprint the server. Suppress by source address for authorized scanner infrastructure, but verify the scan schedule matches the observed timing rather than assuming it — an unscheduled scan from a scanner address is itself worth a question.

Synthetic monitoring, uptime checks, and health probes from load balancers, CDN edges, and application performance monitoring services connect to management and proxy listeners continuously and by design, often at fixed short intervals. These produce a steady high count that will dominate any rate-ordered result set. Baseline and suppress them by source address and by the regularity of their interval, which distinguishes them from an attack burst.

Planned maintenance produces the entire Hypothesis 3 signature legitimately: firmware upgrades and configuration changes cause service restarts, uptime resets, coldStart traps, port flaps, and client-side connection failures simultaneously. Reconcile every restart timestamp against the change management record before treating it as an availability event, and record which restarts were matched to an approved change.

Undersized appliances enter memory conserve mode under legitimate traffic peaks without any attack involved, and this is common on FortiProxy instances sized before a user population grew. A conserve-mode event that recurs on a predictable daily or weekly cycle aligned to business hours is a capacity finding, not a security finding — though it is worth reporting to the operations team.

Legitimate h2c usage exists in real architectures. Reverse proxies and service meshes negotiate cleartext HTTP/2 to backend origins deliberately, and internal service-to-service traffic may use h2c throughout. Establish which internal paths legitimately carry h2c before treating the SIGMA rule's output as suspicious, and scope the rule to externally-sourced traffic where that architecture is present.

External-exposure misattribution is the characteristic false positive of Hypothesis 1. A passive index hit may resolve to shared hosting, a CDN edge, a cloud provider address recycled from another tenant, or a managed service provider's infrastructure rather than to your estate. Never report an index hit as your exposure on a single ownership signal; require at least two independent signals, and record an unattributable hit as inconclusive rather than resolving it in either direction.

Honeypots run by researchers and by threat intelligence providers deliberately present vulnerable-looking Fortinet banners on the public internet. Down-weight any hit carrying a honeypot classification tag from the index, and never report one as client exposure.

Escalation Criteria

The following conditions trigger immediate incident response engagement:

1. A confirmed-owned FortiProxy, FortiPAM, or FortiSwitch Manager instance is observed in at least two passive indices with a version banner inside the affected ranges and a management or proxy listener reachable from the public internet.

2. An exposure identified in condition 1 is shown by historical index data to have been continuously reachable across the June 8, 2026 to present window, meaning the instance should be treated as presumptively enumerated by opportunistic scanners.

3. An instance discovered in a passive index resolves to owned address space but does not appear in the asset inventory, indicating shadow infrastructure outside the patch and monitoring program.

4. Any exposed instance identified in Hypothesis 1 matches a CISA Known Exploited Vulnerabilities catalog entry for any CVE, not solely CVE-2026-49975.

5. A single external source address is observed opening more than 200 sessions per minute to an affected appliance management or proxy listener, with a memory utilization rise on that appliance in the same window.

6. The HTTP/2 cleartext connection preface is observed in a burst from a single external source against an affected appliance or an in-range Apache instance.

7. An appliance memory utilization curve rises steeply and does not recover, or an appliance uptime reset or unexpected restart occurs, with no matching approved change record.

8. An appliance availability event correlates in time with a historian data gap, a SCADA communication-loss alarm, or a documented loss of operator visibility into a control process.

9. Any YARA hit on HTTP2_Bomb_Exploit_Tooling_Disk against a file on any host in the estate, which indicates exploit tooling staged internally regardless of whether it was executed.

10. Any YARA hit on HTTP2_Bomb_Exploit_Tooling_Memory against a running interpreter or runtime process, which indicates exploit tooling executing from inside the estate and constitutes an active internal attack source.

11. An appliance availability event occurs concurrently with any other detection on an adjacent asset, which raises the possibility that the outage is a diversion rather than the objective.

12. An affected appliance is confirmed running an in-range version for which Fortinet has designated a fixed build that is not yet available for download, and no compensating network control has been applied.

Hunt Completion Criteria and Reporting

The hunt is complete when all four hypotheses have been executed to their defined scope and each has produced either a documented finding or a documented negative with its coverage caveat stated. Specifically: the passive external sweep has been run against all three engines for which credentials were available, with every hit attributed or explicitly recorded as unattributable; the appliance-side collection has been executed against forwarded Fortinet syslog, or the absence of that data source has been recorded as a coverage gap rather than reported as a clean result; the endpoint-side collection has covered every sensor-managed host running Apache HTTP Server; the OT platform exports have been completed for every deployed platform; and the reconciled version inventory from Hypothesis 4 accounts for every FortiProxy, FortiPAM, and FortiSwitch Manager instance known to the organization.

The report must contain: the reconciled inventory table from Hypothesis 4 with the affected, exposed, patch-available, and compensating-control columns populated for every instance; the external exposure sweep results with per-hit provenance recording which engines observed the host, the index scan timestamp for each observation, and the ownership signals used to attribute it; an explicit statement of which engines were queried and which were skipped for want of a credential, since a skipped engine is a coverage gap and not a negative; the timeline of every appliance restart and memory-pressure event in the window, each annotated as matched or unmatched to an approved change record; the correlation results between any unmatched availability event and historian, SCADA alarm, and concurrent-detection data; all query outputs with their exact time windows; and a clear statement of which hypotheses returned negative results together with the data sources that were unavailable and therefore bound the strength of that negative.

Every negative finding must state its coverage caveat. A zero result from an appliance query where the syslog connector was not populating is not evidence of absence, and neither is a clean external sweep run on a free-tier Censys plan that cannot search a CIDR. Record these limits alongside the finding so the reader can weigh the conclusion.

Recommend that the passive external-exposure sweep be established as a recurring control rather than a one-time hunt activity. Exposure changes without a change record — a firewall rule edited, a cloud instance rebuilt, a service migrated — and the sweep is the only control in this plan that detects those changes from the attacker's own vantage point. A monthly cadence with the same attribution discipline applied each time is the recommended baseline.

Advisory IoC Reference

IOC Type IOC
CVE CVE-2026-49975 | CVSS v3.1 7.5 (NVD) / 5.8 (Fortinet product context) | Apache HTTP Server 2.4.17-2.4.67; FortiProxy 7.2-7.6.6; FortiPAM 1.0-1.9.1; FortiSwitch Manager 7.2.0-7.2.9 | Memory allocation with excessive size value in mod_http2 lets an unauthenticated remote attacker exhaust server memory with crafted HTTP/2 requests, causing denial of service.
Threat Actor None attributed in source material - exploitation is expected to be opportunistic and commodity-driven; monitor https://www.cisa.gov/known-exploited-vulnerabilities-catalog for actor association
Malware None published in source material - no malware family or attacker tooling is associated with this vulnerability
Network IOC None published in source material - no attacker IP addresses, domains or C2 infrastructure have been released; monitor https://www.cisa.gov/known-exploited-vulnerabilities-catalog and https://httpd.apache.org/security/vulnerabilities_24.html
File IOC None published in source material - no file hashes have been released; detection relies on the structural YARA rules in Section 5
Behavioral Single external source opening more than 200 short-lived TCP sessions per minute to appliance ports 443, 8443, 10443, 80 or 8080 with low bytes-per-session
Behavioral HTTP/2 cleartext connection preface "PRI * HTTP/2.0" observed in a burst from one source (24-byte match at TCP payload offset 0)
Behavioral HTTP/1.1 requests carrying "Upgrade: h2c" header at a rate inconsistent with the client's own baseline
Behavioral HTTP/2 HEADERS or CONTINUATION frames whose decompressed header block size is disproportionate to their wire size
Behavioral Fortinet appliance log entries containing memory conserve, out of memory, watchdog, restart or reboot outside an approved change window
Behavioral Appliance memory utilization (fgSysMemUsage, OID .1.3.6.1.4.1.12356.101.4.1.4.0) rising steeply without recovery
Behavioral Appliance sysUpTime reset or SNMP coldStart (1.3.6.1.6.3.1.1.5.1) / warmStart (1.3.6.1.6.3.1.1.5.2) trap with no matching change record
Behavioral linkDown / linkUp trap flaps (1.3.6.1.6.3.1.1.5.3 / .4) on the switch port facing an affected appliance
Behavioral Apache httpd or apache2 worker processes terminating and respawning above their own baseline rate
Behavioral Windows Event ID 7031 or 7034 naming an Apache service; Event ID 2004 (Resource-Exhaustion-Detector) naming httpd.exe among top memory consumers
Behavioral Linux out-of-memory killer entries in dmesg or the journal naming an httpd or apache2 process
Behavioral Historian data gap or tag quality-flag change, or SCADA communication-loss alarm, coincident with an appliance restart
Behavioral FortiProxy / FortiPAM / FortiSwitch Manager management or proxy listener answering from owned public IP space with an in-range version banner
Behavioral Index-observed exposure of an affected instance continuously across the June 8, 2026 to present window (presumptively enumerated)
Behavioral Instance discovered in a passive index resolving to owned address space but absent from the asset inventory (shadow infrastructure)
Behavioral YARA hit on HTTP2_Bomb_Exploit_Tooling_Disk against any file in the estate
Behavioral YARA hit on HTTP2_Bomb_Exploit_Tooling_Memory against a running interpreter or runtime process