elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.


Tema destacado: AIO elhacker.NET 2021 Compilación herramientas análisis y desinfección malware


+  Foro de elhacker.net
|-+  Programación
| |-+  Scripting
| | |-+  [APORTE] [PowerShell] Modificar aleatoriamente el checksum de un archivo ejecutable
0 Usuarios y 2 Visitantes están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: [APORTE] [PowerShell] Modificar aleatoriamente el checksum de un archivo ejecutable  (Leído 79 veces)
Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.959



Ver Perfil
[APORTE] [PowerShell] Modificar aleatoriamente el checksum de un archivo ejecutable
« en: Hoy a las 15:07 »

El siguiente script, desarrollado en PowerShell, sirve para modificar de forma aleatoria el checksum actual de un archivo ejecutable (formato PE).

Este procedimiento podría ser útil, por ejemplo, para evitar comprobaciones simples de integridad de archivos o verificaciones de firma que dependen de valores de checksum fijos, como los que pudieran estar implementados por sistemas anti-trampas en videojuegos y otro software de protección.

Para cumplir con este objetivo, el script cubre dos técnicas combinadas. La primera consiste en inyectar un valor aleatorio en el campo opcional de checksum del encabezado PE. Esta técnica es necesaria para alterar el resultado de la validación de la API de Windows 'MapFileAndCheckSum', ya que no calcula el checksum de forma corriente sobre todo el archivo, sino que utiliza el valor presente en ese campo del PE.

La segunda técnica consiste en agregar una cantidad pequeña de bytes de relleno o padding (entre 4 y 16 bytes) al final del archivo para alterar el tamaño del mismo, y por consiguiente el cálculo del checksum del archivo, sin afectar a la funcionalidad del ejecutable.







El mismo archivo "reabierto" tras la modificación:


⚠️ Importante: no utilizar el script con archivos PE que tengan un certificado digital, ya que el archivo se corromperá.

Aunque considero haber probado el código lo suficiente, no me hago responsable de posibles daños causados al intentar modificar un archivo. Hagan siempre una copia de seguridad antes de modificar un archivo. 👍



Randomize executable checksum.ps1

El código fuente

Código
  1. <#PSScriptInfo
  2. .VERSION 1.0
  3. .GUID A1B2C3D4-E5F6-7890-ABCD-EF1234567890
  4. .AUTHOR ElektroStudios
  5. .COMPANYNAME ElektroStudios
  6. .COPYRIGHT ElektroStudios © 2025
  7. #>
  8.  
  9. <#
  10. ===========================================================================================
  11. |                                                                                         |
  12. |                                       User Fields                                       |
  13. |                                                                                         |
  14. ===========================================================================================
  15. #>
  16.  
  17. # Path to the executable file to randomize its header and file checksums.
  18. $exePath = ".\MyExecutable.exe"
  19.  
  20. <#
  21. ===========================================================================================
  22. |                                                                                         |
  23. |                                        .NET Code                                        |
  24. |                                                                                         |
  25. ===========================================================================================
  26. #>
  27.  
  28. Add-Type @"
  29. using System;
  30. using System.Runtime.InteropServices;
  31.  
  32. public static class NativeMethods {
  33.    [DllImport("imagehlp.dll", SetLastError = true)]
  34.    public static extern uint MapFileAndCheckSum(string Filename, out uint HeaderSum, out uint CheckSum);
  35. }
  36. "@
  37.  
  38. Add-Type -TypeDefinition @"
  39. using System;
  40.  
  41. public class CRC32
  42. {
  43.    private static readonly uint[] Table = new uint[256];
  44.    private uint crc;
  45.  
  46.    static CRC32()
  47.    {
  48.        uint poly = 0xEDB88320;
  49.        for (uint i = 0; i < 256; i++)
  50.        {
  51.            uint temp = i;
  52.            for (int j = 0; j < 8; j++)
  53.            {
  54.                if ((temp & 1) == 1)
  55.                    temp = (temp >> 1) ^ poly;
  56.                else
  57.                    temp >>= 1;
  58.            }
  59.            Table[i] = temp;
  60.        }
  61.    }
  62.  
  63.    public CRC32()
  64.    {
  65.        crc = 0xFFFFFFFF;
  66.    }
  67.  
  68.    public void Update(byte[] buffer, int offset, int count)
  69.    {
  70.        for (int i = offset; i < offset + count; i++)
  71.        {
  72.            byte index = (byte)((crc ^ buffer[i]) & 0xFF);
  73.            crc = (crc >> 8) ^ Table[index];
  74.        }
  75.    }
  76.  
  77.    public uint Compute(byte[] buffer)
  78.    {
  79.        Update(buffer, 0, buffer.Length);
  80.        return crc ^ 0xFFFFFFFF;
  81.    }
  82.  
  83.    public static uint ComputeChecksum(byte[] buffer)
  84.    {
  85.        CRC32 crc32 = new CRC32();
  86.        return crc32.Compute(buffer);
  87.    }
  88. }
  89. "@
  90.  
  91. <#
  92. ===========================================================================================
  93. |                                                                                         |
  94. |                                    Functions                                            |
  95. |                                                                                         |
  96. ===========================================================================================
  97. #>
  98.  
  99. function Show-WelcomeScreen {
  100.    Clear-Host
  101.    Write-Host ""
  102.    Write-Host " $($host.ui.RawUI.WindowTitle)"
  103.    Write-Host " +================================================================+"
  104.    Write-Host " |                                                                |"
  105.    Write-Host " | This script modifies the file checksum of the specified        |"
  106.    Write-Host " | executable file (PE format) by injecting a new random header   |"
  107.    Write-Host " | checksum field and appending random padding bytes to alter the |"
  108.    Write-Host " | file checksum without affecting the executable's functionality.|"
  109.    Write-Host " |                                                                |"
  110.    Write-Host " | This process is useful to bypass simple file integrity checks  |"
  111.    Write-Host " | or signature verifications that rely on fixed checksum values, |"
  112.    Write-Host " | such as those implemented by anti-cheat videogaming systems    |"
  113.    Write-Host " | and similar software protection agents.                        |"
  114.    Write-Host " +================================================================+"
  115.    Write-Host ""
  116.    Write-Host " Script Settings " -ForegroundColor DarkGray
  117.    Write-Host " ================" -ForegroundColor DarkGray
  118.    Write-Host " Executable Path: $([System.IO.Path]::GetFullPath($exePath))" -ForegroundColor DarkGray
  119.    Write-Host ""
  120. }
  121.  
  122. function Confirm-Continue {
  123.    Write-Host "Press 'Y' key to continue or 'N' to exit."
  124.    Write-Host ""
  125.    Write-Host "-Continue? (Y/N)"
  126.    do {
  127.        $key = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
  128.        $char = $key.Character.ToString().ToUpper()
  129.        if ($char -ne "Y" -and $char -ne "N") {
  130.            [console]::beep(1500, 500)
  131.        }
  132.    } while ($char -ne "Y" -and $char -ne "N")
  133.    if ($char -eq "N") {Exit(0)} else {Clear-Host}
  134. }
  135.  
  136. function Read-UInt16($bytes, $offset) {
  137.    if ($offset -lt 0 -or $offset + 2 -gt $bytes.Length) {
  138.        throw "Offset $offset out of range for Read-UInt16"
  139.    }
  140.    return [BitConverter]::ToUInt16($bytes, $offset)
  141. }
  142.  
  143. function Read-UInt32($bytes, $offset) {
  144.    if ($offset -lt 0 -or $offset + 4 -gt $bytes.Length) {
  145.        throw "Offset $offset out of range for Read-UInt32"
  146.    }
  147.    return [BitConverter]::ToUInt32($bytes, $offset)
  148. }
  149.  
  150. function Write-UInt32([byte[]]$bytes, $offset, [uint32]$value) {
  151.    if ($offset -lt 0 -or $offset + 4 -gt $bytes.Length) {
  152.        throw "Offset $offset out of range for Write-UInt32"
  153.    }
  154.    $valBytes = [BitConverter]::GetBytes($value)
  155.    [Array]::Copy($valBytes, 0, $bytes, $offset, 4)
  156. }
  157.  
  158. function Randomize-ExecutableChecksum{
  159.    param(
  160.        [string]$exePath
  161.    )
  162.  
  163.    # Read the raw file bytes
  164.    if (-Not (Test-Path $exePath)) {
  165.        Show-GoodbyeScreen "File path '$([System.IO.Path]::GetFullPath($exePath))' does not exist." ([System.ConsoleColor]::Red)
  166.    }
  167.    [byte[]]$bytes = [System.IO.File]::ReadAllBytes($exePath)
  168.  
  169.    # Calculate the actual CRC32 file checksum
  170.    $currentCRC32 = '{0:x8}' -f ([CRC32]::ComputeChecksum($bytes))
  171.  
  172.    # Calculate the actual header and file checksums using Windows API
  173.    [uint32]$currentHeaderSum = 0
  174.    [uint32]$currentFileSum = 0
  175.    [NativeMethods]::MapFileAndCheckSum($exePath, [ref]$currentHeaderSum, [ref]$currentFileSum) | Out-Null
  176.  
  177.    # Generate a new random header checksum value
  178.    $randomBytes = New-Object byte[] 4
  179.    [System.Security.Cryptography.RandomNumberGenerator]::Create().GetBytes($randomBytes)
  180.    $newHeaderSum = [BitConverter]::ToUInt32($randomBytes, 0)
  181.  
  182.    # Locate e_lfanew (pointer to PE header)
  183.    $e_lfanew = Read-UInt32 $bytes 0x3C
  184.    # Check that e_lfanew is within valid range (at least 4 bytes from the end)
  185.    if ($e_lfanew -ge $bytes.Length - 4) {
  186.        Show-GoodbyeScreen "Invalid e_lfanew or corrupt file." ([System.ConsoleColor]::Red)
  187.    }
  188.  
  189.    # Read and validate the PE signature (should be "PE\0\0") at the offset pointed by e_lfanew
  190.    $peSignature = [System.Text.Encoding]::ASCII.GetString($bytes, $e_lfanew, 4)
  191.    if ($peSignature -ne "PE`0`0") {
  192.        Show-GoodbyeScreen "Not a valid PE file (PE signature not found)." ([System.ConsoleColor]::Red)
  193.    }
  194.  
  195.    # Calculate Optional Header offset (PE signature + File Header)
  196.    $optionalHeaderOffset = $e_lfanew + 4 + 20
  197.  
  198.    # Read the Magic field in the Optional Header to determine PE32 (32-bit) or PE32+ (64-bit)
  199.    $magic = Read-UInt16 $bytes $optionalHeaderOffset
  200.    if ($magic -eq 0x10b -or $magic -eq 0x20b) {
  201.        $checksumOffset = $optionalHeaderOffset + 64
  202.    } else {
  203.        Show-GoodbyeScreen ("Unknown or unsupported PE format. Magic = 0x{0:X}" -f $magic) ([System.ConsoleColor]::Red)
  204.    }
  205.  
  206.    # Write the new random header checksum value into the file bytes
  207.    Write-UInt32 $bytes $checksumOffset $newHeaderSum
  208.  
  209.    # Add useless padding bytes at the end (overlay) of the file bytes to generate a new file checksum
  210.    $paddingLength = Get-Random -Minimum 4 -Maximum 16
  211.    $padding = New-Object byte[] $paddingLength
  212.    [Security.Cryptography.RandomNumberGenerator]::Create().GetBytes($padding)
  213.    $newBytes = New-Object byte[] ($bytes.Length + $paddingLength)
  214.    [Array]::Copy($bytes, 0, $newBytes, 0, $bytes.Length)
  215.    [Array]::Copy($padding, 0, $newBytes, $bytes.Length, $paddingLength)
  216.  
  217.    # Calculate the new CRC32 file checksum
  218.    $newCRC32 = '{0:x8}' -f ([CRC32]::ComputeChecksum($newBytes))
  219.  
  220.    Write-Host "========== CHECKSUM INFORMATION ==========" -ForegroundColor Cyan
  221.    Write-Host "File: $exePath" -ForegroundColor Yellow
  222.    Write-Host ""
  223.    Write-Host "Header checksum field" -ForegroundColor Cyan
  224.    Write-Host "=====================" -ForegroundColor Gray
  225.    Write-Host "Current    : $currentHeaderSum" -ForegroundColor White
  226.    Write-Host "Replacement: $newHeaderSum" -ForegroundColor White
  227.    Write-Host ""
  228.    Write-Host "Calculated CRC-32 file checksum" -ForegroundColor Cyan
  229.    Write-Host "===============================" -ForegroundColor Gray
  230.    Write-Host "Current    : 0x$($currentCRC32.ToUpper())" -ForegroundColor White
  231.    Write-Host "Replacement: 0x$($newCRC32.ToUpper())" -ForegroundColor White
  232.    Write-Host ""
  233.    Write-Host "Calculated file checksum via 'MapFileAndCheckSum' API" -ForegroundColor Cyan
  234.    Write-Host "=====================================================" -ForegroundColor Gray
  235.    Write-Host "Current    : $currentFileSum" -ForegroundColor White
  236.    Write-Host "Replacement: Can't be calculated until the" -ForegroundColor White
  237.    Write-Host "             new header checksum field is" -ForegroundColor White
  238.    Write-Host "             written to the actual file." -ForegroundColor White
  239.    Write-Host ""
  240.    Write-Host "-----------------------------------------------------" -ForegroundColor Gray
  241.    Write-Host ""
  242.  
  243.    Confirm-Continue
  244.  
  245.    try {
  246.        # Replace the source file by writing the changed bytes, containing the new header checksum and the padding bytes.
  247.        [System.IO.File]::WriteAllBytes($exePath, $newBytes)
  248.    } catch {
  249.        Show-GoodbyeScreen "Failed to write the modified bytes to the actual file. Please check file permissions and path." ([System.ConsoleColor]::Red)
  250.    }
  251.  
  252.    # Calculate the new file checksum using Windows API
  253.    [uint32]$newFileSum = 0
  254.    [NativeMethods]::MapFileAndCheckSum($exePath, [ref]0, [ref]$newFileSum) | Out-Null
  255.  
  256.    Write-Host "========== CHECKSUM INFORMATION ==========" -ForegroundColor Cyan
  257.    Write-Host "File: $exePath" -ForegroundColor Yellow
  258.    Write-Host ""
  259.    Write-Host "Header checksum field" -ForegroundColor Cyan
  260.    Write-Host "=====================" -ForegroundColor Gray
  261.    Write-Host "Previous: $currentHeaderSum" -ForegroundColor White
  262.    Write-Host "Current : $newHeaderSum" -ForegroundColor White
  263.    Write-Host ""
  264.    Write-Host "Calculated CRC-32 file checksum" -ForegroundColor Cyan
  265.    Write-Host "===============================" -ForegroundColor Gray
  266.    Write-Host "Previous: 0x$($currentCRC32.ToUpper())" -ForegroundColor White
  267.    Write-Host "Current : 0x$($newCRC32.ToUpper())" -ForegroundColor White
  268.    Write-Host ""
  269.    Write-Host "Calculated file checksum via 'MapFileAndCheckSum' API" -ForegroundColor Cyan
  270.    Write-Host "=====================================================" -ForegroundColor Gray
  271.    Write-Host "Previous: $currentFileSum" -ForegroundColor White
  272.    Write-Host "Current : $newFileSum" -ForegroundColor White
  273.    Write-Host ""
  274.    Write-Host "-----------------------------------------------------" -ForegroundColor Gray
  275.    Write-Host ""
  276. }
  277.  
  278. function Show-GoodbyeScreen{
  279.    param(
  280.        [string]$msg,
  281.        [string]$forecolor = "White"
  282.    )
  283.  
  284.    Write-Host $msg -BackgroundColor Black -ForegroundColor $forecolor
  285.    Write-Host ""
  286.    Write-Host "Press any key to exit..."
  287.    $key = $Host.UI.RawUI.ReadKey("NoEcho, IncludeKeyDown")
  288.    Exit(0)
  289. }
  290.  
  291. <#
  292. ===========================================================================================
  293. |                                                                                         |
  294. |                                         Main                                            |
  295. |                                                                                         |
  296. ===========================================================================================
  297. #>
  298.  
  299. [System.Console]::Title = "Randomize executable checksum - by Elektro"
  300. #[System.Console]::SetWindowSize(150, 45)
  301. [CultureInfo]::CurrentUICulture = "en-US"
  302.  
  303. if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
  304.    Write-Host "Please run this script as Administrator!" -ForegroundColor Red
  305.    Pause
  306.    exit
  307. }
  308.  
  309. try { Set-ExecutionPolicy -ExecutionPolicy "Unrestricted" -Scope "Process" } catch { }
  310.  
  311. Show-WelcomeScreen
  312. Confirm-Continue
  313. Randomize-ExecutableChecksum $exePath
  314. Show-GoodbyeScreen "Operation Completed!" ([System.ConsoleColor]::Green)
  315.  



Aspectos a tener en cuenta antes de usar

La configuración del script está definida directamente en el código y no admite parámetros por línea de comandos.

Citar
Código
  1. <#
  2. ===========================================================================================
  3. |                                                                                         |
  4. |                                       User Fields                                       |
  5. |                                                                                         |
  6. ===========================================================================================
  7. #>
  8.  
  9. # Path to the executable file to randomize its header and file checksums.
  10. $exePath = ".\MyExecutable.exe"

Atentamente,
Elektro. 👋


« Última modificación: Hoy a las 15:19 por Eleкtro » En línea



Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines