osintkit 0.1.0
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.
- package/README.md +86 -0
- package/bin/osintkit.js +7 -0
- package/osintkit/__init__.py +3 -0
- package/osintkit/__pycache__/__init__.cpython-311.pyc +0 -0
- package/osintkit/__pycache__/cli.cpython-311.pyc +0 -0
- package/osintkit/__pycache__/config.cpython-311.pyc +0 -0
- package/osintkit/__pycache__/profiles.cpython-311.pyc +0 -0
- package/osintkit/__pycache__/risk.cpython-311.pyc +0 -0
- package/osintkit/__pycache__/scanner.cpython-311.pyc +0 -0
- package/osintkit/cli.py +613 -0
- package/osintkit/config.py +51 -0
- package/osintkit/modules/__init__.py +6 -0
- package/osintkit/modules/__pycache__/__init__.cpython-311.pyc +0 -0
- package/osintkit/modules/__pycache__/breach.cpython-311.pyc +0 -0
- package/osintkit/modules/__pycache__/brokers.cpython-311.pyc +0 -0
- package/osintkit/modules/__pycache__/certs.cpython-311.pyc +0 -0
- package/osintkit/modules/__pycache__/dark_web.cpython-311.pyc +0 -0
- package/osintkit/modules/__pycache__/gravatar.cpython-311.pyc +0 -0
- package/osintkit/modules/__pycache__/harvester.cpython-311.pyc +0 -0
- package/osintkit/modules/__pycache__/hibp.cpython-311.pyc +0 -0
- package/osintkit/modules/__pycache__/hibp_kanon.cpython-311.pyc +0 -0
- package/osintkit/modules/__pycache__/holehe.cpython-311.pyc +0 -0
- package/osintkit/modules/__pycache__/libphonenumber_info.cpython-311.pyc +0 -0
- package/osintkit/modules/__pycache__/paste.cpython-311.pyc +0 -0
- package/osintkit/modules/__pycache__/phone.cpython-311.pyc +0 -0
- package/osintkit/modules/__pycache__/sherlock.cpython-311.pyc +0 -0
- package/osintkit/modules/__pycache__/social.cpython-311.pyc +0 -0
- package/osintkit/modules/__pycache__/wayback.cpython-311.pyc +0 -0
- package/osintkit/modules/breach.py +82 -0
- package/osintkit/modules/brokers.py +56 -0
- package/osintkit/modules/certs.py +42 -0
- package/osintkit/modules/dark_web.py +51 -0
- package/osintkit/modules/gravatar.py +50 -0
- package/osintkit/modules/harvester.py +56 -0
- package/osintkit/modules/hibp.py +40 -0
- package/osintkit/modules/hibp_kanon.py +66 -0
- package/osintkit/modules/holehe.py +39 -0
- package/osintkit/modules/libphonenumber_info.py +79 -0
- package/osintkit/modules/paste.py +55 -0
- package/osintkit/modules/phone.py +32 -0
- package/osintkit/modules/sherlock.py +48 -0
- package/osintkit/modules/social.py +58 -0
- package/osintkit/modules/stage2/__init__.py +1 -0
- package/osintkit/modules/stage2/github_api.py +65 -0
- package/osintkit/modules/stage2/hunter.py +64 -0
- package/osintkit/modules/stage2/leakcheck.py +58 -0
- package/osintkit/modules/stage2/numverify.py +62 -0
- package/osintkit/modules/stage2/securitytrails.py +65 -0
- package/osintkit/modules/wayback.py +70 -0
- package/osintkit/output/__init__.py +1 -0
- package/osintkit/output/__pycache__/__init__.cpython-311.pyc +0 -0
- package/osintkit/output/__pycache__/html_writer.cpython-311.pyc +0 -0
- package/osintkit/output/__pycache__/json_writer.cpython-311.pyc +0 -0
- package/osintkit/output/__pycache__/md_writer.cpython-311.pyc +0 -0
- package/osintkit/output/html_writer.py +36 -0
- package/osintkit/output/json_writer.py +31 -0
- package/osintkit/output/md_writer.py +115 -0
- package/osintkit/output/templates/report.html +74 -0
- package/osintkit/profiles.py +116 -0
- package/osintkit/risk.py +42 -0
- package/osintkit/scanner.py +240 -0
- package/osintkit/setup.py +157 -0
- package/package.json +25 -0
- package/pyproject.toml +44 -0
- package/requirements.txt +9 -0
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
"""First-time setup wizard for osintkit."""
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from rich.console import Console
|
|
5
|
+
from rich.prompt import Prompt, Confirm
|
|
6
|
+
from rich.panel import Panel
|
|
7
|
+
from rich.table import Table
|
|
8
|
+
import yaml
|
|
9
|
+
|
|
10
|
+
console = Console()
|
|
11
|
+
|
|
12
|
+
# Free API keys with their limits
|
|
13
|
+
FREE_API_KEYS = {
|
|
14
|
+
"hibp": {
|
|
15
|
+
"name": "Have I Been Pwned",
|
|
16
|
+
"description": "Breach database lookups",
|
|
17
|
+
"limits": "10 requests/minute (free tier)",
|
|
18
|
+
"url": "https://haveibeenpwned.com/API/Key",
|
|
19
|
+
"required": False,
|
|
20
|
+
},
|
|
21
|
+
"numverify": {
|
|
22
|
+
"name": "NumVerify",
|
|
23
|
+
"description": "Phone number validation",
|
|
24
|
+
"limits": "100 requests/month (free tier)",
|
|
25
|
+
"url": "https://numverify.com/",
|
|
26
|
+
"required": False,
|
|
27
|
+
},
|
|
28
|
+
"intelbase": {
|
|
29
|
+
"name": "Intelbase",
|
|
30
|
+
"description": "Dark web & paste search",
|
|
31
|
+
"limits": "100 requests/month (free tier)",
|
|
32
|
+
"url": "https://intelbase.is",
|
|
33
|
+
"required": False,
|
|
34
|
+
},
|
|
35
|
+
"breachdirectory": {
|
|
36
|
+
"name": "BreachDirectory (RapidAPI)",
|
|
37
|
+
"description": "Breach lookups",
|
|
38
|
+
"limits": "50 requests/day (RapidAPI free tier)",
|
|
39
|
+
"url": "https://rapidapi.com/rohan-patel/api/breachdirectory",
|
|
40
|
+
"required": False,
|
|
41
|
+
},
|
|
42
|
+
"google_cse": {
|
|
43
|
+
"name": "Google Custom Search",
|
|
44
|
+
"description": "Data broker detection",
|
|
45
|
+
"limits": "100 requests/day (free tier)",
|
|
46
|
+
"url": "https://developers.google.com/custom-search/v1/introduction",
|
|
47
|
+
"required": False,
|
|
48
|
+
"needs_two_keys": True, # key + cx
|
|
49
|
+
},
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def is_first_run() -> bool:
|
|
54
|
+
"""Check if this is the first run."""
|
|
55
|
+
config_path = Path.home() / ".osintkit" / "config.yaml"
|
|
56
|
+
return not config_path.exists()
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def run_setup_wizard():
|
|
60
|
+
"""Run the first-time setup wizard."""
|
|
61
|
+
console.print(Panel.fit(
|
|
62
|
+
"[bold cyan]Welcome to osintkit![/bold cyan]\n\n"
|
|
63
|
+
"OSINT tool for personal digital footprint analysis.\n"
|
|
64
|
+
"Let's set up your API keys (all optional, free tiers available).",
|
|
65
|
+
title="🚀 First-Time Setup",
|
|
66
|
+
))
|
|
67
|
+
|
|
68
|
+
console.print("\n[yellow]API keys unlock more search capabilities.[/yellow]")
|
|
69
|
+
console.print("[dim]You can skip any key and add them later with 'osintkit setup'[/dim]\n")
|
|
70
|
+
|
|
71
|
+
# Show available APIs
|
|
72
|
+
table = Table(title="Available Free APIs")
|
|
73
|
+
table.add_column("Service", style="cyan")
|
|
74
|
+
table.add_column("What it does")
|
|
75
|
+
table.add_column("Free Limits")
|
|
76
|
+
|
|
77
|
+
for key_id, info in FREE_API_KEYS.items():
|
|
78
|
+
table.add_row(info["name"], info["description"], info["limits"])
|
|
79
|
+
|
|
80
|
+
console.print(table)
|
|
81
|
+
console.print()
|
|
82
|
+
|
|
83
|
+
# Collect API keys
|
|
84
|
+
api_keys = {}
|
|
85
|
+
|
|
86
|
+
if Confirm.ask("\nConfigure API keys now?", default=True):
|
|
87
|
+
for key_id, info in FREE_API_KEYS.items():
|
|
88
|
+
console.print(f"\n[bold]{info['name']}[/bold] - {info['description']}")
|
|
89
|
+
console.print(f"[dim]Limits: {info['limits']}[/dim]")
|
|
90
|
+
console.print(f"[dim]Get key: {info['url']}[/dim]")
|
|
91
|
+
|
|
92
|
+
if info.get("needs_two_keys"):
|
|
93
|
+
key = Prompt.ask(f" API Key", default="")
|
|
94
|
+
cx = Prompt.ask(f" Custom Search Engine ID (cx)", default="")
|
|
95
|
+
api_keys[f"{key_id}_key"] = key.strip()
|
|
96
|
+
api_keys[f"{key_id}_cx"] = cx.strip()
|
|
97
|
+
else:
|
|
98
|
+
key = Prompt.ask(f" API Key (or press Enter to skip)", default="")
|
|
99
|
+
api_keys[key_id] = key.strip()
|
|
100
|
+
else:
|
|
101
|
+
# Initialize with empty keys
|
|
102
|
+
api_keys = {
|
|
103
|
+
"hibp": "",
|
|
104
|
+
"numverify": "",
|
|
105
|
+
"intelbase": "",
|
|
106
|
+
"breachdirectory": "",
|
|
107
|
+
"google_cse_key": "",
|
|
108
|
+
"google_cse_cx": "",
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
# Save config
|
|
112
|
+
config_dir = Path.home() / ".osintkit"
|
|
113
|
+
config_dir.mkdir(parents=True, exist_ok=True)
|
|
114
|
+
|
|
115
|
+
config = {
|
|
116
|
+
"output_dir": "~/osint-results",
|
|
117
|
+
"timeout_seconds": 120,
|
|
118
|
+
"api_keys": api_keys,
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
config_path = config_dir / "config.yaml"
|
|
122
|
+
with open(config_path, "w") as f:
|
|
123
|
+
yaml.dump(config, f, default_flow_style=False)
|
|
124
|
+
|
|
125
|
+
# Create profiles file
|
|
126
|
+
profiles_path = config_dir / "profiles.json"
|
|
127
|
+
if not profiles_path.exists():
|
|
128
|
+
profiles_path.write_text("{}")
|
|
129
|
+
|
|
130
|
+
console.print(f"\n[green]✓[/green] Config saved to: {config_path}")
|
|
131
|
+
console.print("[green]✓[/green] Ready to use!")
|
|
132
|
+
console.print("\n[bold]Next steps:[/bold]")
|
|
133
|
+
console.print(" [cyan]osintkit new[/cyan] - Create a new profile")
|
|
134
|
+
console.print(" [cyan]osintkit list[/cyan] - List all profiles")
|
|
135
|
+
console.print(" [cyan]osintkit setup[/cyan] - Reconfigure API keys")
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def update_api_key(key_name: str, key_value: str):
|
|
139
|
+
"""Update a single API key in config."""
|
|
140
|
+
config_path = Path.home() / ".osintkit" / "config.yaml"
|
|
141
|
+
|
|
142
|
+
if not config_path.exists():
|
|
143
|
+
run_setup_wizard()
|
|
144
|
+
return
|
|
145
|
+
|
|
146
|
+
with open(config_path) as f:
|
|
147
|
+
config = yaml.safe_load(f)
|
|
148
|
+
|
|
149
|
+
if "api_keys" not in config:
|
|
150
|
+
config["api_keys"] = {}
|
|
151
|
+
|
|
152
|
+
config["api_keys"][key_name] = key_value
|
|
153
|
+
|
|
154
|
+
with open(config_path, "w") as f:
|
|
155
|
+
yaml.dump(config, f, default_flow_style=False)
|
|
156
|
+
|
|
157
|
+
console.print(f"[green]✓[/green] Updated {key_name}")
|
package/package.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "osintkit",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "OSINT CLI for personal digital footprint analysis",
|
|
5
|
+
"bin": {
|
|
6
|
+
"osintkit": "./bin/osintkit.js"
|
|
7
|
+
},
|
|
8
|
+
"scripts": {
|
|
9
|
+
"postinstall": "pip3 install -e . --quiet || true"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"bin/",
|
|
13
|
+
"osintkit/",
|
|
14
|
+
"pyproject.toml",
|
|
15
|
+
"requirements.txt",
|
|
16
|
+
"README.md"
|
|
17
|
+
],
|
|
18
|
+
"keywords": ["osint", "security", "privacy", "cli", "recon"],
|
|
19
|
+
"author": "",
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"engines": {
|
|
22
|
+
"node": ">=16",
|
|
23
|
+
"python": ">=3.10"
|
|
24
|
+
}
|
|
25
|
+
}
|
package/pyproject.toml
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
[tool.poetry]
|
|
2
|
+
name = "osintkit"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "OSINT CLI tool for personal digital footprint analysis"
|
|
5
|
+
authors = ["Your Name <you@example.com>"]
|
|
6
|
+
license = "MIT"
|
|
7
|
+
readme = "README.md"
|
|
8
|
+
packages = [{include = "osintkit"}]
|
|
9
|
+
|
|
10
|
+
[tool.poetry.dependencies]
|
|
11
|
+
python = ">=3.10"
|
|
12
|
+
typer = {extras = ["all"], version = ">=0.12.0"}
|
|
13
|
+
httpx = "^0.27.0"
|
|
14
|
+
rich = "^13.7.0"
|
|
15
|
+
jinja2 = "^3.1.2"
|
|
16
|
+
pyyaml = "^6.0.1"
|
|
17
|
+
pydantic = "^2.5.0"
|
|
18
|
+
aiofiles = "^23.2.1"
|
|
19
|
+
phonenumbers = ">=8.13"
|
|
20
|
+
questionary = ">=2.0"
|
|
21
|
+
|
|
22
|
+
[tool.poetry.group.dev.dependencies]
|
|
23
|
+
pytest = "^7.4.0"
|
|
24
|
+
pytest-asyncio = "^0.21.0"
|
|
25
|
+
pytest-httpx = "^0.30"
|
|
26
|
+
black = "^23.0.0"
|
|
27
|
+
ruff = "^0.1.0"
|
|
28
|
+
|
|
29
|
+
[build-system]
|
|
30
|
+
requires = ["poetry-core"]
|
|
31
|
+
build-backend = "poetry.core.masonry.api"
|
|
32
|
+
|
|
33
|
+
[tool.poetry.scripts]
|
|
34
|
+
osintkit = "osintkit.cli:app"
|
|
35
|
+
|
|
36
|
+
[tool.ruff]
|
|
37
|
+
line-length = 100
|
|
38
|
+
target-version = "py311"
|
|
39
|
+
|
|
40
|
+
[tool.pytest.ini_options]
|
|
41
|
+
asyncio_mode = "auto"
|
|
42
|
+
markers = [
|
|
43
|
+
"live: marks tests requiring real network",
|
|
44
|
+
]
|