humanoidprobe 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- humanoidprobe-1.0.0/PKG-INFO +135 -0
- humanoidprobe-1.0.0/README.md +123 -0
- humanoidprobe-1.0.0/humanoidprobe/__init__.py +0 -0
- humanoidprobe-1.0.0/humanoidprobe/core/detector.py +103 -0
- humanoidprobe-1.0.0/humanoidprobe/core/reporter.py +136 -0
- humanoidprobe-1.0.0/humanoidprobe/core/requester.py +72 -0
- humanoidprobe-1.0.0/humanoidprobe/humanoidprobe.py +120 -0
- humanoidprobe-1.0.0/humanoidprobe.egg-info/PKG-INFO +135 -0
- humanoidprobe-1.0.0/humanoidprobe.egg-info/SOURCES.txt +12 -0
- humanoidprobe-1.0.0/humanoidprobe.egg-info/dependency_links.txt +1 -0
- humanoidprobe-1.0.0/humanoidprobe.egg-info/entry_points.txt +2 -0
- humanoidprobe-1.0.0/humanoidprobe.egg-info/top_level.txt +1 -0
- humanoidprobe-1.0.0/pyproject.toml +25 -0
- humanoidprobe-1.0.0/setup.cfg +4 -0
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: humanoidprobe
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: HumanoidProbe is a command-line XSS WAF intelligence tool that probes how a WAF responds to payload variations — telling you what gets blocked, what passes through, and what gets reflected back.
|
|
5
|
+
Author-email: CyberSafeLabs <hello.cybersafe@gmail.com>
|
|
6
|
+
Project-URL: Homepage, https://github.com/hellocybersafe/humanoidprobe
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
9
|
+
Classifier: Operating System :: OS Independent
|
|
10
|
+
Requires-Python: >=3.7
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
|
|
13
|
+
# HumanoidProbe
|
|
14
|
+
**by CyberSafeLabs**
|
|
15
|
+
|
|
16
|
+
> *Analyse WAF behaviour. Think like an attacker.*
|
|
17
|
+
|
|
18
|
+
HumanoidProbe is a command-line XSS WAF intelligence tool that probes how a WAF responds to payload variations — telling you what gets blocked, what passes through, and what gets reflected back.
|
|
19
|
+
|
|
20
|
+
Built from real bug bounty research. Not theory.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## What it does
|
|
25
|
+
|
|
26
|
+
- Fires categorised XSS payload variations at a target URL and parameter
|
|
27
|
+
- Detects WAF blocks via status codes, response body analysis, and response length changes
|
|
28
|
+
- Identifies reflected payloads — the highest value findings
|
|
29
|
+
- Summarises WAF behaviour and what it appears to be filtering
|
|
30
|
+
- Gives you actionable intelligence to craft smarter bypass payloads
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Installation
|
|
35
|
+
|
|
36
|
+
**1. Make sure Python 3 is installed**
|
|
37
|
+
```bash
|
|
38
|
+
python3 --version
|
|
39
|
+
```
|
|
40
|
+
If not:
|
|
41
|
+
```bash
|
|
42
|
+
sudo apt update && sudo apt install python3 python3-pip -y
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**2. Install the dependency**
|
|
46
|
+
```bash
|
|
47
|
+
pip3 install requests
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Usage
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
python3 humanoidprobe.py -u <URL> -p <parameter>
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
**Example:**
|
|
59
|
+
```bash
|
|
60
|
+
python3 humanoidprobe.py -u https://example.com/search -p q
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**With options:**
|
|
64
|
+
```bash
|
|
65
|
+
python3 humanoidprobe.py -u https://example.com/search -p q --delay 1 --timeout 15
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Options
|
|
71
|
+
|
|
72
|
+
| Flag | Description | Default |
|
|
73
|
+
|------|-------------|---------|
|
|
74
|
+
| `-u` / `--url` | Target URL | Required |
|
|
75
|
+
| `-p` / `--parameter` | GET parameter to test | Required |
|
|
76
|
+
| `--payloads` | Custom payload file path | payloads/xss.txt |
|
|
77
|
+
| `--delay` | Seconds between requests | 0.5 |
|
|
78
|
+
| `--timeout` | Request timeout in seconds | 10 |
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Output verdicts
|
|
83
|
+
|
|
84
|
+
| Verdict | Meaning |
|
|
85
|
+
|---------|---------|
|
|
86
|
+
| `REFLECTED` | Payload passed AND appeared in the response — investigate in browser immediately |
|
|
87
|
+
| `PASSED` | WAF did not block — worth exploring further |
|
|
88
|
+
| `BLOCKED` | WAF caught this payload |
|
|
89
|
+
| `ERROR` | Request failed (timeout, connection error) |
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## Project structure
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
humanoidprobe/
|
|
97
|
+
├── humanoidprobe.py # Main entry point — what you run
|
|
98
|
+
├── payloads/
|
|
99
|
+
│ └── xss.txt # XSS payload list
|
|
100
|
+
├── core/
|
|
101
|
+
│ ├── requester.py # Sends HTTP requests
|
|
102
|
+
│ ├── detector.py # Analyses responses (blocked vs passed)
|
|
103
|
+
│ └── reporter.py # Terminal output and summary
|
|
104
|
+
└── README.md
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Roadmap
|
|
110
|
+
|
|
111
|
+
- [ ] WAF memory — builds a profile of WAF behaviour across sessions
|
|
112
|
+
- [ ] Intelligent bypass suggestions — generates mutations based on what passed
|
|
113
|
+
- [ ] POST parameter support
|
|
114
|
+
- [ ] SQLi payload module
|
|
115
|
+
- [ ] Output to file (JSON / txt)
|
|
116
|
+
- [ ] Burp Suite integration
|
|
117
|
+
- [ ] Full recon and attack surface mapping modules
|
|
118
|
+
- [ ] Humanoid Intelligence — AI layer (coming in future versions)
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Legal & ethical use
|
|
123
|
+
|
|
124
|
+
Only use HumanoidProbe against targets you have explicit permission to test.
|
|
125
|
+
Unauthorised testing is illegal. This tool is built for legitimate security research and bug bounty programmes only.
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## About
|
|
130
|
+
|
|
131
|
+
HumanoidProbe is the first tool from **CyberSafeLabs** — an independent cybersecurity research initiative focused on protecting digital assets through offensive research, vulnerability discovery, and practical security tooling.
|
|
132
|
+
|
|
133
|
+
The long-term vision: **Humanoid Intelligence** — an AI-powered security research platform built from real hunting experience.
|
|
134
|
+
|
|
135
|
+
*CyberSafeLabs — protecting digital assets through research*
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# HumanoidProbe
|
|
2
|
+
**by CyberSafeLabs**
|
|
3
|
+
|
|
4
|
+
> *Analyse WAF behaviour. Think like an attacker.*
|
|
5
|
+
|
|
6
|
+
HumanoidProbe is a command-line XSS WAF intelligence tool that probes how a WAF responds to payload variations — telling you what gets blocked, what passes through, and what gets reflected back.
|
|
7
|
+
|
|
8
|
+
Built from real bug bounty research. Not theory.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## What it does
|
|
13
|
+
|
|
14
|
+
- Fires categorised XSS payload variations at a target URL and parameter
|
|
15
|
+
- Detects WAF blocks via status codes, response body analysis, and response length changes
|
|
16
|
+
- Identifies reflected payloads — the highest value findings
|
|
17
|
+
- Summarises WAF behaviour and what it appears to be filtering
|
|
18
|
+
- Gives you actionable intelligence to craft smarter bypass payloads
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
**1. Make sure Python 3 is installed**
|
|
25
|
+
```bash
|
|
26
|
+
python3 --version
|
|
27
|
+
```
|
|
28
|
+
If not:
|
|
29
|
+
```bash
|
|
30
|
+
sudo apt update && sudo apt install python3 python3-pip -y
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
**2. Install the dependency**
|
|
34
|
+
```bash
|
|
35
|
+
pip3 install requests
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Usage
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
python3 humanoidprobe.py -u <URL> -p <parameter>
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**Example:**
|
|
47
|
+
```bash
|
|
48
|
+
python3 humanoidprobe.py -u https://example.com/search -p q
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
**With options:**
|
|
52
|
+
```bash
|
|
53
|
+
python3 humanoidprobe.py -u https://example.com/search -p q --delay 1 --timeout 15
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Options
|
|
59
|
+
|
|
60
|
+
| Flag | Description | Default |
|
|
61
|
+
|------|-------------|---------|
|
|
62
|
+
| `-u` / `--url` | Target URL | Required |
|
|
63
|
+
| `-p` / `--parameter` | GET parameter to test | Required |
|
|
64
|
+
| `--payloads` | Custom payload file path | payloads/xss.txt |
|
|
65
|
+
| `--delay` | Seconds between requests | 0.5 |
|
|
66
|
+
| `--timeout` | Request timeout in seconds | 10 |
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Output verdicts
|
|
71
|
+
|
|
72
|
+
| Verdict | Meaning |
|
|
73
|
+
|---------|---------|
|
|
74
|
+
| `REFLECTED` | Payload passed AND appeared in the response — investigate in browser immediately |
|
|
75
|
+
| `PASSED` | WAF did not block — worth exploring further |
|
|
76
|
+
| `BLOCKED` | WAF caught this payload |
|
|
77
|
+
| `ERROR` | Request failed (timeout, connection error) |
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Project structure
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
humanoidprobe/
|
|
85
|
+
├── humanoidprobe.py # Main entry point — what you run
|
|
86
|
+
├── payloads/
|
|
87
|
+
│ └── xss.txt # XSS payload list
|
|
88
|
+
├── core/
|
|
89
|
+
│ ├── requester.py # Sends HTTP requests
|
|
90
|
+
│ ├── detector.py # Analyses responses (blocked vs passed)
|
|
91
|
+
│ └── reporter.py # Terminal output and summary
|
|
92
|
+
└── README.md
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## Roadmap
|
|
98
|
+
|
|
99
|
+
- [ ] WAF memory — builds a profile of WAF behaviour across sessions
|
|
100
|
+
- [ ] Intelligent bypass suggestions — generates mutations based on what passed
|
|
101
|
+
- [ ] POST parameter support
|
|
102
|
+
- [ ] SQLi payload module
|
|
103
|
+
- [ ] Output to file (JSON / txt)
|
|
104
|
+
- [ ] Burp Suite integration
|
|
105
|
+
- [ ] Full recon and attack surface mapping modules
|
|
106
|
+
- [ ] Humanoid Intelligence — AI layer (coming in future versions)
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Legal & ethical use
|
|
111
|
+
|
|
112
|
+
Only use HumanoidProbe against targets you have explicit permission to test.
|
|
113
|
+
Unauthorised testing is illegal. This tool is built for legitimate security research and bug bounty programmes only.
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## About
|
|
118
|
+
|
|
119
|
+
HumanoidProbe is the first tool from **CyberSafeLabs** — an independent cybersecurity research initiative focused on protecting digital assets through offensive research, vulnerability discovery, and practical security tooling.
|
|
120
|
+
|
|
121
|
+
The long-term vision: **Humanoid Intelligence** — an AI-powered security research platform built from real hunting experience.
|
|
122
|
+
|
|
123
|
+
*CyberSafeLabs — protecting digital assets through research*
|
|
File without changes
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# This module analyses each response and determines whether
|
|
2
|
+
# the payload was BLOCKED by the WAF or PASSED through.
|
|
3
|
+
|
|
4
|
+
# Status codes that typically indicate a WAF block
|
|
5
|
+
BLOCK_STATUS_CODES = [403, 406, 429, 503, 400]
|
|
6
|
+
|
|
7
|
+
# Keywords in the response body that suggest a WAF blocked the request
|
|
8
|
+
BLOCK_BODY_KEYWORDS = [
|
|
9
|
+
"blocked",
|
|
10
|
+
"forbidden",
|
|
11
|
+
"access denied",
|
|
12
|
+
"security",
|
|
13
|
+
"firewall",
|
|
14
|
+
"not acceptable",
|
|
15
|
+
"request rejected",
|
|
16
|
+
"detected as attack",
|
|
17
|
+
"malicious",
|
|
18
|
+
"illegal request",
|
|
19
|
+
"waf",
|
|
20
|
+
"cloudflare",
|
|
21
|
+
"incapsula",
|
|
22
|
+
"sucuri",
|
|
23
|
+
"akamai",
|
|
24
|
+
"barracuda",
|
|
25
|
+
"modsecurity",
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def analyse_result(result, baseline_length=None):
|
|
30
|
+
"""
|
|
31
|
+
Takes a single request result and classifies it as:
|
|
32
|
+
- BLOCKED : WAF caught the payload
|
|
33
|
+
- PASSED : Payload got through
|
|
34
|
+
- ERROR : Request failed entirely
|
|
35
|
+
- REFLECTED : Payload passed AND was reflected in the response body (high interest)
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
# If there was a network error, mark it
|
|
39
|
+
if result["error"]:
|
|
40
|
+
result["verdict"] = "ERROR"
|
|
41
|
+
result["reason"] = result["error"]
|
|
42
|
+
return result
|
|
43
|
+
|
|
44
|
+
status = result["status_code"]
|
|
45
|
+
body = result["response_body"].lower()
|
|
46
|
+
payload = result["payload"].lower()
|
|
47
|
+
|
|
48
|
+
# Check if status code indicates a block
|
|
49
|
+
if status in BLOCK_STATUS_CODES:
|
|
50
|
+
result["verdict"] = "BLOCKED"
|
|
51
|
+
result["reason"] = f"Status code {status}"
|
|
52
|
+
return result
|
|
53
|
+
|
|
54
|
+
# Check if response body contains WAF block keywords
|
|
55
|
+
for keyword in BLOCK_BODY_KEYWORDS:
|
|
56
|
+
if keyword in body:
|
|
57
|
+
result["verdict"] = "BLOCKED"
|
|
58
|
+
result["reason"] = f"Body contains WAF keyword: '{keyword}'"
|
|
59
|
+
return result
|
|
60
|
+
|
|
61
|
+
# Check if response length is significantly shorter than baseline
|
|
62
|
+
# (WAF sometimes returns a short block page)
|
|
63
|
+
if baseline_length and result["response_length"] < (baseline_length * 0.5):
|
|
64
|
+
result["verdict"] = "BLOCKED"
|
|
65
|
+
result["reason"] = "Response significantly shorter than baseline (possible block page)"
|
|
66
|
+
return result
|
|
67
|
+
|
|
68
|
+
# Check if the payload was reflected in the response body
|
|
69
|
+
# This is the most interesting case — payload got through AND appeared in the page
|
|
70
|
+
if result["payload"].lower() in body:
|
|
71
|
+
result["verdict"] = "REFLECTED"
|
|
72
|
+
result["reason"] = "Payload passed through AND was reflected in response"
|
|
73
|
+
return result
|
|
74
|
+
|
|
75
|
+
# If none of the above — payload passed but wasn't reflected
|
|
76
|
+
result["verdict"] = "PASSED"
|
|
77
|
+
result["reason"] = "No block indicators detected"
|
|
78
|
+
return result
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def analyse_all(results, baseline_length=None):
|
|
82
|
+
"""
|
|
83
|
+
Runs analyse_result on every result in the list.
|
|
84
|
+
Returns the full analysed list.
|
|
85
|
+
"""
|
|
86
|
+
return [analyse_result(r, baseline_length) for r in results]
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def get_baseline_length(url, parameter, timeout=10):
|
|
90
|
+
"""
|
|
91
|
+
Sends a clean harmless request first to get a normal response length.
|
|
92
|
+
This gives us a baseline to compare against when looking for block pages.
|
|
93
|
+
"""
|
|
94
|
+
import requests
|
|
95
|
+
|
|
96
|
+
try:
|
|
97
|
+
headers = {
|
|
98
|
+
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 Chrome/120.0.0.0 Safari/537.36"
|
|
99
|
+
}
|
|
100
|
+
response = requests.get(url, params={parameter: "hello"}, headers=headers, timeout=timeout)
|
|
101
|
+
return len(response.text)
|
|
102
|
+
except Exception:
|
|
103
|
+
return None
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# This module handles all terminal output.
|
|
2
|
+
# It prints results cleanly as they come in and gives a final summary.
|
|
3
|
+
|
|
4
|
+
# ANSI colour codes for terminal output
|
|
5
|
+
GREEN = "\033[92m"
|
|
6
|
+
RED = "\033[91m"
|
|
7
|
+
YELLOW = "\033[93m"
|
|
8
|
+
CYAN = "\033[96m"
|
|
9
|
+
BOLD = "\033[1m"
|
|
10
|
+
RESET = "\033[0m"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def print_banner():
|
|
14
|
+
"""Prints the tool banner when it starts."""
|
|
15
|
+
print(f"""
|
|
16
|
+
{CYAN}{BOLD}
|
|
17
|
+
_ _ _ _ _____ _
|
|
18
|
+
| | | | (_) | || __ \ | |
|
|
19
|
+
| |__| |_ _ _ __ ___ __ _ _ __ ___ __| || |__) | __ ___ | |__ ___
|
|
20
|
+
| __ | | | | '_ ` _ \ / _` | '_ \ / _ |/ _` || ___/ '__/ _ \| '_ \ / _ |
|
|
21
|
+
| | | | |_| | | | | | | (_| | | | | (_) | (_| || | | | | (_) | |_) | __/
|
|
22
|
+
|_| |_|\__,_|_| |_| |_|\__,_|_| |_|\___/ \__,_||_| |_| \___/|_.__/ \___|
|
|
23
|
+
{RESET}
|
|
24
|
+
{BOLD} HumanoidProbe — XSS WAF Intelligence Tool{RESET}
|
|
25
|
+
{CYAN} by CyberSafeLabs{RESET}
|
|
26
|
+
Analyse WAF behaviour. Think like an attacker.
|
|
27
|
+
""")
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def print_result(result, index, total):
|
|
31
|
+
"""Prints a single result line as each payload is tested."""
|
|
32
|
+
verdict = result.get("verdict", "UNKNOWN")
|
|
33
|
+
payload = result["payload"]
|
|
34
|
+
|
|
35
|
+
# Truncate long payloads for display
|
|
36
|
+
display_payload = payload if len(payload) <= 60 else payload[:57] + "..."
|
|
37
|
+
|
|
38
|
+
if verdict == "REFLECTED":
|
|
39
|
+
status = f"{GREEN}{BOLD}[REFLECTED]{RESET}"
|
|
40
|
+
elif verdict == "PASSED":
|
|
41
|
+
status = f"{YELLOW}[PASSED]{RESET}"
|
|
42
|
+
elif verdict == "BLOCKED":
|
|
43
|
+
status = f"{RED}[BLOCKED]{RESET}"
|
|
44
|
+
else:
|
|
45
|
+
status = f"{CYAN}[ERROR]{RESET}"
|
|
46
|
+
|
|
47
|
+
print(f" [{index}/{total}] {status} {display_payload}")
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def print_summary(results, url, parameter):
|
|
51
|
+
"""Prints the final WAF behaviour summary after all payloads are tested."""
|
|
52
|
+
|
|
53
|
+
total = len(results)
|
|
54
|
+
blocked = [r for r in results if r.get("verdict") == "BLOCKED"]
|
|
55
|
+
passed = [r for r in results if r.get("verdict") == "PASSED"]
|
|
56
|
+
reflected = [r for r in results if r.get("verdict") == "REFLECTED"]
|
|
57
|
+
errors = [r for r in results if r.get("verdict") == "ERROR"]
|
|
58
|
+
|
|
59
|
+
print(f"\n{BOLD}{'─' * 60}{RESET}")
|
|
60
|
+
print(f"{BOLD} HUMANOIDPROBE — SCAN SUMMARY{RESET}")
|
|
61
|
+
print(f"{BOLD}{'─' * 60}{RESET}")
|
|
62
|
+
print(f" Target : {url}")
|
|
63
|
+
print(f" Parameter : {parameter}")
|
|
64
|
+
print(f" Total : {total} payloads tested")
|
|
65
|
+
print(f" {RED}Blocked : {len(blocked)}{RESET}")
|
|
66
|
+
print(f" {YELLOW}Passed : {len(passed)}{RESET}")
|
|
67
|
+
print(f" {GREEN}Reflected : {len(reflected)}{RESET}")
|
|
68
|
+
print(f" {CYAN}Errors : {len(errors)}{RESET}")
|
|
69
|
+
|
|
70
|
+
# Show reflected payloads — these are the most important findings
|
|
71
|
+
if reflected:
|
|
72
|
+
print(f"\n{GREEN}{BOLD} [!] REFLECTED PAYLOADS (Investigate these):{RESET}")
|
|
73
|
+
for r in reflected:
|
|
74
|
+
print(f" {GREEN}→ {r['payload']}{RESET}")
|
|
75
|
+
|
|
76
|
+
# Show passed payloads
|
|
77
|
+
if passed:
|
|
78
|
+
print(f"\n{YELLOW}{BOLD} [+] PASSED PAYLOADS (WAF did not block):{RESET}")
|
|
79
|
+
for r in passed:
|
|
80
|
+
print(f" {YELLOW}→ {r['payload']}{RESET}")
|
|
81
|
+
|
|
82
|
+
# WAF behaviour analysis
|
|
83
|
+
print(f"\n{BOLD} WAF BEHAVIOUR ANALYSIS:{RESET}")
|
|
84
|
+
|
|
85
|
+
if len(blocked) == total:
|
|
86
|
+
print(f" {RED}→ WAF blocked everything. Highly aggressive filtering.{RESET}")
|
|
87
|
+
print(f" Try: heavy encoding, unusual event handlers, exotic tags.")
|
|
88
|
+
|
|
89
|
+
elif len(blocked) == 0:
|
|
90
|
+
print(f" {GREEN}→ No blocks detected. WAF may be absent or very permissive.{RESET}")
|
|
91
|
+
print(f" Focus on reflected payloads and test for actual execution.")
|
|
92
|
+
|
|
93
|
+
elif len(reflected) > 0:
|
|
94
|
+
print(f" {GREEN}→ Some payloads reflected. Potential XSS surface found.{RESET}")
|
|
95
|
+
print(f" Prioritise reflected payloads and test in browser.")
|
|
96
|
+
|
|
97
|
+
else:
|
|
98
|
+
block_rate = (len(blocked) / total) * 100
|
|
99
|
+
print(f" → WAF blocked {block_rate:.0f}% of payloads.")
|
|
100
|
+
print(f" Review passed payloads — WAF has gaps worth exploring.")
|
|
101
|
+
|
|
102
|
+
# Analyse what types of payloads got blocked
|
|
103
|
+
_analyse_block_patterns(blocked)
|
|
104
|
+
|
|
105
|
+
print(f"\n{CYAN} Humanoid sees what others miss.{RESET}")
|
|
106
|
+
print(f"{BOLD}{'─' * 60}{RESET}\n")
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def _analyse_block_patterns(blocked):
|
|
110
|
+
"""Looks at blocked payloads and tries to identify what the WAF is filtering."""
|
|
111
|
+
if not blocked:
|
|
112
|
+
return
|
|
113
|
+
|
|
114
|
+
payloads = [r["payload"].lower() for r in blocked]
|
|
115
|
+
|
|
116
|
+
patterns = {
|
|
117
|
+
"script tags" : ["<script", "</script>"],
|
|
118
|
+
"event handlers" : ["onerror", "onload", "onfocus", "onclick", "onmouseover"],
|
|
119
|
+
"javascript:" : ["javascript:"],
|
|
120
|
+
"svg tags" : ["<svg"],
|
|
121
|
+
"iframe tags" : ["<iframe"],
|
|
122
|
+
"encoded payloads" : ["%3c", "%3e", "&#x", "%2f"],
|
|
123
|
+
"case variations" : ["<Script", "<SCRIPT", "<sCrIpT"],
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
detected = []
|
|
127
|
+
for pattern_name, keywords in patterns.items():
|
|
128
|
+
for payload in payloads:
|
|
129
|
+
if any(k.lower() in payload for k in keywords):
|
|
130
|
+
detected.append(pattern_name)
|
|
131
|
+
break
|
|
132
|
+
|
|
133
|
+
if detected:
|
|
134
|
+
print(f"\n {BOLD}WAF appears to filter:{RESET}")
|
|
135
|
+
for d in detected:
|
|
136
|
+
print(f" → {d}")
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
import time
|
|
3
|
+
|
|
4
|
+
# This module handles sending HTTP requests to the target URL
|
|
5
|
+
# with each payload injected into the specified GET parameter.
|
|
6
|
+
|
|
7
|
+
def send_payload(url, parameter, payload, timeout=10):
|
|
8
|
+
"""
|
|
9
|
+
Sends a single GET request with the payload injected into the parameter.
|
|
10
|
+
Returns a result dictionary with the payload, status code, and response body.
|
|
11
|
+
"""
|
|
12
|
+
try:
|
|
13
|
+
# Build the parameters dict — injects payload into the target parameter
|
|
14
|
+
params = {parameter: payload}
|
|
15
|
+
|
|
16
|
+
# Set a browser-like User-Agent to avoid being blocked for looking like a bot
|
|
17
|
+
headers = {
|
|
18
|
+
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 Chrome/120.0.0.0 Safari/537.36"
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
# Send the GET request
|
|
22
|
+
response = requests.get(url, params=params, headers=headers, timeout=timeout)
|
|
23
|
+
|
|
24
|
+
return {
|
|
25
|
+
"payload": payload,
|
|
26
|
+
"status_code": response.status_code,
|
|
27
|
+
"response_body": response.text,
|
|
28
|
+
"response_length": len(response.text),
|
|
29
|
+
"error": None
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
except requests.exceptions.Timeout:
|
|
33
|
+
return {
|
|
34
|
+
"payload": payload,
|
|
35
|
+
"status_code": None,
|
|
36
|
+
"response_body": "",
|
|
37
|
+
"response_length": 0,
|
|
38
|
+
"error": "Timeout"
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
except requests.exceptions.ConnectionError:
|
|
42
|
+
return {
|
|
43
|
+
"payload": payload,
|
|
44
|
+
"status_code": None,
|
|
45
|
+
"response_body": "",
|
|
46
|
+
"response_length": 0,
|
|
47
|
+
"error": "Connection error"
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
except Exception as e:
|
|
51
|
+
return {
|
|
52
|
+
"payload": payload,
|
|
53
|
+
"status_code": None,
|
|
54
|
+
"response_body": "",
|
|
55
|
+
"response_length": 0,
|
|
56
|
+
"error": str(e)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def send_all_payloads(url, parameter, payloads, delay=0.5):
|
|
61
|
+
"""
|
|
62
|
+
Loops through every payload, sends each one, and collects the results.
|
|
63
|
+
delay = seconds to wait between requests (be respectful to the target server).
|
|
64
|
+
"""
|
|
65
|
+
results = []
|
|
66
|
+
|
|
67
|
+
for payload in payloads:
|
|
68
|
+
result = send_payload(url, parameter, payload)
|
|
69
|
+
results.append(result)
|
|
70
|
+
time.sleep(delay) # Small delay between requests
|
|
71
|
+
|
|
72
|
+
return results
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
humanoidprobe.py — HumanoidProbe
|
|
5
|
+
CyberSafeLabs
|
|
6
|
+
|
|
7
|
+
Usage:
|
|
8
|
+
python3 humanoidprobe.py -u <url> -p <parameter>
|
|
9
|
+
|
|
10
|
+
Example:
|
|
11
|
+
python3 humanoidprobe.py -u https://example.com/search -p q
|
|
12
|
+
|
|
13
|
+
For ethical use only. Only test targets you have permission to test.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
import argparse
|
|
17
|
+
import os
|
|
18
|
+
import sys
|
|
19
|
+
|
|
20
|
+
from .core.requester import send_all_payloads
|
|
21
|
+
from .core.detector import analyse_all, get_baseline_length
|
|
22
|
+
from .core.reporter import print_banner, print_result, print_summary
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def load_payloads(filepath):
|
|
26
|
+
"""Loads payloads from a text file, one per line. Skips blank lines."""
|
|
27
|
+
if not os.path.exists(filepath):
|
|
28
|
+
print(f"[ERROR] Payload file not found: {filepath}")
|
|
29
|
+
sys.exit(1)
|
|
30
|
+
|
|
31
|
+
with open(filepath, "r") as f:
|
|
32
|
+
payloads = [line.strip() for line in f if line.strip()]
|
|
33
|
+
|
|
34
|
+
return payloads
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def main():
|
|
38
|
+
print_banner()
|
|
39
|
+
|
|
40
|
+
# --- Argument parsing ---
|
|
41
|
+
parser = argparse.ArgumentParser(
|
|
42
|
+
description="HumanoidProbe — XSS WAF Probe by CyberSafeLabs",
|
|
43
|
+
epilog="Example: python3 humanoidprobe.py -u https://example.com/search -p q"
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
parser.add_argument(
|
|
47
|
+
"-u", "--url",
|
|
48
|
+
required=True,
|
|
49
|
+
help="Target URL (e.g. https://example.com/search)"
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
parser.add_argument(
|
|
53
|
+
"-p", "--parameter",
|
|
54
|
+
required=True,
|
|
55
|
+
help="GET parameter to inject into (e.g. q)"
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
parser.add_argument(
|
|
59
|
+
"--payloads",
|
|
60
|
+
default=os.path.join(os.path.dirname(__file__), "payloads", "xss.txt"),
|
|
61
|
+
help="Path to custom payload file (default: payloads/xss.txt)"
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
parser.add_argument(
|
|
65
|
+
"--delay",
|
|
66
|
+
type=float,
|
|
67
|
+
default=0.5,
|
|
68
|
+
help="Delay in seconds between requests (default: 0.5)"
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
parser.add_argument(
|
|
72
|
+
"--timeout",
|
|
73
|
+
type=int,
|
|
74
|
+
default=10,
|
|
75
|
+
help="Request timeout in seconds (default: 10)"
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
args = parser.parse_args()
|
|
79
|
+
|
|
80
|
+
# --- Load payloads ---
|
|
81
|
+
print(f" [*] Loading payloads from: {args.payloads}")
|
|
82
|
+
payloads = load_payloads(args.payloads)
|
|
83
|
+
print(f" [*] Loaded {len(payloads)} payloads\n")
|
|
84
|
+
|
|
85
|
+
# --- Get baseline response length ---
|
|
86
|
+
print(f" [*] Getting baseline response for: {args.url}")
|
|
87
|
+
baseline_length = get_baseline_length(args.url, args.parameter, timeout=args.timeout)
|
|
88
|
+
if baseline_length:
|
|
89
|
+
print(f" [*] Baseline response length: {baseline_length} bytes\n")
|
|
90
|
+
else:
|
|
91
|
+
print(f" [!] Could not get baseline — continuing without it\n")
|
|
92
|
+
|
|
93
|
+
# --- Run the probe ---
|
|
94
|
+
print(f" [*] Starting probe on parameter '{args.parameter}'")
|
|
95
|
+
print(f" [*] Delay between requests: {args.delay}s\n")
|
|
96
|
+
print(f" {'─' * 60}")
|
|
97
|
+
|
|
98
|
+
total = len(payloads)
|
|
99
|
+
all_results = []
|
|
100
|
+
|
|
101
|
+
# Send payloads one by one and print result as we go
|
|
102
|
+
for i, payload in enumerate(payloads, start=1):
|
|
103
|
+
from core.requester import send_payload
|
|
104
|
+
from core.detector import analyse_result
|
|
105
|
+
|
|
106
|
+
raw_result = send_payload(args.url, args.parameter, payload, timeout=args.timeout)
|
|
107
|
+
analysed_result = analyse_result(raw_result, baseline_length)
|
|
108
|
+
all_results.append(analysed_result)
|
|
109
|
+
|
|
110
|
+
print_result(analysed_result, i, total)
|
|
111
|
+
|
|
112
|
+
import time
|
|
113
|
+
time.sleep(args.delay)
|
|
114
|
+
|
|
115
|
+
# --- Print final summary ---
|
|
116
|
+
print_summary(all_results, args.url, args.parameter)
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
if __name__ == "__main__":
|
|
120
|
+
main()
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: humanoidprobe
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: HumanoidProbe is a command-line XSS WAF intelligence tool that probes how a WAF responds to payload variations — telling you what gets blocked, what passes through, and what gets reflected back.
|
|
5
|
+
Author-email: CyberSafeLabs <hello.cybersafe@gmail.com>
|
|
6
|
+
Project-URL: Homepage, https://github.com/hellocybersafe/humanoidprobe
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
9
|
+
Classifier: Operating System :: OS Independent
|
|
10
|
+
Requires-Python: >=3.7
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
|
|
13
|
+
# HumanoidProbe
|
|
14
|
+
**by CyberSafeLabs**
|
|
15
|
+
|
|
16
|
+
> *Analyse WAF behaviour. Think like an attacker.*
|
|
17
|
+
|
|
18
|
+
HumanoidProbe is a command-line XSS WAF intelligence tool that probes how a WAF responds to payload variations — telling you what gets blocked, what passes through, and what gets reflected back.
|
|
19
|
+
|
|
20
|
+
Built from real bug bounty research. Not theory.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## What it does
|
|
25
|
+
|
|
26
|
+
- Fires categorised XSS payload variations at a target URL and parameter
|
|
27
|
+
- Detects WAF blocks via status codes, response body analysis, and response length changes
|
|
28
|
+
- Identifies reflected payloads — the highest value findings
|
|
29
|
+
- Summarises WAF behaviour and what it appears to be filtering
|
|
30
|
+
- Gives you actionable intelligence to craft smarter bypass payloads
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Installation
|
|
35
|
+
|
|
36
|
+
**1. Make sure Python 3 is installed**
|
|
37
|
+
```bash
|
|
38
|
+
python3 --version
|
|
39
|
+
```
|
|
40
|
+
If not:
|
|
41
|
+
```bash
|
|
42
|
+
sudo apt update && sudo apt install python3 python3-pip -y
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**2. Install the dependency**
|
|
46
|
+
```bash
|
|
47
|
+
pip3 install requests
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Usage
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
python3 humanoidprobe.py -u <URL> -p <parameter>
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
**Example:**
|
|
59
|
+
```bash
|
|
60
|
+
python3 humanoidprobe.py -u https://example.com/search -p q
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**With options:**
|
|
64
|
+
```bash
|
|
65
|
+
python3 humanoidprobe.py -u https://example.com/search -p q --delay 1 --timeout 15
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Options
|
|
71
|
+
|
|
72
|
+
| Flag | Description | Default |
|
|
73
|
+
|------|-------------|---------|
|
|
74
|
+
| `-u` / `--url` | Target URL | Required |
|
|
75
|
+
| `-p` / `--parameter` | GET parameter to test | Required |
|
|
76
|
+
| `--payloads` | Custom payload file path | payloads/xss.txt |
|
|
77
|
+
| `--delay` | Seconds between requests | 0.5 |
|
|
78
|
+
| `--timeout` | Request timeout in seconds | 10 |
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Output verdicts
|
|
83
|
+
|
|
84
|
+
| Verdict | Meaning |
|
|
85
|
+
|---------|---------|
|
|
86
|
+
| `REFLECTED` | Payload passed AND appeared in the response — investigate in browser immediately |
|
|
87
|
+
| `PASSED` | WAF did not block — worth exploring further |
|
|
88
|
+
| `BLOCKED` | WAF caught this payload |
|
|
89
|
+
| `ERROR` | Request failed (timeout, connection error) |
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## Project structure
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
humanoidprobe/
|
|
97
|
+
├── humanoidprobe.py # Main entry point — what you run
|
|
98
|
+
├── payloads/
|
|
99
|
+
│ └── xss.txt # XSS payload list
|
|
100
|
+
├── core/
|
|
101
|
+
│ ├── requester.py # Sends HTTP requests
|
|
102
|
+
│ ├── detector.py # Analyses responses (blocked vs passed)
|
|
103
|
+
│ └── reporter.py # Terminal output and summary
|
|
104
|
+
└── README.md
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Roadmap
|
|
110
|
+
|
|
111
|
+
- [ ] WAF memory — builds a profile of WAF behaviour across sessions
|
|
112
|
+
- [ ] Intelligent bypass suggestions — generates mutations based on what passed
|
|
113
|
+
- [ ] POST parameter support
|
|
114
|
+
- [ ] SQLi payload module
|
|
115
|
+
- [ ] Output to file (JSON / txt)
|
|
116
|
+
- [ ] Burp Suite integration
|
|
117
|
+
- [ ] Full recon and attack surface mapping modules
|
|
118
|
+
- [ ] Humanoid Intelligence — AI layer (coming in future versions)
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Legal & ethical use
|
|
123
|
+
|
|
124
|
+
Only use HumanoidProbe against targets you have explicit permission to test.
|
|
125
|
+
Unauthorised testing is illegal. This tool is built for legitimate security research and bug bounty programmes only.
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## About
|
|
130
|
+
|
|
131
|
+
HumanoidProbe is the first tool from **CyberSafeLabs** — an independent cybersecurity research initiative focused on protecting digital assets through offensive research, vulnerability discovery, and practical security tooling.
|
|
132
|
+
|
|
133
|
+
The long-term vision: **Humanoid Intelligence** — an AI-powered security research platform built from real hunting experience.
|
|
134
|
+
|
|
135
|
+
*CyberSafeLabs — protecting digital assets through research*
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
humanoidprobe/__init__.py
|
|
4
|
+
humanoidprobe/humanoidprobe.py
|
|
5
|
+
humanoidprobe.egg-info/PKG-INFO
|
|
6
|
+
humanoidprobe.egg-info/SOURCES.txt
|
|
7
|
+
humanoidprobe.egg-info/dependency_links.txt
|
|
8
|
+
humanoidprobe.egg-info/entry_points.txt
|
|
9
|
+
humanoidprobe.egg-info/top_level.txt
|
|
10
|
+
humanoidprobe/core/detector.py
|
|
11
|
+
humanoidprobe/core/reporter.py
|
|
12
|
+
humanoidprobe/core/requester.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
humanoidprobe
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "humanoidprobe"
|
|
7
|
+
version = "1.0.0"
|
|
8
|
+
authors = [
|
|
9
|
+
{ name="CyberSafeLabs", email="hello.cybersafe@gmail.com" },
|
|
10
|
+
]
|
|
11
|
+
description = "HumanoidProbe is a command-line XSS WAF intelligence tool that probes how a WAF responds to payload variations — telling you what gets blocked, what passes through, and what gets reflected back."
|
|
12
|
+
readme = "README.md"
|
|
13
|
+
requires-python = ">=3.7"
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Programming Language :: Python :: 3",
|
|
16
|
+
"License :: OSI Approved :: MIT License",
|
|
17
|
+
"Operating System :: OS Independent",
|
|
18
|
+
]
|
|
19
|
+
dependencies = []
|
|
20
|
+
|
|
21
|
+
[project.urls]
|
|
22
|
+
"Homepage" = "https://github.com/hellocybersafe/humanoidprobe"
|
|
23
|
+
|
|
24
|
+
[project.scripts]
|
|
25
|
+
humanoidprobe = "humanoidprobe.humanoidprobe:main"
|