Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .bandit.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
skips:
- B101 # assert_used - Permitido em testes
- B301 # pickle - Não usado
- B303 # md5 - Permitido para hash de arquivos (não senhas)
- B403 # import_subprocess - Necessário para nmap
- B602 # subprocess_popen_with_shell_equals_true - Controlado via validação
- B608 # sql_injection - Usamos ORM ou validação

exclude_dirs:
- tests
- venv
- .venv

include:
- main.py
- network_scanner.py
- sniffer.py
- info_analysis.py
57 changes: 57 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg

# Virtual environments
venv/
ENV/
env/
.venv/

# IDE
.idea/
.vscode/
*.swp
*.swo
*~

# OS
.DS_Store
Thumbs.db

# Logs
*.log
errors.log

# Test
.coverage
htmlcov/
.tox/
.nox/

# Local config
.env
.env.local
.env.*.local

# Project specific
*.vault
*.bak
47 changes: 47 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Dockerfile para pentest-toolkit
# Usa imagem oficial do Python
FROM python:3.11-slim

# Definir variáveis de ambiente
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
PIP_NO_CACHE_DIR=1 \
PIP_DISABLE_PIP_VERSION_CHECK=1

# Configurar local para evitar problemas de encoding
ENV LANG=C.UTF-8 \
LC_ALL=C.UTF-8

# Criar e definir diretório de trabalho
WORKDIR /app

# Copiar arquivos de dependências
COPY requirements.txt .

