nomostatic

Your IPS needs to see inside your HTTPS!!!

THE ESSENTIAL ARGUMENT≈ 3 MIN READ

Before the deep dive

Our PHP2Shell mitigation article[1] raised a practical question: what does an intrusion policy actually protect when the application traffic is encrypted? In short, it is a lot less than you think! We built this lab to demonstrate the significance of decryption while validating the associated Snort signatures.

Local test On a Cisco Secure Firewall 1210CE running FTD 10.1.0 build 160, managed by cloud-delivered FMC, we established a working TLS 1.3 Resign path and exercised harmless request and response fixtures. The lab contained no vulnerable PHP runtime. These were signature and traffic-inspection controls.

Three checks before trusting a mitigation

01DecryptConfirm the actual TLS action and the certificate the client receives.
02InspectMatch the exact signature and action to the tested connection.
03CorrelateCompare client delivery, origin logs and negative controls.

Published Encrypted traffic classification is not the same as reading an HTTP body or response cookie. Cisco describes decryption as the step that makes encrypted application data available for inspection. An HTTPS Allow rule with an intrusion policy is therefore only part of the path. Cisco traffic decryption overview[2]

Local test The measured configuration used Decrypt – Resign, a dedicated signing CA, TCP/443 scope, and Cert Status = Any for every certificate-status match condition. The origin CA remained trusted, backend issuer protection remained enabled, and the client continued validating the hostname and certificate chain. Any was a matching setting, not an instruction to disable certificate verification.

Local test Over that path, the local body marker alerted selectively and then blocked selectively. Talos 1:67360:2 blocked the eleventh matching multipart candidate after the first ten completed. Talos 1:67375:1 blocked the synthetic response cookie: FMC recorded the exact SID at Block, the client reported zero response bytes, and three negative responses completed normally. Cleanup and normal traffic were confirmed.

Local test Two details changed how we interpreted those results. SID 67360 included a count-10, five-second rate condition; Block did not mean every matching request was stopped. SID 67375 inspected the server response; a successful origin header write did not mean the client received that cookie.

Needs lab Earlier Valid=Yes trials bypassed decryption with an unsupported-cipher classification. The later Any configuration worked, but discovery, rule scope and cache history prevent us from calling that a proven vendor defect or a universal fix. Invalid-backend-certificate behavior and selective fail-closed handling remain separate experiments.

THE PRACTICAL DECISION

What this establishes: the tested TLS flow was decrypted, specific synthetic patterns matched, and selected traffic was blocked. It does not establish prevention of the full PHP2Shell exploitation chain. Patching remains the remediation; these observations help validate an inspection path.

The full walkthrough covers the measured Resign configuration, local-marker controls, rate-aware SID 67360 enforcement, response-cookie SID 67375 enforcement and evidence limits.

GO DEEPER · COMPLETE WALKTHROUGHFull technical walkthroughResign trust, HTTPS controls, evidence and referencesOpenCollapse

Validating Snort with Resign decryption and synthetic PHP2Shell request and response controls.

Evidence labels: Published — linked documentation; Local test — recorded lab observations; Proposed — future work; Needs lab — unverified claim.

The measured path

Local test The two lab segments crossed the firewall through dedicated routed interfaces. The client used 192.0.2.50 and addressed app.nomostatic.test at VIP 192.0.2.10:443. Static NAT translated the VIP to the origin at 10.20.30.40:443. The lab-specific access rule carried the selected intrusion policy.

Proposed Readers can reproduce this method on a compatible FTD platform managed by cdFMC or self-hosted FMC. The 1210CE, Ethernet1/5 and Ethernet1/6, and the listed IP addresses identify our measured baseline. Substitute available interfaces and unused addresses consistently across policies, NAT, routing, service binds and collector checks; the companion guide explains the fixed-topology toolkit boundary. Cisco documents the corresponding rule-based decryption workflow for self-hosted FMC. Cisco self-hosted FMC decryption guide[3]

The appliance also carried normal traffic. The lab exception was narrowly scoped and surrounded by isolation rules. Tests used fresh batch IDs, explicit deployment completion, actual source ports and matching origin logs. The host routes and firewall policies mattered as much as the fixture: an incorrect interface IP initially prevented ARP, and earlier normal-LAN permit rules interfered with isolation until ordering was corrected.

Published The decryption policy associates with the access control policy. The intrusion policy associates with the matching Allow rule. Keep those two attachment points distinct when inspecting configuration and events. Cisco access-control policy associations[4]

One application flow, two TLS legs
01 · CLIENTVerified Resign certificateThe controlled client trusts the dedicated signing CA.
02 · FTD + SNORTDecrypt · inspect · re-encryptExact host/zone scope, TCP/443 and certificate-status conditions Any.
03 · ORIGINSeparate origin certificateFTD retains the configured origin trust and issuer protection.
Client verification and backend trust remain separate from certificate-status rule matching. Invalid-backend denial was not established by these controls.

What Cert Status Any means here

Published Cisco defines Any as skipping that certificate-status condition when matching the rule. Yes matches the presence of a status and No matches its absence. This setting controls rule selection; it is not a replacement for trust and validation policy. Cisco certificate-status matching[5]

Local test Our working rule, LAB-RESIGN-SCOPE, selected the lab client and origin zones, their exact host objects and TCP/443. It used LAB-RESIGN-CA, Replace Key Only enabled, and every certificate-status condition set to Any. Application, URL, DN, cipher-suite and TLS-version matching conditions were unset. TLS 1.3 decryption and the existing server-identity discovery settings remained enabled.

The client offered TLS 1.3 with TLS_AES_128_GCM_SHA256, P-256 and HTTP/1.1. The recorded health events showed actual Decrypt (Resign) through the named rule, certificate status Valid, and successful HTTP 204. The client saw the dedicated Resign issuer rather than the original origin issuer.

Two trust decisions: the client validates the certificate presented on the client-facing TLS leg. FTD uses its configured trust for the origin-facing leg. The lab client explicitly trusts the dedicated Resign CA; FTD trusts the separate origin CA. We kept these controls in place, but did not test every invalid-certificate outcome.

Published Cisco recommends Resign for outgoing traffic and Known Key or Replace Certificate for incoming traffic. Cisco decryption-action guidance[6]

Local test Our client-to-lab-origin experiment explicitly administers the client’s CA trust. It demonstrates inspection behavior on that controlled path, not compatibility with arbitrary Internet visitors, pinned clients, mutual TLS or a default production ingress design.

Establish visibility before testing the Talos patterns

Local test We first calibrated an inert local body marker in plaintext HTTP. Then the HTTPS trials used a fixed request body at one path and two negative controls: a clean body at the inspected path, and the marker body at a different URI.

In HTTPS-ALERT-01, clean and marker requests returned HTTP 204. The URI-negative received the responder’s expected HTTP 404. Only marker port 33615 produced 2000:1000001:2 Alert. All three flows used actual Resign decryption through LAB-RESIGN-SCOPE.

In HTTPS-BLOCK-02, marker port 42203 received no HTTP response and timed out. FMC confirmed the same exact local SID at Block. Clean and URI-negative completed normally without marker events, and the supplied origin journal contained their completions with no completed marker response. That absence does not prove that zero request bytes reached the origin.

Local test A retained FMC CSV corroborates the Alert batch’s three decrypted connections and marker-only Alert rows. Exact SID identity came from the event details/operator confirmation because that export omitted Snort-ID fields. The later Block result combines supplied client/origin output with matching FMC details and confirmed cleanup.

Read the rate condition in SID 67360

Local test Installed 1:67360:2, “PHP session upload progress remote code execution attempt,” included a multipart content-type match, Content-Disposition, PHP_SESSION_UPLOAD_PROGRESS, and:

detection_filter:track by_src,count 10,seconds 5;

Published A Snort detection_filter requires the configured rate to be exceeded before generating an event. Its presence changes the experiment: a single matching request is not an adequate positive control for this revision. Snort detection_filter[7]

Local test The plaintext calibration established the fixture and rate behavior first. The HTTPS control, TALOS-67360-HTTPS-BLOCK-01, then sent a clean control, observed a six-second quiet interval, and collected eleven fixed candidate upload notifications over 0.49295092 seconds.

Candidates one through ten completed HTTP 204 and had matching origin records for their 313-byte bodies. Candidate eleven, client port 51317, received no HTTP response and timed out. FMC recorded 1:67360:2 Block in LAB-IPS-HTTPS-67360 with TLS Status Decrypt (Resign). The supplied matching origin output contained no completed candidate-eleven response.

The clean and field-name-negative controls completed normally without SID 67360 events. The operator confirmed the intended Resign rule on the matching connections, the negative SID searches and cleanup.

The material limit: the first ten matching synthetic requests reached the origin in this trial. The 0.493-second measure comes from client upload notifications, not Snort match timestamps. An unmodified rate-qualified rule at Block is not a promise to prevent the first matching request.

Test the response with SID 67375

Local test Installed 1:67375:1, “PHP PHPSESSID memory leak attempt,” inspected established traffic toward the client and had no detection_filter. Our fixed response profiles changed only the relevant cookie pattern:

  • CLEAN: PHPSESSID=nomostatic-lab
  • CANDIDATE: PHPSESSID=nomostatic%00%00lab
  • NAME-NEGATIVE: LABSESSID=nomostatic%00%00lab
  • SINGLE-NEGATIVE: PHPSESSID=nomostatic%00lab

The wire held printable percent encodings, not literal NUL bytes or real session data. Every profile retained the same narrow Path, Secure, HttpOnly and SameSite attributes.

Published Snort places response Set-Cookie values in cookie buffers. The normalized buffer supports transformations such as percent-decoding, while the raw buffer retains the encoded value. This explains why the calibrated fixture included both the cookie name and the two encoded nulls. The installed rule and its effective action remain the authority for a particular run. Snort cookie buffers[8]

Local test In TALOS-67375-HTTPS-BLOCK-03, the author deliberately configured the separate policy LAB-IPS-HTTPS-67375 at Block. Candidate port 33169 completed verified Resign TLS and then timed out with response_bytes=0. FMC recorded 1:67375:1, actual Block, Snort Version 3 and TLS Status Decrypt (Resign), in the response direction 10.20.30.40:443 → 192.0.2.50:33169.

Clean port 59431, name-negative 39799 and single-negative 33101 each received the exact expected HTTP 200 response over verified Resign TLS. The operator confirmed no SID events on those negative ports. The origin logged all four local header writes, including the candidate, between 20:30:10 and 20:30:31 UTC.

The client delivery check matters. A timeout after receiving a cookie would not establish that delivery was prevented. Here the supplied client collector reports zero application-response bytes for the candidate. The origin’s successful local write is consistent with subsequent inspection and blocking on the response path.

Local test The original service initially failed to restart after the temporary cookie service stopped. The operator later confirmed original Python active/listening, the temporary service inactive, deployed firewall cleanup and working normal traffic. This recovery check belongs in the result, not in a later assumption.

Deploy, correlate and restore

Local test Several avoidable mistakes became useful controls: a pending deployment meant one earlier batch could not validate the intended signature action; a short readiness check stopped a service before it had time to bind; and a Connection/Allow export did not answer whether an Intrusion/Alert existed.

For every phase, finish deployment before sending traffic. Record the effective intrusion action and the matched access-control rule. Use the actual client port and UTC window to correlate connection, intrusion and origin evidence. For response rules, search both directions. Export detailed TLS and SID/action fields separately if the CSV does not include them.

Local test The temporary cookie service was bounded to ten minutes and sixteen accepted connections. Its automatic stop did not restore the original responder. The updated helper waited for the exact original PID to own the expected listener; service “active” alone was insufficient. Preserve failure journals and verify restoration before opening another test window.

Proposed Carry those checks into future deployments. Validate every protocol and workflow you intend to support, test relevant body sizes and encodings, and measure representative resource use before making a capacity claim. A new connection or deployment is not evidence that firewall caches were cleared.

What we can publish from this lab

Local test The recorded scope covers a controlled TLS 1.3 / AES-128-GCM / HTTP/1.1 client, a Python origin, the named lab policies, a local marker, rate-aware SID 67360 enforcement and SID 67375 response-cookie enforcement. Both Talos HTTPS controls have matching Block observations and passing negative controls. An additional Alert-only HTTPS cookie trial is not needed for that specific Block result; we do not claim one was performed successfully.

The preserved plaintext archives and selected exports were independently reviewed. Later HTTPS conclusions use supplied client/journal output, FMC details and operator confirmations; full native archives for those later batches remain unreviewed. BLOCK-03 is the canonical publication label. Its working journal extracts were normalized by author request, with original source records and the ID mapping retained separately.

Needs lab This work does not establish invalid-backend-certificate denial, revocation enforcement, a selective fail-closed design, every TLS mode, every exploit variant or PHP2Shell execution prevention. The earlier unsupported-cipher classification remains under investigation. None of those unresolved claims is necessary to publish the measured visibility and synthetic-signature results above.

Published Talos recommends fixed PHP releases and states that temporary controls do not provide comprehensive protection. Use the lab to verify what a mitigation actually sees and blocks while completing the software remediation. Talos advisory and coverage[9]

References

  1. PHP2Shell mitigation article

  2. Cisco traffic decryption overview

  3. Cisco self-hosted FMC decryption guide

  4. Cisco access-control policy associations

  5. Cisco certificate-status matching

  6. Cisco decryption-action guidance

  7. Snort detection_filter

  8. Snort cookie buffers

  9. Talos advisory and coverage

Work through the lab….

2 responses to “Your IPS needs to see inside your HTTPS!!!”

  1. […] Read the techtorial here…. to get the background on why we decrypt. […]

  2. […] Your IPS Needs to See Inside Your HTTPS documents the lab’s TLS Resign path, certificate-status matching, local-marker controls, […]

Leave a Reply

Your email address will not be published. Required fields are marked *

Verified by MonsterInsights