Skip to content

[New Rule] Toolshell Exploit Chain Detections #4928

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: main
Choose a base branch
from

Conversation

terrancedejesus
Copy link
Contributor

@terrancedejesus terrancedejesus commented Jul 23, 2025

Pull Request

Issue link(s):

Summary - What I changed

Adds detections for initial CVE-2025-53771 and CVE-2025-53770 exploit attempts and for VIEWSTATE RCE attempts later in the Toolshell attack chain. Relies on Network Traffic integration, specifically HTTP traffic. Max signals have been set for the exploit attempts due to potential scanning. Also HTTP response 200 for the initial exploit should only flag on successful attempts but it does not confirm webshell deployment (this would be endpoint). No need to include HTTP response 200 on VIEWSTATE RCE as this is later in the attack chain and assumed machine keys were stolen and VIEWSTATE payloads are signed so we want to capture all of these. Also, the http.request.body.bytes being over 500 should indicate larger payloads, likely commands, being sent.

How To Test

  • Queries can be used in TRADE serverless stack. For VIEWSTATE RCE, reduce byte size to 20.

Checklist

  • Added a label for the type of pr: bug, enhancement, schema, maintenance, Rule: New, Rule: Deprecation, Rule: Tuning, Hunt: New, or Hunt: Tuning so guidelines can be generated
  • Added the meta:rapid-merge label if planning to merge within 24 hours
  • Secret and sensitive material has been managed correctly
  • Automated testing was updated or added to match the most common scenarios
  • Documentation and comments were added for features that require explanation

Contributor checklist

@terrancedejesus terrancedejesus requested a review from w0rk3r July 23, 2025 14:28
@tradebot-elastic
Copy link

tradebot-elastic commented Jul 23, 2025

⛔️ Test failed

Results
  • ❌ Potential Toolshell Initial Exploit (CVE-2025-53770 & CVE-2025-53771) (kuery)
    • coverage_issue: no_rta
    • stack_validation_failed: no_rta
  • ❌ Potential VIEWSTATE RCE Attempt on SharePoint/IIS (kuery)
    • coverage_issue: no_rta
    • stack_validation_failed: no_rta

@tradebot-elastic
Copy link

tradebot-elastic commented Jul 23, 2025

⛔️ Test failed

Results
  • ❌ Potential Toolshell Initial Exploit (CVE-2025-53770 & CVE-2025-53771) (kuery)
    • coverage_issue: no_rta
    • stack_validation_failed: no_rta
  • ❌ Potential VIEWSTATE RCE Attempt on SharePoint/IIS (kuery)
    • coverage_issue: no_rta
    • stack_validation_failed: no_rta

@tradebot-elastic
Copy link

tradebot-elastic commented Jul 23, 2025

⛔️ Test failed

Results
  • ❌ Potential Toolshell Initial Exploit (CVE-2025-53770 & CVE-2025-53771) (kuery)
    • coverage_issue: no_rta
    • stack_validation_failed: no_rta
  • ❌ Potential VIEWSTATE RCE Attempt on SharePoint/IIS (kuery)
    • coverage_issue: no_rta
    • stack_validation_failed: no_rta

@terrancedejesus
Copy link
Contributor Author

terrancedejesus commented Jul 23, 2025

This PR is blocked. event.dataset appears to be removed here. We rely on event.dataset for integration schema validation.

Update

Added these to the non-ecs.json for now. We can remove when the issue has been solved.

@tradebot-elastic
Copy link

tradebot-elastic commented Jul 23, 2025

⛔️ Test failed

Results
  • ❌ Potential Toolshell Initial Exploit (CVE-2025-53770 & CVE-2025-53771) (kuery)
    • coverage_issue: no_rta
    • stack_validation_failed: no_rta
  • ❌ Potential VIEWSTATE RCE Attempt on SharePoint/IIS (kuery)
    • coverage_issue: no_rta
    • stack_validation_failed: no_rta

Copy link
Contributor

Rule: New - Guidelines

These guidelines serve as a reminder set of considerations when proposing a new rule.

Documentation and Context

  • Detailed description of the rule.
  • List any new fields required in ECS/data sources.
  • Link related issues or PRs.
  • Include references.

Rule Metadata Checks

  • creation_date matches the date of creation PR initially merged.
  • min_stack_version should support the widest stack versions.
  • name and description should be descriptive and not include typos.
  • query should be inclusive, not overly exclusive, considering performance for diverse environments. Non ecs fields should be added to non-ecs-schema.json if not available in an integration.
  • min_stack_comments and min_stack_version should be included if the rule is only compatible starting from a specific stack version.
  • index pattern should be neither too specific nor too vague, ensuring it accurately matches the relevant data stream (e.g., use logs-endpoint.process-* for process data).
  • integration should align with the index. If the integration is newly introduced, ensure the manifest, schemas, and new_rule.yaml template are updated.
  • setup should include the necessary steps to configure the integration.
  • note should include any additional information (e.g. Triage and analysis investigation guides, timeline templates).
  • tags should be relevant to the threat and align/added to the EXPECTED_RULE_TAGS in the definitions.py file.
  • threat, techniques, and subtechniques should map to ATT&CK always if possible.

