Durante una auditoría, muchas veces tenemos acceso a información sensible como listas de usuarios, credenciales (por ejemplo, al descargar el archivo NTDS.dit para crackeo offline), datos de enumeración que revelan detalles clave de la infraestructura de red o del entorno de Active Directory, entre otros. Por eso, es fundamental cifrar esa información o usar conexiones seguras como SSH, SFTP o HTTPS siempre que sea posible.
Sin embargo, a veces no tenemos acceso a esos canales cifrados y toca buscar otra forma de proteger los datos. En esos casos, cifrar los archivos antes de transferirlos es una buena práctica para evitar que puedan ser leídos si son interceptados.
File Enctryption on Windows
Se pueden usar muchos métodos diferentes para cifrar archivos e información en sistemas Windows. Uno de los más sencillos es el script de PowerShell Invoke-AESEncryption.ps1. Este script es pequeño y permite cifrar archivos y cadenas.
Invoke-AESEncryption.ps1
Se pueden usar muchos métodos diferentes para cifrar archivos e información en sistemas Windows. Uno de los más sencillos es el script de PowerShell Invoke-AESEncryption.ps1. Este script es pequeño y permite cifrar archivos y cadenas.
<#
.SYNOPSIS
Encryptes or Decrypts Strings or Byte-Arrays with AES
.DESCRIPTION
Takes a String or File and a Key and encrypts or decrypts it with AES256 (CBC)
.PARAMETER Mode
Encryption or Decryption Mode
.PARAMETER Key
Key used to encrypt or decrypt
.PARAMETER Text
String value to encrypt or decrypt
.PARAMETER Path
Filepath for file to encrypt or decrypt
.EXAMPLE
Invoke-AESEncryption -Mode Encrypt -Key "p@ssw0rd" -Text "Secret Text"
Description
-----------
Encrypts the string "Secret Test" and outputs a Base64 encoded cipher text.
.EXAMPLE
Invoke-AESEncryption -Mode Decrypt -Key "p@ssw0rd" -Text "LtxcRelxrDLrDB9rBD6JrfX/czKjZ2CUJkrg++kAMfs="
Description
-----------
Decrypts the Base64 encoded string "LtxcRelxrDLrDB9rBD6JrfX/czKjZ2CUJkrg++kAMfs=" and outputs plain text.
.EXAMPLE
Invoke-AESEncryption -Mode Encrypt -Key "p@ssw0rd" -Path file.bin
Description
-----------
Encrypts the file "file.bin" and outputs an encrypted file "file.bin.aes"
.EXAMPLE
Invoke-AESEncryption -Mode Encrypt -Key "p@ssw0rd" -Path file.bin.aes
Description
-----------
Decrypts the file "file.bin.aes" and outputs an encrypted file "file.bin"
#>
function Invoke-AESEncryption {
[CmdletBinding()]
[OutputType([string])]
Param
(
[Parameter(Mandatory = $true)]
[ValidateSet('Encrypt', 'Decrypt')]
[String]$Mode,
[Parameter(Mandatory = $true)]
[String]$Key,
[Parameter(Mandatory = $true, ParameterSetName = "CryptText")]
[String]$Text,
[Parameter(Mandatory = $true, ParameterSetName = "CryptFile")]
[String]$Path
)
Begin {
$shaManaged = New-Object System.Security.Cryptography.SHA256Managed
$aesManaged = New-Object System.Security.Cryptography.AesManaged
$aesManaged.Mode = [System.Security.Cryptography.CipherMode]::CBC
$aesManaged.Padding = [System.Security.Cryptography.PaddingMode]::Zeros
$aesManaged.BlockSize = 128
$aesManaged.KeySize = 256
}
Process {
$aesManaged.Key = $shaManaged.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($Key))
switch ($Mode) {
'Encrypt' {
if ($Text) {$plainBytes = [System.Text.Encoding]::UTF8.GetBytes($Text)}
if ($Path) {
$File = Get-Item -Path $Path -ErrorAction SilentlyContinue
if (!$File.FullName) {
Write-Error -Message "File not found!"
break
}
$plainBytes = [System.IO.File]::ReadAllBytes($File.FullName)
$outPath = $File.FullName + ".aes"
}
$encryptor = $aesManaged.CreateEncryptor()
$encryptedBytes = $encryptor.TransformFinalBlock($plainBytes, 0, $plainBytes.Length)
$encryptedBytes = $aesManaged.IV + $encryptedBytes
$aesManaged.Dispose()
if ($Text) {return [System.Convert]::ToBase64String($encryptedBytes)}
if ($Path) {
[System.IO.File]::WriteAllBytes($outPath, $encryptedBytes)
(Get-Item $outPath).LastWriteTime = $File.LastWriteTime
return "File encrypted to $outPath"
}
}
'Decrypt' {
if ($Text) {$cipherBytes = [System.Convert]::FromBase64String($Text)}
if ($Path) {
$File = Get-Item -Path $Path -ErrorAction SilentlyContinue
if (!$File.FullName) {
Write-Error -Message "File not found!"
break
}
$cipherBytes = [System.IO.File]::ReadAllBytes($File.FullName)
$outPath = $File.FullName -replace ".aes"
}
$aesManaged.IV = $cipherBytes[0..15]
$decryptor = $aesManaged.CreateDecryptor()
$decryptedBytes = $decryptor.TransformFinalBlock($cipherBytes, 16, $cipherBytes.Length - 16)
$aesManaged.Dispose()
if ($Text) {return [System.Text.Encoding]::UTF8.GetString($decryptedBytes).Trim([char]0)}
if ($Path) {
[System.IO.File]::WriteAllBytes($outPath, $decryptedBytes)
(Get-Item $outPath).LastWriteTime = $File.LastWriteTime
return "File decrypted to $outPath"
}
}
}
}
End {
$shaManaged.Dispose()
$aesManaged.Dispose()
}
}
Import Module Invoke-AESEncryption.ps1
Podemos usar cualquiera de los métodos de transferencia de archivos mostrados anteriormente para transferir este archivo al host de destino. Una vez transferido el script, solo es necesario importarlo como módulo, como se muestra a continuación.
Tras importar el script, este puede cifrar cadenas o archivos, como se muestra en los siguientes ejemplos. Este comando crea un archivo cifrado con el mismo nombre que el archivo cifrado, pero con la extensión ".aes".
Es fundamental utilizar contraseñas de cifrado muy seguras y únicas para cada empresa donde se realice una prueba de penetración. Esto evita que archivos e información confidenciales se descifren con una sola contraseña que podría haber sido filtrada y descifrada por un tercero.