[Bat + PowerShell] How to mask (hide) input such as password in batch file!

Windows


Hello!This time I would like to introduce how to mask the input to "*" in a batch file.

Don't you remember the word "shoulder hacking"?If you work for a company, you may have heard of it in security classes.

The point is that you can peep at the information you are entering over your shoulder.

The human eye cannot pay attention to the back ...

Not limited to personal computers, passbooks, letters, confidential materials, etc ... There are many things that can be peeped at!

This time, I will introduce how to create a batch file that prevents the input as it is displayed on the screen when entering a password etc.

Thing you want to do

First of all, I often use "set / p" to let the user enter in just a batch.
As an example, I think the code will look like ↓.

@echo off
set /p PASSWORD="パスワード="

Try doing this and enter "password".

Then you can see all the contents entered like this.
You can't complain even if you peep at this.

In order to improve this, I will hide (mask) it by the method introduced.

Then, like this, the entered characters will be replaced with "*".
In this case, even if you look at the screen, you do not know what was entered!

Script example

@echo off

set "pscmd=powershell.exe -Command " ^
$inputPass = read-host 'パスワード=' -AsSecureString ; ^
$BSTR=[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($inputPass); ^
[System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)""

for /f "tokens=*" %%a in ('%pscmd%') do set PASSWORD=%%a

echo %PASSWORD%
pause

You can test it by pasting this code in a text file etc. and changing the extension to ".bat".

Commentary

Execute a PowerShell command in a batch file

This time, I want to realize it with a batch file, but I could not find the option to mask in the command for input provided.Therefore, the power shell takes over the input work.

set "pscmd=powershell.exe -Command "[PowerShellコマンド]""

If you want to execute a PowerShell command in a batch, you can write the PowerShell command in the [PowerShell command] part with "powershell.exe -Command".

The command is stored in a variable called "pscmd" for easy handling when getting the result later.

It is a rule of thumb to enclose it in "" "because there is a risk of misrecognizing it as another command if there is a space in the batch file. You'll need it for the entire set and for the PowerShell command part.

The "^" in the script code means that the code is broken.
If you use "^" in a batch file, you can execute commands that are difficult to read if they are on one line, with line breaks.

Mask input (PowerShell)

Powershell has an option to mask the input, so it's easy.

$inputPass = read-host 'パスワード=' -AsSecureString ;

If you add "-AsSecureString" to the "read-host" command as an option, the input will be automatically converted to "*".The input result is stored in "$ inputPass" as it is.

Undo the masked string

The contents of $ inputPass contain data that cannot be deciphered as it is.
Therefore, it is necessary to restore the original data once.

$BSTR=[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($inputPass);
[System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)

"SecureStringToBSTR" is a command to restore the data in ().
By doing this, the data that can be read properly is stored in "$ BSTR".

"PtrToStringAuto" is a command to read the completed data, and when executed, the value in () is output.

* [System.Runtime.InteropServices.Marshal] is for manipulating data in memory.
There are quite a lot of things you can do, but I'll omit them here.

Pass the restored string to the batch

Finally, read the value output on the batch side.
In order to read the result of PowerShell, it is common to read it in the form of using "for".

for /f "tokens=*" %%a in ('%pscmd%') do set PASSWORD=%%a

It is a form to execute the command enclosed in "'" and store it in "%% a".
I put the powershell command in% pscmd% first, so the code is clean.

Afterword

This time, I introduced how to mask the entered characters to "*".

To be honest, it's very annoying that I can't mask the input in a batch file.
This is because there is always a wall called the login screen in batches that sandwich a restart.
It is also used when accessing a shared server.

It's okay if the user inputs it, but I want to do it automatically.Because if you leave it alone, it is more certain that the process will be completed. (The user may make a typo ...

There is a lot of information that can be leaked no matter how much the engineer takes measures against shoulder hacking.
I'm not relieved that the security of my computer is perfect, and I'm also concerned about physical security such as "locking my house" and "don't leave gold" that can be cashed if stolen. I want to go.

There is even a word that the devil points, so that's itBehavior that does not tempt youI think that is important regardless of IT.

bonus

Code that inputs twice and confirms that it is correct before proceeding with processing

@echo off
:input

set "pscmd=powershell.exe -Command " ^
$inputPass = read-host 'パスワード=' -AsSecureString ; ^
$BSTR=[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($inputPass); ^
[System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)""

for /f "tokens=*" %%a in ('%pscmd%') do set PASSWORD=%%a

set "pscmd=powershell.exe -Command " ^
$inputPass = read-host 'もう一度入力してください=' -AsSecureString ; ^
$BSTR=[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($inputPass); ^
[System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)""

for /f "tokens=*" %%a in ('%pscmd%') do set PASSWORD_C=%%a

if %PASSWORD% neq %PASSWORD_C% (
   echo 入力が間違っています
   pause
   cls
   goto :input
)

echo 入力OK
pause

Very simply, I store the input in another variable twice and compare.
If you make a mistake, clear the screen and then jump to ": input", and if it's OK, proceed as it is.

I hope it helps you.

Reference site

Enter password in Powershell-Qiita
I investigated how to enter a simple password and how to check the entered characters with PowerShell, so I will describe it. Enter password and confirm input characters with PowerShell $ secstr = Read-Host -Prompt "Please ...
Marshal class (System.Runtime.InteropServices)
It provides a variety of methods that you can use when working with unmanaged code.You can use these methods to allocate unmanaged memory, copy unmanaged memory blocks, convert from managed to unmanaged, and so on. Provides a collection of methods for allo ...

Thank you!

Comment

Translate »
I copied the title and URL