milenium 0.3.0__tar.gz → 0.4.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.
- {milenium-0.3.0 → milenium-0.4.0}/PKG-INFO +6 -2
- milenium-0.4.0/milenium/__init__.py +23 -0
- {milenium-0.3.0 → milenium-0.4.0}/milenium/cli.py +26 -6
- milenium-0.4.0/milenium/modules/breach_local.py +26 -0
- milenium-0.4.0/milenium/modules/dns_history.py +14 -0
- milenium-0.4.0/milenium/modules/hibp.py +21 -0
- milenium-0.4.0/milenium/modules/ip_reputation.py +28 -0
- milenium-0.4.0/milenium/modules/shodan_lite.py +18 -0
- milenium-0.4.0/milenium/modules/telegram_osint.py +20 -0
- milenium-0.4.0/milenium/tui.py +69 -0
- {milenium-0.3.0 → milenium-0.4.0}/milenium.egg-info/PKG-INFO +6 -2
- {milenium-0.3.0 → milenium-0.4.0}/milenium.egg-info/SOURCES.txt +6 -0
- {milenium-0.3.0 → milenium-0.4.0}/milenium.egg-info/requires.txt +1 -0
- {milenium-0.3.0 → milenium-0.4.0}/pyproject.toml +8 -7
- milenium-0.3.0/milenium/__init__.py +0 -1
- milenium-0.3.0/milenium/modules/breach_local.py +0 -0
- {milenium-0.3.0 → milenium-0.4.0}/README.md +0 -0
- {milenium-0.3.0 → milenium-0.4.0}/milenium/modules/__init__.py +0 -0
- {milenium-0.3.0 → milenium-0.4.0}/milenium/modules/aggregator.py +0 -0
- {milenium-0.3.0 → milenium-0.4.0}/milenium/modules/breach.py +0 -0
- {milenium-0.3.0 → milenium-0.4.0}/milenium/modules/dehashed.py +0 -0
- {milenium-0.3.0 → milenium-0.4.0}/milenium/modules/domain.py +0 -0
- {milenium-0.3.0 → milenium-0.4.0}/milenium/modules/dorker.py +0 -0
- {milenium-0.3.0 → milenium-0.4.0}/milenium/modules/email.py +0 -0
- {milenium-0.3.0 → milenium-0.4.0}/milenium/modules/ip.py +0 -0
- {milenium-0.3.0 → milenium-0.4.0}/milenium/modules/leakcheck.py +0 -0
- {milenium-0.3.0 → milenium-0.4.0}/milenium/modules/logger.py +0 -0
- {milenium-0.3.0 → milenium-0.4.0}/milenium/modules/permutator.py +0 -0
- {milenium-0.3.0 → milenium-0.4.0}/milenium/modules/phone.py +0 -0
- {milenium-0.3.0 → milenium-0.4.0}/milenium/modules/pwned_passwords.py +0 -0
- {milenium-0.3.0 → milenium-0.4.0}/milenium/modules/report.py +0 -0
- {milenium-0.3.0 → milenium-0.4.0}/milenium/modules/social.py +0 -0
- {milenium-0.3.0 → milenium-0.4.0}/milenium/modules/username.py +0 -0
- {milenium-0.3.0 → milenium-0.4.0}/milenium.egg-info/dependency_links.txt +0 -0
- {milenium-0.3.0 → milenium-0.4.0}/milenium.egg-info/entry_points.txt +0 -0
- {milenium-0.3.0 → milenium-0.4.0}/milenium.egg-info/top_level.txt +0 -0
- {milenium-0.3.0 → milenium-0.4.0}/setup.cfg +0 -0
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: milenium
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: OSINT / dox / deanon toolkit
|
|
5
|
-
|
|
5
|
+
Requires-Python: >=3.9
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
6
7
|
Requires-Dist: requests
|
|
7
8
|
Requires-Dist: dnspython
|
|
8
9
|
Requires-Dist: phonenumbers
|
|
9
10
|
Requires-Dist: beautifulsoup4
|
|
10
11
|
Requires-Dist: rich
|
|
11
12
|
Requires-Dist: click
|
|
13
|
+
Requires-Dist: python-whois
|
|
14
|
+
|
|
15
|
+
# milenium
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import subprocess
|
|
2
|
+
import sys
|
|
3
|
+
import importlib
|
|
4
|
+
|
|
5
|
+
def _ensure_deps():
|
|
6
|
+
deps = {
|
|
7
|
+
"whois": "python-whois",
|
|
8
|
+
"dns": "dnspython",
|
|
9
|
+
"phonenumbers": "phonenumbers",
|
|
10
|
+
"requests": "requests",
|
|
11
|
+
"bs4": "beautifulsoup4",
|
|
12
|
+
"rich": "rich",
|
|
13
|
+
"click": "click",
|
|
14
|
+
}
|
|
15
|
+
for mod, pkg in deps.items():
|
|
16
|
+
try:
|
|
17
|
+
importlib.import_module(mod)
|
|
18
|
+
except ImportError:
|
|
19
|
+
subprocess.check_call([sys.executable, "-m", "pip", "install", pkg])
|
|
20
|
+
|
|
21
|
+
_ensure_deps()
|
|
22
|
+
|
|
23
|
+
__version__ = "0.4.0"
|
|
@@ -17,6 +17,24 @@ def main():
|
|
|
17
17
|
"""milenium — OSINT / dox / deanon toolkit"""
|
|
18
18
|
pass
|
|
19
19
|
|
|
20
|
+
@main.command()
|
|
21
|
+
def tui():
|
|
22
|
+
"""Интерактивный TUI-интерфейс"""
|
|
23
|
+
from milenium.tui import interactive
|
|
24
|
+
interactive()
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@main.command()
|
|
28
|
+
@click.argument("channel")
|
|
29
|
+
def telegram(channel):
|
|
30
|
+
"""Парсинг публичного Telegram-канала"""
|
|
31
|
+
logger = _init_logger()
|
|
32
|
+
from milenium.modules import telegram_osint
|
|
33
|
+
res = telegram_osint.check_channel(channel)
|
|
34
|
+
for k, v in res.items():
|
|
35
|
+
console.print(f"[bold]{k}:[/bold] {v}")
|
|
36
|
+
logger.close()
|
|
37
|
+
|
|
20
38
|
@main.command()
|
|
21
39
|
@click.argument("nick")
|
|
22
40
|
def user(nick):
|
|
@@ -74,15 +92,17 @@ def phone_cmd(number):
|
|
|
74
92
|
@main.command()
|
|
75
93
|
@click.argument("address")
|
|
76
94
|
def ip_cmd(address):
|
|
77
|
-
"""Гео, ASN, reverse DNS
|
|
95
|
+
"""Гео, ASN, reverse DNS, Shodan, репутация"""
|
|
78
96
|
logger = _init_logger()
|
|
79
|
-
|
|
80
|
-
|
|
97
|
+
from milenium.modules import ip as ip_mod, shodan_lite, ip_reputation
|
|
98
|
+
results = ip_mod.check(address)
|
|
99
|
+
results["shodan"] = shodan_lite.check_ip(address)
|
|
100
|
+
results["reputation"] = ip_reputation.check(address)
|
|
101
|
+
|
|
81
102
|
for k, v in results.items():
|
|
82
103
|
console.print(f"[bold]{k}:[/bold] {v}")
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
console.print(f"\n[bold cyan]Отчёт сохранён:[/bold cyan] {path}")
|
|
104
|
+
path = report.save_text([f"{k}: {v}" for k, v in results.items()], name=f"ip_{address.replace('.','_')}")
|
|
105
|
+
console.print(f"\n[bold cyan]Отчёт:[/bold cyan] {path}")
|
|
86
106
|
console.print(f"[bold cyan]Лог:[/bold cyan] {logger.path}")
|
|
87
107
|
logger.close()
|
|
88
108
|
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import re
|
|
3
|
+
|
|
4
|
+
def search(query, db_path):
|
|
5
|
+
"""
|
|
6
|
+
Ищет query (email, username, домен) в локальной базе BreachCompilation.
|
|
7
|
+
db_path — путь к папке с распакованными файлами дампа.
|
|
8
|
+
"""
|
|
9
|
+
results = []
|
|
10
|
+
if not os.path.isdir(db_path):
|
|
11
|
+
return {"error": f"path not found: {db_path}"}
|
|
12
|
+
|
|
13
|
+
pattern = re.compile(re.escape(query), re.IGNORECASE)
|
|
14
|
+
for root, _, files in os.walk(db_path):
|
|
15
|
+
for fname in files:
|
|
16
|
+
fpath = os.path.join(root, fname)
|
|
17
|
+
try:
|
|
18
|
+
with open(fpath, "r", encoding="utf-8", errors="ignore") as f:
|
|
19
|
+
for line in f:
|
|
20
|
+
if pattern.search(line):
|
|
21
|
+
results.append(line.strip())
|
|
22
|
+
if len(results) >= 1000:
|
|
23
|
+
return {"matches": results, "truncated": True}
|
|
24
|
+
except Exception:
|
|
25
|
+
continue
|
|
26
|
+
return {"matches": results, "truncated": False}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
|
|
3
|
+
def check(domain):
|
|
4
|
+
try:
|
|
5
|
+
r = requests.get(f"https://crt.sh/?q=%25.{domain}&output=json", timeout=15)
|
|
6
|
+
if r.status_code == 200:
|
|
7
|
+
subs = set()
|
|
8
|
+
for entry in r.json():
|
|
9
|
+
for name in entry.get("name_value", "").split("\n"):
|
|
10
|
+
subs.add(name.strip())
|
|
11
|
+
return {"subdomains": sorted(subs)}
|
|
12
|
+
return {"error": f"HTTP {r.status_code}"}
|
|
13
|
+
except Exception as e:
|
|
14
|
+
return {"error": str(e)}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
|
|
3
|
+
HIBP_KEY = "" # вставь ключ с https://haveibeenpwned.com/API/Key
|
|
4
|
+
|
|
5
|
+
def check_email(email):
|
|
6
|
+
if not HIBP_KEY:
|
|
7
|
+
return {"error": "no HIBP key configured"}
|
|
8
|
+
headers = {"hibp-api-key": HIBP_KEY, "User-Agent": "milenium"}
|
|
9
|
+
try:
|
|
10
|
+
r = requests.get(
|
|
11
|
+
f"https://haveibeenpwned.com/api/v3/breachedaccount/{email}",
|
|
12
|
+
headers=headers, timeout=15
|
|
13
|
+
)
|
|
14
|
+
if r.status_code == 200:
|
|
15
|
+
return {"breaches": [b["Name"] for b in r.json()]}
|
|
16
|
+
elif r.status_code == 404:
|
|
17
|
+
return {"breaches": []}
|
|
18
|
+
else:
|
|
19
|
+
return {"error": f"HTTP {r.status_code}"}
|
|
20
|
+
except Exception as e:
|
|
21
|
+
return {"error": str(e)}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
|
|
3
|
+
def check(ip):
|
|
4
|
+
out = {}
|
|
5
|
+
try:
|
|
6
|
+
r = requests.get(f"https://ipinfo.io/{ip}/json", timeout=10).json()
|
|
7
|
+
out.update({
|
|
8
|
+
"org": r.get("org"),
|
|
9
|
+
"city": r.get("city"),
|
|
10
|
+
"region": r.get("region"),
|
|
11
|
+
"country": r.get("country"),
|
|
12
|
+
"timezone": r.get("timezone"),
|
|
13
|
+
})
|
|
14
|
+
except Exception as e:
|
|
15
|
+
out["ipinfo_error"] = str(e)
|
|
16
|
+
|
|
17
|
+
try:
|
|
18
|
+
r = requests.get(f"https://api.abuseipdb.com/api/v2/check",
|
|
19
|
+
params={"ipAddress": ip, "maxAgeInDays": 90},
|
|
20
|
+
headers={"Key": "", "Accept": "application/json"},
|
|
21
|
+
timeout=10)
|
|
22
|
+
if r.status_code == 200:
|
|
23
|
+
d = r.json().get("data", {})
|
|
24
|
+
out["abuse_score"] = d.get("abuseConfidenceScore")
|
|
25
|
+
out["total_reports"] = d.get("totalReports")
|
|
26
|
+
except Exception:
|
|
27
|
+
pass
|
|
28
|
+
return out
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
|
|
3
|
+
def check_ip(ip):
|
|
4
|
+
"""Публичная информация об IP через Shodan InternetDB (без ключа)."""
|
|
5
|
+
try:
|
|
6
|
+
r = requests.get(f"https://internetdb.shodan.io/{ip}", timeout=10)
|
|
7
|
+
if r.status_code == 200:
|
|
8
|
+
data = r.json()
|
|
9
|
+
return {
|
|
10
|
+
"ports": data.get("ports", []),
|
|
11
|
+
"hostnames": data.get("hostnames", []),
|
|
12
|
+
"cpes": data.get("cpes", []),
|
|
13
|
+
"vulns": data.get("vulns", []),
|
|
14
|
+
"tags": data.get("tags", []),
|
|
15
|
+
}
|
|
16
|
+
return {"error": f"HTTP {r.status_code}"}
|
|
17
|
+
except Exception as e:
|
|
18
|
+
return {"error": str(e)}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
from bs4 import BeautifulSoup
|
|
3
|
+
|
|
4
|
+
def check_channel(username):
|
|
5
|
+
"""Парсит публичную страницу t.me/<username> без API."""
|
|
6
|
+
try:
|
|
7
|
+
r = requests.get(f"https://t.me/{username}", timeout=10)
|
|
8
|
+
if r.status_code != 200:
|
|
9
|
+
return {"error": f"HTTP {r.status_code}"}
|
|
10
|
+
soup = BeautifulSoup(r.text, "html.parser")
|
|
11
|
+
title = soup.find("meta", property="og:title")
|
|
12
|
+
desc = soup.find("meta", property="og:description")
|
|
13
|
+
return {
|
|
14
|
+
"exists": True,
|
|
15
|
+
"title": title["content"] if title else None,
|
|
16
|
+
"description": desc["content"] if desc else None,
|
|
17
|
+
"url": f"https://t.me/{username}",
|
|
18
|
+
}
|
|
19
|
+
except Exception as e:
|
|
20
|
+
return {"error": str(e)}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
from rich.console import Console
|
|
2
|
+
from rich.panel import Panel
|
|
3
|
+
from rich.table import Table
|
|
4
|
+
from rich.prompt import Prompt
|
|
5
|
+
from rich.text import Text
|
|
6
|
+
from rich.align import Align
|
|
7
|
+
|
|
8
|
+
console = Console()
|
|
9
|
+
|
|
10
|
+
BANNER = """
|
|
11
|
+
[bold cyan]
|
|
12
|
+
███╗ ███╗██╗██╗ ███████╗███╗ ██╗██╗██╗ ██╗███╗ ███╗
|
|
13
|
+
████╗ ████║██║██║ ██╔════╝████╗ ██║██║██║ ██║████╗ ████║
|
|
14
|
+
██╔████╔██║██║██║ █████╗ ██╔██╗ ██║██║██║ ██║██╔████╔██║
|
|
15
|
+
██║╚██╔╝██║██║██║ ██╔══╝ ██║╚██╗██║██║██║ ██║██║╚██╔╝██║
|
|
16
|
+
██║ ╚═╝ ██║██║███████╗███████╗██║ ╚████║██║╚██████╔╝██║ ╚═╝ ██║
|
|
17
|
+
╚═╝ ╚═╝╚═╝╚══════╝╚══════╝╚═╝ ╚═══╝╚═╝ ╚═════╝ ╚═╝ ╚═╝
|
|
18
|
+
[/bold cyan]
|
|
19
|
+
[bold green] OSINT / DOX / DEANON TOOLKIT v0.4.0[/bold green]
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
def show_banner():
|
|
23
|
+
console.print(BANNER)
|
|
24
|
+
|
|
25
|
+
def show_menu():
|
|
26
|
+
table = Table(title="[bold]Команды[/bold]", show_header=True, header_style="bold magenta")
|
|
27
|
+
table.add_column("Команда", style="cyan")
|
|
28
|
+
table.add_column("Описание", style="white")
|
|
29
|
+
rows = [
|
|
30
|
+
("user <ник>", "Поиск по 17+ соцсетям + вариации + Google Dorks"),
|
|
31
|
+
("mail <email>", "MX, HIBP, Gravatar"),
|
|
32
|
+
("phone_cmd <номер>", "Оператор, страна, часовой пояс"),
|
|
33
|
+
("ip_cmd <IP>", "Гео, ASN, reverse DNS, Shodan, репутация"),
|
|
34
|
+
("dom <домен>", "WHOIS, DNS, subdomains, crt.sh"),
|
|
35
|
+
("leaks <email>", "HIBP утечки"),
|
|
36
|
+
("social_cmd <ник>", "Поиск соцсетей"),
|
|
37
|
+
("pwned <пароль>", "Проверка пароля в утечках (бесплатно)"),
|
|
38
|
+
("full --email ... --username ... --password ...", "Агрегатор всех модулей"),
|
|
39
|
+
("telegram <канал>", "Парсинг публичного Telegram-канала"),
|
|
40
|
+
]
|
|
41
|
+
for cmd, desc in rows:
|
|
42
|
+
table.add_row(cmd, desc)
|
|
43
|
+
console.print(table)
|
|
44
|
+
|
|
45
|
+
def interactive():
|
|
46
|
+
show_banner()
|
|
47
|
+
show_menu()
|
|
48
|
+
console.print("\n[bold yellow]Введи команду (или 'exit'):[/bold yellow]")
|
|
49
|
+
while True:
|
|
50
|
+
try:
|
|
51
|
+
cmd = Prompt.ask("[bold cyan]milenium[/bold cyan]")
|
|
52
|
+
if cmd.strip().lower() in ("exit", "quit", "q"):
|
|
53
|
+
console.print("[bold red]Выход.[/bold red]")
|
|
54
|
+
break
|
|
55
|
+
if not cmd.strip():
|
|
56
|
+
continue
|
|
57
|
+
# Парсим как CLI
|
|
58
|
+
import shlex
|
|
59
|
+
from milenium.cli import main
|
|
60
|
+
args = shlex.split(cmd)
|
|
61
|
+
try:
|
|
62
|
+
main(args, standalone_mode=False)
|
|
63
|
+
except SystemExit:
|
|
64
|
+
pass
|
|
65
|
+
except Exception as e:
|
|
66
|
+
console.print(f"[bold red]Ошибка:[/bold red] {e}")
|
|
67
|
+
except KeyboardInterrupt:
|
|
68
|
+
console.print("\n[bold red]Прервано.[/bold red]")
|
|
69
|
+
break
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: milenium
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: OSINT / dox / deanon toolkit
|
|
5
|
-
|
|
5
|
+
Requires-Python: >=3.9
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
6
7
|
Requires-Dist: requests
|
|
7
8
|
Requires-Dist: dnspython
|
|
8
9
|
Requires-Dist: phonenumbers
|
|
9
10
|
Requires-Dist: beautifulsoup4
|
|
10
11
|
Requires-Dist: rich
|
|
11
12
|
Requires-Dist: click
|
|
13
|
+
Requires-Dist: python-whois
|
|
14
|
+
|
|
15
|
+
# milenium
|
|
@@ -2,6 +2,7 @@ README.md
|
|
|
2
2
|
pyproject.toml
|
|
3
3
|
milenium/__init__.py
|
|
4
4
|
milenium/cli.py
|
|
5
|
+
milenium/tui.py
|
|
5
6
|
milenium.egg-info/PKG-INFO
|
|
6
7
|
milenium.egg-info/SOURCES.txt
|
|
7
8
|
milenium.egg-info/dependency_links.txt
|
|
@@ -13,15 +14,20 @@ milenium/modules/aggregator.py
|
|
|
13
14
|
milenium/modules/breach.py
|
|
14
15
|
milenium/modules/breach_local.py
|
|
15
16
|
milenium/modules/dehashed.py
|
|
17
|
+
milenium/modules/dns_history.py
|
|
16
18
|
milenium/modules/domain.py
|
|
17
19
|
milenium/modules/dorker.py
|
|
18
20
|
milenium/modules/email.py
|
|
21
|
+
milenium/modules/hibp.py
|
|
19
22
|
milenium/modules/ip.py
|
|
23
|
+
milenium/modules/ip_reputation.py
|
|
20
24
|
milenium/modules/leakcheck.py
|
|
21
25
|
milenium/modules/logger.py
|
|
22
26
|
milenium/modules/permutator.py
|
|
23
27
|
milenium/modules/phone.py
|
|
24
28
|
milenium/modules/pwned_passwords.py
|
|
25
29
|
milenium/modules/report.py
|
|
30
|
+
milenium/modules/shodan_lite.py
|
|
26
31
|
milenium/modules/social.py
|
|
32
|
+
milenium/modules/telegram_osint.py
|
|
27
33
|
milenium/modules/username.py
|
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
[build-system]
|
|
2
|
-
requires = ["setuptools>=61.0", "wheel"]
|
|
3
|
-
build-backend = "setuptools.build_meta"
|
|
4
|
-
|
|
5
1
|
[project]
|
|
6
2
|
name = "milenium"
|
|
7
|
-
version = "0.
|
|
3
|
+
version = "0.4.0"
|
|
8
4
|
description = "OSINT / dox / deanon toolkit"
|
|
9
|
-
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.9"
|
|
10
7
|
dependencies = [
|
|
11
8
|
"requests",
|
|
12
9
|
"dnspython",
|
|
@@ -14,7 +11,11 @@ dependencies = [
|
|
|
14
11
|
"beautifulsoup4",
|
|
15
12
|
"rich",
|
|
16
13
|
"click",
|
|
14
|
+
"python-whois",
|
|
17
15
|
]
|
|
18
16
|
|
|
19
17
|
[project.scripts]
|
|
20
|
-
milenium = "milenium.cli:main"
|
|
18
|
+
milenium = "milenium.cli:main"
|
|
19
|
+
|
|
20
|
+
[tool.setuptools.packages.find]
|
|
21
|
+
include = ["milenium*"]
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.1.0"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|