
Honeypot SSH autossuficiente para capturar interações de atacantes e transformá-las em inteligência de segurança estruturada.
SSHintel é um honeypot SSH leve construído com Python e Paramiko. Ele simula um shell Linux falso para registrar tentativas de acesso não autorizado, capturar credenciais e analisar o comportamento de atacantes em um ambiente controlado.
ls, cd, pwd, , , , , , , , , , , , , , , , etc.)catechogrepfindtreeheadtailwcstatpsdffreeenvidwhoami--tarpit opcional para desacelerar atacantes com saída atrasadaO SSHintel não é um shell Bash/Linux completo. Ele simula um subconjunto plausível de comandos comuns para coletar telemetria de atacantes. Os comandos são despachados por um registro leve; adicionar um comando significa adicionar uma pequena função de manipulador.
pip install -r requirements.txt
Nota: A chave de host SSH é gerada automaticamente na primeira execução. Nenhuma geração manual de chave é necessária.
Execute o honeypot com uma porta, nome de usuário e senha específicos:
python3 run.py serve --port 2222 --username user1 --password pass123
A porta padrão é
2222e o host é0.0.0.0.
O honeypot gera automaticamente uma chave de host SSH em static/server.key na primeira execução se ela não existir. Nenhuma geração manual de chave é necessária.
Para habilitar o modo tarpit:
python3 run.py serve --port 2222 --username user1 --password pass123 --tarpit
Para desabilitar a telemetria SQLite (somente JSONL):
python3 run.py serve --port 2222 --username user1 --password pass123 --no-db
O SSHintel protege contra o esgotamento de recursos causado por muitas conexões simultâneas ou conexões mantidas ativas indefinidamente. Eles são configuráveis via CLI:
| Flag | Padrão | Finalidade |
|---|---|---|
--max-connections | 50 | Máximo de conexões ativas simultâneas; conexões extras são rejeitadas e registradas como um evento connection_rejected |
--auth-timeout | 60 (s) | Tempo permitido para concluir o handshake/autenticação SSH; clientes travados são desconectados |
--session-idle-timeout | 300 (s) | Timeout de inatividade para um shell autenticado; uma sessão ociosa é encerrada, mas um atacante digitando ativamente nunca é morto |
Exemplo:
python3 run.py serve --port 2222 --username user1 --password pass123 \
--max-connections 25 --auth-timeout 30 --session-idle-timeout 300
Quando muitas conexões estão abertas, a conexão extra é fechada imediatamente e um evento de segurança connection_rejected (com reason: connection_limit) é gravado no log JSONL. Uma autenticação travada é registrada como uma desconexão com reason: auth_timeout; um shell ocioso termina com reason: idle_timeout.
O modo tarpit envia intencionalmente a saída lentamente para manter um atacante engajado, portanto o loop do banner tarpit não está sujeito ao timeout de inatividade — mas as sessões tarpit contam para o limite de conexões.
O SSHintel inclui um painel web local que visualiza a telemetria de segurança armazenada no SQLite.
python3 run.py dashboard
Em seguida, abra http://localhost:5000 no seu navegador.
O painel lê do banco de dados SQLite em
data/sshintel.dbpor padrão. Inicie o honeypot primeiro para que a telemetria seja capturada e, em seguida, inicie o painel para vê-lo se popular.
Clique em um ID de sessão (ou navegue até /session/<session_id>) para abrir a visualização de investigação de sessão, que reconstrói um único ataque cronologicamente:
$ comando de tudo o que o atacante digitou, com diretórios de trabalho# Terminal 1: iniciar o honeypot
python3 run.py serve --port 2222 --username user1 --password pass123
# Terminal 2: iniciar o painel
python3 run.py dashboard
# Terminal 3: simular um atacante
ssh user1@localhost -p 2222
# (execute alguns comandos e depois saia)
Em seguida, abra http://localhost:5000 para inspecionar a atividade capturada.
O painel suporta telemetria ao vivo — ele consulta o honeypot a cada 2 segundos e atualiza automaticamente. Novas sessões, comandos e eventos aparecem em tempo real sem atualizar a página. Um indicador ao vivo (● Live) mostra o status da conexão.
Abra um segundo terminal e tente conectar:
ssh user1@localhost -p 2222
Se as credenciais corresponderem, você será colocado no shell emulado.
Para remover impressões digitais SSH obsoletas:
notepad "%USERPROFILE%\.ssh\known_hosts"
Exclua a linha relevante contendo
localhostou o IP do honeypot.
creds_loggerfunnel_loggerlog_files/events.jsonl como JSON Lines (JSONL) — um objeto JSON válido por linhaCada evento JSONL inclui um timestamp UTC ISO-8601, um event_type, um session_id único e o source_ip. Conexão, tentativas/resultados de autenticação, execução de comandos, ativação do tarpit e desconexões são todos registrados como eventos estruturados.
Cada conexão SSH recebida é rastreada como uma sessão independente com seu próprio session_id. Uma sessão registra o IP de origem, horários de conexão/desconexão, o resultado da autenticação e a duração da conexão, e cada evento gerado dentro dessa conexão carrega o mesmo session_id (para que tentativas de autenticação, comandos e desconexões possam ser vinculados a uma única conexão). As sessões são isoladas por conexão — nenhum estado é compartilhado entre clientes simultâneos.
Cada sessão também recebe seu próprio sistema de arquivos falso isolado, em memória — o sistema de arquivos simulado é criado do zero para cada conexão e limpo quando a conexão termina. Arquivos, diretórios e o diretório de trabalho criados ou alterados por um atacante nunca são visíveis para outro atacante conectado ao mesmo tempo. Todo o sistema de arquivos é simulado na memória do Python e nunca toca o sistema de arquivos real do host.
Valores atuais de event_type: connect, auth_attempt, auth_success, auth_failure, command, disconnect, connection_rejected, tarpit.
SSHintel/
├── honeypot/ # Lógica central do honeypot
│ ├── __init__.py
│ ├── main.py # Loop de aceitação + limite de conexões
│ ├── handlers.py # Configuração do transporte SSH + shell emulado
│ ├── server.py # Interface do servidor Paramiko (autenticação)
│ ├── session.py # Rastreamento de sessão por conexão
│ ├── fs.py # Sistema de arquivos falso em memória (isolado por sessão)
│ ├── shell.py # Shell falso: registro de comandos + despachante
│ ├── limits.py # Limite de conexões simultâneas seguro para threads
│ ├── logger.py # Registro de eventos JSONL + ponte SQLite
│ └── telemetry_store.py # Armazenamento de telemetria SQLite + camada de consulta
│
├── dashboard/ # Painel web local
│ ├── app.py # Aplicação Flask + rotas de API
│ ├── templates/
│ │ ├── index.html # Modelo principal do painel
│ │ └── session.html # Modelo de investigação de sessão
│ └── static/
│ ├── style.css # Estilos do painel
│ ├── dashboard.js # JS principal do painel (atualizações ao vivo)
│ └── session.js # JS de investigação de sessão
│
├── log_files/ # Logs de execução (ignorados pelo git)
│ ├── creds_audits.log # Tentativas de credenciais
│ ├── cmd_audits.log # Trilha de auditoria de comandos
│ └── events.jsonl # Eventos de segurança JSONL estruturados
│
├── data/ # Banco de dados SQLite (ignorado pelo git)
│ └── sshintel.db
│
├── static/ # Chave de host SSH (gerada automaticamente)
│ └── server.key
│
├── .github/workflows/ # Configuração de CI
│ └── tests.yml
│
├── Dockerfile
├── README.md
├── requirements.txt # Dependências de execução (paramiko, flask)
├── requirements-dev.txt # Dependências de teste (pytest, pytest-cov)
└── run.py # Ponto de entrada CLI
Se você preferir executar o honeypot em um ambiente conteinerizado, pode usar o Dockerfile incluído.
docker build -t sshintel .
Isso cria uma imagem Docker chamada
sshintel.
docker run -p 2222:2222 sshintel
Isso irá:
static/server.key (se ela ainda não existir)2222 com credenciais padrão:username: user1, password: pass123Abra um segundo terminal e conecte via SSH:
ssh user1@localhost -p 2222
Você será colocado no shell simulado se as credenciais corresponderem.
Para parar o contêiner:
docker ps # Encontre o ID do contêiner
docker stop <container_id>
Para remover a imagem:
docker rmi sshintel
Você também pode exportar a imagem usando
docker save -o sshintel.tar sshintele carregá-la depois comdocker load -i sshintel.tar.
Este projeto está licenciado sob a Licença MIT.