New BBR Rules

  • building_block_type should be included if the rule is a building block and the rule should be located in the rules_building_block folder.
  • bypass_bbr_timing should be included if adding custom lookback timing to the rule.

Testing and Validation

  • Provide evidence of testing and detecting the expected threat.
  • Check for existence of coverage to prevent duplication.

data_stream.dataset : "network_traffic.http" and
url.path: /_layouts*ToolPane.aspx and
http.request.referrer: *SignOut.aspx and
http.request.headers.content-type: "application/x-www-form-urlencoded" and
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if they use other content-types like multipart/form-data?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. It's safe to exclude this I'd think without jeopardizing fidelity.

http.request.body.content: *__VIEWSTATE=* and
http.request.headers.content-type: "application/x-www-form-urlencoded" and
http.request.body.bytes >= 500 and
http.response.headers.server: Microsoft-IIS*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This indicator could vary right? Do we need this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could be inferred if the body contains _VIEWSTATE that IIS & Sharepoint are the intended target. A response indicating IIS suggests that the request is on-target which we would care about.

http.request.referrer: *SignOut.aspx and
http.request.body.content: *__VIEWSTATE=* and
http.request.headers.content-type: "application/x-www-form-urlencoded" and
http.request.body.bytes >= 500 and
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why 500? Is this arbitrary?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its more arbitrary but we can expect the body to be larger in most cases. See https://swapneildash.medium.com/deep-dive-into-net-viewstate-deserialization-and-its-exploitation-54bf5b788817 as a reference. The research here shows examples of the serialized data in the body and how the requests are. It also talks about machine key use and ysoserial, just like the toolshell exploit chain.

http.request.headers.content-type: "application/x-www-form-urlencoded" and
network.direction: "ingress" and
http.request.method: "POST" and
request: (*MSOTlPn_Uri* and *DisplayMode*) and
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this an IOC? Can this be easily changed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No these are specific to the PoC and what researchers are reporting from their honeypots.

Ref: https://github.com/kaizensecurity/CVE-2025-53770/blob/master/payload

See SANS report as well that just came out: https://isc.sans.edu/diary/Analyzing+Sharepoint+Exploits+CVE202553770+CVE202553771/32138/

network.direction: "ingress" and
http.request.method: "POST" and
request: (*MSOTlPn_Uri* and *DisplayMode*) and
http.request.body.bytes > 5000
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same thing here, is 5000 arbitrary?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Arbitrary again, but we can expect that the initial deserialization exploit includes a rather large HTTP body as it includes a large payload that mimics a legit web config. If you look at the PoC https://swapneildash.medium.com/deep-dive-into-net-viewstate-deserialization-and-its-exploitation-54bf5b788817 you will see the URL encoded string with ASP.NET markup with an encoded datablock that is deserialized by the server. So yes, we expect the body to be rather larger than normal.

risk_score = 73
rule_id = "99c9af5a-67cf-11f0-b69e-f661ea17fbcd"
setup = """### Network Traffic Setup

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

once you add an investigation guide, it would be nice to cover the FPs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one may have some FPs, not sure as we don't have a production IIS environment to run the query against to establish baseline but I suspect they will be low. The other rule, FPs should be low. It's more noise I'd be concerned about which is why I added a max number of signals.

@tradebot-elastic
Copy link

tradebot-elastic commented Jul 24, 2025

⛔️ Test failed

Results
  • ❌ Potential Toolshell Initial Exploit (CVE-2025-53770 & CVE-2025-53771) (kuery)
    • coverage_issue: no_rta
    • stack_validation_failed: no_rta
  • ❌ Potential VIEWSTATE RCE Attempt on SharePoint/IIS (kuery)
    • coverage_issue: no_rta
    • stack_validation_failed: no_rta

@tradebot-elastic
Copy link

tradebot-elastic commented Jul 24, 2025

⛔️ Test failed

Results
  • ❌ Potential Toolshell Initial Exploit (CVE-2025-53770 & CVE-2025-53771) (kuery)
    • coverage_issue: no_rta
    • stack_validation_failed: no_rta
  • ❌ Potential VIEWSTATE RCE Attempt on SharePoint/IIS (kuery)
    • coverage_issue: no_rta
    • stack_validation_failed: no_rta

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants