165 lines
7.4 KiB
Python
Executable File
165 lines
7.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""WEVIA Cyber Engine — recon, scan, scrape, infiltrate
|
|
Usage: python3 wevia-cyber.py --mode MODE --target TARGET
|
|
Modes: recon, portscan, vulnscan, webscan, subdomains, techstack, waf, headers, scrape, osint, dork, full
|
|
"""
|
|
import asyncio, json, sys, subprocess, re, os, socket
|
|
from datetime import datetime
|
|
|
|
def run(cmd, timeout=30):
|
|
try:
|
|
r = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=timeout)
|
|
return r.stdout.strip()
|
|
except: return ""
|
|
|
|
def cyber_recon(target):
|
|
"""Full recon: DNS + WHOIS + headers + tech"""
|
|
results = {"target": target, "mode": "recon", "timestamp": datetime.now().isoformat()}
|
|
|
|
# DNS
|
|
try:
|
|
ips = socket.getaddrinfo(target, None)
|
|
results["ips"] = list(set([ip[4][0] for ip in ips]))
|
|
except: results["ips"] = []
|
|
|
|
# WHOIS
|
|
whois = run(f"whois {target} 2>/dev/null | head -30")
|
|
if whois:
|
|
results["registrar"] = re.search(r'Registrar:\s*(.+)', whois)
|
|
results["registrar"] = results["registrar"].group(1) if results["registrar"] else ""
|
|
results["creation"] = re.search(r'Creation Date:\s*(.+)', whois)
|
|
results["creation"] = results["creation"].group(1) if results["creation"] else ""
|
|
|
|
# HTTP headers
|
|
headers = run(f'curl -sI https://{target} 2>/dev/null | head -20')
|
|
results["server"] = re.search(r'[Ss]erver:\s*(.+)', headers)
|
|
results["server"] = results["server"].group(1).strip() if results["server"] else ""
|
|
|
|
# Security headers
|
|
sec_headers = ["Strict-Transport-Security","Content-Security-Policy","X-Frame-Options","X-Content-Type-Options","X-XSS-Protection","Permissions-Policy"]
|
|
results["security_headers"] = {}
|
|
for h in sec_headers:
|
|
m = re.search(f'{h}:\\s*(.+)', headers, re.I)
|
|
results["security_headers"][h] = m.group(1).strip() if m else "MISSING"
|
|
|
|
# Tech stack
|
|
results["tech"] = run(f"whatweb -q {target} 2>/dev/null | head -3") or run(f'curl -s https://{target} 2>/dev/null | grep -oP "(?<=<meta name=\"generator\" content=\")[^\"]*" | head -1')
|
|
|
|
# WAF detection
|
|
results["waf"] = run(f"wafw00f https://{target} 2>/dev/null | grep -i 'is behind' | head -1") or "unknown"
|
|
|
|
return results
|
|
|
|
def cyber_portscan(target):
|
|
"""Port scan with service detection"""
|
|
results = {"target": target, "mode": "portscan"}
|
|
nmap = run(f"nmap -sV -sC --top-ports 100 -T4 {target} 2>/dev/null", timeout=60)
|
|
results["nmap_raw"] = nmap[:1000]
|
|
# Parse open ports
|
|
ports = re.findall(r'(\d+)/tcp\s+open\s+(.+)', nmap)
|
|
results["open_ports"] = [{"port": p[0], "service": p[1]} for p in ports]
|
|
return results
|
|
|
|
def cyber_vulnscan(target):
|
|
"""Vulnerability scan via nuclei"""
|
|
results = {"target": target, "mode": "vulnscan"}
|
|
nuclei = run(f"nuclei -u https://{target} -severity critical,high,medium -silent -nc 2>/dev/null", timeout=120)
|
|
results["vulnerabilities"] = nuclei.split('\n') if nuclei else []
|
|
results["count"] = len(results["vulnerabilities"])
|
|
return results
|
|
|
|
def cyber_subdomains(target):
|
|
"""Subdomain enumeration"""
|
|
results = {"target": target, "mode": "subdomains"}
|
|
# subfinder
|
|
subs = run(f"subfinder -d {target} -silent 2>/dev/null", timeout=30)
|
|
results["subdomains"] = subs.split('\n') if subs else []
|
|
# crt.sh fallback
|
|
if not results["subdomains"]:
|
|
crt = run(f'curl -sf "https://crt.sh/?q=%25.{target}&output=json" 2>/dev/null | python3 -c "import json,sys;[print(x[\'name_value\']) for x in json.load(sys.stdin)]" 2>/dev/null | sort -u | head -20')
|
|
results["subdomains"] = crt.split('\n') if crt else []
|
|
results["count"] = len(results["subdomains"])
|
|
return results
|
|
|
|
def cyber_scrape(url):
|
|
"""Deep scrape with stealth"""
|
|
results = {"url": url, "mode": "scrape"}
|
|
try:
|
|
import cloudscraper
|
|
s = cloudscraper.create_scraper()
|
|
r = s.get(url, timeout=15)
|
|
results["status"] = r.status_code
|
|
results["length"] = len(r.text)
|
|
# Extract: emails, phones, links, social
|
|
results["emails"] = list(set(re.findall(r'[\w.+-]+@[\w-]+\.[\w.]+', r.text)))[:10]
|
|
results["phones"] = list(set(re.findall(r'[\+]?[(]?\d{1,4}[)]?[-\s\./0-9]{7,}', r.text)))[:10]
|
|
results["social"] = list(set(re.findall(r'https?://(?:www\.)?(?:linkedin|twitter|facebook|instagram|github)\.com/[\w/-]+', r.text)))[:10]
|
|
# Extract all links
|
|
results["links"] = list(set(re.findall(r'href="(https?://[^"]+)"', r.text)))[:20]
|
|
# Title + meta
|
|
title = re.search(r'<title>(.*?)</title>', r.text, re.I|re.S)
|
|
results["title"] = title.group(1).strip() if title else ""
|
|
desc = re.search(r'<meta name="description" content="([^"]*)"', r.text, re.I)
|
|
results["description"] = desc.group(1) if desc else ""
|
|
except Exception as e:
|
|
results["error"] = str(e)[:80]
|
|
return results
|
|
|
|
def cyber_osint(person):
|
|
"""OSINT on a person/username"""
|
|
results = {"target": person, "mode": "osint"}
|
|
# Sherlock
|
|
sherlock = run(f"sherlock {person} --print-found --timeout 5 2>/dev/null | head -20", timeout=30)
|
|
results["sherlock"] = sherlock.split('\n') if sherlock else []
|
|
# Holehe (email check)
|
|
if '@' in person:
|
|
holehe = run(f"holehe {person} --only-used 2>/dev/null | head -20", timeout=20)
|
|
results["holehe"] = holehe.split('\n') if holehe else []
|
|
return results
|
|
|
|
def cyber_dork(query):
|
|
"""Google dork search via SearXNG"""
|
|
results = {"query": query, "mode": "dork"}
|
|
r = run(f'curl -sf "http://127.0.0.1:8888/search?q={query}&format=json" 2>/dev/null | head -c 2000')
|
|
try:
|
|
d = json.loads(r)
|
|
results["results"] = [{"title": x.get("title",""), "url": x.get("url","")} for x in d.get("results",[])[:10]]
|
|
except: results["results"] = []
|
|
return results
|
|
|
|
def cyber_full(target):
|
|
"""FULL audit: recon + ports + vulns + subs + scrape"""
|
|
results = {"target": target, "mode": "full_audit", "timestamp": datetime.now().isoformat()}
|
|
results["recon"] = cyber_recon(target)
|
|
results["subdomains"] = cyber_subdomains(target)
|
|
results["scrape"] = cyber_scrape(f"https://{target}")
|
|
# Ports + vulns take longer, run quick versions
|
|
results["ports"] = {"hint": "run --mode portscan for full nmap"}
|
|
results["vulns"] = {"hint": "run --mode vulnscan for full nuclei"}
|
|
return results
|
|
|
|
if __name__ == "__main__":
|
|
import argparse
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("--mode", default="recon")
|
|
parser.add_argument("--target", default="weval-consulting.com")
|
|
args = parser.parse_args()
|
|
|
|
modes = {
|
|
"recon": lambda: cyber_recon(args.target),
|
|
"portscan": lambda: cyber_portscan(args.target),
|
|
"vulnscan": lambda: cyber_vulnscan(args.target),
|
|
"subdomains": lambda: cyber_subdomains(args.target),
|
|
"scrape": lambda: cyber_scrape(args.target if args.target.startswith("http") else f"https://{args.target}"),
|
|
"osint": lambda: cyber_osint(args.target),
|
|
"dork": lambda: cyber_dork(args.target),
|
|
"full": lambda: cyber_full(args.target),
|
|
"headers": lambda: cyber_recon(args.target),
|
|
"waf": lambda: {"waf": run(f"wafw00f https://{args.target} 2>/dev/null | tail -3")},
|
|
"techstack": lambda: {"tech": run(f"whatweb -v {args.target} 2>/dev/null | head -10")},
|
|
}
|
|
|
|
fn = modes.get(args.mode, modes["recon"])
|
|
result = fn()
|
|
print(json.dumps(result, ensure_ascii=False, indent=2))
|