How do I create a password that timeouts after cer

2020-02-16 03:05发布

I want to make this code to ask for a password that timeouts after 10 seconds and if you wrote the correct password it goes to :wow but if it's incorrect it just continues the code . (the code is just an example)

@ECHO OFF
TIMEOUT /t 10>nul
exit
:wow
echo now this is fun!
pause
exit

2条回答
叛逆
2楼-- · 2020-02-16 03:31

You could start a VBS file with a password prompt. http://www.robvanderwoude.com/vbstech_ui_password.php

The link above links to a page with a password prompt script. You could add a timeout wich would wait for 10 seconds and then close.

查看更多
forever°为你锁心
3楼-- · 2020-02-16 03:33

MD5sum

Batch scripts, as they live in the world of plain text files, aren't very conducive to storing and matching passwords. After all, the person running the script could just as easily open it in Notepad and see the expected password. That's not very hacksy, now, is it?

These batch password questions pop up from time to time, and hard-coded passwords in scripts always irritate me. So how about, for a change, we obfuscate the password with an MD5 hash? There's no simple command built into Windows that makes this happen, but it can be accomplished with a (admittedly convoluted) PowerShell one-liner.

Save this helper script as md5sum.bat:

@echo off
setlocal

if "%~1"=="" goto :EOF

powershell "[Security.Cryptography.HashAlgorithm]::Create('MD5').ComputeHash([Text.Encoding]::UTF8.GetBytes('%~1')) | %%{write-host -n $_.tostring('x2')}"

Then use it to find the MD5 hash of the password you want like this:

md5sum.bat "password"

The result will output

5f4dcc3b5aa765d61d8327deb882cf99

Rather than hard coding the password itself into your script, you can now hard code 5f4dcc3b5aa765d61d8327deb882cf99.


User Entry

Now comes the interesting stuff. You can also borrow from Powershell to obfuscate the user entry like this:

@echo off
setlocal

<NUL set /P "=Password? "
set "psCommand=powershell -command "$p=read-host -AsSecureString;^
$m=[Runtime.InteropServices.Marshal];$m::PtrToStringAuto($m::SecureStringToBSTR($p))""
for /f "usebackq delims=" %%p in (`%psCommand%`) do set "pass=%%p"

setlocal enabledelayedexpansion
echo You entered !pass!
endlocal

Combine the two methods and you can check to see whether the password entered by the user matches the hash hard coded into the script.

@echo off
setlocal

<NUL set /P "=Password? "
set "psCommand=powershell "$p=read-host -AsSecureString;^
$m=[Runtime.InteropServices.Marshal];$x=$m::PtrToStringAuto($m::SecureStringToBSTR($p));^
[Security.Cryptography.HashAlgorithm]::Create('MD5').ComputeHash([Text.Encoding]::UTF8.GetBytes($x)) ^| %%{write-host -n $_.tostring('x2')}""

for /f "usebackq delims=" %%I in (`%psCommand%`) do (
    if "%%~I"=="5f4dcc3b5aa765d61d8327deb882cf99" goto :match
)

echo Nope.
goto :EOF

:match
echo w00!

Voila! Now you can expect a user entry of password but the user can't easily see by opening in Notepad that password is the correct password. Cool, huh?


Self-Destruct

Back to your original question of how you can make this timeout after 10 seconds, you'll have to get a little creative. One solution would be to launch a helper script in the background that waits for 10 seconds, then kills all powershell.exe tasks. This can interfere with other powershell-ish stuff you might have running -- but let's be honest. Given the elementary nature of the question, I think it's safe to assume that won't be a problem in this situation.

I would do it this way:

@echo off
setlocal

if "%~1"=="helper" goto helper
start /b "" "%~f0" helper

<NUL set /P "=Password? "
set "psCommand=powershell "$p=read-host -AsSecureString;^
$m=[Runtime.InteropServices.Marshal];$x=$m::PtrToStringAuto($m::SecureStringToBSTR($p));^
[Security.Cryptography.HashAlgorithm]::Create('MD5').ComputeHash([Text.Encoding]::UTF8.GetBytes($x)) ^| %%{write-host -n $_.tostring('x2')}""

for /f "usebackq delims=" %%I in (`%psCommand%`) do (
    waitfor /s %computername% /si PasswordEntered >NUL 2>NUL
    if "%%~I"=="5f4dcc3b5aa765d61d8327deb882cf99" goto :match
)

echo Nope.
goto :EOF

:match
echo w00!
goto :EOF
:: // END MAIN RUNTIME

:helper
>NUL 2>NUL (
    title Enter password.
    waitfor PasswordEntered /t 10 || taskkill /im "powershell.exe" /f
)
exit

If you'd rather not taskkill Powershell, it is possible to make read-host time out, but I'll leave that as an exercise for the reader.

查看更多
登录 后发表回答