# Instalar dependências
RUN apt-get update && apt-get install -y --no-install-recommends \
nmap \
tcpdump \
&& rm -rf /var/lib/apt/lists/*

# Instalar dependências Python
RUN pip install --no-cache-dir -r requirements.txt

# Copiar código fonte
COPY . .

# Criar usuário não-root para segurança
RUN useradd -m pentest && \
chown -R pentest:pentest /app

# Trocar para usuário não-root
USER pentest

# Expor porta (opcional, para futuras funcionalidades web)
EXPOSE 8000

# Comando padrão
ENTRYPOINT ["python", "main.py"]

# Comando alternativo para desenvolvimento
CMD ["--help"]
72 changes: 57 additions & 15 deletions info_analysis.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,23 @@
import hashlib
import os
import whois
import requests
import socket
from functools import lru_cache
from concurrent.futures import ThreadPoolExecutor, TimeoutError as FutureTimeoutError
from colorama import Fore, Style

def calculate_file_hash(file_path, algorithm='sha256'):
# Import ipwhois (substituto seguro para whois)
try:
import ipwhois
USE_IPWHOIS = True
except ImportError:
USE_IPWHOIS = False
try:
import whois
except ImportError:
whois = None


def calculate_file_hash(file_path: str, algorithm: str = 'sha256') -> str | None:
"""
Calcula o hash de um arquivo usando o algoritmo especificado.
"""
Expand All @@ -28,40 +41,67 @@ def calculate_file_hash(file_path, algorithm='sha256'):
print(f"{Fore.RED}Ocorreu um erro ao calcular o hash: {e}{Style.RESET_ALL}")
return None

# Nota: A extração de metadados de arquivos (como PDF, DOCX, Imagens) geralmente requer bibliotecas específicas (ex: PIL, exifread, python-docx, PyPDF2).
# Para manter o escopo inicial e evitar muitas dependências, focaremos no hash e Whois.
# Uma função de metadados básica pode ser adicionada posteriormente.

def whois_lookup(domain):
@lru_cache(maxsize=100)
def whois_lookup(domain: str) -> dict | None:
"""
Realiza uma consulta Whois para um domínio.
Usa ipwhois (recomendado) ou whois (legacy).
"""
print(f"{Fore.CYAN}Realizando consulta Whois para {domain}...{Style.RESET_ALL}")
try:
w = whois.whois(domain)
print(f"{Fore.GREEN}Consulta Whois concluída.{Style.RESET_ALL}")
return w
if USE_IPWHOIS:
# Usar ipwhois (mais seguro e mantido)
from ipwhois import IPWhois
obj = IPWhois(domain)
result = obj.lookup_rdap()

# Remover campos sensíveis
sensitive_fields = ['email', 'phone', 'address', 'registrant', 'abuse_contact']
for field in sensitive_fields:
if field in result:
result[field] = "[REDACTED]"

print(f"{Fore.GREEN}Consulta Whois concluída.{Style.RESET_ALL}")
return result
elif whois:
# Fallback para whois (legacy)
w = whois.whois(domain)
print(f"{Fore.GREEN}Consulta Whois concluída.{Style.RESET_ALL}")
return w
else:
print(f"{Fore.RED}Erro: Nenhuma biblioteca Whois disponível. Instale 'ipwhois' ou 'whois'.{Style.RESET_ALL}")
return None

except Exception as e:
print(f"{Fore.RED}Ocorreu um erro durante a consulta Whois: {e}{Style.RESET_ALL}")
return None

def dns_lookup(domain):

def dns_lookup(domain: str, timeout: int = 5) -> str | None:
"""
Realiza uma consulta DNS básica para obter o endereço IP.
Com timeout para evitar DoS.
"""
print(f"{Fore.CYAN}Realizando consulta DNS para {domain}...{Style.RESET_ALL}")
try:
ip_address = socket.gethostbyname(domain)
with ThreadPoolExecutor(max_workers=1) as executor:
future = executor.submit(socket.gethostbyname, domain)
ip_address = future.result(timeout=timeout)

print(f"{Fore.GREEN}Consulta DNS concluída. IP: {ip_address}{Style.RESET_ALL}")
return ip_address
except socket.gaierror:
print(f"{Fore.RED}Erro: Não foi possível resolver o nome do domínio: {domain}{Style.RESET_ALL}")
return None
except FutureTimeoutError:
print(f"{Fore.RED}Erro: Timeout na consulta DNS para {domain}{Style.RESET_ALL}")
return None
except Exception as e:
print(f"{Fore.RED}Ocorreu um erro durante a consulta DNS: {e}{Style.RESET_ALL}")
return None


if __name__ == '__main__':
# Exemplo de uso
# Criar um arquivo de teste
Expand All @@ -76,12 +116,14 @@ def dns_lookup(domain):
# Testar Whois
whois_info = whois_lookup("google.com")
if whois_info:
print(f"Registrante: {whois_info.registrar}")
print(f"Data de Criação: {whois_info.creation_date}\n")
print(f"Whois Info: {whois_info}\n")

# Testar DNS Lookup
ip = dns_lookup("github.com")
print(f"IP do GitHub: {ip}")

# Limpar arquivo de teste
os.remove(test_file_path)
try:
os.remove(test_file_path)
except:
pass
31 changes: 20 additions & 11 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,29 @@
print(f"{Fore.RED}Certifique-se de que todos os arquivos (network_scanner.py, info_analysis.py, sniffer.py) estão no mesmo diretório e as dependências estão instaladas.{Style.RESET_ALL}")
sys.exit(1)


def print_banner():
"""Imprime o banner da aplicação."""
banner = f"""
{Fore.RED}
____ _ _ ____ _____ _____ _____ _ _ _____ _____
| _ \| \ | | _ \| ____| ____|_ _| \ | | ____|_ _|
| |_) | \| | |_) | _| | _| | | | \| | _| | |
| __/| |\ | _ <| |___| |___ | | | |\ | |___ | |
|_| |_| \_|_| \_\_____|_____| |_| |_| \_|_____| |_|
| __/| |\\ | _ <| |___| |___ | | | |\\ | |___ | |
|_| |_| \\_|_| \\_\_____|_____| |_| |_| \\_|_____| |_|
{Style.RESET_ALL}
{Fore.GREEN} Toolkit de Pentest em Python - Manus AI{Style.RESET_ALL}
{Fore.GREEN} Toolkit de Pentest em Python - Paulus Mass{Style.RESET_ALL}
"""
print(banner)

def display_results(title, data):

def display_results(title: str, data):
"""Exibe os resultados de forma formatada."""
print(f"\n{Fore.BLUE}--- {title} ---{Style.RESET_ALL}")
if data is None:
print(f"{Fore.YELLOW}Nenhum resultado encontrado ou erro na operação.{Style.RESET_ALL}")
return

if isinstance(data, list):
if not data:
print(f"{Fore.YELLOW}Nenhum resultado encontrado.{Style.RESET_ALL}")
Expand Down Expand Up @@ -64,14 +70,17 @@ def display_results(title, data):

elif data is not None:
# Exibição de Whois/DNS/Hash
if isinstance(data, whois.parser.WhoisEntry):
print(f"{Fore.MAGENTA}Registrante:{Style.RESET_ALL} {data.registrar}")
print(f"{Fore.MAGENTA}Data de Criação:{Style.RESET_ALL} {data.creation_date}")
print(f"{Fore.MAGENTA}Data de Expiração:{Style.RESET_ALL} {data.expiration_date}")
print(f"{Fore.MAGENTA}Servidores de Nome:{Style.RESET_ALL} {', '.join(data.name_servers) if data.name_servers else 'N/A'}")
# print(str(data)) # Para ver todos os dados brutos
if isinstance(data, dict):
# Whois result (ipwhois)
for key, value in data.items():
if isinstance(value, dict):
print(f"{Fore.MAGENTA}{key}:{Style.RESET_ALL}")
for subkey, subvalue in value.items():
print(f" {subkey}: {subvalue}")
else:
print(f"{Fore.MAGENTA}{key}:{Style.RESET_ALL} {value}")
else:
print(data)
print(data)
else:
print(f"{Fore.YELLOW}A operação não retornou dados ou falhou.{Style.RESET_ALL}")

Expand Down
Loading