Saltar al contenido

¿Puedo enmascarar un texto de entrada en un archivo bat?

Solución:

Sí, llego 4 años tarde.

Pero encontré una manera de hacer esto en una línea sin tener que crear un script externo; llamando a los comandos de PowerShell desde un archivo por lotes.

Gracias a TessellatesHeckler, sin generar un archivo de texto (configuré el comando powershell en una variable, porque es bastante complicado en una línea larga dentro de un bucle for).

@echo off
set "psCommand=powershell -Command "$pword = read-host 'Enter Password' -AsSecureString ; ^
    $BSTR=[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($pword); ^
        [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)""
for /f "usebackq delims=" %%p in (`%psCommand%`) do set password=%%p
echo %password%

Originalmente lo escribí para enviarlo a un archivo de texto, luego lo leí desde ese archivo de texto. Pero el método anterior es mejor. En una línea extremadamente larga, casi incomprensible:

@echo off
powershell -Command $pword = read-host "Enter password" -AsSecureString ; $BSTR=[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($pword) ; [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR) > .tmp.txt & set /p password=<.tmp.txt & del .tmp.txt
echo %password%

Desglosaré esto: puedes dividirlo en unas pocas líneas usando el símbolo de intercalación ^, que es mucho mejor …

@echo off
powershell -Command $pword = read-host "Enter password" -AsSecureString ; ^
    $BSTR=[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($pword) ; ^
        [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR) > .tmp.txt 
set /p password=<.tmp.txt & del .tmp.txt
echo %password%

Este artículo explica qué están haciendo los comandos de PowerShell; esencialmente obtiene entrada usando Read-Host -AsSecureString – las siguientes dos líneas convierten esa cadena segura de nuevo en texto sin formato, la salida (contraseña de texto sin formato) se envía a un archivo de texto usando >.tmp.txt. Luego, ese archivo se lee en una variable y se elimina.

Hasta XP y Server 2003, puede utilizar otra herramienta incluida (VBScript): los dos scripts siguientes hacen el trabajo que desea.

Primero, getpwd.cmd:

@echo off
<nul: set /p passwd=Password: 
for /f "delims=" %%i in ('cscript /nologo getpwd.vbs') do set passwd=%%i
echo.

Luego, getpwd.vbs:

Set oScriptPW = CreateObject("ScriptPW.Password")
strPassword = oScriptPW.GetPassword()
Wscript.StdOut.WriteLine strPassword

los getpwd.vbs simplemente usa el objeto de contraseña para ingresar la contraseña del usuario y luego imprimirla en la salida estándar (el siguiente párrafo explicará por qué eso no aparece en la terminal).

los getpwd.cmd El script de comando es un poco más complicado, pero básicamente funciona de la siguiente manera.

El efecto de la "<nul: set /p passwd=Password: " comando es generar el símbolo del sistema sin un carácter de nueva línea final; es una forma astuta de emular el "echo -n" comando desde el bash cascarón. Establece passwd a una cadena vacía como un efecto secundario irrelevante y no espera la entrada ya que está tomando su entrada del nul: dispositivo.

los "for /f "delims=" %%i in ('cscript /nologo getpwd.vbs') do set passwd=%%i" La declaración es la parte más complicada. Ejecuta VBScript sin “publicidad” de Microsoft, por lo que la única salida de línea es la contraseña (de VBscript "Wscript.StdOut.WriteLine strPassword".

No es necesario establecer los delimitadores en nada para capturar una línea de entrada completa con espacios; de lo contrario, solo obtiene la primera palabra. los "for ... do set ..." conjuntos de bits passwd para que sea la salida de contraseña real de VBScript.

Luego hacemos eco de una línea en blanco (para terminar el "Password: " línea) y la contraseña estará en el passwd variable de entorno después de que se haya ejecutado el código.


Ahora, como se mencionó, scriptpw.dll sólo está disponible hasta XP / 2003. Para rectificar esto, simplemente puede copiar el scriptpw.dll archivo de la WindowsSystem32 carpeta de un sistema XP / 2003 a la WinntSystem32 o WindowsSystem32 carpeta en su propio sistema. Una vez que se haya copiado la DLL, deberá registrarla ejecutando:

regsvr32 scriptpw.dll

Para registrar correctamente la DLL en Vista y versiones posteriores, necesitará privilegios de administrador. No he examinado la legalidad de un movimiento así, lector de cuevas.


Si no estás demasiado interesado en intentar rastrear y registrar archivos DLL más antiguos (por conveniencia o razones legales), hay otra forma. Versiones posteriores de Windows (las que no tiene la DLL requerida) debe tener Powershell disponible para usted.

Y, de hecho, debería considerar actualizar sus scripts para usarlos por completo, ya que es un lenguaje de scripts mucho más capaz que cmd.exe. Sin embargo, si desea mantener la mayor parte de su código como cmd.exe guiones (por ejemplo, si tiene un lote de código que no desea convertir), puede usar el mismo truco.

Primero, modifique el cmd script para que llame a Powershell en lugar de CScript:

@echo off
for /f "delims=" %%i in ('powershell -file getpwd.ps1') do set passwd=%%i

El script de Powershell es igualmente simple:

$password = Read-Host "Enter password" -AsSecureString
$password = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($password)
$password = [Runtime.InteropServices.Marshal]::PtrToStringAuto($password)
echo $password

aunque con algunas referencias para obtener el texto real de la contraseña.

Recuerde que, para ejecutar scripts de Powershell locales sin firmar en su máquina, es posible que deba modificar la política de ejecución del valor predeterminado (draconiano, aunque muy seguro), con algo como:

set-executionpolicy remotesigned

desde el propio Powershell.

1.Solución por lotes pura que (ab) usa XCOPY comando y su /P /L interruptores que se encuentran aquí (algunas mejoras en esto se pueden encontrar aquí):

:: Hidden.cmd
::Tom Lavedas, 02/05/2013, 02/20/2013
::Carlos, 02/22/2013
::https://groups.google.com/forum/#!topic/alt.msdos.batch.nt/f7mb_f99lYI


@Echo Off
:HInput
SetLocal EnableExtensions EnableDelayedExpansion
Set "FILE=%Temp%.T"
Set "FILE=.T"
Keys List >"%File%"
Set /P "=Hidden text ending with Ctrl-C?: " <Nul
Echo.
Set "HInput="
:HInput_
For /F "tokens=1* delims=?" %%A In (
 '"Xcopy /P /L "%FILE%" "%FILE%" 2>Nul"'
) Do (
  Set "Text=%%B"
  If Defined Text (
    Set "Char=!Text:~1,1!"
    Set "Intro=1"
    For /F delims^=^ eol^= %%Z in ("!Char!") Do Set "Intro=0"
    Rem If press Intro
    If 1 Equ !Intro! Goto :HInput#
    Set "HInput=!HInput!!Char!"
  )
)
Goto :HInput_
:HInput#
Echo(!HInput!
Goto :Eof 

1.2 Otra forma basada en el comando reemplazar

@Echo Off
SetLocal EnableExtensions EnableDelayedExpansion

Set /P "=Enter a Password:" < Nul
Call :PasswordInput
Echo(Your input was:!Line!

Goto :Eof

:PasswordInput
::Author: Carlos Montiers Aguilera
::Last updated: 20150401. Created: 20150401.
::Set in variable Line a input password
For /F skip^=1^ delims^=^ eol^= %%# in (
'"Echo(|Replace.exe "%~f0" . /U /W"') Do Set "CR=%%#"
For /F %%# In (
'"Prompt $H &For %%_ In (_) Do Rem"') Do Set "BS=%%#"
Set "Line="
:_PasswordInput_Kbd
Set "CHR=" & For /F skip^=1^ delims^=^ eol^= %%# in (
'Replace.exe "%~f0" . /U /W') Do Set "CHR=%%#"
If !CHR!==!CR! Echo(&Goto :Eof
If !CHR!==!BS! (If Defined Line (Set /P "=!BS! !BS!" <Nul
Set "Line=!Line:~0,-1!"
)
) Else (Set /P "=*" <Nul
If !CHR!==! (Set "Line=!Line!^!"
) Else Set "Line=!Line!!CHR!"
)
Goto :_PasswordInput_Kbd

2.Remitente de contraseña que utiliza una ventana emergente de HTA
. Este es un archivo hybrit .bat / jscript / mshta y debe guardarse como .bat:

<!-- :
:: PasswordSubmitter.bat
@echo off
for /f "tokens=* delims=" %%p in ('mshta.exe "%~f0"') do (
    set "pass=%%p"
)

echo your password is %pass%
exit /b
-->

<html>
<head><title>Password submitter</title></head>
<body>

    <script language="javascript" >
        window.resizeTo(300,150);
        function entperPressed(e){
                if (e.keyCode == 13) {
                    pipePass();
                }
        }
        function pipePass() {
            var pass=document.getElementById('pass').value;
            var fso= new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1);
            close(fso.Write(pass));

        }
    </script>

    <input type="password" name="pass" size="15" onkeypress="return entperPressed(event)" ></input>
    <hr>
    <button onclick='pipePass()'>Submit</button>

</body>
</html>

3.Un híbrido .net autocompilado .De nuevo debe guardarse como .bat A diferencia de otras soluciones, creará / compilará un pequeño archivo .exe que se llamará (si lo desea, puede eliminarlo). También requiere un marco .net instalado, pero eso no es un problema:

@if (@X)==(@Y) @end /* JScript comment
@echo off
setlocal enableDelayedExpansion

for /f "tokens=* delims=" %%v in ('dir /b /s /a:-d  /o:-n "%SystemRoot%Microsoft.NETFramework*jsc.exe"') do (
   set "jsc=%%v"
)

if not exist "%~n0.exe" (
    "%jsc%" /nologo /out:"%~n0.exe" "%~dpsfnx0"
)

for /f "tokens=* delims=" %%p in ('"%~n0.exe"') do (
    set "pass=%%p"
)

echo your password is !pass!

endlocal & exit /b %errorlevel%

*/



import System;



var pwd = "";
var key;

Console.Error.Write("Enter password: ");

        do {
           key = Console.ReadKey(true);

           if ( (key.KeyChar.ToString().charCodeAt(0)) >= 20 && (key.KeyChar.ToString().charCodeAt(0) <= 126) ) {
              pwd=pwd+(key.KeyChar.ToString());
              Console.Error.Write("*");
           }

           if ( key.Key == ConsoleKey.Backspace && pwd.Length > 0 ) {
               pwd=pwd.Remove(pwd.Length-1);
               Console.Error.Write("b b");
           }


        } while (key.Key != ConsoleKey.Enter);
        Console.Error.WriteLine();
        Console.WriteLine(pwd);
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *