{"id":2476,"date":"2025-08-28T19:16:00","date_gmt":"2025-08-28T19:16:00","guid":{"rendered":"https:\/\/www.mainmind.com\/blog\/?p=2476"},"modified":"2026-03-09T12:11:36","modified_gmt":"2026-03-09T12:11:36","slug":"progreso-john-the-ripper-en-windows","status":"publish","type":"post","link":"https:\/\/www.mainmind.com\/blog\/progreso-john-the-ripper-en-windows\/","title":{"rendered":"Progreso John the Ripper\u00a0en Windows"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Que s\u00ed, que lo normal ser\u00eda utilizarlo en Linux o WSL&#8230; pero para una \u00abpeque\u00f1a prueba\u00bb acabas generando un script en PowerShell donde&#8230;<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Busca el ejecutable john.exe en directorios habituales<\/li>\n\n\n\n<li>Ordena las sesiones por fecha y pre-selecciona la m\u00e1s reciente<\/li>\n\n\n\n<li>Refresca cada minutos el estado de la sesi\u00f3n y si sigue activa<\/li>\n<\/ul>\n\n\n\n<!--more-->\n\n\n\n<p class=\"wp-block-paragraph\">Los \u00abya que\u00bb&#8230; mientras la gr\u00e1fica est\u00e1 al 100%:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: powershell; title: ; notranslate\" title=\"\">\n&lt;#\nEste script est\u00e1 disponible bajo la licencia MIT.\nCopyright (c) 2025 Kaizen Development Solutions.\n\nSe permite el uso, copia, modificaci\u00f3n y distribuci\u00f3n del software\nsiempre que se mantenga este aviso de copyright y la referencia a la\nlicencia MIT. El software se proporciona &quot;tal cual&quot;, sin garant\u00edas de\nning\u00fan tipo. Para m\u00e1s detalles consulte el archivo LICENSE del\nrepositorio.\n\n.SYNOPSIS\nMuestra el estado de sesiones activas de John the Ripper en Windows,\npermitiendo refresco autom\u00e1tico y autodetecci\u00f3n del ejecutable john.exe.\n\n.DESCRIPTION\nEste script lista las sesiones .rec en el directorio del usuario,\npermite seleccionar una, detecta autom\u00e1ticamente si John est\u00e1 ejecutando\nesa sesi\u00f3n y muestra el progreso con formato compacto y marca temporal.\n\n.EXAMPLE\n.\\jtr-status.ps1\n\nMuestra la lista de sesiones y realiza una consulta del estado.\n\n.EXAMPLE\n.\\jtr-status.ps1 -RefreshSeconds 30\n\nRefresca continuamente el estado de la sesi\u00f3n seleccionada cada\n30 segundos hasta que deje de estar activa.\n#&gt;\n\nparam(\n    # Ruta al ejecutable john.exe (se intentar\u00e1 autodetectar si no existe)\n    &#x5B;string]$JohnExe = &quot;C:\\DATOS\\JtR\\run\\john.exe&quot;,\n\n    # Intervalo de refresco en segundos.\n    # 0 o negativo -&gt; solo consulta una vez y termina.\n    &#x5B;int]$RefreshSeconds = 60\n)\n\n$sessionDir = Join-Path $env:USERPROFILE &quot;.john\\sessions&quot;\n\n# --- Autodetecci\u00f3n de john.exe ---\nif (-not (Test-Path $JohnExe)) {\n    $candidates = @()\n\n    # Carpetas base donde buscar\n    $roots = @()\n    if ($PSScriptRoot) { $roots += $PSScriptRoot }\n    $roots += (Get-Location).Path\n\n    foreach ($root in $roots) {\n        $candidates += (Join-Path $root &quot;john.exe&quot;)\n        $candidates += (Join-Path $root &quot;run\\john.exe&quot;)\n        $candidates += (Join-Path $root &quot;JtR\\john.exe&quot;)\n        $candidates += (Join-Path $root &quot;JtR\\run\\john.exe&quot;)\n    }\n\n    $found = $null\n    foreach ($c in $candidates) {\n        if (Test-Path $c) {\n            $found = $c\n            break\n        }\n    }\n\n    if ($found) {\n        Write-Host (&quot;john.exe no encontrado en la ruta configurada. Usando autodetectado: {0}&quot; -f $found) -ForegroundColor Yellow\n        $JohnExe = $found\n    }\n    else {\n        Write-Host &quot;ERROR: No se encontr\u00f3 john.exe. Revisa la variable `\\$JohnExe` en el script o coloca john.exe en una de estas rutas:&quot; -ForegroundColor Red\n        Write-Host &quot;  - (carpeta del script)\\john.exe&quot;\n        Write-Host &quot;  - (carpeta del script)\\run\\john.exe&quot;\n        Write-Host &quot;  - (carpeta actual)\\john.exe&quot;\n        Write-Host &quot;  - (carpeta actual)\\run\\john.exe&quot;\n        Write-Host &quot;  - (carpeta actual)\\JtR\\john.exe&quot;\n        Write-Host &quot;  - (carpeta actual)\\JtR\\run\\john.exe&quot;\n        exit 1\n    }\n}\n\nif (-not (Test-Path $sessionDir)) {\n    Write-Host &quot;ERROR: No existe la carpeta de sesiones: $sessionDir&quot; -ForegroundColor Red\n    exit 1\n}\n\n# Obtener las sesiones .rec ordenadas por \u00faltima modificaci\u00f3n (m\u00e1s reciente primero)\n$sessions = Get-ChildItem -Path $sessionDir -Filter &quot;*.rec&quot; |\n            Sort-Object LastWriteTime -Descending\n\nif ($sessions.Count -eq 0) {\n    Write-Host &quot;No se encontraron sesiones (.rec) en $sessionDir&quot; -ForegroundColor Yellow\n    exit 0\n}\n\nWrite-Host &quot;&quot;\nWrite-Host (&quot;Sesiones encontradas en {0}:&quot; -f $sessionDir)\nWrite-Host &quot;&quot;\n\n# La m\u00e1s reciente es la preseleccionada\n$defaultIndex = 1\n\n# Mostrar lista numerada\nfor ($i = 0; $i -lt $sessions.Count; $i++) {\n    $idx  = $i + 1\n    $name = &#x5B;System.IO.Path]::GetFileNameWithoutExtension($sessions&#x5B;$i].Name)\n    $time = $sessions&#x5B;$i].LastWriteTime.ToString(&quot;yyyy-MM-dd HH:mm:ss&quot;)\n\n    if ($idx -eq $defaultIndex) {\n        Write-Host (&quot;&#x5B;{0}] {1}  (\u00faltima actividad: {2})  &lt;-- RECIENTE&quot; -f $idx, $name, $time) -ForegroundColor Cyan\n    }\n    else {\n        Write-Host (&quot;&#x5B;{0}] {1}  (\u00faltima actividad: {2})&quot; -f $idx, $name, $time)\n    }\n}\n\n# Preguntar selecci\u00f3n\n$selection = Read-Host (&quot;Selecciona sesi\u00f3n (1-{0}) &#x5B;ENTER = {1}]&quot; -f $sessions.Count, $defaultIndex)\n\nif (&#x5B;string]::IsNullOrWhiteSpace($selection)) {\n    $selection = $defaultIndex\n}\n\nif (-not ($selection -as &#x5B;int]) -or $selection -lt 1 -or $selection -gt $sessions.Count) {\n    Write-Host &quot;Selecci\u00f3n inv\u00e1lida.&quot; -ForegroundColor Red\n    exit 1\n}\n\n# Sesi\u00f3n seleccionada:\n$chosen            = $sessions&#x5B;$selection - 1]\n$sessionId         = &#x5B;System.IO.Path]::GetFileNameWithoutExtension($chosen.Name)     # solo nombre, sin ruta\n$sessionPathNoExt  = &#x5B;System.IO.Path]::Combine($chosen.DirectoryName, $sessionId)    # ruta completa sin .rec\n\nWrite-Host &quot;&quot;\nWrite-Host (&quot;Mostrando estado de la sesi\u00f3n: {0}&quot; -f $sessionPathNoExt) -ForegroundColor Green\nWrite-Host &quot;&quot;\n\ndo {\n    # Mostrar estado de la sesi\u00f3n (una sola llamada a john)\n    $output = &amp; $JohnExe &quot;--status=$sessionPathNoExt&quot; 2&gt;&amp;1\n\n    # Buscar la l\u00ednea de estado (empieza normalmente por &quot;0g &quot; o &quot;1g &quot;)\n    $statusLine = $output | Where-Object { $_ -match &#039;^\\d+g &#039; } | Select-Object -Last 1\n\n    if (-not $statusLine) {\n        # Si por lo que sea no cuadra el patr\u00f3n, usamos la \u00faltima l\u00ednea no vac\u00eda\n        $statusLine = ($output | Where-Object { $_.Trim().Length -gt 0 } | Select-Object -Last 1)\n    }\n\n    $timestamp = Get-Date -Format &quot;yyyy-MM-dd HH:mm:ss&quot;\n    Write-Host (&quot;{0} - {1}&quot; -f $timestamp, $statusLine)\n\n    # Si el refresco es 0 o negativo, solo mostramos una vez\n    if ($RefreshSeconds -le 0) {\n        break\n    }\n\n    # Detectar si la sesi\u00f3n sigue activa (buscamos procesos john.exe cuyo CommandLine contenga el nombre de la sesi\u00f3n)\n    $procs    = Get-CimInstance Win32_Process -Filter &quot;Name = &#039;john.exe&#039;&quot; -ErrorAction SilentlyContinue\n    $isActive = $false\n\n    foreach ($p in $procs) {\n        if ($p.CommandLine -and $p.CommandLine -like &quot;*$sessionId*&quot;) {\n            $isActive = $true\n            break\n        }\n    }\n\n    if (-not $isActive) {\n        Write-Host (&quot;{0} - La sesi\u00f3n ya no est\u00e1 activa (no hay procesos john.exe con ese nombre de sesi\u00f3n).&quot; -f (Get-Date -Format &quot;yyyy-MM-dd HH:mm:ss&quot;)) -ForegroundColor Yellow\n        break\n    }\n\n    Start-Sleep -Seconds $RefreshSeconds\n\n} while ($true)\n\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">ACTUALIZADO 2025-11-25: a\u00f1adido al <a href=\"https:\/\/github.com\/mainmind83\/PowerShell\/blob\/main\/JtR-status.ps1\" data-type=\"link\" data-id=\"https:\/\/github.com\/mainmind83\/PowerShell\/blob\/main\/JtR-status.ps1\">repositorio de PowerShell<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Que s\u00ed, que lo normal ser\u00eda utilizarlo en Linux o WSL&#8230; pero para una \u00abpeque\u00f1a prueba\u00bb acabas generando un script en PowerShell donde&#8230;<\/p>\n","protected":false},"author":1,"featured_media":2199,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[19],"tags":[953,1018,949],"class_list":["post-2476","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-seguridad","tag-john-the-ripper","tag-jtr","tag-wsl"],"_links":{"self":[{"href":"https:\/\/www.mainmind.com\/blog\/wp-json\/wp\/v2\/posts\/2476","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.mainmind.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.mainmind.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.mainmind.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.mainmind.com\/blog\/wp-json\/wp\/v2\/comments?post=2476"}],"version-history":[{"count":4,"href":"https:\/\/www.mainmind.com\/blog\/wp-json\/wp\/v2\/posts\/2476\/revisions"}],"predecessor-version":[{"id":2518,"href":"https:\/\/www.mainmind.com\/blog\/wp-json\/wp\/v2\/posts\/2476\/revisions\/2518"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.mainmind.com\/blog\/wp-json\/wp\/v2\/media\/2199"}],"wp:attachment":[{"href":"https:\/\/www.mainmind.com\/blog\/wp-json\/wp\/v2\/media?parent=2476"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.mainmind.com\/blog\/wp-json\/wp\/v2\/categories?post=2476"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.mainmind.com\/blog\/wp-json\/wp\/v2\/tags?post=2476"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}