Skip to content

Instantly share code, notes, and snippets.

@ticarpi
Created April 5, 2022 12:43
Show Gist options
  • Save ticarpi/af515e0a57b7f9422733be8e69f7df47 to your computer and use it in GitHub Desktop.
Save ticarpi/af515e0a57b7f9422733be8e69f7df47 to your computer and use it in GitHub Desktop.
@echo off
REM Title: lolcheckz.cmd
REM Version: 1.1
REM Description: A script to check local policy settings on the local machine. Does not require Powershell, but does require elevation.
REM Author: Chris Hogarth
REM Created: March 2019
REM Modified: July 2021
:switchoptions
set logoutput=""
set logdebug=""
set thirdparty=""
if "%1" == "/log" set logoutput=TRUE
if "%2" == "/log" set logoutput=TRUE
if "%1" == "/logdebug" set logdebug=TRUE
if "%2" == "/logdebug" set logdebug=TRUE
if "%1" == "/3rdparty" set thirdparty=TRUE
if "%2" == "/3rdparty" set thirdparty=TRUE
if "%logdebug%" == "TRUE" (echo on & call :LolCheckz > %computername%-debug.txt 2> NUL & echo off & goto LolCheckz)
if "%logoutput%" == "TRUE" (call :LolCheckz > %computername%-output.txt 2> NUL & goto LolCheckz)
if "%1" NEQ "" goto :LolCheckz
:optionscheck
cls
echo WARNING!
echo You do not appear to have specified any log options with this script, it is highly recommended to run with the following:
echo lolcheckz.cmd /log
echo Ideally this should also be run using the following (separately):
echo lolcheckz.cmd /logdebug
echo To enable checking of third party programs, use the following (note: this can be time consuming):
echo lolcheckz.cmd /3rdparty
set /p AREYOUSURE=Are you sure you want to continue? (Y/[N])?
if /i "%AREYOUSURE%" NEQ "Y" goto end
echo.
:LolCheckz
echo Expanding Screen
mode con cols=160 lines=2000
echo Creating TEMP folder
set TEMPDIRECTORY=TEMPCHECKSEC%RANDOM%%RANDOM%
echo %TEMPDIRECTORY%
mkdir %TEMPDIRECTORY%
echo Deleting old log if exists
if exist %computername%-log.txt del %computername%-log.txt
echo Setting default KEY variable
set KEY=NULL
echo Generating Colours config
for /F "tokens=1,2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do (set "DEL=%%a")
echo Checking process is elevated
net session >nul 2>&1
if %errorlevel% == 0 (echo Success: Administrative permissions confirmed.) else (echo Failure: Current permissions inadequate. & exit /b)
echo Checking if Windows 2003 or XP
ver | findstr /c:"Microsoft Windows [Version 5."
if errorlevel 1 (echo This system is NOT running Windows 2003 or XP & set win2003=FALSE) else (echo This system appears to be running Windows 2003 or XP & set win2003=TRUE)
echo Checking if Client or Server Operating System
wmic os get caption | findstr /v Caption > %TEMPDIRECTORY%\os.txt
set /p os= < %TEMPDIRECTORY%\os.txt
type %TEMPDIRECTORY%\os.txt | findstr Server > NUL
if errorlevel 1 (set clientorserver=Client) else (set clientorserver=Server)
:clientserverend
echo %clientorserver% - %os%
goto startchecks
REM Major functions
:log
echo. >> %computername%-log.txt
echo Test: %TEST% >> %computername%-log.txt
echo Status: %STATUS% >> %computername%-log.txt
if %KEY% == NULL set KEY="secedit.exe /export /cfg sec.txt"
echo Location: %KEY% >> %computername%-log.txt
if not "%ACTUAL%" == "" echo Expect: %EXPECTED% >> %computername%-log.txt
if not "%ACTUAL%" == "" echo Actual: "%ACTUAL%" >> %computername%-log.txt
goto :eof
:lognot
call :log
echo SHOULD NOT BE EXPECTED VALUE >> %computername%-log.txt
goto :eof
:set
set TEST=%TEST:"=%
set %TEST%=
set TEST=
set STATUS=
set EXPECTED=
set ACTUAL=
set NUMEXPECTED=
set NUMACTUAL=
set KEY=NULL
set EXCEPT=
set SEARCH=
set LOG=
set FILE=
set SHARES=
set NOT=
set EXPECTEDNESSUS=
set EXPECTEDOR=
set EXPECTEDWARN=
set NUMEXPECTEDWARN=
set NULLSID=
set windirwmi=
set pre2008r2=
set pre2012r2=
set pre2016=
set SysmaxSizeEXPECTED=
set ResetLockoutCountEXPECTED=
set replace=
set PLUGINID=
set LAPSDLL=
set applocker=
set srp=
set fDenyTSConnections=
set version=
goto :eof
:functionCompareTxtNUMATLEAST
set TEST=%1
set EXPECTED=%2
echo Expect: %EXPECTED%
type %TEMPDIRECTORY%\sec.txt | findstr %1 > %TEMPDIRECTORY%\%1.txt
set /p ACTUAL= < %TEMPDIRECTORY%\%1.txt
if "%ACTUAL%" == "" set ACTUAL=NULL
echo Actual: "%ACTUAL%"
set /a NUMEXPECTED = %EXPECTED%
set /a NUMACTUAL = %ACTUAL%
if %NUMACTUAL% GEQ %NUMEXPECTED% (call :ColourText 0a "PASS" & set STATUS=PASS) else (call :ColourText 0c "FAIL" & set STATUS=FAIL)
call :log
if not "%STATUS%" == "PASS" call :startnessustxtfinding
call :set
goto :eof
:functionCompareTxtNUMATLEASTEXCEPT
set TEST=%1
set EXPECTED=%2
set EXCEPT=%3
echo Expect: %EXPECTED%
type %TEMPDIRECTORY%\sec.txt | findstr %1 > %TEMPDIRECTORY%\%1.txt
set /p ACTUAL= < %TEMPDIRECTORY%\%1.txt
if "%ACTUAL%" == "" set ACTUAL=NULL
echo Actual: "%ACTUAL%"
set /a NUMEXPECTED = %EXPECTED%
set /a NUMACTUAL = %ACTUAL%
if "%ACTUAL%" == %EXCEPT% (call :ColourText 0a "PASS" & set STATUS=PASS) else if %NUMACTUAL% GEQ %NUMEXPECTED% (call :ColourText 0a "PASS" & set STATUS=PASS) else (call :ColourText 0c "FAIL" & set STATUS=FAIL)
call :log
if not "%STATUS%" == "PASS" call :startnessustxtfinding
call :set
goto :eof
:functionCompareTxtNUMATLEASTRANGE
set TEST=%1
set EXPECTED=%2
set EXPECTEDWARN=%3
echo Expect: %EXPECTED%
type %TEMPDIRECTORY%\sec.txt | findstr %1 > %TEMPDIRECTORY%\%1.txt
set /p ACTUAL= < %TEMPDIRECTORY%\%1.txt
if "%ACTUAL%" == "" set ACTUAL=NULL
echo Actual: "%ACTUAL%"
set /a NUMEXPECTED = %EXPECTED%
set /a NUMEXPECTEDWARN = %EXPECTEDWARN%
set /a NUMACTUAL = %ACTUAL%
if %NUMACTUAL% GEQ %NUMEXPECTED% (call :ColourText 0a "PASS" & set STATUS=PASS) else if %NUMACTUAL% GEQ %NUMEXPECTEDWARN% (call :ColourText 0e "WARN" & set STATUS=WARN) else (call :ColourText 0c "FAIL" & set STATUS=FAIL)
call :log
if not "%STATUS%" == "PASS" call :startnessustxtfinding
call :set
goto :eof
:functionCompareTxtNUMLESSTHAN
set TEST=%1
set EXPECTED=%2
echo Expect: %EXPECTED%
type %TEMPDIRECTORY%\sec.txt | findstr %1 > %TEMPDIRECTORY%\%1.txt
set /p ACTUAL= < %TEMPDIRECTORY%\%1.txt
echo Actual: "%ACTUAL%"
set /a NUMEXPECTED = %EXPECTED%
set /a NUMACTUAL = %ACTUAL%
if %NUMACTUAL% LEQ %NUMEXPECTED% (call :ColourText 0a "PASS" & set STATUS=PASS) else (call :ColourText 0c "FAIL" & set STATUS=FAIL)
call :log
if not "%STATUS%" == "PASS" call :startnessustxtfinding
call :set
goto :eof
:functionCompareTxtNUMLESSTHANORWARN
set TEST=%1
set EXPECTED=%2
echo Expect: %EXPECTED%
type %TEMPDIRECTORY%\sec.txt | findstr %1 > %TEMPDIRECTORY%\%1.txt
set /p ACTUAL= < %TEMPDIRECTORY%\%1.txt
echo Actual: "%ACTUAL%"
set /a NUMEXPECTED = %EXPECTED%
set /a NUMACTUAL = %ACTUAL%
if %NUMACTUAL% LEQ %NUMEXPECTED% (call :ColourText 0a "PASS" & set STATUS=PASS) else (call :ColourText 0e "WARN" & set STATUS=WARN)
call :log
if not "%STATUS%" == "PASS" call :startnessustxtfinding
call :set
goto :eof
:functionCompareTxtNUMLESSTHANEXCEPT
set TEST=%1
set EXPECTED=%2
set EXCEPT=%3
echo Expect: %EXPECTED%
type %TEMPDIRECTORY%\sec.txt | findstr %1 > %TEMPDIRECTORY%\%1.txt
set /p ACTUAL= < %TEMPDIRECTORY%\%1.txt
echo Actual: "%ACTUAL%"
set /a NUMEXPECTED = %EXPECTED%
set /a NUMACTUAL = %ACTUAL%
if "%ACTUAL%" == %EXCEPT% (call :ColourText 0c "FAIL" & set STATUS=FAIL) else if %NUMACTUAL% LEQ %NUMEXPECTED% (call :ColourText 0a "PASS" & set STATUS=PASS) else (call :ColourText 0c "FAIL" & set STATUS=FAIL)
call :log
if not "%STATUS%" == "PASS" call :startnessustxtfinding
call :set
goto :eof
:functionCompareTxtEXACT
set TEST=%1
set EXPECTED=%2
echo Expect: %EXPECTED%
type %TEMPDIRECTORY%\sec.txt | findstr %1 > %TEMPDIRECTORY%\%1.txt
set /p ACTUAL= < %TEMPDIRECTORY%\%1.txt
echo Actual: "%ACTUAL%"
if "%ACTUAL%" == %EXPECTED% (call :ColourText 0a "PASS" & set STATUS=PASS) else (call :ColourText 0c "FAIL" & set STATUS=FAIL)
call :log
if not "%STATUS%" == "PASS" call :startnessustxtfinding
call :set
goto :eof
:functionCompareTxtNOT
set NOT=TRUE
set TEST=%1
set EXPECTED=%2
echo Expect: NOT= %EXPECTED%
type %TEMPDIRECTORY%\sec.txt | findstr %1 > %TEMPDIRECTORY%\%1.txt
set /p ACTUAL= < %TEMPDIRECTORY%\%1.txt
echo Actual: SET= "%ACTUAL%"
if "%ACTUAL%" == %EXPECTED% (call :ColourText 0c "FAIL" & set STATUS=FAIL) else (call :ColourText 0a "PASS" & set STATUS=PASS)
call :lognot
if not "%STATUS%" == "PASS" call :startnessustxtfinding
call :set
goto :eof
:functionCompareRegEXACT
set TEST=%1
set EXPECTED=%2
set KEY=%3
echo Expect: %EXPECTED%
reg query %KEY% /v %1 | findstr /i %1 > %TEMPDIRECTORY%\%1.txt
set /p ACTUAL= < %TEMPDIRECTORY%\%1.txt
echo Actual: "%ACTUAL%"
if "%ACTUAL%" == %EXPECTED% (call :ColourText 0a "PASS" & set STATUS=PASS) else (call :ColourText 0c "FAIL" & set STATUS=FAIL)
call :log
if not "%STATUS%" == "PASS" call :startnessusregfinding
call :set
goto :eof
:functionCompareRegEXACTORNOTSET
set TEST=%1
set EXPECTED=%2
set KEY=%3
echo Expect: %EXPECTED%
reg query %KEY% /v %1 | findstr /i %1 > %TEMPDIRECTORY%\%1.txt
set /p ACTUAL= < %TEMPDIRECTORY%\%1.txt
echo Actual: "%ACTUAL%"
if "%ACTUAL%" == "" (call :ColourText 0a "PASS" & set STATUS=PASS) else if "%ACTUAL%" == %EXPECTED% (call :ColourText 0a "PASS" & set STATUS=PASS) else (call :ColourText 0c "FAIL" & set STATUS=FAIL)
call :log
if not "%STATUS%" == "PASS" call :startnessusregfinding
call :set
goto :eof
:functionCompareRegNOT
set NOT=TRUE
set TEST=%1
set EXPECTED=%2
set KEY=%3
echo Expect: NOT= %EXPECTED%
reg query %KEY% /v %1 | findstr /i %1 > %TEMPDIRECTORY%\%1.txt
set /p ACTUAL= < %TEMPDIRECTORY%\%1.txt
echo Actual: SET= "%ACTUAL%"
if "%ACTUAL%" == %EXPECTED% (call :ColourText 0c "FAIL" & set STATUS=FAIL) else (call :ColourText 0a "PASS" & set STATUS=PASS)
call :lognot
if not "%STATUS%" == "PASS" call :startnessusregfinding
call :set
goto :eof
:functionCompareAuditPolTxtEXACT
set TEST=%1
set EXPECTED=%2
set SEARCH=%3
set KEY="auditpol.exe /get /category:*"
echo Expect: %EXPECTED%
auditpol.exe /get /category:* | findstr /c:%SEARCH% > %TEMPDIRECTORY%\%TEST%.txt
set /p ACTUAL= < %TEMPDIRECTORY%\%TEST%.txt
echo Actual: "%ACTUAL%"
if "%ACTUAL%" == %EXPECTED% (call :ColourText 0a "PASS" & set STATUS=PASS) else (call :ColourText 0c "FAIL" & set STATUS=FAIL)
call :log
if not "%STATUS%" == "PASS" call :startnessusauditfinding
call :set
goto :eof
:functionCompareAuditPolTxtEXACTOR
set TEST=%1
set EXPECTED=%2
set SEARCH=%3
set EXPECTEDOR=%4
set KEY="auditpol.exe /get /category:*"
echo Expect: %EXPECTED%
auditpol.exe /get /category:* | findstr /c:%SEARCH% > %TEMPDIRECTORY%\%TEST%.txt
set /p ACTUAL= < %TEMPDIRECTORY%\%TEST%.txt
echo Actual: "%ACTUAL%"
if "%ACTUAL%" == %EXPECTED% (call :ColourText 0a "PASS" & set STATUS=PASS) else if "%ACTUAL%" == %EXPECTEDOR% (call :ColourText 0a "PASS" & set STATUS=PASS) else (call :ColourText 0c "FAIL" & set STATUS=FAIL)
call :log
if not "%STATUS%" == "PASS" call :startnessusauditfinding
call :set
goto :eof
:functionCompareAuditPolLogOnOffSubTxtEXACT
set TEST=%1
set EXPECTED=%2
set SEARCH=%3
echo Expect: %EXPECTED%
set KEY="auditpol.exe /get /subcategory:%TEST%"
auditpol.exe /get /subcategory:%TEST% | findstr /c:%TEST% | findstr /v /c:"Logon/Logoff" > %TEMPDIRECTORY%\%TEST%.txt
set /p ACTUAL= < %TEMPDIRECTORY%\%TEST%.txt
echo Actual: "%ACTUAL%"
if "%ACTUAL%" == %EXPECTED% (call :ColourText 0a "PASS" & set STATUS=PASS) else (call :ColourText 0c "FAIL" & set STATUS=FAIL)
call :log
if not "%STATUS%" == "PASS" call :startnessusauditfinding
call :set
goto :eof
:functionCompareAuditPolLogOnOffSubTxtEXACTOR
set TEST=%1
set EXPECTED=%2
set SEARCH=%3
set EXPECTEDOR=%4
echo Expect: %EXPECTED%
set KEY="auditpol.exe /get /subcategory:%TEST%"
auditpol.exe /get /subcategory:%TEST% | findstr /c:%TEST% | findstr /v /c:"Logon/Logoff" > %TEMPDIRECTORY%\%TEST%.txt
set /p ACTUAL= < %TEMPDIRECTORY%\%TEST%.txt
echo Actual: "%ACTUAL%"
if "%ACTUAL%" == %EXPECTED% (call :ColourText 0a "PASS" & set STATUS=PASS) else if "%ACTUAL%" == %EXPECTEDOR% (call :ColourText 0a "PASS" & set STATUS=PASS) else (call :ColourText 0c "FAIL" & set STATUS=FAIL)
call :log
if not "%STATUS%" == "PASS" call :startnessusauditfinding
call :set
goto :eof
:functionCompareTxtEvtNUMATLEAST
set TEST=%1
set EXPECTED=%2
set LOG=%3
set KEY="wevtutil gl %LOG% | findstr maxSize"
echo Expect: %EXPECTED%
wevtutil gl %LOG% | findstr maxSize > %TEMPDIRECTORY%\%TEST%.txt
set /p ACTUAL= < %TEMPDIRECTORY%\%TEST%.txt
echo Actual: "%ACTUAL%"
set ACTUAL=%ACTUAL:maxSize: =%
set EXPECTED=%EXPECTED:maxSize: =%
set /a NUMEXPECTED = %EXPECTED%
set /a NUMACTUAL = %ACTUAL%
if %NUMACTUAL% GEQ %NUMEXPECTED% (call :ColourText 0a "PASS" & set STATUS=PASS) else (call :ColourText 0c "FAIL" & set STATUS=FAIL)
call :log
if not "%STATUS%" == "PASS" call :startnessusauditfinding
call :set
goto :eof
:functionCompareTxtEvtRetEXACT
set TEST=%1
set EXPECTED=%2
set LOG=%3
set KEY="wevtutil gl %LOG% | findstr retention"
echo Expect: %EXPECTED%
wevtutil gl %LOG% | findstr retention > %TEMPDIRECTORY%\%TEST%.txt
set /p ACTUAL= < %TEMPDIRECTORY%\%TEST%.txt
echo Actual: "%ACTUAL%"
if "%ACTUAL%" == %EXPECTED% (call :ColourText 0a "PASS" & set STATUS=PASS) else (call :ColourText 0c "FAIL" & set STATUS=FAIL)
call :log
if not "%STATUS%" == "PASS" call :startnessusauditfinding
call :set
goto :eof
REM Colours Function
:ColourText
cd %TEMPDIRECTORY%
<nul set /p ".=%DEL%" > "%~2"
echo|set /p="Status: "
findstr /v /a:%1 /R "^$" "%~2" nul
echo.
del "%~2" > nul 2>&1
cd ..
goto :eof
REM Nessus Canopy Generation
:startnessusheader
echo ^<?xml version="1.0" ?^> >%computername%.nessus
echo ^<LolCheckz^> >>%computername%.nessus
echo ^<Report name="%computername%" xmlns:cm="http://www.nessus.org/cm" ^> >>%computername%.nessus
echo ^<ReportHost name="%computername%"^>^<HostProperties^> >>%computername%.nessus
echo ^</HostProperties^> >>%computername%.nessus
:endnessusheader
goto :eof
:startnessustxtfinding
set PLUGINID=%TEST:"=%
echo ^<ReportItem port="0" svc_name="" protocol="" severity="0" pluginID="Lolz_%PLUGINID%" pluginName=%TEST% pluginFamily="Windows"^> >>%computername%.nessus
echo ^<description^>There's an issue with the %TEST% settings on the host. Please modify the settings for %TEST%^</description^> >>%computername%.nessus
echo ^<plugin_type^>remote^</plugin_type^> >>%computername%.nessus
echo ^<risk_factor^>Low^</risk_factor^> >>%computername%.nessus
echo ^<solution^>CCS Recommends fixing the issues with %TEST% on the host^</solution^> >>%computername%.nessus
echo ^<synopsis^>There's an issue with the %TEST% settings on the host^</synopsis^> >>%computername%.nessus
echo ^<plugin_output^>The following information has been gathered: >>%computername%.nessus
echo. >>%computername%.nessus
echo Location: %KEY% >>%computername%.nessus
echo Expect: %EXPECTED% >>%computername%.nessus
echo Actual: "%ACTUAL%" >>%computername%.nessus
echo Status: %STATUS% >>%computername%.nessus
if "%NOT%" == "TRUE" echo SHOULD NOT BE EXPECTED VALUE >>%computername%.nessus
echo ^</plugin_output^> >>%computername%.nessus
echo ^</ReportItem^> >>%computername%.nessus
:endnessusfinding
goto :eof
:startnessusregfinding
set PLUGINID=%TEST:"=%
set EXPECTED=%EXPECTED:"=%
set ACTUAL=%ACTUAL: = %
set EXPECTED=%EXPECTED: = %
if "%ACTUAL%" == " = " set ACTUAL= Not Set
echo ^<ReportItem port="0" svc_name="" protocol="" severity="0" pluginID="Lolz_%PLUGINID%" pluginName=%TEST% pluginFamily="Windows"^> >>%computername%.nessus
echo ^<description^>There's an issue with the %TEST% settings on the host. Please modify the settings for %TEST%^</description^> >>%computername%.nessus
echo ^<plugin_type^>remote^</plugin_type^> >>%computername%.nessus
echo ^<risk_factor^>Low^</risk_factor^> >>%computername%.nessus
echo ^<solution^>CCS Recommends fixing the issues with %TEST% on the host^</solution^> >>%computername%.nessus
echo ^<synopsis^>There's an issue with the %TEST% settings on the host^</synopsis^> >>%computername%.nessus
echo ^<plugin_output^>The following information has been gathered: >>%computername%.nessus
echo. >>%computername%.nessus
echo Location: %KEY% >>%computername%.nessus
echo Expect:%EXPECTED% >>%computername%.nessus
echo Actual:%ACTUAL% >>%computername%.nessus
echo Status: %STATUS% >>%computername%.nessus
if "%NOT%" == "TRUE" echo SHOULD NOT BE EXPECTED VALUE >>%computername%.nessus
echo ^</plugin_output^> >>%computername%.nessus
echo ^</ReportItem^> >>%computername%.nessus
:endnessusfinding
goto :eof
:startnessusauditfinding
set PLUGINID=%TEST:"=%
set EXPECTED=%EXPECTED:"=%
set ACTUAL=%ACTUAL: = %
set EXPECTED=%EXPECTED: = %
echo ^<ReportItem port="0" svc_name="" protocol="" severity="0" pluginID="Lolz_%PLUGINID%" pluginName=%TEST% pluginFamily="Windows"^> >>%computername%.nessus
echo ^<description^>There's an issue with the %TEST% settings on the host. Please modify the settings for %TEST%^</description^> >>%computername%.nessus
echo ^<plugin_type^>remote^</plugin_type^> >>%computername%.nessus
echo ^<risk_factor^>Low^</risk_factor^> >>%computername%.nessus
echo ^<solution^>CCS Recommends fixing the issues with %TEST% on the host^</solution^> >>%computername%.nessus
echo ^<synopsis^>There's an issue with the %TEST% settings on the host^</synopsis^> >>%computername%.nessus
echo ^<plugin_output^>The following information has been gathered: >>%computername%.nessus
echo. >>%computername%.nessus
echo Location: %KEY% >>%computername%.nessus
echo Expect:%EXPECTED% >>%computername%.nessus
echo Actual:%ACTUAL% >>%computername%.nessus
echo Status: %STATUS% >>%computername%.nessus
if "%NOT%" == "TRUE" echo SHOULD NOT BE EXPECTED VALUE >>%computername%.nessus
echo ^</plugin_output^> >>%computername%.nessus
echo ^</ReportItem^> >>%computername%.nessus
:endnessusfinding
goto :eof
:startnessusfindingreadtxt
if "%NULLSID%" == "TRUE" call :startaccountdomainnotfoundstringreplace
set PLUGINID=%TEST:"=%
echo ^<ReportItem port="0" svc_name="" protocol="" severity="0" pluginID="Lolz_%PLUGINID%" pluginName=%TEST% pluginFamily="Windows"^> >>%computername%.nessus
echo ^<description^>There's an issue with the %TEST% settings on the host. Please modify the settings for %TEST%^</description^> >>%computername%.nessus
echo ^<plugin_type^>remote^</plugin_type^> >>%computername%.nessus
echo ^<risk_factor^>Low^</risk_factor^> >>%computername%.nessus
echo ^<solution^>CCS Recommends fixing the issues with %TEST% on the host^</solution^> >>%computername%.nessus
echo ^<synopsis^>There's an issue with the %TEST% settings on the host^</synopsis^> >>%computername%.nessus
echo ^<plugin_output^>The following information has been gathered: >>%computername%.nessus
echo. >>%computername%.nessus
echo Location: %KEY% >>%computername%.nessus
if not "%STATUS%" == "CHECK OUTPUT" echo Expect: %EXPECTED% >>%computername%.nessus
if not "%STATUS%" == "CHECK OUTPUT" echo Actual: "%ACTUAL%" >>%computername%.nessus
echo Status: %STATUS% >>%computername%.nessus
if "%NOT%" == "TRUE" echo SHOULD NOT BE EXPECTED VALUE >>%computername%.nessus
type %FILE% >>%computername%.nessus
echo ^</plugin_output^> >>%computername%.nessus
echo ^</ReportItem^> >>%computername%.nessus
:endnessusfindingreadtxt
goto :eof
:startnessusfooter
echo ^</ReportHost^> >>%computername%.nessus
echo ^</Report^> >>%computername%.nessus
echo ^</LolCheckz^> >>%computername%.nessus
:endnessusfooter
goto :eof
:startaccountdomainnotfoundstringreplace
set "search=^<Account Domain not found^>"
set "replace=^&lt;Account Domain not found^&gt;"
setlocal enableextensions disabledelayedexpansion
set "textFile=%FILE%"
for /f "delims=" %%i in ('type "%textFile%" ^& break ^> "%textFile%" ') do (
set "line=%%i"
setlocal enabledelayedexpansion
>>"%textFile%" echo(!line:%search%=%replace%!
endlocal
)
:endaccountdomainnotfoundstringreplace
goto :eof
:startchecks
echo Checking security configuration of local computer
echo Generating .nessus header for Canopy
call :startnessusheader
echo Exporting Security Policy to File
secedit.exe /export /cfg %TEMPDIRECTORY%\sec.txt > NUL
echo.
REM Checking if domain joined
wmic computersystem get domainrole | findstr -i -v DomainRole > %TEMPDIRECTORY%\domainrole.txt
set /p DomainRole= < %TEMPDIRECTORY%\domainrole.txt
echo.
echo ====OS:
echo.
echo Hostname:
wmic computersystem get name | findstr /v Name
echo NOTES: Provides the hostname of the system
echo IP Addreses:
wmic nicconfig get ipaddress | findstr {
echo NOTES: Provides a list of IPv4 and IPv6 IP addresses on the system
echo.
echo OS Version and Service Pack Level:
wmic os get caption,version,ServicePackMajorVersion | findstr /v Caption
echo NOTES: Provides the name and version of Windows installed on the host
echo.
echo Installed Patches:
wmic qfe | findstr /v Caption
echo NOTES: Treat the above check with caution. On some systems (eg. Windows 10) nothing is reported for the above query even when additonal patches have been installed)
echo.
echo Anti-Virus Installed:
wmic /Namespace:\\root\SecurityCenter2 Path AntiVirusProduct Get displayName | findstr -v displayName
echo NOTES: Treat the above check with caution. On some systems (eg. Server 2016) nothing is reported for the above query even if Windows Defender is installed)
echo.
echo ====Password policy (local):
echo.
echo Password history (KB262):
call :functionCompareTxtNUMATLEASTRANGE "PasswordHistorySize" "PasswordHistorySize = 24" "PasswordHistorySize = 10"
echo NOTES: Should be at least expected value
echo.
echo Maximum password age (KB262):
call :functionCompareTxtNUMLESSTHANORWARN "MaximumPasswordAge" "MaximumPasswordAge = 0"
echo NOTES: Should be at less than or equal to expected value, otherwise warn. Password expiration no longer recommended.
echo.
echo Minimum password age (KB262):
call :functionCompareTxtEXACT "MinimumPasswordAge" "MinimumPasswordAge = 1"
echo NOTES: Should be expected value
echo.
echo Minimum password length (KB262):
call :functionCompareTxtNUMATLEASTRANGE "MinimumPasswordLength" "MinimumPasswordLength = 12" "MinimumPasswordLength = 8"
echo NOTES: Should be at least expected value. Warn for less than 12. Fail for less than 8.
echo.
echo Password complexity (KB262):
call :functionCompareTxtNUMLESSTHANORWARN "PasswordComplexity" "PasswordComplexity = 0"
echo NOTES: Should be expected value. Password complexity enforcement no longer recommended.
echo.
echo Store Passwords using Reversible Encryption (KB262):
call :functionCompareTxtEXACT "ClearTextPassword" "ClearTextPassword = 0"
echo NOTES: Should be expected value
echo.
echo.
echo ====Account lockout policy (local):
echo.
echo Lockout duration (KB263):
call :functionCompareTxtNUMATLEASTEXCEPT "LockoutDuration" "LockoutDuration = 15" "LockoutDuration = -1"
echo NOTES: Should be at least expected value, or alternatively -1.
echo.
echo Lockout threshold (KB263):
call :functionCompareTxtNUMLESSTHANEXCEPT "LockoutBadCount" "LockoutBadCount = 15" "LockoutBadCount = 0"
echo NOTES: Should be less than or equal to expected value, but not 0
echo.
echo Account reset time (KB263):
set ResetLockoutCountEXPECTED=ResetLockoutCount = 15
call :functionCompareTxtNUMATLEAST "ResetLockoutCount" "ResetLockoutCount = 15"
echo NOTES: Should be at least expected value
echo.
echo.
echo ====Security Options (local):
echo.
echo Rename Administrator account (KB309):
call :functionCompareTxtNOT "NewAdministratorName" "NewAdministratorName = "Administrator""
echo NOTES: Should NOT be expected value
echo.
echo Rename Guest account:
call :functionCompareTxtNOT "NewGuestName" "NewGuestName = "Guest""
echo NOTES: Should NOT be expected value
echo.
echo Administrator account status
call :functionCompareTxtEXACT "EnableAdminAccount" "EnableAdminAccount = 0"
echo NOTES: Should be expected value
net user administrator | findstr active
echo NOTES: Account should be disabled, this is the actual current value (as opposed to policy settings)
echo.
echo Guest account status
call :functionCompareTxtEXACT "EnableGuestAccount" "EnableGuestAccount = 0"
echo NOTES: Should be expected value
net user guest | findstr active
echo NOTES: NOTES: Account should be disabled, this is the actual current value (as opposed to policy settings)
echo.
echo Network Access: Allow Anonymous SID/Name Translation:
call :functionCompareTxtEXACT "LSAAnonymousNameLookup" "LSAAnonymousNameLookup = 0"
echo NOTES: Should be expected value
echo.
echo Interactive Logon: Do Not Display Last User Name (KB308):
call :functionCompareRegEXACT "dontdisplaylastusername" " dontdisplaylastusername REG_DWORD 0x1" "HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System"
echo NOTES: Should be expected value
echo.
echo Interactive Logon: Do Not require CTRL + ALT + DEL:
call :functionCompareRegNOT "DisableCAD" " DisableCAD REG_DWORD 0x1" "HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System"
echo NOTES: This is often not set, so may error. This value should NOT be set to 0x1
echo.
echo Interactive Logon: Number of Previous Logons to Cache (KB282):
call :functionCompareRegEXACT "CachedLogonsCount" " CachedLogonsCount REG_SZ 0" "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon"
echo NOTES: Should be expected value
echo.
echo Interactive Logon: Message Text for Users Attempting to Log On (KB467):
call :functionCompareRegNOT "legalnoticetext" " legalnoticetext REG_SZ " "HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System"
echo NOTES: Should contain some value
echo.
echo Interactive Logon: Message Title for Users Attempting to Log On (KB467):
call :functionCompareRegNOT "legalnoticecaption" " legalnoticecaption REG_SZ " "HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System"
echo NOTES: Should contain some value
echo.
echo Network access: Restrict anonymous access to Named Pipes and Shares (KB81):
call :functionCompareRegEXACT "RestrictNullSessAccess" " RestrictNullSessAccess REG_DWORD 0x1" "HKLM\System\CurrentControlSet\Services\LanManServer\Parameters"
echo NOTES: Should be expected value
echo.
echo Network Access: Shares that can be accessed anonymously:
call :functionCompareRegEXACTORNOTSET "NullSessionShares" " NullSessionShares REG_MULTI_SZ " "HKLM\System\CurrentControlSet\Services\LanManServer\Parameters"
echo NOTES: This is often not set, so may error. This value should always be empty
echo.
echo Network Access: Do not allow Anonymous Enumeration of SAM Accounts (KB81):
call :functionCompareRegEXACT "RestrictAnonymous" " RestrictAnonymous REG_DWORD 0x1" "HKLM\System\CurrentControlSet\Control\Lsa"
echo NOTES: Should be expected value
echo.
echo Network Access: Do not allow Anonymous Enumeration of SAM Accounts and Shares:
call :functionCompareRegEXACT "RestrictAnonymousSAM" " RestrictAnonymousSAM REG_DWORD 0x1" "HKLM\System\CurrentControlSet\Control\Lsa"
echo NOTES: Should be expected value
echo.
echo Network Security: Do not store LAN Manager password hash value on next password change (KB510):
call :functionCompareRegEXACT "NoLMHash" " NoLMHash REG_DWORD 0x1" "HKLM\System\CurrentControlSet\Control\Lsa"
echo NOTES: Should be expected value
echo.
echo Network Security: LAN Manager Authentication Level (KB436):
REM NONFUNCTION
set TEST="LmCompatibilityLevel"
set EXPECTED=" LmCompatibilityLevel REG_DWORD 0x5"
set KEY=HKLM\System\CurrentControlSet\Control\Lsa
echo Expect: %EXPECTED%
reg query %KEY% /v %TEST% | findstr /i %TEST% > %TEMPDIRECTORY%\%TEST%.txt
set /p ACTUAL= < %TEMPDIRECTORY%\%TEST%.txt
echo Actual: "%ACTUAL%"
if "%ACTUAL%" == %EXPECTED% (call :ColourText 0a "PASS" & set STATUS=PASS) else if "%ACTUAL%" ==" LmCompatibilityLevel REG_DWORD 0x4" (call :ColourText 0e "WARN" & set STATUS=WARN) else if "%ACTUAL%" ==" LmCompatibilityLevel REG_DWORD 0x3" (call :ColourText 0e "WARN" & set STATUS=WARN) else (call :ColourText 0c "FAIL" & set STATUS=FAIL)
call :log
if not "%STATUS%" == "PASS" call :startnessusregfinding
call :set
echo NOTES: Should be at least 0x3, ideally 0x5
echo.
echo.
echo ====Auditing (KB438):
echo.
echo Audit account logon events:
call :functionCompareTxtNUMATLEAST "AuditAccountLogon" "AuditAccountLogon = 3"
echo NOTES: Should be at least expected value
echo.
echo Audit account management:
call :functionCompareTxtNUMATLEAST "AuditAccountManage" "AuditAccountManage = 3"
echo NOTES: Should be at least expected value
echo.
echo Audit directory service:
call :functionCompareTxtNUMATLEAST "AuditDSAccess" "AuditDSAccess = 3"
echo NOTES: Should be at least expected value
echo.
echo Audit logon events:
call :functionCompareTxtNUMATLEAST "AuditLogonEvents" "AuditLogonEvents = 3"
echo NOTES: Should be at least expected value
echo.
echo Audit object access:
call :functionCompareTxtNUMATLEAST "AuditObjectAccess" "AuditObjectAccess = 3"
echo NOTES: Should be at least expected value
echo.
echo Audit policy change:
call :functionCompareTxtNUMATLEAST "AuditPolicyChange" "AuditPolicyChange = 3"
echo NOTES: Should be at least expected value
echo.
echo Audit privilege use
call :functionCompareTxtNUMATLEAST "AuditPrivilegeUse" "AuditPrivilegeUse = 2"
echo NOTES: Should be at least expected value
echo.
echo Audit process tracking:
call :functionCompareTxtNUMATLEAST "AuditProcessTracking" "AuditProcessTracking = 2"
echo NOTES: Should be at least expected value
echo.
echo Audit system events:
call :functionCompareTxtNUMATLEAST "AuditSystemEvents" "AuditSystemEvents = 2"
echo NOTES: Should be at least expected value
echo.
if %win2003% EQU TRUE goto :skip2003
echo.
echo ====Advanced Auditing (KB438):
echo.
echo Audit Policy: System: IPsec Driver:
call :functionCompareAuditPolTxtEXACT "IPSecDriver" " IPsec Driver Success and Failure" "IPsec Driver"
echo NOTES: Should be at least expected value
echo.
echo Audit Policy: System: Security State Change:
call :functionCompareAuditPolTxtEXACT "SecurityStateChange" " Security State Change Success and Failure" "Security State Change"
echo NOTES: Should be at least expected value
echo.
echo Audit Policy: System: Security System Extension:
call :functionCompareAuditPolTxtEXACT "SecuritySystemExtension" " Security System Extension Success and Failure" "Security System Extension"
echo NOTES: Should be at least expected value
echo.
echo Audit Policy: System: System Integrity:
call :functionCompareAuditPolTxtEXACT "SystemIntegrity" " System Integrity Success and Failure" "System Integrity"
echo NOTES: Should be at least expected value
echo.
echo Audit Policy: Logon-Logoff: Logoff:
call :functionCompareAuditPolLogOnOffSubTxtEXACTOR "Logoff" " Logoff Success" "Logoff" " Logoff Success and Failure"
echo NOTES: Should be at least expected value
echo.
echo Audit Policy: Logon-Logoff: Logon:
call :functionCompareAuditPolLogOnOffSubTxtEXACT "Logon" " Logon Success and Failure" "Logon"
echo NOTES: Should be at least expected value
echo.
echo Audit Policy: Logon-Logoff: Special Logon:
call :functionCompareAuditPolTxtEXACTOR "SpecialLogon" " Special Logon Success" "Special Logon" " Special Logon Success and Failure"
echo NOTES: Should be at least expected value
echo.
echo Audit Policy: Object Access: File System:
call :functionCompareAuditPolTxtEXACTOR "FileSystem" " File System Failure" "File System" " File System Success and Failure"
echo NOTES: Should be at least expected value
echo.
echo Audit Policy: Object Access: Registry:
call :functionCompareAuditPolTxtEXACTOR "Registry" " Registry Failure" "Registry" " Registry Success and Failure"
echo NOTES: Should be at least expected value
echo.
echo Audit Policy: Privilege Use: Sensitive Privilege Use:
REM Filthy fix here by adding 2 spaces to 3rd parameter, to avoid it finding 'Non Sensitive Privilege Use' first. It works, so who cares :)
call :functionCompareAuditPolTxtEXACT "SensitivePrivilegeUse" " Sensitive Privilege Use Success and Failure" " Sensitive Privilege Use"
echo NOTES: Should be at least expected value
echo.
echo Audit Policy: Detailed Tracking: Process Creation:
call :functionCompareAuditPolTxtEXACTOR "ProcessCreation" " Process Creation Success" "Process Creation" " Process Creation Success and Failure"
echo NOTES: Should be at least expected value
echo.
echo Audit Policy: Policy Change: Audit Policy Change:
call :functionCompareAuditPolTxtEXACT "AuditPolicyChange" " Audit Policy Change Success and Failure" "Audit Policy Change"
echo NOTES: Should be at least expected value
echo.
echo Audit Policy: Policy Change: Authentication Policy Change:
call :functionCompareAuditPolTxtEXACTOR "AuthenticationPolicyChange" " Authentication Policy Change Success" "Authentication Policy Change" " Authentication Policy Change Success and Failure"
echo NOTES: Should be at least expected value
echo.
echo Audit Policy: Account Management: Computer Account Management:
call :functionCompareAuditPolTxtEXACT "ComputerAccountManagement" " Computer Account Management Success and Failure" "Computer Account Management"
echo NOTES: Should be at least expected value
echo.
echo Audit Policy: Account Management: Other Account Management Events:
call :functionCompareAuditPolTxtEXACT "Other Account Management Events" " Other Account Management Events Success and Failure" "Other Account Management Events"
echo NOTES: Should be at least expected value
echo.
echo Audit Policy: Account Management: Security Group Management
call :functionCompareAuditPolTxtEXACT "SecurityGroupManagement" " Security Group Management Success and Failure" "Security Group Management"
echo NOTES: Should be at least expected value
echo.
echo Audit Policy: Account Management: User Account Management:
call :functionCompareAuditPolTxtEXACT "UserAccountManagement" " User Account Management Success and Failure" "User Account Management"
echo NOTES: Should be at least expected value
echo.
echo Audit Policy: Account Logon: Credential Validation:
call :functionCompareAuditPolTxtEXACT "CredentialValidation" " Credential Validation Success and Failure" "Credential Validation"
echo NOTES: Should be at least expected value
echo.
echo.
echo ====Event Logging:
echo.
echo Application Event Log Maximum Size:
call :functionCompareTxtEvtNUMATLEAST "AppmaxSize" " maxSize: 16777216" Application
echo NOTES: Value should be at least the value of maxSize
echo.
echo Application Log Retention Method:
call :functionCompareTxtEvtRetEXACT "AppLogRetention" " retention: false" Application
echo NOTES: Retention should be false to ensure event log rollover
echo.
echo Security Event Log Maximum Size (KB449):
call :functionCompareTxtEvtNUMATLEAST "SecmaxSize" " maxSize: 83886080" Security
echo NOTES: Value should be at least the value of maxSize
echo.
echo Security Log Retention Method:
call :functionCompareTxtEvtRetEXACT "SecLogRetention" " retention: false" Security
echo NOTES: Retention should be false to ensure event log rollover
echo.
echo System Event Log Maximum Size:
set SysmaxSizeEXPECTED= maxSize: 16777216
call :functionCompareTxtEvtNUMATLEAST "SysmaxSize" " maxSize: 16777216" System
echo NOTES: Value should be at least the value of maxSize
echo.
echo System Log Retention Method:
call :functionCompareTxtEvtRetEXACT "SysLogRetention" " retention: false" System
echo NOTES: Retention should be false to ensure event log rollover
echo.
echo ====Event Log forwarding (KB468):
REM NONFUNCTION
set TEST="eventlogforward"
SET KEY="sc query Wecsvc | findstr STATE"
set EXPECTED=" STATE : 4 RUNNING "
echo Expect: %EXPECTED%
sc query Wecsvc | findstr STATE > %TEMPDIRECTORY%\%TEST%.txt
set /p ACTUAL= < %TEMPDIRECTORY%\%TEST%.txt
echo Actual: "%ACTUAL%"
if "%ACTUAL%" == %EXPECTED% (call :ColourText 0a "PASS" & set STATUS=PASS) else (call :ColourText 0e "WARN" & set STATUS=WARN)
call :log
if not "%STATUS%" == "PASS" call :startnessusauditfinding
call :set
echo NOTES: Basic check to see if event logs are forwarded to collector or SIEM. This doesn't check 3rd party solutions
echo NOTES: This only checks whether the forwarder service is running, it doesn't go deeper than that
:skip2003
echo.
REM NONFUNCTION
echo ====Group Memberships (KB232):
set TEST="localadmins"
set FILE=%TEMPDIRECTORY%\localadmins.txt
set KEY="net localgroup Administrators"
set EXPECTED=""
echo.
echo Local Accounts and Groups:
net localgroup Administrators | findstr /v /c:"Alias name" /c:"Comment" /c:"Members" /c:"-------------" /c:"The command completed successfully." > %FILE%
type %FILE%
REM TODO: CHECK ACCOUNTS IF ACTIVE, MAYBE USE WMI? ALSO SHOULD CHECK DOMAIN USERS IF IN DOMAIN
(call :ColourText 09 "CHECK OUTPUT" & set STATUS=CHECK OUTPUT)
call :log
if not "%STATUS%" == "PASS" call :startnessusfindingreadtxt
call :set
echo NOTES: This currently does not check domain users for active accounts
echo.
echo.
echo ====Shares:
REM NONFUNCTION
REM TODO: NOT CHECKING SHARES WITH SPACES IN PATH DUE TO ISSUES WITH WMIC OUTPUT
echo.
echo ====Shares and Permissions (KB519):
set TEST="sharesandpermissions"
set FILE=%TEMPDIRECTORY%\sharesoutput.txt
set KEY="wmic share get Name,Path"
set NULLSID=TRUE
set EXPECTED=""
wmic share WHERE "NOT Caption like 'Remote Admin' AND NOT Caption like 'Default share' AND NOT Caption like 'Remote IPC' AND NOT Path like '%% %%'" get Name,path | findstr /v Name > %TEMPDIRECTORY%\sharestemp.txt
type %TEMPDIRECTORY%\sharestemp.txt | findstr . > %TEMPDIRECTORY%\shares.txt
for /f "tokens=1,2" %%a in (%TEMPDIRECTORY%\shares.txt) do echo Share Name: %%a >> %FILE% & cacls %%b >> %FILE% & echo. >> %FILE%
set /p SHARES= < %TEMPDIRECTORY%\shares.txt
echo.
type %FILE%
if "%SHARES%" == "" (call :ColourText 0a "PASS" & set STATUS=PASS) else (call :ColourText 09 "CHECK OUTPUT" & set STATUS=CHECK OUTPUT)
call :log
if not "%STATUS%" == "PASS" call :startnessusfindingreadtxt
call :set
echo NOTES: Check share NTFS and share permissions for weak ACLs. Ideally this value will be empty
echo.
echo ====Permissions:
if exist %systemroot%\system32\icacls.exe (set acls=icacls.exe) else (set acls==cacls.exe)
REM NONFUNCTION
echo.
echo PATH Permissions (KB470):
set TEST="pathpermissions"
set FILE=%TEMPDIRECTORY%\pathperms.txt
set KEY="cacls [paths]"
set NULLSID=TRUE
set EXPECTED=""
for %%A in ("%path:;=";"%") do cacls "%%~A" >> %FILE%
type %FILE%
(call :ColourText 09 "CHECK OUTPUT" & set STATUS=CHECK OUTPUT)
call :log
if not "%STATUS%" == "PASS" call :startnessusfindingreadtxt
call :set
echo NOTES: Check for weak permissions on folders in PATH variable
echo .
echo Drive Permissions (KB516):
set TEST="drivepermissions"
set FILE=%TEMPDIRECTORY%\driveperms.txt
set KEY="%acls% [drive]:\"
set NULLSID=TRUE
set EXPECTED=""
for %%B in (A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z) do (if exist %%B:\ (%acls% %%B:\ >> %FILE%))
type %FILE%
echo.
(call :ColourText 09 "CHECK OUTPUT" & set STATUS=CHECK OUTPUT)
call :log
if not "%STATUS%" == "PASS" call :startnessusfindingreadtxt
call :set
echo NOTES: Check for weak permissions on drive root folder
echo.
echo.
echo ====Firewall (KB237):
REM NONFUNCTION
set TEST="windowsfirewall"
set FILE=%TEMPDIRECTORY%\windowsfirewall.txt
set KEY="netsh advfirewall monitor show firewall | findstr /c:Profile /c:State | findstr -v Stateful"
set EXPECTED="State ON"
echo.
echo Firewall status:
echo Expect: State ON
netsh advfirewall monitor show firewall | findstr /c:Profile /c:State | findstr -v Stateful > %FILE%
echo.>> %FILE%
echo Active Profile(s): >> %FILE%
netsh advfirewall monitor show current | findstr /v /c:Ok. /c:- | findstr . >> %FILE%
type %FILE%
echo.
findstr OFF %FILE% > nul
if errorlevel 1 (call :ColourText 0a "PASS" & set STATUS=PASS) else (call :ColourText 0c "FAIL" & set STATUS=FAIL & set ACTUAL=State OFF)
call :log
if not "%STATUS%" == "PASS" call :startnessusfindingreadtxt
call :set
echo NOTES: Firewall Should be enabled for all profiles, double check with 'wf.msc'
echo.
echo.
echo ======WSUS Settings (KB305):
REM NONFUNCTION
set TEST="WSUS"
set FILE=%TEMPDIRECTORY%\WSUS.txt
SET KEY="HKLM\Software\Policies\Microsoft\Windows\WindowsUpdate"
set EXPECTED=""
echo.
echo ====WSUS status:
reg query "HKLM\Software\Policies\Microsoft\Windows\WindowsUpdate" | findstr /v /i /c:"WindowsUpdate\AU" > %FILE%
type %FILE%
findstr WindowsUpdate %FILE% > NUL
if %errorlevel% == 0 (call :ColourText 0a "PASS" & set STATUS=PASS) else (call :ColourText 0e "CHECK OUTPUT" & set STATUS=CHECK OUTPUT)
call :log
if not "%STATUS%" == "PASS" echo Host does not appear to be using WSUS
call :set
echo.
echo ====WSUS Using HTTPS:
set TEST="WSUSHTTPS"
set FILE=%TEMPDIRECTORY%\WSUS.txt
SET KEY="HKLM\Software\Policies\Microsoft\Windows\WindowsUpdate"
set EXPECTED=""
findstr /c:"http://" %FILE%
if errorlevel 1 (call :ColourText 0a "PASS" & set STATUS=PASS) else (call :ColourText 0c "FAIL" & set STATUS=FAIL & set EXPECTED="https" & set ACTUAL=http)
call :log
if not "%STATUS%" == "PASS" call :startnessusfindingreadtxt
call :set
echo NOTES: Keys should be present if using WSUS. WSUS server should be HTTPS
echo.
echo.
echo ====WSUS Service Running:
set TEST="WSUSDisabled"
set FILE=%TEMPDIRECTORY%\WSUSDisabled.txt
SET KEY="wmic service where 'name like "wuauserv"' get startmode"
set EXPECTED="NOT Disabled"
wmic service where 'name like "wuauserv"' get startmode | findstr -v StartMode | findstr . > %FILE%
findstr /v Disabled %FILE%
if %errorlevel% == 0 (call :ColourText 0a "PASS" & set STATUS=PASS) else (call :ColourText 0c "FAIL" & set STATUS=FAIL & set ACTUAL=Disabled)
call :log
if not "%STATUS%" == "PASS" call :startnessusfindingreadtxt
call :set
echo NOTES: The wuauserv service should NOT be disabled
echo.
echo ====IIS Passwords (KB631):
set FILE=%TEMPDIRECTORY%\IISPasswords.txt
set TEST="IISPasswords"
set KEY="%systemroot%\system32\inetsrv\appcmd.exe list [apppool/site/vdir] /text:*"
set EXPECTED=""
if exist %systemroot%\system32\inetsrv\appcmd.exe (
echo.
REM NONFUNCTION
echo.
%systemroot%\system32\inetsrv\appcmd.exe list apppool /text:* | findstr "userName password" > %FILE%
%systemroot%\system32\inetsrv\appcmd.exe list site /text:* | findstr "userName password" >> %FILE%
%systemroot%\system32\inetsrv\appcmd.exe list vdir /text:* | findstr "userName password" >> %FILE%
type %FILE%
(call :ColourText 09 "CHECK OUTPUT" & set STATUS=CHECK OUTPUT)
call :log
if not "%STATUS%" == "PASS" call :startnessusfindingreadtxt
echo NOTES: Check for domain user passwords that could be used elsewhere
echo.) else (
echo.
echo IIS Tools not found
call :ColourText 0a "PASS"
echo.)
call :set
echo ====IIS Sites Permissions (KB518):
set TEST="IISPermissions"
set FILE=%TEMPDIRECTORY%\IISPermissions.txt
set KEY="cacls [paths]"
set NULLSID=TRUE
set EXPECTED=""
if exist %systemroot%\system32\inetsrv\appcmd.exe (
echo.
REM NONFUNCTION
echo.
echo Listing Sites:
echo.
%systemroot%\system32\inetsrv\appcmd.exe list app /xml | %systemroot%\system32\inetsrv\appcmd.exe list vdir /in /text:APP.NAME
echo.
echo Getting Permissions:
echo.
%systemroot%\system32\inetsrv\appcmd.exe list app /xml | %systemroot%\system32\inetsrv\appcmd.exe list vdir /in /text:physicalPath > %TEMPDIRECTORY%\sitespaths.txt
for /f "tokens=*" %%D in (%TEMPDIRECTORY%\sitespaths.txt) do (echo cacls "%%D" >> %TEMPDIRECTORY%\caclssites.cmd)
call %TEMPDIRECTORY%\caclssites.cmd > %FILE%
type %FILE%
(call :ColourText 09 "CHECK OUTPUT" & set STATUS=CHECK OUTPUT)
call :log
if not "%STATUS%" == "PASS" call :startnessusfindingreadtxt
echo NOTES: Check for weak permissions, such as 'Users' group present
echo.) else (
echo.
echo IIS Tools not found
call :ColourText 0a "PASS"
echo.)
call :set
echo.
echo ====Unquoted Service Paths (KB222):
REM NONFUNCTION
set TEST="unquotedservicepaths"
set FILE=%TEMPDIRECTORY%\unquotedservicepaths.txt
set KEY="wmic service"
set EXPECTED=""
echo.
set windirwmi=%windir:\=\\%
wmic service WHERE "NOT PathName like '%%PROGRA~%%\\%%' AND NOT PathName like '"%%"%%' AND PathName like '%% %%' AND NOT PathName like '%windirwmi%\\%%'" get name,displayname,pathname | findstr /v DisplayName | findstr /v DisplayName > %FILE%
findstr ":" %FILE%
if errorlevel 1 (call :ColourText 0a "PASS" & set STATUS=PASS) else (call :ColourText 0c "FAIL" & set STATUS=FAIL & set EXPECTED="No Services should be listed" & set ACTUAL=Services listed)
call :log
if not "%STATUS%" == "PASS" call :startnessusfindingreadtxt
call :set
echo NOTES: No services should be listed here
echo.
echo ====WDigest Registry Key (KB504):
REM check for presence of wdigest key set to 1 = fail
call :functionCompareRegNOT "UseLogonCredential" " UseLogonCredential REG_DWORD 0x1" "HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest"
REM if Pre2012r2, check if key set to 0x0
for /f %%i in ('wmic os get version ^| findstr . ^| findstr /v Version') do set version=%%i
echo %version% | findstr "10 6.3" > NUL
if errorlevel 1 (set pre2012r2=true) else (set pre2012r2=false)
if %pre2012r2% == true call :functionCompareRegEXACT "UseLogonCredential" " UseLogonCredential REG_DWORD 0x0" "HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest"
echo NOTES: If before Windows 2012r2/Windows 8.1, key should be present and set to 0x0. Also requires KB2871997
echo.
echo ====AlwaysInstallElevated Registry Key:
call :functionCompareRegEXACTORNOTSET "AlwaysInstallElevated" " AlwaysInstallElevated REG_DWORD 0x0" "HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer"
echo NOTES: Should always be empty, so normally this check will error. Note only the HKLM key has been checked for this issue.
echo.
echo ====Remote Desktop NLA (KB422):
REM PARTIAL NONFUNCTION
reg query "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections | findstr /i fDenyTSConnections > %TEMPDIRECTORY%\fDenyTSConnections.txt
set /p fDenyTSConnections= < %TEMPDIRECTORY%\fDenyTSConnections.txt
echo %fDenyTSConnections% | findstr "0x1" > NUL
if errorlevel 1 (echo Terminal Services Enabled & goto CheckNLA) else (echo Terminal Services Not Enabled & goto SkipNLA)
:CheckNLA
call :functionCompareRegEXACT "UserAuthentication" " UserAuthentication REG_DWORD 0x1" "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp"
goto RDPEnd
:SkipNLA
(call :ColourText 0a "PASS" & set STATUS=PASS)
:RDPEnd
echo NOTES: Should be set to 0x1 if Terminal Services is enabled. Bear this in mind if value does not match expected value
echo NOTES: I've also found this to be problematic on some hosts, so check the gui using 'control.exe sysdm.cpl,,5'
echo.
echo.
echo ======Software Restriction Policies and AppLocker (KB430 + KB450):
echo.
REM NONFUNCTION
set TEST="SRPAppLocker"
set FILE=%TEMPDIRECTORY%\SRPAppLocker.txt
set EXPECTED=""
set KEY="HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\safer\codeidentifiers\0 and HKEY_LOCAL_Machine\Software\Policies\Microsoft\Windows\SrpV2"
echo ====Software Restriction Policies:
reg query HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\safer\codeidentifiers\0 >> %FILE%
if errorlevel 1 (echo SRP Not Enabled & set srp=false) else (echo SRP Enabled & set srp=true)
echo ====AppLocker:
reg query HKEY_LOCAL_Machine\Software\Policies\Microsoft\Windows\SrpV2 >> %FILE%
if errorlevel 1 (echo AppLocker Not Enabled & set applocker=false) else (echo AppLocker Enabled & set applocker=true)
if %srp% == true goto srpapplockerfound
if %applocker% == true goto srpapplockerfound
:srpapplockernotfound
(call :ColourText 0c "FAIL" & set STATUS=FAIL & set EXPECTED="SRP or AppLocker found" & set ACTUAL=SRP or AppLocker not found)
goto srpapplockerend
:srpapplockerfound
(call :ColourText 0a "PASS" & set STATUS=PASS)
:srpapplockerend
call :log
if not "%STATUS%" == "PASS" call :startnessusfindingreadtxt
call :set
echo NOTES: This is a basic check to see if SRP or AppLocker are enabled by checking for presence in the registry
echo NOTES: The policies are not enumerated, so this needs checking manually if you see PASS
echo.
echo ====NoAutoplayfornonVolume (KB680):
call :functionCompareRegEXACT "NoAutoplayfornonVolume" " NoAutoplayfornonVolume REG_DWORD 0x1" "HKLM\SOFTWARE\policies\Microsoft\Windows\Explorer"
echo NOTES: Should be expected value
echo.
echo ====SEHOP (KB690):
call :functionCompareRegEXACT "DisableExceptionChainValidation" " DisableExceptionChainValidation REG_DWORD 0x0" "HKLM\System\CurrentControlSet\Control\Session Manager\Kernel"
echo NOTES: Should be expected value
echo.
echo ====LLMNR (KB437):
call :functionCompareRegEXACT "EnableMulticast" " EnableMulticast REG_DWORD 0x0" "HKLM\Software\Policies\Microsoft\Windows NT\DNSClient"
echo NOTES: Should be expected value
echo.
echo ====NetBIOS Over TCP/IP (KB693):
REM NONFUNCTION
REM START PREREQ CHECK
reg query HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NetBT\Parameters /v NodeType | findstr /i 0x2 > NUL
if %errorlevel% == 0 goto skipnetbiosovertcpip
REM END PREREQ CHECK
set TEST="NetBIOSoverTCP"
set FILE=%TEMPDIRECTORY%\NetBIOSoverTCPoutput.txt
set KEY="HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\NetBT\Parameters\Interfaces\Tcpip_[guid]"
set EXPECTED=" NetbiosOptions REG_DWORD 0x2"
set EXPECTEDNESSUS=NetbiosOptions REG_DWORD 0x2
wmic nic where "guid like '%%'" get guid | findstr /v GUID | findstr {*} > %TEMPDIRECTORY%\netbiosovertcp.txt
for /f %%A in (%TEMPDIRECTORY%\netbiosovertcp.txt) do (
setlocal enabledelayedexpansion
echo Interface Name:
wmic nic where "guid like '%%A'" get Name | findstr /v Name
echo Interface Value:
reg query HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\NetBT\Parameters\Interfaces\Tcpip_%%A /v NetbiosOptions | findstr NetbiosOptions > %TEMPDIRECTORY%\NetbiosOptions.txt
set /p ACTUAL= < %TEMPDIRECTORY%\NetbiosOptions.txt
echo Expect: %EXPECTED%
echo Actual: "!ACTUAL!"
set ACTUALNESSUS=!ACTUAL: = !
echo. >> %FILE%
echo Interface Name: >> %FILE%
wmic nic where "guid like '%%A'" get Name | findstr /v Name >> %FILE%
echo Interface Value: >> %FILE%
echo Expect: %EXPECTEDNESSUS% >> %FILE%
echo Actual:!ACTUALNESSUS! >> %FILE%
if "!ACTUAL!" == %EXPECTED% (call :ColourText 0a "PASS" & echo Status: PASS >> %FILE%) else (call :ColourText 0c "FAIL" & echo Status: FAIL >> %FILE%)
echo.
endlocal
)
call :log
findstr FAIL %FILE% > NUL
if errorlevel 1 (set STATUS=PASS) else (set STATUS=FAIL & set ACTUAL= NetbiosOptions REG_DWORD 0x0)
if not "%STATUS%" == "PASS" call :startnessusfindingreadtxt
call :set
echo NOTES: Values should be set to 2
echo.
goto netbiosovertcpipdone
:skipnetbiosovertcpip
REM HARDCODED NONFUNCTION
set TEST="NetBIOSoverTCP"
set KEY="HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NetBT\Parameters"
set EXPECTED=" NodeType REG_DWORD 0x2"
set ACTUAL= NodeType REG_DWORD 0x2
echo EXPECT: %EXPECTED%
echo ACTUAL: "%ACTUAL%"
(call :ColourText 0a "PASS" & set STATUS=PASS)
call :log
call :set
echo NOTES: NodeType appears to be set to 0x2, skipping NetBIOS Over TCP/IP checks
echo.
:netbiosovertcpipdone
echo ====SMB Server Signing (KB78):
call :functionCompareRegEXACT "RequireSecuritySignature" " RequireSecuritySignature REG_DWORD 0x1" "HKLM\System\CurrentControlSet\Services\LanManServer\Parameters"
echo NOTES: Should be expected value
echo.
echo ====Require Strong (Windows 2000 or Later) Session Key:
call :functionCompareRegEXACT "RequireStrongKey" " RequireStrongKey REG_DWORD 0x1" "HKLM\System\CurrentControlSet\Services\Netlogon\Parameters"
echo NOTES: Should be expected value
echo.
echo ====Users Can Add Printer Drivers (KB522):
call :functionCompareRegEXACT "AddPrinterDrivers" " AddPrinterDrivers REG_DWORD 0x1" "HKLM\System\CurrentControlSet\Control\Print\Providers\LanMan Print Services\Servers"
echo NOTES: Should be expected value
echo.
echo ====Disable HTTP Printing (KB627):
call :functionCompareRegEXACT "DisableHTTPPrinting" " DisableHTTPPrinting REG_DWORD 0x1" "HKLM\SOFTWARE\policies\Microsoft\windows NT\Printers"
echo NOTES: Should be expected value
echo.
echo ====Disable WebPnP Download (KB674):
call :functionCompareRegEXACT "DisableWebPnPDownload" " DisableWebPnPDownload REG_DWORD 0x1" "HKLM\SOFTWARE\policies\Microsoft\windows NT\Printers"
echo NOTES: Should be expected value
echo.
echo ====Print Spooler Service Disabled:
set TEST="PrintSpoolerDisabled"
set FILE=%TEMPDIRECTORY%\SpoolerDisabled.txt
SET KEY="wmic service where 'name like "spooler"' get startmode"
set EXPECTED="Disabled"
wmic service where 'name like "spooler"' get startmode | findstr -v StartMode | findstr . > %FILE%
findstr /v Disabled %FILE%
if %errorlevel% == 1 (call :ColourText 0a "PASS" & set STATUS=PASS) else (call :ColourText 0c "FAIL" & set STATUS=FAIL & set ACTUAL=Enabled)
REM call :log
REM if not "%STATUS%" == "PASS" call :startnessusfindingreadtxt
if "%STATUS%" == "PASS" goto SkipRegisterSpoolerRemoteRpcEndPoint
call :set
echo.
echo ====Remote Print Spooler Registration:
call :functionCompareRegEXACT "RegisterSpoolerRemoteRpcEndPoint" " RegisterSpoolerRemoteRpcEndPoint REG_DWORD 0x2" "HKLM\SOFTWARE\policies\Microsoft\windows NT\Printers"
echo NOTES: Should be expected value
:SkipRegisterSpoolerRemoteRpcEndPoint
echo NOTES: The spooler service should be disabled, unless RegisterSpoolerRemoteRpcEndPoint is set to 2.
echo.
echo ====Block UNC/SMB/WebDAV DLL loading (KB668):
call :functionCompareRegEXACT "CWDIllegalInDLLSearch" " CWDIllegalInDLLSearch REG_DWORD 0x2" "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager"
echo NOTES: Should be expected value
echo.
echo ====Server SPN target name validation level (KB521):
call :functionCompareRegEXACT "SmbServerNameHardeningLevel" " SmbServerNameHardeningLevel REG_DWORD 0x2" "HKLM\System\CurrentControlSet\Services\LanManServer\Parameters"
echo NOTES: Should be at least 0x1, ideally 0x2
echo.
echo ====Localsystem NULL session fallback (KB666):
REM if not Pre2008r2, run check
for /f %%i in ('wmic os get version ^| findstr . ^| findstr /v Version') do set version=%%i
echo %version% | findstr "10 6.3 6.2" > NUL
if errorlevel 1 (set pre2008r2=true) else (set pre2008r2=false)
if %pre2008r2% == true (call :functionCompareRegEXACT "allownullsessionfallback" " allownullsessionfallback REG_DWORD 0x0" "HKLM\System\CurrentControlSet\Control\Lsa\MSV1_0 /v allownullsessionfallback") else (echo This option is disabled by default on the host, skipping check. & call :ColourText 0a "PASS" & set STATUS=PASS)
echo NOTES: Should be expected value depending on OS
echo NOTES: Should be set to 0 if before 2008 R2/Win 7, otherwise disabled by default
echo.
echo ====Allow LocalSystem to use computer identity for NTLM:
call :functionCompareRegEXACT "UseMachineId" " UseMachineId REG_DWORD 0x1" "HKLM\System\CurrentControlSet\Control\Lsa"
echo NOTES: Should be expected value
echo.
echo ====Disable TS Drive redirection (KB452):
call :functionCompareRegEXACT "fDisableCdm" " fDisableCdm REG_DWORD 0x1" "HKLM\SOFTWARE\policies\Microsoft\windows NT\Terminal Services"
echo NOTES: Should be expected value
echo.
echo ====Restrictions for Unauthenticated RPC Clients (KB623):
call :functionCompareRegEXACT "RestrictRemoteClients" " RestrictRemoteClients REG_DWORD 0x1" "HKLM\SOFTWARE\policies\Microsoft\windows NT\Rpc"
echo NOTES: Should be expected value
echo.
echo ====RDP Session host: Require Secure RPC comms (KB675):
call :functionCompareRegEXACT "fEncryptRPCTraffic" " fEncryptRPCTraffic REG_DWORD 0x1" "HKLM\SOFTWARE\policies\Microsoft\windows NT\Terminal Services"
echo NOTES: Should be expected value
echo.
echo ====RPC Endpoint Mapper Client Authentication (KB623):
call :functionCompareRegEXACT "EnableAuthEpResolution" " EnableAuthEpResolution REG_DWORD 0x1" "HKLM\SOFTWARE\policies\Microsoft\windows NT\Rpc"
echo NOTES: Should be expected value
echo.
echo ====Additional LSA Protection (KB671):
REM if not Pre2012r2, run check
for /f %%i in ('wmic os get version ^| findstr . ^| findstr /v Version') do set version=%%i
echo %version% | findstr "10 6.3" > NUL
if errorlevel 1 (set pre2012r2=true) else (set pre2012r2=false)
if %pre2012r2% == false (call :functionCompareRegEXACT "RunAsPPL" " RunAsPPL REG_DWORD 0x1" "HKLM\System\CurrentControlSet\Control\Lsa") else (echo This option is not supported on the host, skipping check. & call :ColourText 0a "PASS" & set STATUS=PASS)
echo NOTES: Should be expected value depending on OS
echo.
echo ====Insecure Guest SMB2 Logons (KB686):
REM if not Pre2016/win10 run check
for /f %%i in ('wmic os get version ^| findstr . ^| findstr /v Version') do set version=%%i
echo %version% | findstr "10" > NUL
if errorlevel 1 (set pre2016=true) else (set pre2016=false)
if %pre2016% == true (call :functionCompareRegEXACT "AllowInsecureGuestAuth" " AllowInsecureGuestAuth REG_DWORD 0x0" "HKLM\Software\Policies\Microsoft\Windows\LanmanWorkstation") else (echo This option is disabled by default on the host, skipping check. & call :ColourText 0a "PASS" & set STATUS=PASS)
echo NOTES: Should be expected value depending on OS
echo.
echo ====Winlogon Automatic Restart Sign-On ARSO (KB670):
REM if not Pre2012r2, run check
for /f %%i in ('wmic os get version ^| findstr . ^| findstr /v Version') do set version=%%i
echo %version% | findstr "10 6.3" > NUL
if errorlevel 1 (set pre2012r2=true) else (set pre2012r2=false)
if %pre2012r2% == true (call :functionCompareRegEXACT "DisableAutomaticRestartSignOn" " DisableAutomaticRestartSignOn REG_DWORD 0x1" "HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System") else (echo This option is disabled by default on the host, skipping check. & call :ColourText 0a "PASS" & set STATUS=PASS)
echo NOTES: Should be expected value depending on OS
echo.
echo ====UAC Enabled (KB517):
REM Should be set to 1 if 2008/Win Vista and above, prior to that doesn't support UAC so still a finding
call :functionCompareRegEXACT "EnableLUA" " EnableLUA REG_DWORD 0x1" "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"
echo NOTES: Should be expected value depending on OS
echo NOTES: Can also check in GUI in Win 7 and above using UserAccountControlSettings.exe
echo.
echo ====UAC Prompt Behaviour (KB269):
REM TODO: ADD OS LOGIC
REM Need to check OS. Should be set to 0 if 2008/Win Vista and above
call :functionCompareRegNOT "ConsentPromptBehaviorAdmin" " ConsentPromptBehaviorAdmin REG_DWORD 0x0" "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"
echo NOTES: Should NOT be expected value
echo NOTES: Can also check in GUI in Win 7 and above using UserAccountControlSettings.exe
echo.
echo ====Password reveal option at logon (KB621):
REM if not Pre2012r2, run check
for /f %%i in ('wmic os get version ^| findstr . ^| findstr /v Version') do set version=%%i
echo %version% | findstr "10 6.3" > NUL
if errorlevel 1 (set pre2012r2=true) else (set pre2012r2=false)
if %pre2012r2% == false (call :functionCompareRegEXACT "DisablePasswordReveal" " DisablePasswordReveal REG_DWORD 0x1" "HKLM\Software\Policies\Microsoft\Windows\CredUI") else (echo This option is not supported on the host, skipping check. & call :ColourText 0a "PASS" & set STATUS=PASS)
echo NOTES: Should be expected value depending on OS
echo.
echo ====Non-Zero Screen Saver Grace Period (KB515):
call :functionCompareRegEXACT "ScreenSaverGracePeriod" " ScreenSaverGracePeriod REG_SZ 0" "HKLM\Software\Microsoft\Windows NT\CurrentVersion\winlogon"
echo NOTES: Should be expected value
echo.
REM Needs AD Tools so removing this for now, will probably use ADSI in vbscript instead when I have time.
REM Maybe use a stripped down version of https://github.com/GAThrawnMIA/Work-Scripts/blob/master/VbScript/LAPS-Password.vbs
REM echo ====Search domain for LAPS passwords:
REM dsquery * -attr name ms-MCS-AdmPwd -limit 9999999999 -filter ms-MCS-AdmPwd=*
REM echo NOTES: More AD specific, but useful for privesc if local machine is in there
if %DomainRole% == 1 goto lapsstart
if %DomainRole% == 3 goto lapsstart
goto lapsend
:lapsstart
echo ====LAPS Installed Locally (KB258):
REM NONFUNCTION
set TEST="lapsinstalledlocal"
set FILE=%TEMPDIRECTORY%\laps.txt
set LAPSDLL="c:\program files\LAPS\CSE\Admpwd.dll"
set KEY="dir "%LAPSDLL%""
set EXPECTED=""
echo dir %LAPSDLL% > %FILE%
echo. >> %FILE%
dir %LAPSDLL% >> %FILE%
dir %LAPSDLL% 2>> %FILE%
if exist %LAPSDLL% (echo LAPS Installed & call :ColourText 0a "PASS" & set STATUS=PASS) else (echo LAPS Not Installed & call :ColourText 0c "FAIL" & set STATUS=FAIL & set EXPECTED="LAPS DLL found" & set ACTUAL=LAPS DLL not found)
call :log
if not "%STATUS%" == "PASS" call :startnessusfindingreadtxt
call :set
echo NOTES: DLL should be present if installed
echo NOTES: This doesn't check whether DLL is registered however
echo.
:lapsend
if %DomainRole% == 1 goto checkdenylogonstart
if %DomainRole% == 3 goto checkdenylogonstart
goto checkdenylogonend
:checkdenylogonstart
echo ====Check Deny Logon Rights (KB479):
echo Checking denyrights
REM NONFUNCTION
set TEST="CheckDenyLogon"
set FILE=%TEMPDIRECTORY%\checkdenylogon.txt
set KEY="secedit.exe /export /cfg sec.txt &amp; type sec.txt | findstr LogonRight"
set EXPECTED=""
type %TEMPDIRECTORY%\sec.txt | findstr LogonRight > %FILE%
echo Deny Rights:
type %FILE% | findstr SeDeny > %TEMPDIRECTORY%\SeDeny.txt
type %TEMPDIRECTORY%\SeDeny.txt
echo Allow Rights:
type %FILE% | findstr -v SeDeny > %TEMPDIRECTORY%\seAllow.txt
type %TEMPDIRECTORY%\seAllow.txt
REM Sort output and merge into nessus finding:
type %TEMPDIRECTORY%\seAllow.txt > %FILE%
type %TEMPDIRECTORY%\seDeny.txt >> %FILE%
(call :ColourText 09 "CHECK OUTPUT" & set STATUS=CHECK OUTPUT)
call :log
if not "%STATUS%" == "PASS" call :startnessusfindingreadtxt
call :set
echo NOTES: Domain Admins generally should have SeDeny rights to logon locally, via terminal services, batch job, service and network
echo NOTES: Privileged accounts should NOT be able to logon to standard member servers
echo NOTES: See https://support.microsoft.com/en-gb/help/243330/well-known-security-identifiers-in-windows-operating-systems for list of well known sids
echo.
:checkdenylogonend
echo ====Checking Powershell Version (KB667):
REM NONFUNCTION
set TEST="powershellversion"
set FILE=%TEMPDIRECTORY%\psversion.txt
set KEY="powershell.exe $PSVersionTable.PSVersion.Major"
set EXPECTED="5"
if exist %SYSTEMDRIVE%\Windows\System32\WindowsPowerShell\v1.0\powershell.exe powershell.exe $PSVersionTable.PSVersion.Major > %FILE%
echo Expect: %EXPECTED%
set /p ACTUAL= < %FILE%
if "%ACTUAL%" == "" set ACTUAL=NULL
echo Actual: "%ACTUAL%"
set /a NUMEXPECTED = %EXPECTED%
set /a NUMACTUAL = %ACTUAL%
if %NUMACTUAL% GEQ %NUMEXPECTED% (call :ColourText 0a "PASS" & set STATUS=PASS) else (call :ColourText 0c "FAIL" & set STATUS=FAIL)
call :log
if not "%STATUS%" == "PASS" (call :startnessustxtfinding & set powershelladditionalstart=true) else (set powershelladditionalstart=false)
call :set
echo NOTES: Should be running Powershell 5 or above
echo.
if not %powershelladditionalstart% == true (goto :powershelladditionalstart) else (goto :powershelladditionalend)
:powershelladditionalstart
echo ====Checking Powershell Version 2:
REM NONFUNCTION
set TEST="powershellversion2"
set FILE=%TEMPDIRECTORY%\psversion2.txt
set KEY="powershell.exe -version 2 $PSVersionTable.PSVersion.Major"
set EXPECTED="5"
if exist %SYSTEMDRIVE%\Windows\System32\WindowsPowerShell\v1.0\powershell.exe powershell.exe -version 2 $PSVersionTable.PSVersion.Major > %FILE%
type %FILE% | findstr /c:"Version v2.0.50727 of the .NET Framework is not installed and it is required to run version 2 of Windows PowerShell."
if errorlevel 1 (set ACTUAL=5) else (set ACTUAL=%ACTUAL%)
echo Expect: %EXPECTED%
set /p ACTUAL= < %FILE%
if "%ACTUAL%" == "" set ACTUAL=NULL
echo Actual: "%ACTUAL%"
set /a NUMEXPECTED = %EXPECTED%
set /a NUMACTUAL = %ACTUAL%
if %NUMACTUAL% GEQ %NUMEXPECTED% (call :ColourText 0a "PASS" & set STATUS=PASS) else (call :ColourText 0c "FAIL" & set STATUS=FAIL)
call :log
if not "%STATUS%" == "PASS" call :startnessustxtfinding
call :set
echo NOTES: Should NOT be able to run Powershell v2.
echo.
echo ====PowerShell Module Logging:
call :functionCompareRegEXACT "EnableModuleLogging" " EnableModuleLogging REG_DWORD 0x1" "HKLM\Software\Policies\Microsoft\Windows\Powershell\ModuleLogging"
echo NOTES: Should be expected value
echo.
echo ====PowerShell Script Block Logging Logging:
call :functionCompareRegEXACT "EnableScriptBlockLogging" " EnableScriptBlockLogging REG_DWORD 0x1" "HKLM\Software\Policies\Microsoft\Windows\Powershell\ScriptBlockLogging"
echo NOTES: Should be expected value
echo.
echo ====PowerShell Transcription Logging:
call :functionCompareRegEXACT "EnableTranscripting" " EnableTranscripting REG_DWORD 0x1" "HKLM\Software\Policies\Microsoft\Windows\Powershell\Transcription"
echo NOTES: Should be expected value
echo.
:powershelladditionalend
set powershelladditionalstart=
echo ====PowerShell Execution Policy:
call :functionCompareRegNOT "ExecutionPolicy" " ExecutionPolicy REG_SZ Unrestricted" "HKLM\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell"
echo NOTES: Should contain some value
echo.
if "%thirdparty%" == "TRUE" (goto 3rdparty) else (goto cleanup)
:3rdparty
echo ====Checking 3rd Party Apps:
REM NONFUNCTION
set TEST="3rdpartyapps"
set FILE=%TEMPDIRECTORY%\3rdpartyapps.txt
set KEY="where.exe /R [driveletter]:\ iexplore.exe chrome.exe firefox.exe java.exe bla.exe"
set EXPECTED=""
REM Need to test names for additional products, if missing add below
wmic process get name | findstr -v "svchost.exe winlogon.exe RuntimeBroker.exe TrustedInstaller.exe TiWorker.exe conhost.exe WmiPrvSE.exe dllhost.exe cmd.exe ShellExperienceHost.exe ctfmon.exe cmd.exe findstr.exe System smss.exe explorer.exe crss.exe SearchUI.exe ServerManager.exe sihost.exe fontdrvhost.exe rdpclip.exe smartscreen.exe LogonUI.exe mctray.exe csrss.exe dwm.exe UpdaterUI.exe tasklist.exe nlp.exe mmc.exe VSSVC.exe services.exe spoolsv.exe lsass.exe wininit.exe taskhostw.exe ApplicationFrameHost.exe MFEConsole.exe mfemms.exe mfevtps.exe mfeesp.exe mfefire.exe mfehcs.exe mfeensppl.exe mfetp.exe mfemactl.exe macompatsvc.exe macmnsvc.exe masvc.exe Taskmgr.exe cscript.exe ASMHost.exe MonitoringHost.exe HealthService.exe WindowsAzureGuestAgent WindowsAzureNetAgent.exe WindowsAzureTelemetryServ MMAExtensionHeartbeatServ WaSecAgentProv.exe WaAppAgent.exe VFPlugin.exe msdtc.exe sort.exe WMIC.exe rundll32.exe sppsvc.exe vds.exe WUDFHost.exe unsecapp.exe WmiApSrv.exe w3wp.exe mqsvc.exe powershell.exe backgroundTaskHost.exe InetMgr.exe Name Registry" > %TEMPDIRECTORY%\processes.txt
for /f %%a in (%TEMPDIRECTORY%\processes.txt) do (
<nul set /p processes=%%a
) >> %TEMPDIRECTORY%\processes2.txt
set /p processes=<%TEMPDIRECTORY%\processes2.txt
for %%D IN (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z) do (if exist %%D:\ echo Checking %%D:\ & where.exe /R %%D:\ iexplore.exe chrome.exe firefox.exe java.exe vpnui.exe putty.exe winscp.exe wireshark.exe 7z.exe flash.ocx acrobat.exe AcroRd32.exe SwHelper_*.exe clr.dll %processes% | findstr -v -i "Windows\WinSxS Windows\Installer" | findstr -v -i "Windows\servicing" >> %TEMPDIRECTORY%\3rdpartyfiles.txt)
for /f "delims=" %%G in (%TEMPDIRECTORY%\3rdpartyfiles.txt) do (
setlocal enabledelayedexpansion
set "line=%%G"
set "line=!line:\=\\!"
wmic datafile where Name="!line!" get Version | findstr /v Version > %TEMPDIRECTORY%\3rdpartyfile.txt
set /p Version= < %TEMPDIRECTORY%\3rdpartyfile.txt
echo File: %%G Version: !version! >> %FILE%
del %TEMPDIRECTORY%\3rdpartyfile.txt
endlocal
timeout /t 1 > NUL
)
type %FILE%
del %TEMPDIRECTORY%\3rdpartyfiles.txt
(call :ColourText 09 "CHECK OUTPUT" & set STATUS=CHECK OUTPUT)
call :log
if not "%STATUS%" == "PASS" call :startnessusfindingreadtxt
call :set
echo.
:cleanup
echo.
echo Generating .nessus footer for Canopy
call :startnessusfooter
echo Cleaning up
rd /q /s %TEMPDIRECTORY% > NUL
set DEL=
set AREYOUSURE=
set DomainRole=
set win2003=
set os=
set clientorserver=
set logdebug=
set logoutput=
set thirdparty=
set KEY=
:end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment