﻿---
title: Suspicious .NET Reflection via PowerShell
description: Detects PowerShell scripts that invoke Reflection.Assembly or Assembly.Load to load .NET assemblies. Attackers use this method to load executables and...
url: https://www.elastic.co/elastic/docs-builder/docs/2847/reference/security/prebuilt-rules/rules/windows/defense_evasion_posh_assembly_load
products:
  - Elastic Security
---

# Suspicious .NET Reflection via PowerShell
Detects PowerShell scripts that invoke Reflection.Assembly or Assembly.Load to load .NET assemblies. Attackers use this
method to load executables and DLLs without writing to the disk, bypassing security solutions.
**Rule type**: query
**Rule indices**:
- winlogbeat-*
- logs-windows.powershell*

**Rule Severity**: medium
**Risk Score**: 47
**Runs every**: 
**Searches indices from**: `now-9m`
**Maximum alerts per execution**: 100
**References**:
- [[https://docs.microsoft.com/en-us/dotnet/api/system.reflection.assembly.load](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.assembly.load)](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.assembly.load)

**Tags**:
- Domain: Endpoint
- OS: Windows
- Use Case: Threat Detection
- Tactic: Defense Evasion
- Tactic: Execution
- Resources: Investigation Guide
- Data Source: PowerShell Logs

**Version**: 321
**Rule authors**:
- Elastic

**Rule license**: Elastic License v2

## Setup

PowerShell Script Block Logging must be enabled to generate the events used by this rule (e.g., 4104).
Setup instructions: [https://ela.st/powershell-logging-setup](https://ela.st/powershell-logging-setup)

## Investigation guide


## Triage and analysis> **Disclaimer**:
This guide was created by humans with the assistance of generative AI. While its contents have been manually curated to include the most valuable information, always validate assumptions and adjust procedures to match your internal runbooks and incident triage and response policies.

### Investigating Suspicious .NET Reflection via PowerShell

This alert indicates PowerShell script block content attempted to load a .NET assembly using reflection-based APIs (for example, `[System.Reflection.Assembly]::Load` or `Assembly.Load(...)`). While this can be used for legitimate extensibility, it is also commonly used to execute .NET payloads in memory and reduce file-based artifacts.

#### Key alert fields to review

- `user.name`, `user.domain`, `user.id`: Account execution context for correlation, prioritization, and scoping.
- `host.name`, `host.id`: Host execution context for correlation, prioritization, and scoping.
- `powershell.file.script_block_text`: Script block content that matched the detection logic.
- `powershell.file.script_block_id`, `powershell.sequence`, `powershell.total`: Script block metadata to pivot to other fragments or reconstruct full script content when split across multiple events.
- `file.path`, `file.directory`, `file.name`: File-origin context when the script block is sourced from an on-disk file.
- `powershell.file.script_block_length`: Script block length (size) context.


#### Possible investigation steps

- Triage the execution context:
  - Identify the affected host and user using `host.name`, `host.id`, `user.name`, `user.domain`, and `user.id`.
- Prioritize alerts where the user is unexpected for the host role, or where the same user appears across multiple hosts in a short time window.
- Analyze the assembly load behavior in `powershell.file.script_block_text`:
  - Identify what is being passed into the load call (assembly name vs. byte array or dynamically generated content).
- Check for indicators of staged content within the same script block, such as long encoded blobs, dynamic string construction, or multiple transformation steps (decoding, decompression, or concatenation) that produce the assembly bytes.
- Look for immediate follow-on actions suggesting the loaded assembly is executed (for example, accessing types/methods and invoking them after the load).
- Reconstruct the full script block when needed:
  - If the content appears partial, group related events by `powershell.file.script_block_id` and order by `powershell.sequence` to `powershell.total` to rebuild the full script block before assessing intent.
- Use `powershell.file.script_block_length` as a signal for embedded content (large or unusually variable sizes can indicate payload staging).
- Determine script origin and persistence indicators:
  - If `file.path`/`file.name` are present, assess whether the script is stored in an expected location for the user and host role, or in a user-writable / temporary directory indicated by `file.directory`.
- If `file.path` is present, retrieve and review the corresponding script file for additional context (embedded payloads, additional functions, or execution logic not visible in a single script block event).
- If `file.path` is not present, treat the activity as potentially interactive or remotely delivered and rely on `powershell.file.script_block_id` and time-based pivots to gather surrounding context.
- Scope related PowerShell activity on the same host and user:
  - Pivot on `host.id` and `user.id` to identify additional script blocks around the alert time that may show setup, staging, or follow-on actions.
- Check for repeated `Assembly.Load` usage across multiple `powershell.file.script_block_id` values, which may indicate iterative execution attempts or multiple payload stages.
- Scope across the environment:
  - Search for the same `file.path`/`file.name` and similar `powershell.file.script_block_text` patterns on other hosts to identify propagation or reuse.
- Identify whether the same `user.id` is associated with similar script blocks across multiple `host.id` values to assess potential lateral movement or shared automation.
- Correlate with adjacent telemetry (if available in your environment):
  - Process telemetry: Determine how PowerShell was launched and by what parent process around the alert time to understand delivery (interactive use, scheduled execution, service context, or another process).
- Network telemetry: Review outbound activity near the alert time for signs of payload retrieval, staging infrastructure, or command-and-control.
- File/registry telemetry: Look for newly created or modified scripts, DLLs, or persistence-related changes temporally aligned with the script block execution.
- Authentication telemetry: Review logon patterns for the same user and host around the alert time to identify unusual access patterns that could explain the execution.
- If response actions are available:
  - Collect host DNS cache and a snapshot of running/installed services to support scoping and to identify suspicious services or recent name resolution consistent with payload staging.


### False positive analysis

- Legitimate scripts may load assemblies to support internal tooling, plugin models, packaged dependencies, or automation tasks that embed .NET functionality in PowerShell.
- Benign activity is more likely when:
  - `file.path`/`file.name` map to a known, owned script with a stable operational purpose.
- The same `user.id` consistently runs the same script on the same `host.id` as part of normal operations.
- `powershell.file.script_block_text` is readable and clearly loads expected assemblies without embedded blobs or multi-step content staging.
- Suspicious activity is more likely when:
  - The assembly is loaded from dynamically generated bytes (encoded or transformed content) and is followed by reflection-based invocation.
- The script originates from an unusual `file.directory` or the execution context (`user.name`/`host.name`) is inconsistent with expected administrative workflows.
- If confirmed benign, document the owning team, expected execution pattern, and the specific script identity (`file.path`/`file.name`) to enable narrowly scoped tuning.


### Response and remediation

- If the activity is confirmed or strongly suspected to be malicious:
  - Isolate the affected host to prevent further in-memory execution and follow-on activity.
- Preserve evidence from the alert:
  - Export the full reconstructed script block content using `powershell.file.script_block_id` with `powershell.sequence`/`powershell.total`.
- Capture `host.id`, `host.name`, `user.id`, `user.name`, `user.domain`, and any associated `file.path`/`file.name` context.
- Identify and contain related activity:
  - Hunt for additional related script blocks on the same host/user and across other hosts for similar `powershell.file.script_block_text` patterns.
- Contain any identified infrastructure or artifacts based on indicators found in the script content (for example, domains, IPs, or downloaded file names).
- Remediate:
  - Remove persistence and stop any related malicious processes discovered during triage and correlation.
- Review the impacted account (`user.id`) for compromise and rotate credentials as appropriate, prioritizing privileged access.
- Validate the host is remediated and monitored for recurrence before returning it to service.
- If the activity is benign but requires reduction in alert volume:
  - Record the approved use case and expected execution context (host role, user role, and script location).
- Apply targeted tuning anchored to stable identifiers (for example, specific `file.path` and expected accounts) rather than broadly suppressing assembly load behavior.
- Review PowerShell governance and monitoring to ensure in-memory loading is limited to approved workflows.


## Rule Query

```kuery
event.category:process and host.os.type:windows and
(
  powershell.file.script_block_text : (
    "[System.Reflection.Assembly]::Load" or
    "[Reflection.Assembly]::Load" or
    "Assembly.Load("
  ) and
  powershell.file.script_block_text : (
      "FromBase64String" or "GzipStream" or "DeflateStream" or "IO.Compression" or
      "MemoryStream" or "DownloadData" or "WebClient" or "ReadAllBytes"
  )
)
```

**Framework:** MITRE ATT&CK
- Tactic:
  - Name: Defense Evasion
- Id: TA0005
- Reference URL: [[https://attack.mitre.org/tactics/TA0005/](https://attack.mitre.org/tactics/TA0005/)](https://attack.mitre.org/tactics/TA0005/)
- Technique:
  - Name: Process Injection
- Id: T1055
- Reference URL: [[https://attack.mitre.org/techniques/T1055/](https://attack.mitre.org/techniques/T1055/)](https://attack.mitre.org/techniques/T1055/)
- Sub Technique:
  - Name: Dynamic-link Library Injection
- Id: T1055.001
- Reference URL: [[https://attack.mitre.org/techniques/T1055/001/](https://attack.mitre.org/techniques/T1055/001/)](https://attack.mitre.org/techniques/T1055/001/)
- Sub Technique:
  - Name: Portable Executable Injection
- Id: T1055.002
- Reference URL: [[https://attack.mitre.org/techniques/T1055/002/](https://attack.mitre.org/techniques/T1055/002/)](https://attack.mitre.org/techniques/T1055/002/)
- Technique:
  - Name: Reflective Code Loading
- Id: T1620
- Reference URL: [[https://attack.mitre.org/techniques/T1620/](https://attack.mitre.org/techniques/T1620/)](https://attack.mitre.org/techniques/T1620/)

**Framework:** MITRE ATT&CK
- Tactic:
  - Name: Execution
- Id: TA0002
- Reference URL: [[https://attack.mitre.org/tactics/TA0002/](https://attack.mitre.org/tactics/TA0002/)](https://attack.mitre.org/tactics/TA0002/)
- Technique:
  - Name: Command and Scripting Interpreter
- Id: T1059
- Reference URL: [[https://attack.mitre.org/techniques/T1059/](https://attack.mitre.org/techniques/T1059/)](https://attack.mitre.org/techniques/T1059/)
- Sub Technique:
  - Name: PowerShell
- Id: T1059.001
- Reference URL: [[https://attack.mitre.org/techniques/T1059/001/](https://attack.mitre.org/techniques/T1059/001/)](https://attack.mitre.org/techniques/T1059/001/)