Years ago I saw some batch scripts that contain nothing relevant at a fist look, but with a lot of content. The content was base64 encoded, and when you run the scripts, they are just running the commands that are encoded there.
Something like
SET mypath=%~dp0
echo "%mypath%
will look similar with
some_base_64_decoding_function(
U0VUIG15cGF0aD0lfmRwMA0KIGVjaG8gIiVteXBhdGgl
)
I don't really remember how those file were, and I can't find anything relevant on the Internet, except this article: Convert PowerShell script into non-readable format
but this only refeer to PowerShell scripts, and I need it for .bat scripts.
Anyone to give me a hint?
This is a sample batch file for encoding files in Base 64 with Certutil utility.
How to use it?
Just save this code on your notepad or on notepad++ or on any text editor as :
Certutil_B64_Encoding_Files.bat and drag and drop any file over it to be encoded
#echo off
Title Encoding files with CERTUTIL utility by Hackoo 2017
color 0A & Mode 83,3
If "%~1"=="" (
color 0C & Mode 80,3
echo(
echo You must drag and drop a file over this batch script to be encoded !
Timeout /T 5 /nobreak>nul & exit /b
)
#for /f %%i in ("certutil.exe") do if not exist "%%~$path:i" (
echo CertUtil.exe not found.
pause
exit /b
)
set "TempFile=%Temp%\Temp_b64
set "OutputFile=%~nx1_encoded%~x0"
If exist "%OutputFile%" Del "%OutputFile%" >nul 2>&1
echo(
echo Please wait a while ... Encoding "%~nx1" is in progress ...
certutil.exe -f -encode "%~1" "%TempFile%" >nul 2>&1
(
echo #echo off
echo CERTUTIL -f -decode "%%~f0" "%%Temp%%\%~nx1" ^>nul 2^>^&1
echo Start "%~n1" "%%Temp%%\%~nx1"
echo Exit
)>> "%OutputFile%"
copy "%OutputFile%" /b + "%TempFile%" /b >nul 2>&1
If exist "%TempFile%" Del "%TempFile%" >nul 2>&1
Timeout /T 2 /NoBreak>nul & exit
Encoded HTA Example: CommandLine.hta_encoded.bat
This is a result of an encoded output of a HTA file of mine named as CommandLine.hta_encoded.bat
So, you should copy and paste this code as CommandLine.hta_encoded.bat and execute it by double click. And you will get something like this :
Encoded VBS Example : DJBuzzRadio.vbs_encoded.bat
#echo off
CERTUTIL -f -decode "%~f0" "%Temp%\DJBuzzRadio.vbs" >nul 2>&1
Start "DJBuzzRadio" "%Temp%\DJBuzzRadio.vbs"
Exit
-----BEGIN CERTIFICATE-----
UGxheSAiaHR0cDovL3d3dy5jaG9jcmFkaW9zLmNoL2RqYnV6enJhZGlvX3dpbmRv
d3MubXAzLmFzeCINClN1YiBQbGF5KFVSTCkNCiAgIERpbSBTb3VuZA0KICAgU2V0
IFNvdW5kID0gQ3JlYXRlT2JqZWN0KCJXTVBsYXllci5PQ1giKQ0KICAgU291bmQu
VVJMID0gVVJMDQogICBTb3VuZC5zZXR0aW5ncy52b2x1bWUgPSAxMDANCiAgIFNv
dW5kLkNvbnRyb2xzLnBsYXkNCiAgIGRvIHdoaWxlIFNvdW5kLmN1cnJlbnRtZWRp
YS5kdXJhdGlvbiA9IDANCiAgICAgICB3c2NyaXB0LnNsZWVwIDEwMA0KICAgbG9v
cA0KICAgd3NjcmlwdC5zbGVlcCAoaW50KFNvdW5kLmN1cnJlbnRtZWRpYS5kdXJh
dGlvbikrMSkqMTAwMA0KRW5kIFN1Yg0K
-----END CERTIFICATE-----
MACRO-b64decode.bat
#echo off
SETLOCAL DISABLEDELAYEDEXPANSION
::DEFINITIONS
( set LF=^
%= EMPTY =%
)
set ^"NL=^^^%LF%%LF%^%LF%%LF%^^"
set $MACRO.ForEntireLine=^^^^^^^"eol^^^^=^^^^^^^%LF%%LF%^%LF%%LF%^^^%LF%%LF%^%LF%%LF%^^^^ delims^^^^=^^^^^^^"
::MACRO
ENDLOCAL &^
set $MACRO.b64exec=FOR %%? in (args main) do if "%%?" == "main" (%NL%
FOR %%a in (!args!) do (%NL%
^>encoded.txt echo %%a%NL%
^>nul certutil -decodehex encoded.txt decoded.txt 1%NL%
FOR /F %$MACRO.ForEntireLine% %%x in (decoded.txt) do %%x%NL%
del /F /Q encoded.txt decoded.txt%NL%
)%NL%
) ELSE SETLOCAL ENABLEDELAYEDEXPANSION ^& set args=
To call the macro inside your batch file:
call MACRO-b64decode.bat
%$MACRO.b64exec% ZWNobyBoZWxsbywgd29ybGReIQ==
which will output:
hello, world!
Note: DELAYEDEXPANSION is enabled
Related
My script isn't logging the contents of run.txt to log.txt
I've tried to remove the delete command to see if it was deleting it too quickly and therefore couldn't log. But that wasn't the case.
What should I change?
#ECHO OFF &setlocal
SET File=run.txt
type %File%
for /f "tokens=*" %%A in (%File%) do (echo >> log.txt)
del "%File%" /s /f /q > nul
pause
Here is a very simple way to do the task you are requiring.
#echo off
REM Will only grab the first line of the file
set /p file=<run.txt
REM For the last line use a for loop
for /f "tokens=*" %%a in (%file%) do set last_line=%%a
(
echo %file%
)>>log.txt
del /f %file% >nul
If not %errorlevel% equ 0 (
ECHO ERROR - %errorlevel%
pause
exit /b
)
ECHO Success!
timeout /t 003
exit /b %errorlevel%
EXPLANATION
set /p is for set prompt. For more information you can use set /? in your CMD window or check out this site.
I wish I could speak more on what < does, but what it is doing here is piping the content of run.txt to our variable.
Then we echo out our variable to our log file with (ECHO This is our %file%)>>destination
>> is to append where > is to overwrite the file.
(
echo %file%
echo.
)>>%file%
Checking for an error is probably unnecessary, but I believe it is a good habit to build on which is what I am trying to do with that If not %errorlevel% statement.
No error? We Success and timeout ourselves for xxx seconds.
Try:
#ECHO OFF &setlocal
SET "File=run.txt"
type "%File%" >> "log.txt" && (del "%File%" /f > nul)
pause
So I am trying to make a running batch file to create a new batch file which contains:
#setlocal enableextensions enabledelayedexpansion
#echo off
:remloop
set recfilepath=%pof%
set filename=%pof%
SET filename=%_filename:*\=%
if not x%pof:bcd=%==x%pof% goto remloop
endlocal
(Variable POF has already been declared in another file)
So I tried using echo command to make another batch file
echo #setlocal enableextensions enabledelayedexpansion > file2.bat
echo #echo off > file2.bat
echo :remloop >> file2.bat
echo set recfilepath=%pof% >> file2.bat
echo set filename=%pof% >> file2.bat
echo SET filename=%_filename:*\=% >> file2.bat
echo if not x%pof:bcd=%==x%pof% goto remloop >> file2.bat
echo endlocal >> file2.bat
but the result was unexpected, the results are:
#echo off
:remloop
set recfilepath=C:\Users\Palm2570Playz\Desktop\djfbjfbfbj.txt
set filename=C:\Users\Palm2570Playz\Desktop\djfbjfbfbj.txt
SET filename=*\=
if not xC:\Users\Palm2570Playz\Desktop\djfbjfbfbj.txt==xC:\Users\Palm2570Playz\Desktop\djfbjfbfbj.txt goto remloop
endlocal
The "SET filename=*= " lines was unexpected so the code cannot run correctly
Is there any command to fix this?
To show you what your question asks, without providing any fixes for any of the content of `file2.bat`:
#( Echo #setlocal enableextensions enabledelayedexpansion
Echo #echo off
Echo :remloop
Echo set recfilepath=%%pof%%
Echo set filename=%%pof%%
Echo SET filename=%%_filename:*\=%%
Echo if not x%%pof:bcd=%%==x%%pof%% goto remloop
Echo endlocal)>"file2.bat"
If you don't need escaping anything?!
The best and most efficient way to escape is to use no escape, use only the bat file itself to decode the second bat file with the content in Base64 itself:
Where it is possible to use CertUtil to decode File2.bat, taking advantage that it already comes with Windows.
Your code bat:
#(%__APPDIR__%CertUtil.exe -f -decode "%~f0" "%~dp0File2.bat" >nul & goto :EOF)
<-----BEGIN -----QGVjaG8gb2ZmICYmIHNldGxvY2FsIGVuYWJsZWRlbGF5ZWRleHBhbnNpb24NCj
psb29wDQpzZXQgInJlY2ZpbGVwYXRoPSVwb2YlIiAmJiBjbWQuZXhlIC92Om9uIC9jICJzZXQgImZpb
GVuYW1lPSFyZWNmaWxlcGF0aDoqXD0hIiAiDQplY2hvOyJ4IXBvZjpiY2Q9ISJ8ZmluZC9pIC92ICJ4
IXBvZiEiID5udWwgJiYgZ290byA6bG9vcCB8fCBlbmRsb2NhbCAmIGdvdG86RU9G-----END ----->
The File2.bat content result:
#echo off && setlocal enabledelayedexpansion
:loop
set "recfilepath=%pof%" && cmd.exe /v:on /c "set "filename=!recfilepath:*\=!" "
echo;"x!pof:bcd=!"|find/i /v "x!pof!" >nul && goto :loop || endlocal & goto:EOF
This code above has some suggestions, liable to (critical/not), so follow code use the same method using your current code without modifications:
#(%__APPDIR__%CertUtil.exe -f -decode "%~f0" "%~dp0File2.bat" >nul & goto :EOF)
<-----BEGIN CERTIFICATE----- QHNldGxvY2FsIGVuYWJsZWV4dGVuc2lvbnMgZW5hYmxlZGVsYX
llZGV4cGFuc2lvbg0KQGVjaG8gb2ZmDQo6cmVtbG9vcA0Kc2V0IHJlY2ZpbGVwYXRoPSVwb2YlDQpzZ
XQgZmlsZW5hbWU9JXBvZiUNClNFVCBmaWxlbmFtZT0lX2ZpbGVuYW1lOipcPSUNCmlmIG5vdCB4JXBv
ZjpiY2Q9JT09eCVwb2YlIGdvdG8gcmVtbG9vcA0KZW5kbG9jYWw= -----END CERTIFICATE----->
The File2.bat content result:
#setlocal enableextensions enabledelayedexpansion
#echo off
:remloop
set recfilepath=%pof%
set filename=%pof%
SET filename=%_filename:*\=%
if not x%pof:bcd=%==x%pof% goto remloop
endlocal
Some further reading:
[√] CertUtil -Decode
[√] CertUtil -Encode / -Decode
[√] CertUtil (Microsoft Documentation)
You can use FINDSTR / a FOR loop (eol&skip) / MORE on the batch file itself, and redirect it to file2.bat. That way no parsing is involved.
I made no edits/improvements as it's out of scope of the question.
#echo off
%__APPDIR__%findstr.exe /R "^;" "%~f0" >file2.bat
exit /b
<--- FILE2.BAT --->
;#setlocal enableextensions enabledelayedexpansion
;#echo off
;:remloop
;set recfilepath=%pof%
;set filename=%pof%
;SET filename=%_filename:*\=%
;if not x%pof:bcd=%==x%pof% goto remloop
;endlocal
I have a piece of code:
for /F "tokens=*" %%A in (myfile.txt) do (
echo echo %%A ^>^>myfile.txt>>myfile.bat
)
As some of you can see, this code reads myfile.txt, and creates myfile.bat, which when opened creates an exact copy of the original myfile.txt. The problem comes in when myfile.txt contains special characters, such as >. How can I escape the %%A variable?
any help is appreciated.
I have this idea : using Certutil command to encode your text file and generate it again like this batch script can do :
#echo off
set "MyTxtFile=myfile.txt"
for %%i in (%MyTxtFile%) do (
set "MyBatchFile=%%~ni.bat"
set "TempFile=%%~ni.B64"
Set "NewFile=%%~ni__%%~xi"
)
#for /f %%i in ("certutil.exe") do if not exist "%%~$path:i" (
echo CertUtil.exe not found.
pause
exit /b
)
Rem to encode your text file to a temporary file
Certutil -encode "%MyTxtFile%" "%TempFile%" >nul 2>&1
(
echo #echo off
echo Title Generate code of "%MyTxtFile%" to "%NewFile%"
echo CERTUTIL -f -decode "%%~f0" "%NewFile%" ^>nul 2^>^&1
echo Exit
)> "%MyBatchFile%"
#Copy "%MyBatchFile%" /b + "%TempFile%" /b >nul 2>&1
Del "%TempFile%" >nul 2>&1
Timeout /T 2 /NoBreak>nul & exit
EDIT
This code can generate what you want based on your last comment test >> Hello :
#echo off
Title Generate code of "myfile.txt" to "myfile__.txt"
CERTUTIL -f -decode "%~f0" "myfile__.txt" >nul 2>&1
Exit
-----BEGIN CERTIFICATE-----
dGVzdCA+PiBIZWxsbw0KDQo=
-----END CERTIFICATE-----
The following commented code snippet could help (see Variable Edit/Replace):
#ECHO OFF
SETLOCAL EnableExtensions EnableDelayedExpansion
rem silently create empty output files - just for testing
>NUL COPY /Y NUL myfile46134196.bat
>NUL COPY /Y NUL myfile46134196ou.txt
for /F "tokens=*" %%A in (myfile46134196in.txt) do (
set "_aux=%%A"
rem replace every `Greater Than` symbol with a properly escaped one
echo echo !_aux:^>=^^^>! ^>^>myfile46134196ou.txt>>myfile46134196.bat
rem ^> properly escape `Greater Than` symbol - input string
rem ^> -output string
rem ^^ add a caret (Circumflex Accent) to output string
)
rem debugging outputs
echo ON
type myfile46134196.bat
#ECHO OFF
rem test: run currently created .bat file
call myfile46134196.bat
rem test: and show result
echo ON
type myfile46134196in.txt
type myfile46134196ou.txt
#ECHO OFF
Output:
==> .\so\46134196.bat
==> type myfile46134196.bat
echo test^>^>hello >>myfile46134196ou.txt
==> type myfile46134196in.txt
test>>hello
==> type myfile46134196ou.txt
test>>hello
==>
Further resources (required reading, incomplete):
(command reference) An A-Z Index of the Windows CMD command line
(helpful particularities) Windows CMD Shell Command Line Syntax
(%A etc. special page) Command Line arguments (Parameters)
(special page) EnableDelayedExpansion
(> etc. special page) Redirection
(^ caret) Escape Characters, Delimiters and Quotes
I want to decode a base64 encoded text and use it to login to a website. The base64 encoded text is the username and password. I hav found tools like Base64.exe and b64.exe but they take input as a file whereas in my case input is a string. plz help me out. All this shud be done in a batch file only and also am reading the encoded text from a config.txt file.
You can use the CERTUTIL command without installing external software (though it will need temp files):
#echo off
del /q /f "%temp%\b64" >nul 2>nul
del /q /f "%temp%\decoded" >nul 2>nul
set "base64string=YmFzZTY0c3RyaW5n"
echo -----BEGIN CERTIFICATE----->"%temp%\b64"
<nul set /p=%base64string% >>"%temp%\b64"
echo -----END CERTIFICATE----->>"%temp%\b64"
certutil /decode "%temp%\b64" "%temp%\decoded" >nul 2>nul
for /f "useback tokens=* delims=" %%# in ("%temp%\decoded") do set "decoded=%%#"
echo %decoded%
del /q /f "%temp%\b64" >nul 2>nul
del /q /f "%temp%\decoded" >nul 2>nul
You can also use powershell which will be slower despite there will be no temp files:
set "base64string=YmFzZTY0c3RyaW5n"
for /f "tokens=* delims=" %%# in ('powershell [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("""%base64string%"""^)^)') do set "decoded=%%#"
echo %decoded%
You can try also with atob.bat :
call atob.bat YmFzZTY0c3RyaW5n decoded
echo %decoded%
Or with base64.bat
for /f "tokens=* delims=" %%# in ('base64.bat -decode YmFzZTY0c3RyaW5n') do set "decoded=%%#"
echo %decoded%
I found the solution. I am extracting the base64 encoded text from "config.txt" to a new file say "tmp.txt". now I run the cmd "b64.exe -d tmp.txt tmp2.txt".I get the decoded text in the new "tmp2.txt" file. I delete the "tmp.txt" and "tmp2.txt" once i read the username and password.
Thank you
You can use the macro style invented by #jeb, #dbenham and #Ed Dyreen:
#echo off
====SETLOCAL DisableDelayedExpansion EnableExtensions
set ^"LF=^
%===EXPANDS TO NOTHING===%
"
REM \n is an escaped LF + caret
set ^"\n=^^^%LF%%LF%^%LF%%LF%^^"
REM Initalize macro
set ^"$b64d=FOR %%$ in (%%$ MainMacro) do if "%%$" == "MainMacro" (%\n%
^>nul %__APPDIR__%CERTUTIL.EXE -f -decodehex args.tmp proc.tmp 1%\n%
type proc.tmp%\n%
del args.tmp proc.tmp%\n%
) ELSE ^>args.tmp echo("
echo BEFORE :: %time%
%$b64d%dGhpcwppcwpzaWNrIQo=
echo AFTER :: %time%
Output:
BEFORE :: 21:13:31.94
this
is
sick!
AFTER :: 21:13:32.02
This script tries to:
get an input from a txt file, which is a list of computer names,
check if a log file on a computer from the list is bigger than 1000 bytes,
create a txt report with the names of those computers where the log file is more than 1000 bytes,
create another txt report with the names of the computers where the file is less than 1000 bytes.
However, something goes wrong. Any help could be nice.
#echo off
for /f "tokens=*" %%I in (computernames.txt)do call :checksz %%I
goto :eof
:checksz
setlocal
set file="\\%1\c$\data\info.log"
set min=1000
FOR /F "usebackq" %%A IN ('%file%') DO set size=%%~zA
if %size% GTQ %min% (
echo. %1 >>logsizemin.txt
) ELSE (
echo. %1>>logsizemax.txt
)
Hello everyone,
thanks for your valuable support. I congratulate whith those who conceived and built this site is really well done and useful.
I made some modifications to the script that you have kindly suggested to incorporate other features, but something is not working as I would like .. as you can view I use editv32 in order to hide password in my batch, the principle is the same but as you can see after checking the size of the log, "maxlongsize.txt" is used in order to take the names of the PCs on which do the next activity. I wish that the activities were performed sequentially on all PCs in the file "logsizemax.txt" with only one authentication at the beginning. I noticed that, for some reason sometimes the file "logsizemin.txt" is not created but i don't understand why. The maximum would be to put in another file such as "computer unreachable" those PCs that are not reached on the network but I have absolutely no idea how implement it. I hope I have sufficiently explained. Sorry for bad English! I think you understand my intention :). Following the batch
#setlocal
#echo off
editv32 -p "Enter username:" USR
editv32 -m -p "Enter password:" PWD
for /f "tokens=1" %%I in (computernames.txt) do call :checksz %%I
endlocal
goto :eof
:checksz
setlocal
set file="\\%1\c$\data\data.log"
set min=1000
type NUL>logsizemax.txt
type NUL>logsizemin.txt
if not exist %file% goto :eof
FOR /F "usebackq delims=" %%A IN ('%file%') DO set size=%%~zA
if %size% GEQ %min% ( echo %1>>logsizemax.txt ) ELSE ( echo %1>>logsizemin.txt )
endlocal
#setlocal
for /f "tokens=1" %%I in (logsizemax.txt) do call :sw %%I
endlocal
goto :eof
:sw
echo.
echo *****************************************
echo * VBS & Deploy script *
echo *****************************************
echo.
echo Run VBS and deploy script .....
psexec \\%1 -u %USR% -p %PWD% cscript "\\rep\Reg.vbs"
psexec \\%1 -u %USR% -p %PWD% cmd /c "\\rep\deploy.cmd"
echo.
echo **************************
echo * EXE Run *
echo **************************
echo.
echo Running exe .....
psexec -u %USR% -p %PWD% \\%1 "c:\Program Files\test.exe"
echo.
echo ***********************************
echo * Exe application launched *
echo ***********************************
echo.
goto END
:END
exit
You can avoid using environment variables and using the second FOR alltogether. Try this simpler version of your bat, with a more generic :checksz routine.
#echo off
for /f "tokens=*" %%a in (computernames.txt) do (
call :checksz "\\%%a\c$\data\info.log" 1000 "%%a"
)
goto :eof
:checksz
if %~z1 GTR %2 (
echo %~3 >> logsizemin.txt
) ELSE (
echo %~3 >> logsizemax.txt
)
goto :eof
see HELP CALL for more information.
Changes: GTG->GEQ, don't surround variable with quotes twice, remove leading space from echo, and a little clean up.
#setlocal
#echo off
for /f "tokens=1" %%I in (computernames.txt) do call :checksz %%I
endlocal
goto :eof
:checksz
setlocal
set file=\\%1\c$\data\info.log
set min=1000
if not exist %file% endlocal && goto :eof
FOR /F "usebackq delims=" %%A IN ('%file%') DO set size=%%~zA
if %size% GEQ %min% ( echo %1>>logsizemin.txt ) ELSE ( echo %1>>logsizemax.txt )
endlocal
goto :eof
edit: updated per comments from PA and Andriy M - endlocal if the file doesn't exist, and remove \ update note.