righettod/toolbox-pentest-web
GitHub: righettod/toolbox-pentest-web
Stars: 183 | Forks: 37
# :factory: Welcome to my digital forge
* [PDF document](misc/doc-pdf-with-link-to-malicious-file.pdf) with a link to a file considered as a malware by some Antivirus or Browsers.
* [PDF document](misc/doc-pdf-with-qrcode-to-malicious-file.pdf) with a QRCODE with a link to a file considered as a malware by some Antivirus or Browsers.
* [PDF document](misc/doc-pdf-with-embedded-lazagne-file.pdf) with an embedded (attached) build of [LaZagne](https://github.com/AlessandroZ/LaZagne) file considered as a malware by some Antivirus or Browsers.
* [PDF document](misc/doc-pdf-with-embedded-netcat-file.pdf) with an embedded (attached) build of [NetCat](static-binaries/windows/netcat) file considered as a malware by some Antivirus or Browsers.
* [PDF document](misc/doc-pdf-with-embedded-malicious-file.pdf) with an embedded (attached) file simulating a malicious file.
* [PDF document](misc/doc-pdf-with-malicious-files-concatenated.pdf) with a malicious file, considered as a malware by some Antivirus or Browsers, concatenated at the end after the delimiter `[NEWFILE]` (see below for the extraction of the malicious file from the pdf).
* [PDF document](misc/doc-pdf-with-js-code.pdf) with JS code showing an alert box when the document is open.
* [PDF document](misc/doc-pdf-with-js-code-opening-a-url.pdf) with JS code opening a specific URL when the document is open.
* [PDF document](misc/doc-pdf-with-xxe-in-xfa-form.pdf) with a XXE payload embedded in a XFA form (based on [CVE-2025-54988](https://nvd.nist.gov/vuln/detail/CVE-2025-54988) and [POC-CVE-2025-54988](https://github.com/mgthuramoemyint/POC-CVE-2025-54988)).
* [XPS document](misc/doc-xps-with-malicious-apps.xps) embedding files ([LaZagne](https://github.com/AlessandroZ/LaZagne) and [Mimikatz](https://github.com/gentilkiwi/mimikatz)) detected, as malicious programs, by antivirus (at least from [VirusTotal](https://www.virustotal.com/) ones).
* SVG image with an XSS payload, see files `misc/doc-test-xss-*.svg` for the different versions.
* [Java application](misc/malicious-java-app.jar), as an executable jar file compiled for Java 1.8 minimum runtime, performing an HTTP GET request to a defined domain.
* [Go application](misc/malicious-go-app.go), as a native executable, performing an HTTP GET request to a defined domain:
* [Build for Windows 64 bits](misc/malicious-go-app-windows-amd64.exe).
* [Build for Linux 64 bits](misc/malicious-go-app-linux-amd64.bin).
* [VBS script](misc/doc-vbs-exfiltrating-envvars.vbs) exfiltrating environment variables, via an HTTP POST request, to a defined domain.
💻 Use the code below to extract the executable file ([LaZagne.exe](https://github.com/AlessandroZ/LaZagne/releases/tag/v2.4.6)) from the PDF file [doc-pdf-with-malicious-files-concatenated.pdf](misc/doc-pdf-with-malicious-files-concatenated.pdf):
delimiter = "5b4e455746494c455d" # String "[NEWFILE]" encoded in HEX
with open("doc-pdf-with-malicious-files-concatenated.pdf", mode="rb") as f:
content_hex = f.read().hex()
delimiter_position = content_hex.find(delimiter)
bin_file_hex = content_hex[delimiter_position + len(delimiter):]
bin_file_bytes = bytes.fromhex(bin_file_hex)
with open("malicious-files.exe", mode="wb") as f:
f.write(bin_file_bytes[1:])
## Templates
The folder **[templates](templates)** contains several scripts/files that can be used, as a basis for custom scripts, to speed up the implementation of a POC.
## Dictionaries
The folder **[dictionaries](dictionaries)** contains several, home-made custom dictionaries, that can be used for discovery operations.
## Technical hints
This **[file](docs/README.md)** contains several technical hints for different kinds of context/issues/goals.
💻 It's my tailor-made cheat sheet.
# 🔨 Build image locally
Use the following set of commands:
$ git clone https://github.com/righettod/toolbox-pentest-web.git
$ cd toolbox-pentest-web
$ docker build . -t righettod/toolbox-pentest-web --file Dockerfile
...
# 💡 Container usage
## On a docker host for direct access
### Native docker on Linux or MacOS
# Create a volume to share files with the container (ex: reports)
$ docker volume create --name shared_space
$ docker volume inspect shared_space
# Run container
$ docker run -v shared_space:/tools/reports -p 127.0.0.1:80:80 -i -t ghcr.io/righettod/toolbox-pentest-web:master
$ docker run -v shared_space:/tools/reports -p 192.168.206.128:80:80 -p 192.168.206.128:443:443 -i -t ghcr.io/righettod/toolbox-pentest-web:master
# Build image into local cache
$ docker build -t righettod/toolbox-pentest-web .
# Remove image from local cache
$ docker rmi -f righettod/toolbox-pentest-web
### Docker for Windows
rem Run container and defines a shared folder
C:\> docker run -v F:/SharedFolder:/tools/reports -p 127.0.0.1:80:80 -i -t ghcr.io/righettod/toolbox-pentest-web:master
## For remote access
The tool [ttyd](https://github.com/tsl0922/ttyd) is used to expose a **zsh shell** via the browser on port TCP `8000`. This mode of exposure is used by the launch script [container-launcher.sh](container-launcher.sh) when an environment variable named `WEB_SHELL_ACCESS_PASSWORD` is defined. This variable refers to the password used for the BASIC authentication defined to access the container with the user named `righettod`.
💡 When the environment variable is not defined then the launch script start a zsh shell directly.
$ docker run -p 8000:8000 -e "WEB_SHELL_ACCESS_PASSWORD=MyComplexPassword" ghcr.io/righettod/toolbox-pentest-web:master
ttyd 1.7.7 (libwebsockets 4.3.5)
tty configuration:
...
$ docker run -p 8000:8000 -p 9000:9000 -e "WEB_SHELL_ACCESS_PASSWORD=MyComplexPassword" ghcr.io/righettod/toolbox-pentest-web:master
ttyd 1.7.7 (libwebsockets 4.3.5)
tty configuration:
...
# 📦 Container registries
Image is published into the [GitHub](https://github.com/righettod/toolbox-pentest-web/pkgs/container/toolbox-pentest-web) container registry, every week, via this [workflow](https://github.com/righettod/toolbox-pentest-web/actions).
🔒 Build attestations are [here](https://github.com/righettod/toolbox-pentest-web/attestations).
# 🛡️ Security
* Refer [here](SECURITY.md) for information about reporting a vulnerability.
* Image is audited every week by [Snyk](https://snyk.io/) to detect presence of any vulnerability.
# 🪟 Assessment in a Windows domain context
Tools commonly used in such type of assessment can be added by appending this content to the script [add-tools.sh](build/add-tools.sh) of your fork of this repository:
# Add NetExec, impacket and Responder tools
python -m pip install impacket aioquic
git clone --depth 1 https://github.com/lgandx/Responder.git /tools/Responder
python -m pip install git+https://github.com/Pennyw0rth/NetExec
CFLAGS="-Wno-int-conversion" python -m pip install netifaces
netexec --version
python /tools/Responder/Responder.py --version
# 🤔 Troubleshooting
## Deployment issue on OpenShift
### Issue faced and question asked to ChatGPT
I deploy a container on a OpenShift instance. The container is launched with another user that the one specified by the **USER** directive. What is the reason ?
### Reply from ChatGPT
**The Root Cause?**
OpenShift (unlike plain Docker or Kubernetes) **does not run containers as the user specified in your image’s `USER` directive by default**.
Instead, **it enforces a random, non-root user ID at runtime** for security reasons.
This happens because of **OpenShift’s Security Context Constraints (SCCs)** — especially the default one, called **`restricted`**.
**Why OpenShift Overrides the `USER` Directive?**
In OpenShift’s **restricted SCC**:
* Containers **must not run as root**.
* Containers **must run as an arbitrary, non-root UID** assigned dynamically when the pod starts.
* This UID is **not necessarily** the same as the one defined in your Dockerfile (`USER` directive).
This design ensures:
**What This Means Practically?**
If your Dockerfile contains:
USER 1001
and you deploy it on OpenShift, your container may run as something like UID `1023840001` instead.
This UID:
* Has **no name mapping** in `/etc/passwd` inside the container.
* Still has the **same group ID** as the `root` group (GID `0`) unless overridden.
* Can access files owned by `0` (root group), which is why many OpenShift images use `chmod g+w` on directories that need to be writable.
**How to Make Your Image Compatible?**
If your app needs write access to certain directories, do the following in your Dockerfile:
# Allow group write permissions
RUN mkdir -p /app && chgrp -R 0 /app && chmod -R g+rwX /app
# Switch to non-root user
USER 1001
💡 This ensures that even if OpenShift assigns an arbitrary UID, it will still belong to group `0` (**root**) and have the necessary permissions.
**Summary**
| Behavior | Explanation |
| -------------------------------------------- | ----------------------------------------------------------------- |
| Container runs as different user than `USER` | OpenShift enforces non-root random UID via SCC. |
| Why | Security isolation (no privilege escalation, multi-tenant safety).|
| Fix | Ensure filesystem permissions are `g+rwX` and owned by group `0`. |
| Common SCC name | `restricted` |
