## New Security Documentation Structure
/security/
├── README.md # Security overview & contacts
├── forensics-checklist.md # Incident investigation guide
├── persistence-scan.sh # Quick persistence detector
├── runtime-detector.sh # Mining/suspicious process detector
└── hardening/
├── docker.md # Docker security baseline
├── kubernetes.md # K8s policies (future reference)
└── cloud.md # Hetzner-specific hardening
## Key Components
### Forensics Checklist
- Process analysis commands
- Persistence mechanism detection
- Network connection analysis
- File system inspection
- Authentication audit
- Decision matrix for threat response
### Scripts
- persistence-scan.sh: Cron, systemd, executables, SSH keys
- runtime-detector.sh: Mining process detection with --kill option
### Hardening Guides
- Docker: Secure compose template, Dockerfile best practices
- Kubernetes: NetworkPolicy, PodSecurityStandard, Falco rules
- Cloud: Egress firewall, SSH hardening, fail2ban, monitoring
## Post-Incident Documentation
Based on lessons learned from Incidents #1 and #2 (Jan 2026)
Co-authored-by: Cursor Agent <agent@cursor.sh>
171 lines
5.2 KiB
Bash
Executable File
171 lines
5.2 KiB
Bash
Executable File
#!/bin/bash
|
|
# ============================================
|
|
# Persistence Scanner — DAARION Security
|
|
# Version: 1.0.0
|
|
# Purpose: Quick detection of persistence mechanisms
|
|
# Usage: ./persistence-scan.sh
|
|
# ============================================
|
|
|
|
set -e
|
|
|
|
# Colors
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m'
|
|
|
|
echo -e "${BLUE}============================================${NC}"
|
|
echo -e "${BLUE} DAARION Persistence Scanner${NC}"
|
|
echo -e "${BLUE}============================================${NC}"
|
|
echo ""
|
|
|
|
FINDINGS=0
|
|
|
|
# ============================================
|
|
# 1. Cron Jobs
|
|
# ============================================
|
|
echo -e "${YELLOW}[1/7] Checking cron jobs...${NC}"
|
|
|
|
echo "User crontab:"
|
|
crontab -l 2>/dev/null || echo " (none)"
|
|
|
|
echo ""
|
|
echo "System cron directories:"
|
|
for dir in /etc/cron.d /etc/cron.daily /etc/cron.hourly /etc/cron.weekly /etc/cron.monthly; do
|
|
if [ -d "$dir" ]; then
|
|
count=$(ls -1 "$dir" 2>/dev/null | wc -l)
|
|
echo " $dir: $count files"
|
|
if [ $count -gt 0 ]; then
|
|
ls -la "$dir" 2>/dev/null | grep -v "^total" | head -10
|
|
fi
|
|
fi
|
|
done
|
|
|
|
# ============================================
|
|
# 2. Systemd Services
|
|
# ============================================
|
|
echo ""
|
|
echo -e "${YELLOW}[2/7] Checking systemd services...${NC}"
|
|
|
|
echo "Enabled services (excluding common):"
|
|
systemctl list-unit-files --state=enabled 2>/dev/null | \
|
|
grep -vE "(ssh|network|system|docker|cron|rsyslog|ufw|fail2ban|nginx)" | \
|
|
head -20
|
|
|
|
echo ""
|
|
echo "Custom services in /etc/systemd/system:"
|
|
ls -la /etc/systemd/system/*.service 2>/dev/null | grep -v "wants" | head -10 || echo " (none)"
|
|
|
|
# ============================================
|
|
# 3. Suspicious Executables
|
|
# ============================================
|
|
echo ""
|
|
echo -e "${YELLOW}[3/7] Checking for suspicious executables...${NC}"
|
|
|
|
echo "Executables in /tmp, /var/tmp, /dev/shm:"
|
|
SUSPICIOUS_EXEC=$(find /tmp /var/tmp /dev/shm -type f -executable 2>/dev/null)
|
|
if [ -n "$SUSPICIOUS_EXEC" ]; then
|
|
echo -e "${RED}⚠️ FOUND:${NC}"
|
|
echo "$SUSPICIOUS_EXEC"
|
|
FINDINGS=$((FINDINGS + 1))
|
|
else
|
|
echo -e " ${GREEN}(none)${NC}"
|
|
fi
|
|
|
|
echo ""
|
|
echo "Recently modified binaries (last 3 days):"
|
|
MODIFIED_BIN=$(find /usr/bin /usr/local/bin /usr/sbin -mtime -3 -type f 2>/dev/null)
|
|
if [ -n "$MODIFIED_BIN" ]; then
|
|
echo -e "${YELLOW}Modified:${NC}"
|
|
echo "$MODIFIED_BIN" | head -10
|
|
else
|
|
echo -e " ${GREEN}(none)${NC}"
|
|
fi
|
|
|
|
# ============================================
|
|
# 4. High CPU Processes
|
|
# ============================================
|
|
echo ""
|
|
echo -e "${YELLOW}[4/7] Checking high CPU processes...${NC}"
|
|
|
|
echo "Top 15 by CPU:"
|
|
ps -eo pid,user,cmd,%cpu --sort=-%cpu | head -n 16
|
|
|
|
# Check for known mining process names
|
|
MINING_PATTERNS="xmrig|catcal|softirq|vrarhpb|G4NQXBp|kswapd|ksoftirqd|kworker.*mining|cryptonight"
|
|
MINING_PROC=$(ps aux | grep -iE "$MINING_PATTERNS" | grep -v grep)
|
|
if [ -n "$MINING_PROC" ]; then
|
|
echo ""
|
|
echo -e "${RED}⚠️ POTENTIAL MINING PROCESSES DETECTED:${NC}"
|
|
echo "$MINING_PROC"
|
|
FINDINGS=$((FINDINGS + 1))
|
|
fi
|
|
|
|
# ============================================
|
|
# 5. Network Connections
|
|
# ============================================
|
|
echo ""
|
|
echo -e "${YELLOW}[5/7] Checking network connections...${NC}"
|
|
|
|
echo "Outbound connections:"
|
|
ss -antp 2>/dev/null | grep ESTAB | grep -v "127.0.0.1" | head -20
|
|
|
|
# Check for connections to known mining ports
|
|
MINING_PORTS="3333|5555|7777|14433|45700|45560"
|
|
MINING_CONN=$(ss -antp 2>/dev/null | grep -E ":($MINING_PORTS)")
|
|
if [ -n "$MINING_CONN" ]; then
|
|
echo ""
|
|
echo -e "${RED}⚠️ POTENTIAL MINING POOL CONNECTIONS:${NC}"
|
|
echo "$MINING_CONN"
|
|
FINDINGS=$((FINDINGS + 1))
|
|
fi
|
|
|
|
# ============================================
|
|
# 6. Docker Containers
|
|
# ============================================
|
|
echo ""
|
|
echo -e "${YELLOW}[6/7] Checking Docker containers...${NC}"
|
|
|
|
if command -v docker &> /dev/null; then
|
|
echo "Containers with auto-restart:"
|
|
docker ps -a --filter "restart=always" --filter "restart=unless-stopped" --format "{{.Names}}: {{.Status}}" 2>/dev/null || echo " (none)"
|
|
|
|
echo ""
|
|
echo "All running containers:"
|
|
docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Status}}" 2>/dev/null || echo " Docker not available"
|
|
else
|
|
echo " Docker not installed"
|
|
fi
|
|
|
|
# ============================================
|
|
# 7. SSH Keys
|
|
# ============================================
|
|
echo ""
|
|
echo -e "${YELLOW}[7/7] Checking SSH keys...${NC}"
|
|
|
|
echo "Authorized keys for root:"
|
|
if [ -f /root/.ssh/authorized_keys ]; then
|
|
wc -l /root/.ssh/authorized_keys
|
|
echo "Keys:"
|
|
cat /root/.ssh/authorized_keys | cut -d' ' -f3 | head -5
|
|
else
|
|
echo " (no authorized_keys file)"
|
|
fi
|
|
|
|
# ============================================
|
|
# Summary
|
|
# ============================================
|
|
echo ""
|
|
echo -e "${BLUE}============================================${NC}"
|
|
if [ $FINDINGS -gt 0 ]; then
|
|
echo -e "${RED} ⚠️ FINDINGS: $FINDINGS potential issues${NC}"
|
|
echo -e "${RED} Review the output above carefully!${NC}"
|
|
else
|
|
echo -e "${GREEN} ✓ No obvious persistence mechanisms found${NC}"
|
|
fi
|
|
echo -e "${BLUE}============================================${NC}"
|
|
echo ""
|
|
echo "For detailed investigation, see:"
|
|
echo " security/forensics-checklist.md"
|