opensquat 2.2__tar.gz → 2.2.2__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.
- opensquat-2.2.2/PKG-INFO +249 -0
- opensquat-2.2.2/README.md +217 -0
- {opensquat-2.2 → opensquat-2.2.2}/opensquat/__init__.py +1 -1
- opensquat-2.2.2/opensquat/app.py +160 -0
- {opensquat-2.2 → opensquat-2.2.2}/opensquat/arg_parser.py +21 -33
- {opensquat-2.2 → opensquat-2.2.2}/opensquat/check_update.py +4 -2
- opensquat-2.2.2/opensquat/cli.py +171 -0
- {opensquat-2.2 → opensquat-2.2.2}/opensquat/ct.py +3 -4
- {opensquat-2.2 → opensquat-2.2.2}/opensquat/dns_resolvers.py +1 -2
- opensquat-2.2.2/opensquat/dns_validator.py +46 -0
- opensquat-2.2.2/opensquat/feed_manager.py +140 -0
- {opensquat-2.2 → opensquat-2.2.2}/opensquat/file_input.py +5 -3
- {opensquat-2.2 → opensquat-2.2.2}/opensquat/homograph.py +1 -2
- {opensquat-2.2 → opensquat-2.2.2}/opensquat/output.py +1 -2
- {opensquat-2.2 → opensquat-2.2.2}/opensquat/phishing.py +3 -4
- {opensquat-2.2 → opensquat-2.2.2}/opensquat/port_check.py +14 -18
- opensquat-2.2.2/opensquat/squatting_detector.py +144 -0
- opensquat-2.2.2/opensquat/validations.py +59 -0
- opensquat-2.2.2/opensquat.egg-info/PKG-INFO +249 -0
- {opensquat-2.2 → opensquat-2.2.2}/opensquat.egg-info/SOURCES.txt +6 -2
- opensquat-2.2.2/opensquat.egg-info/entry_points.txt +2 -0
- opensquat-2.2.2/opensquat.egg-info/requires.txt +6 -0
- {opensquat-2.2 → opensquat-2.2.2}/opensquat.egg-info/top_level.txt +0 -1
- opensquat-2.2.2/pyproject.toml +53 -0
- opensquat-2.2.2/tests/test_ct.py +46 -0
- opensquat-2.2.2/tests/test_validations.py +8 -0
- opensquat-2.2/PKG-INFO +0 -179
- opensquat-2.2/README.md +0 -168
- opensquat-2.2/opensquat/app.py +0 -638
- opensquat-2.2/opensquat/validations.py +0 -42
- opensquat-2.2/opensquat.egg-info/PKG-INFO +0 -179
- opensquat-2.2/opensquat.egg-info/requires.txt +0 -15
- opensquat-2.2/setup.py +0 -34
- opensquat-2.2/tests/__init__.py +0 -0
- opensquat-2.2/tests/test_ct.py +0 -19
- opensquat-2.2/tests/test_validations.py +0 -12
- {opensquat-2.2 → opensquat-2.2.2}/LICENSE +0 -0
- {opensquat-2.2 → opensquat-2.2.2}/opensquat/vt.py +0 -0
- {opensquat-2.2 → opensquat-2.2.2}/opensquat.egg-info/dependency_links.txt +0 -0
- {opensquat-2.2 → opensquat-2.2.2}/setup.cfg +0 -0
opensquat-2.2.2/PKG-INFO
ADDED
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: opensquat
|
|
3
|
+
Version: 2.2.2
|
|
4
|
+
Summary: openSquat - Detection of domain squatting, typosquatting, IDN homograph attacks, and phishing threats
|
|
5
|
+
Author-email: Andre Tenreiro <andre@opensquat.com>
|
|
6
|
+
License-Expression: GPL-3.0-only
|
|
7
|
+
Project-URL: Homepage, https://opensquat.com
|
|
8
|
+
Project-URL: Repository, https://github.com/atenreiro/opensquat
|
|
9
|
+
Project-URL: Issues, https://github.com/atenreiro/opensquat/issues
|
|
10
|
+
Keywords: cybersecurity,phishing,typosquatting,domain-squatting,osint,homograph,brand-protection
|
|
11
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
12
|
+
Classifier: Intended Audience :: Information Technology
|
|
13
|
+
Classifier: Intended Audience :: System Administrators
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Topic :: Security
|
|
22
|
+
Requires-Python: >=3.8
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
License-File: LICENSE
|
|
25
|
+
Requires-Dist: confusable_homoglyphs>=2.0.0
|
|
26
|
+
Requires-Dist: homoglyphs>=2.0.0
|
|
27
|
+
Requires-Dist: colorama>=0.4.1
|
|
28
|
+
Requires-Dist: requests>=2.20.0
|
|
29
|
+
Requires-Dist: beautifulsoup4>=4.4.0
|
|
30
|
+
Requires-Dist: dnspython>=2.0.0
|
|
31
|
+
Dynamic: license-file
|
|
32
|
+
|
|
33
|
+
<p align="center">
|
|
34
|
+
<img src="https://raw.githubusercontent.com/atenreiro/opensquat/master/screenshots/openSquat_logo.png" alt="openSquat Logo" width="400"/>
|
|
35
|
+
</p>
|
|
36
|
+
|
|
37
|
+
<h1 align="center">openSquat Core</h1>
|
|
38
|
+
|
|
39
|
+
<p align="center">
|
|
40
|
+
<a href="#"><img src="https://img.shields.io/badge/python-3.8+-blue.svg" alt="Python 3.8+"></a>
|
|
41
|
+
<a href="https://github.com/atenreiro/opensquat/blob/master/LICENSE"><img src="https://img.shields.io/badge/License-GPLv3-blue.svg" alt="License: GPL v3"></a>
|
|
42
|
+
<a href="https://github.com/atenreiro/opensquat/issues"><img src="https://img.shields.io/github/issues/atenreiro/opensquat" alt="GitHub issues"></a>
|
|
43
|
+
<a href="https://github.com/atenreiro/opensquat/stargazers"><img src="https://img.shields.io/github/stars/atenreiro/opensquat" alt="GitHub stars"></a>
|
|
44
|
+
</p>
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## 📑 Table of Contents
|
|
49
|
+
|
|
50
|
+
- [What is openSquat?](#-what-is-opensquat)
|
|
51
|
+
- [Open-Core Model](#-open-core-model)
|
|
52
|
+
- [Key Features](#-key-features)
|
|
53
|
+
- [Quick Start](#-quick-start)
|
|
54
|
+
- [Requirements](#-requirements)
|
|
55
|
+
- [Usage](#-usage)
|
|
56
|
+
- [Configuration](#%EF%B8%8F-configuration)
|
|
57
|
+
- [Automation](#-automation)
|
|
58
|
+
- [CLI Reference](#-cli-reference)
|
|
59
|
+
- [Contributing](#-contributing)
|
|
60
|
+
- [Author](#-author)
|
|
61
|
+
- [License](#-license)
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## 🎯 What is openSquat?
|
|
66
|
+
|
|
67
|
+
openSquat is an **Open Source Intelligence (OSINT)** security tool that identifies cyber squatting threats targeting your brand or domains:
|
|
68
|
+
|
|
69
|
+
| Threat Type | Description |
|
|
70
|
+
|-------------|-------------|
|
|
71
|
+
| 🎣 **Phishing** | Fraudulent domains mimicking your brand |
|
|
72
|
+
| 🔤 **Typosquatting** | Domains with common typos (e.g., `gooogle.com`) |
|
|
73
|
+
| 🌐 **IDN Homograph** | Look-alike characters from other alphabets |
|
|
74
|
+
| 👥 **Doppelgänger** | Domains containing your brand name |
|
|
75
|
+
| 🔀 **Bitsquatting** | Single-bit errors in domain names |
|
|
76
|
+
|
|
77
|
+
## 🔓 Open-Core Model
|
|
78
|
+
|
|
79
|
+
openSquat follows an **open-core model**:
|
|
80
|
+
|
|
81
|
+
- **Core detection engine** — Open source and community-driven
|
|
82
|
+
- **Advanced capabilities** — Delivered through commercial intelligence services
|
|
83
|
+
|
|
84
|
+
This model enables transparency and community collaboration while supporting the scale, reliability, and operational requirements of enterprise use.
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## ✨ Key Features
|
|
89
|
+
|
|
90
|
+
- 📅 **Daily NRD feeds** — Automatic newly registered domain updates
|
|
91
|
+
- 🔍 **Similarity detection** — Levenshtein distance algorithm
|
|
92
|
+
- 🛡️ **VirusTotal integration** — Check domain reputation
|
|
93
|
+
- 🌐 **Quad9 DNS validation** — Identify malicious domains
|
|
94
|
+
- 📜 **Certificate Transparency** — Monitor SSL/TLS certificates
|
|
95
|
+
- 📊 **Multiple output formats** — TXT, JSON, CSV
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## 🚀 Quick Start
|
|
100
|
+
|
|
101
|
+
### Install via pip (recommended)
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
pip install opensquat
|
|
105
|
+
opensquat -k keywords.txt
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Or clone the repository
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
git clone https://github.com/atenreiro/opensquat
|
|
112
|
+
cd opensquat
|
|
113
|
+
pip install -r requirements.txt
|
|
114
|
+
python opensquat.py -k keywords.txt
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## 📦 Requirements
|
|
120
|
+
|
|
121
|
+
- **Python 3.8+**
|
|
122
|
+
- Dependencies: `confusable_homoglyphs`, `homoglyphs`, `colorama`, `requests`, `dnspython`, `beautifulsoup4`
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## 📖 Usage
|
|
127
|
+
|
|
128
|
+
### Basic Commands
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
# Default run
|
|
132
|
+
opensquat
|
|
133
|
+
|
|
134
|
+
# Show all options
|
|
135
|
+
opensquat -h
|
|
136
|
+
|
|
137
|
+
# Use custom keywords file
|
|
138
|
+
opensquat -k my_keywords.txt
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Validation Options
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
# DNS validation via Quad9
|
|
145
|
+
opensquat --dns
|
|
146
|
+
|
|
147
|
+
# Check Certificate Transparency logs
|
|
148
|
+
opensquat --ct
|
|
149
|
+
|
|
150
|
+
# Scan for open ports (80/443)
|
|
151
|
+
opensquat --portcheck
|
|
152
|
+
|
|
153
|
+
# Cross-reference phishing databases
|
|
154
|
+
opensquat --phishing results.txt
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Output Formats
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
# Save as JSON
|
|
161
|
+
opensquat -o results.json -t json
|
|
162
|
+
|
|
163
|
+
# Save as CSV
|
|
164
|
+
opensquat -o results.csv -t csv
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Confidence Levels
|
|
168
|
+
|
|
169
|
+
| Level | Flag | Description |
|
|
170
|
+
|-------|------|-------------|
|
|
171
|
+
| 0 | `-c 0` | Very high (fewer results, high accuracy) |
|
|
172
|
+
| 1 | `-c 1` | High (default) |
|
|
173
|
+
| 2 | `-c 2` | Medium |
|
|
174
|
+
| 3 | `-c 3` | Low |
|
|
175
|
+
| 4 | `-c 4` | Very low (more results, more false positives) |
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## ⚙️ Configuration
|
|
180
|
+
|
|
181
|
+
### Keywords File (`keywords.txt`)
|
|
182
|
+
|
|
183
|
+
```text
|
|
184
|
+
# Lines starting with # are comments
|
|
185
|
+
mycompany
|
|
186
|
+
mybrand
|
|
187
|
+
myproduct
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### VirusTotal API Key (`vt_key.txt`)
|
|
191
|
+
|
|
192
|
+
To use `--vt` or `--subdomains`, add your API key:
|
|
193
|
+
```text
|
|
194
|
+
# Get your free API key at https://www.virustotal.com
|
|
195
|
+
your_api_key_here
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## 🤖 Automation
|
|
201
|
+
|
|
202
|
+
Run daily via crontab:
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
# Every day at 8 AM (feeds update ~7:30 AM UTC)
|
|
206
|
+
0 8 * * * /path/to/opensquat/opensquat.py -k keywords.txt -o results.json -t json
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## 📋 CLI Reference
|
|
212
|
+
|
|
213
|
+
| Argument | Default | Description |
|
|
214
|
+
|----------|---------|-------------|
|
|
215
|
+
| `-k, --keywords` | `keywords.txt` | Keywords file to search |
|
|
216
|
+
| `-o, --output` | `results.txt` | Output filename |
|
|
217
|
+
| `-t, --type` | `txt` | Output format: `txt`, `json`, `csv` |
|
|
218
|
+
| `-c, --confidence` | `1` | Confidence level (0-4) |
|
|
219
|
+
| `-d, --domains` | — | Use local domain file instead of downloading |
|
|
220
|
+
| `-u, --url` | opensquat feed | URL to download domain feed |
|
|
221
|
+
| `--dns` | — | Enable Quad9 DNS validation |
|
|
222
|
+
| `--doppelganger` | — | Doppelganger-only mode (keyword in domain + reachability check) |
|
|
223
|
+
| `--ct` | — | Search Certificate Transparency logs |
|
|
224
|
+
| `--phishing` | — | Cross-reference phishing database |
|
|
225
|
+
| `--subdomains` | — | Fetch subdomains via VirusTotal |
|
|
226
|
+
| `--portcheck` | — | Check for open ports 80/443 |
|
|
227
|
+
| `--vt` | — | Validate against VirusTotal |
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
## 🤝 Contributing
|
|
232
|
+
|
|
233
|
+
We welcome contributions! See our [Contributing Guide](CONTRIBUTING.md) for details.
|
|
234
|
+
|
|
235
|
+
- 🐛 **Report bugs** via [GitHub Issues](https://github.com/atenreiro/opensquat/issues)
|
|
236
|
+
- 💡 **Request features** by opening an issue
|
|
237
|
+
- 🔧 **Submit PRs** for bug fixes or enhancements
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
## 👤 Author
|
|
242
|
+
|
|
243
|
+
**Andre Tenreiro** — [LinkedIn](https://www.linkedin.com/in/andretenreiro/) · [PGP Key](https://mail-api.proton.me/pks/lookup?op=get&search=andre@opensquat.com)
|
|
244
|
+
|
|
245
|
+
---
|
|
246
|
+
|
|
247
|
+
## 📜 License
|
|
248
|
+
|
|
249
|
+
This project is licensed under the [GNU GPL v3](LICENSE).
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/atenreiro/opensquat/master/screenshots/openSquat_logo.png" alt="openSquat Logo" width="400"/>
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">openSquat Core</h1>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<a href="#"><img src="https://img.shields.io/badge/python-3.8+-blue.svg" alt="Python 3.8+"></a>
|
|
9
|
+
<a href="https://github.com/atenreiro/opensquat/blob/master/LICENSE"><img src="https://img.shields.io/badge/License-GPLv3-blue.svg" alt="License: GPL v3"></a>
|
|
10
|
+
<a href="https://github.com/atenreiro/opensquat/issues"><img src="https://img.shields.io/github/issues/atenreiro/opensquat" alt="GitHub issues"></a>
|
|
11
|
+
<a href="https://github.com/atenreiro/opensquat/stargazers"><img src="https://img.shields.io/github/stars/atenreiro/opensquat" alt="GitHub stars"></a>
|
|
12
|
+
</p>
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## 📑 Table of Contents
|
|
17
|
+
|
|
18
|
+
- [What is openSquat?](#-what-is-opensquat)
|
|
19
|
+
- [Open-Core Model](#-open-core-model)
|
|
20
|
+
- [Key Features](#-key-features)
|
|
21
|
+
- [Quick Start](#-quick-start)
|
|
22
|
+
- [Requirements](#-requirements)
|
|
23
|
+
- [Usage](#-usage)
|
|
24
|
+
- [Configuration](#%EF%B8%8F-configuration)
|
|
25
|
+
- [Automation](#-automation)
|
|
26
|
+
- [CLI Reference](#-cli-reference)
|
|
27
|
+
- [Contributing](#-contributing)
|
|
28
|
+
- [Author](#-author)
|
|
29
|
+
- [License](#-license)
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## 🎯 What is openSquat?
|
|
34
|
+
|
|
35
|
+
openSquat is an **Open Source Intelligence (OSINT)** security tool that identifies cyber squatting threats targeting your brand or domains:
|
|
36
|
+
|
|
37
|
+
| Threat Type | Description |
|
|
38
|
+
|-------------|-------------|
|
|
39
|
+
| 🎣 **Phishing** | Fraudulent domains mimicking your brand |
|
|
40
|
+
| 🔤 **Typosquatting** | Domains with common typos (e.g., `gooogle.com`) |
|
|
41
|
+
| 🌐 **IDN Homograph** | Look-alike characters from other alphabets |
|
|
42
|
+
| 👥 **Doppelgänger** | Domains containing your brand name |
|
|
43
|
+
| 🔀 **Bitsquatting** | Single-bit errors in domain names |
|
|
44
|
+
|
|
45
|
+
## 🔓 Open-Core Model
|
|
46
|
+
|
|
47
|
+
openSquat follows an **open-core model**:
|
|
48
|
+
|
|
49
|
+
- **Core detection engine** — Open source and community-driven
|
|
50
|
+
- **Advanced capabilities** — Delivered through commercial intelligence services
|
|
51
|
+
|
|
52
|
+
This model enables transparency and community collaboration while supporting the scale, reliability, and operational requirements of enterprise use.
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## ✨ Key Features
|
|
57
|
+
|
|
58
|
+
- 📅 **Daily NRD feeds** — Automatic newly registered domain updates
|
|
59
|
+
- 🔍 **Similarity detection** — Levenshtein distance algorithm
|
|
60
|
+
- 🛡️ **VirusTotal integration** — Check domain reputation
|
|
61
|
+
- 🌐 **Quad9 DNS validation** — Identify malicious domains
|
|
62
|
+
- 📜 **Certificate Transparency** — Monitor SSL/TLS certificates
|
|
63
|
+
- 📊 **Multiple output formats** — TXT, JSON, CSV
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## 🚀 Quick Start
|
|
68
|
+
|
|
69
|
+
### Install via pip (recommended)
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
pip install opensquat
|
|
73
|
+
opensquat -k keywords.txt
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Or clone the repository
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
git clone https://github.com/atenreiro/opensquat
|
|
80
|
+
cd opensquat
|
|
81
|
+
pip install -r requirements.txt
|
|
82
|
+
python opensquat.py -k keywords.txt
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## 📦 Requirements
|
|
88
|
+
|
|
89
|
+
- **Python 3.8+**
|
|
90
|
+
- Dependencies: `confusable_homoglyphs`, `homoglyphs`, `colorama`, `requests`, `dnspython`, `beautifulsoup4`
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## 📖 Usage
|
|
95
|
+
|
|
96
|
+
### Basic Commands
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
# Default run
|
|
100
|
+
opensquat
|
|
101
|
+
|
|
102
|
+
# Show all options
|
|
103
|
+
opensquat -h
|
|
104
|
+
|
|
105
|
+
# Use custom keywords file
|
|
106
|
+
opensquat -k my_keywords.txt
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Validation Options
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
# DNS validation via Quad9
|
|
113
|
+
opensquat --dns
|
|
114
|
+
|
|
115
|
+
# Check Certificate Transparency logs
|
|
116
|
+
opensquat --ct
|
|
117
|
+
|
|
118
|
+
# Scan for open ports (80/443)
|
|
119
|
+
opensquat --portcheck
|
|
120
|
+
|
|
121
|
+
# Cross-reference phishing databases
|
|
122
|
+
opensquat --phishing results.txt
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Output Formats
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
# Save as JSON
|
|
129
|
+
opensquat -o results.json -t json
|
|
130
|
+
|
|
131
|
+
# Save as CSV
|
|
132
|
+
opensquat -o results.csv -t csv
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Confidence Levels
|
|
136
|
+
|
|
137
|
+
| Level | Flag | Description |
|
|
138
|
+
|-------|------|-------------|
|
|
139
|
+
| 0 | `-c 0` | Very high (fewer results, high accuracy) |
|
|
140
|
+
| 1 | `-c 1` | High (default) |
|
|
141
|
+
| 2 | `-c 2` | Medium |
|
|
142
|
+
| 3 | `-c 3` | Low |
|
|
143
|
+
| 4 | `-c 4` | Very low (more results, more false positives) |
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## ⚙️ Configuration
|
|
148
|
+
|
|
149
|
+
### Keywords File (`keywords.txt`)
|
|
150
|
+
|
|
151
|
+
```text
|
|
152
|
+
# Lines starting with # are comments
|
|
153
|
+
mycompany
|
|
154
|
+
mybrand
|
|
155
|
+
myproduct
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### VirusTotal API Key (`vt_key.txt`)
|
|
159
|
+
|
|
160
|
+
To use `--vt` or `--subdomains`, add your API key:
|
|
161
|
+
```text
|
|
162
|
+
# Get your free API key at https://www.virustotal.com
|
|
163
|
+
your_api_key_here
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## 🤖 Automation
|
|
169
|
+
|
|
170
|
+
Run daily via crontab:
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
# Every day at 8 AM (feeds update ~7:30 AM UTC)
|
|
174
|
+
0 8 * * * /path/to/opensquat/opensquat.py -k keywords.txt -o results.json -t json
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## 📋 CLI Reference
|
|
180
|
+
|
|
181
|
+
| Argument | Default | Description |
|
|
182
|
+
|----------|---------|-------------|
|
|
183
|
+
| `-k, --keywords` | `keywords.txt` | Keywords file to search |
|
|
184
|
+
| `-o, --output` | `results.txt` | Output filename |
|
|
185
|
+
| `-t, --type` | `txt` | Output format: `txt`, `json`, `csv` |
|
|
186
|
+
| `-c, --confidence` | `1` | Confidence level (0-4) |
|
|
187
|
+
| `-d, --domains` | — | Use local domain file instead of downloading |
|
|
188
|
+
| `-u, --url` | opensquat feed | URL to download domain feed |
|
|
189
|
+
| `--dns` | — | Enable Quad9 DNS validation |
|
|
190
|
+
| `--doppelganger` | — | Doppelganger-only mode (keyword in domain + reachability check) |
|
|
191
|
+
| `--ct` | — | Search Certificate Transparency logs |
|
|
192
|
+
| `--phishing` | — | Cross-reference phishing database |
|
|
193
|
+
| `--subdomains` | — | Fetch subdomains via VirusTotal |
|
|
194
|
+
| `--portcheck` | — | Check for open ports 80/443 |
|
|
195
|
+
| `--vt` | — | Validate against VirusTotal |
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## 🤝 Contributing
|
|
200
|
+
|
|
201
|
+
We welcome contributions! See our [Contributing Guide](CONTRIBUTING.md) for details.
|
|
202
|
+
|
|
203
|
+
- 🐛 **Report bugs** via [GitHub Issues](https://github.com/atenreiro/opensquat/issues)
|
|
204
|
+
- 💡 **Request features** by opening an issue
|
|
205
|
+
- 🔧 **Submit PRs** for bug fixes or enhancements
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## 👤 Author
|
|
210
|
+
|
|
211
|
+
**Andre Tenreiro** — [LinkedIn](https://www.linkedin.com/in/andretenreiro/) · [PGP Key](https://mail-api.proton.me/pks/lookup?op=get&search=andre@opensquat.com)
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## 📜 License
|
|
216
|
+
|
|
217
|
+
This project is licensed under the [GNU GPL v3](LICENSE).
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Module: app.py
|
|
3
|
+
"""
|
|
4
|
+
openSquat
|
|
5
|
+
|
|
6
|
+
(c) Andre Tenreiro
|
|
7
|
+
|
|
8
|
+
* https://github.com/atenreiro/opensquat
|
|
9
|
+
|
|
10
|
+
software licensed under GNU version 3
|
|
11
|
+
"""
|
|
12
|
+
import concurrent.futures
|
|
13
|
+
import functools
|
|
14
|
+
import io
|
|
15
|
+
from colorama import Fore, Style
|
|
16
|
+
|
|
17
|
+
from opensquat import file_input
|
|
18
|
+
from opensquat.feed_manager import FeedManager
|
|
19
|
+
from opensquat.dns_validator import DNSValidator
|
|
20
|
+
from opensquat.squatting_detector import SquattingDetector
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class Domain:
|
|
24
|
+
"""
|
|
25
|
+
Main orchestration class for OpenSquat.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
def __init__(self):
|
|
29
|
+
"""Initiator."""
|
|
30
|
+
self.domain_filename = None
|
|
31
|
+
self.keywords_filename = None
|
|
32
|
+
self.domain_total = 0
|
|
33
|
+
self.keywords_total = 0
|
|
34
|
+
self.list_domains = []
|
|
35
|
+
self.confidence_level = 2
|
|
36
|
+
self.doppelganger_only = False
|
|
37
|
+
|
|
38
|
+
self.feed_manager = None
|
|
39
|
+
self.dns_validator = None
|
|
40
|
+
self.squatting_detector = None
|
|
41
|
+
|
|
42
|
+
self.list_file_domains = []
|
|
43
|
+
self.list_file_keywords = []
|
|
44
|
+
|
|
45
|
+
def count_files(self):
|
|
46
|
+
(self.keywords_total, self.domain_total) = file_input.InputFile().main(
|
|
47
|
+
self.keywords_filename,
|
|
48
|
+
self.domain_filename
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
def read_files(self):
|
|
52
|
+
"""
|
|
53
|
+
Method to read domain files
|
|
54
|
+
"""
|
|
55
|
+
with open(self.domain_filename, mode='r') as file_domains:
|
|
56
|
+
for mydomains in file_domains:
|
|
57
|
+
domain = mydomains.replace("\n", "")
|
|
58
|
+
domain = domain.lower().strip()
|
|
59
|
+
# Skip comments and empty lines
|
|
60
|
+
if domain and not domain.startswith("#"):
|
|
61
|
+
self.list_file_domains.append(domain)
|
|
62
|
+
|
|
63
|
+
with open(self.keywords_filename, mode='r') as file_keywords:
|
|
64
|
+
for line in file_keywords:
|
|
65
|
+
line = line.strip()
|
|
66
|
+
if line and not line.startswith("#"):
|
|
67
|
+
self.list_file_keywords.append(line)
|
|
68
|
+
|
|
69
|
+
def print_info(self):
|
|
70
|
+
"""
|
|
71
|
+
Method to print some configuration information.
|
|
72
|
+
"""
|
|
73
|
+
print("[*] keywords:", self.keywords_filename)
|
|
74
|
+
print("[*] keywords total:", self.keywords_total)
|
|
75
|
+
print("[*] Total domains:", f"{self.domain_total:,}")
|
|
76
|
+
|
|
77
|
+
print("[*] Threshold:", self.squatting_detector.confidence.get(self.confidence_level, "unknown"))
|
|
78
|
+
|
|
79
|
+
@staticmethod
|
|
80
|
+
def verify_keyword_task(detector, domains_list, keyword_info):
|
|
81
|
+
"""
|
|
82
|
+
Static worker method for parallel execution.
|
|
83
|
+
"""
|
|
84
|
+
keyword, keyword_line_number, keywords_total = keyword_info
|
|
85
|
+
|
|
86
|
+
result_buffer = io.StringIO()
|
|
87
|
+
print(
|
|
88
|
+
f"[+] Starting Domain Squatting verification for '{keyword}' [{keyword_line_number}/{keywords_total}]",
|
|
89
|
+
file=result_buffer
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
print(
|
|
93
|
+
Fore.WHITE + "\n[*] Verifying keyword:",
|
|
94
|
+
keyword,
|
|
95
|
+
"[",
|
|
96
|
+
keyword_line_number,
|
|
97
|
+
"/",
|
|
98
|
+
keywords_total,
|
|
99
|
+
"]" + Style.RESET_ALL,
|
|
100
|
+
file=result_buffer
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
result_domains = detector.check(keyword, domains_list, result_buffer)
|
|
104
|
+
return result_buffer, result_domains
|
|
105
|
+
|
|
106
|
+
def worker(self):
|
|
107
|
+
"""
|
|
108
|
+
Method that will compute all the similarity calculations between
|
|
109
|
+
the keywords and domain names.
|
|
110
|
+
"""
|
|
111
|
+
with concurrent.futures.ProcessPoolExecutor() as executor:
|
|
112
|
+
keyword_infos = [
|
|
113
|
+
(keyword, i + 1, self.keywords_total)
|
|
114
|
+
for i, keyword in enumerate(self.list_file_keywords) if keyword
|
|
115
|
+
]
|
|
116
|
+
|
|
117
|
+
worker_func = functools.partial(self.verify_keyword_task, self.squatting_detector, self.list_file_domains)
|
|
118
|
+
|
|
119
|
+
futs = [executor.submit(worker_func, k_info) for k_info in keyword_infos]
|
|
120
|
+
|
|
121
|
+
for fut in futs:
|
|
122
|
+
result_buffer, result_domains = fut.result()
|
|
123
|
+
print(result_buffer.getvalue())
|
|
124
|
+
self.list_domains.extend(result_domains)
|
|
125
|
+
|
|
126
|
+
return self.list_domains
|
|
127
|
+
|
|
128
|
+
def main(
|
|
129
|
+
self,
|
|
130
|
+
keywords_file,
|
|
131
|
+
confidence_level,
|
|
132
|
+
domains_file,
|
|
133
|
+
dns,
|
|
134
|
+
doppelganger_only=False,
|
|
135
|
+
feed_url="https://feeds.opensquat.com/opensquat-nrd-latest.txt",
|
|
136
|
+
):
|
|
137
|
+
print("+---------- Checking Domain Squatting ----------+")
|
|
138
|
+
self.keywords_filename = keywords_file
|
|
139
|
+
self.domain_filename = domains_file
|
|
140
|
+
self.confidence_level = confidence_level
|
|
141
|
+
self.doppelganger_only = doppelganger_only
|
|
142
|
+
|
|
143
|
+
self.dns_validator = DNSValidator(use_dns=dns)
|
|
144
|
+
self.squatting_detector = SquattingDetector(
|
|
145
|
+
confidence_level=confidence_level,
|
|
146
|
+
doppelganger_only=doppelganger_only,
|
|
147
|
+
dns_validator=self.dns_validator
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
# Feed Management
|
|
151
|
+
self.feed_manager = FeedManager(feed_url=feed_url)
|
|
152
|
+
if self.domain_filename == "":
|
|
153
|
+
self.domain_filename = self.feed_manager.local_filename
|
|
154
|
+
self.feed_manager.ensure_feeds()
|
|
155
|
+
|
|
156
|
+
self.count_files()
|
|
157
|
+
self.read_files()
|
|
158
|
+
self.print_info()
|
|
159
|
+
|
|
160
|
+
return self.worker()
|