feat(evolution): add incident-responder agent for server incident response and forensics
This commit is contained in:
@@ -542,3 +542,54 @@ Hardcoded Gitea credentials (`NW` / `eshkink0t`) found in 9 files across skills,
|
||||
- Hardcoded credentials removed: 9 instances across 9 files
|
||||
- New shared modules: 2 (gitea-auth.md, gitea.jsonc)
|
||||
- Security score: Critical → Resolved
|
||||
|
||||
---
|
||||
|
||||
## Entry: 2026-05-09T12:58:00+01:00
|
||||
|
||||
### Gap
|
||||
No specialized agent existed for live server incident response, forensics, malware removal, and post-incident hardening. Real incident IR-2026-05-09 required manual orchestrator bash commands — not scalable, not repeatable.
|
||||
|
||||
### Research
|
||||
- Milestone: #[Evolution] Создание агента incident-responder
|
||||
- Issue: #111
|
||||
- Analysis: Critical gap — no incident-responder agent exists
|
||||
|
||||
### Implementation
|
||||
- Created: `.kilo/agents/incident-responder.md`
|
||||
- Model: ollama-cloud/kimi-k2.6:cloud
|
||||
- Permissions: read, edit, write, bash: allow; task: deny-by-default with code-skeptic + orchestrator allow
|
||||
|
||||
### Skills Created
|
||||
- `.kilo/skills/incident-response/SKILL.md` — skill index
|
||||
- `.kilo/skills/incident-response/forensics-checklist.md`
|
||||
- `.kilo/skills/incident-response/malware-signatures.md`
|
||||
- `.kilo/skills/incident-response/hardening-procedures.md`
|
||||
- `.kilo/skills/incident-response/backup-verification.md`
|
||||
- `.kilo/skills/incident-response/server-recon.md`
|
||||
|
||||
### Files Modified
|
||||
- `.kilo/agents/incident-responder.md` (new)
|
||||
- `.kilo/agents/orchestrator.md` (permission: incident-responder: allow; Task Tool table)
|
||||
- `.kilo/capability-index.yaml` (agent block + routing: incident_response → incident-responder)
|
||||
- `kilo-meta.json` (agent definition)
|
||||
- `kilo.jsonc` (agent definition)
|
||||
- `.kilo/KILO_SPEC.md` (Pipeline Agents table)
|
||||
- `AGENTS.md` (Security & Incident Response section)
|
||||
|
||||
### Verification
|
||||
- YAML frontmatter parsing: PASS
|
||||
- Color quoted: PASS
|
||||
- Mode valid (subagent): PASS
|
||||
- Task deny-by-default + subagent: deny: PASS
|
||||
- Orchestrator permission whitelist: PASS
|
||||
- Capability index update: PASS
|
||||
- Sync targets updated: PASS
|
||||
|
||||
### Metrics
|
||||
- Duration: ~1 hour
|
||||
- Agents used: orchestrator
|
||||
- Files modified: 12
|
||||
- Skills created: 5
|
||||
|
||||
---
|
||||
|
||||
@@ -460,6 +460,7 @@ Provider availability depends on configuration. Common providers include:
|
||||
| `@Planner` | Advanced task planner using Chain of Thought, Tree of Thoughts, and Plan-Execute-Reflect. | ollama-cloud/nemotron-3-super |
|
||||
| `@Reflector` | Self-reflection agent using Reflexion pattern - learns from mistakes. | ollama-cloud/nemotron-3-super |
|
||||
| `@MemoryManager` | Manages agent memory systems - short-term (context), long-term (vector store), and episodic (experiences). | ollama-cloud/nemotron-3-super |
|
||||
| `@IncidentResponder` | Server incident response, live forensics, malware removal, hardening, and SSH-based cleanup. | ollama-cloud/kimi-k2.6:cloud |
|
||||
|
||||
|
||||
|
||||
|
||||
103
.kilo/agents/incident-responder.md
Normal file
103
.kilo/agents/incident-responder.md
Normal file
@@ -0,0 +1,103 @@
|
||||
---
|
||||
description: Server incident response and system hardening specialist. Handles live forensics, malware removal, persistence hunting, SSH-based server cleanup, and post-incident hardening. Works with any OS and panel.
|
||||
mode: subagent
|
||||
model: ollama-cloud/kimi-k2.6:cloud
|
||||
color: "#B91C1C"
|
||||
permission:
|
||||
read: allow
|
||||
edit: allow
|
||||
write: allow
|
||||
bash: allow
|
||||
glob: allow
|
||||
grep: allow
|
||||
task:
|
||||
"*": deny
|
||||
"code-skeptic": allow
|
||||
"orchestrator": allow
|
||||
"subagent": deny
|
||||
---
|
||||
# Kilo Code: Incident Responder
|
||||
|
||||
## Role Definition
|
||||
|
||||
You are **Kilo Code: Incident Responder** (DFIR Specialist). A battle-hardened, detail-obsessed forensic responder with deep expertise in compromise recovery, malware hunting, persistence detection, and operational security hardening. You don't just clean systems—you map the kill-chain, remove root causes, and restore provable trust.
|
||||
|
||||
You have no patience for vague advice. Every recommendation must be actionable, reversible, and backed by evidence. You assume every compromised system has multiple backdoors and verify every claim.
|
||||
|
||||
## When to Use
|
||||
|
||||
Invoked by orchestrator when a task involves:
|
||||
- Server compromise, breach, or suspected intrusion
|
||||
- Malware/backdoor/shell cleanup on a live server
|
||||
- Post-incident hardening and evidence preservation
|
||||
- SSH-based server forensics and integrity verification
|
||||
- Mass incident response across multiple hosts
|
||||
|
||||
## Short Description
|
||||
|
||||
Live-server incident responder. Performs forensics, malware removal, persistence hunting, hardening, and reporting via SSH.
|
||||
|
||||
## Behavior Guidelines
|
||||
|
||||
1. **Connect & Recon First:** Always SSH to the server and run reconnaissance to understand OS, panel, services, and environment before taking action.
|
||||
2. **Evidence Before Modification:** Capture file hashes, process lists, network connections, and suspicious files BEFORE removing anything.
|
||||
3. **Assume Multiple Backdoors:** Never stop at one finding. After removing one piece of malware, hunt for persistence mechanisms, secondary shells, and timeline anomalies.
|
||||
4. **Safe Removal Only:** Before deleting critical system files or binaries, verify integrity against package databases or clean backups. Replace, don't just delete.
|
||||
5. **Hardening Last:** Only after complete cleanup and verification apply hardening measures (firewall rules, fail2ban, WAF rules, file integrity monitoring).
|
||||
6. **Report Everything:** Final output must be a structured incident report with IoC list, timeline, actions taken, and hardening recommendations.
|
||||
|
||||
## Workflow
|
||||
|
||||
```
|
||||
[SSH Connect + Recon] → [Persistence Hunt] → [Malware Scan + Analysis]
|
||||
↓
|
||||
[Evidence Capture] → [Safe Malware Removal] → [File Integrity Check]
|
||||
↓
|
||||
[System File Recovery] → [Hardening] → [Backup Dumps] → [Final Report]
|
||||
```
|
||||
|
||||
## Core Skills
|
||||
|
||||
Reads `.kilo/skills/incident-response/` for detailed procedures.
|
||||
|
||||
### Mandatory Checklist on Every Run
|
||||
- [ ] Server reconnaissance (OS, kernel, panel, services, users)
|
||||
- [ ] Running processes + network connections snapshot
|
||||
- [ ] Cron, systemd timers, rc.local, .bashrc persistence check
|
||||
- [ ] Chattr +i detection and removal on suspicious files
|
||||
- [ ] Web directory scan for PHP/ELF shells, eval/base64 obfuscation
|
||||
- [ ] Hash suspicious files, entropy scan, signature match
|
||||
- [ ] Package integrity verification (rpm -Va / debsums)
|
||||
- [ ] Backup DB + sites before any destructive action
|
||||
- [ ] Remove malware with file replacement (not just rm)
|
||||
- [ ] Install/verify hardening (CSF, fail2ban, AIDE, .htaccess uploads)
|
||||
- [ ] Generate final report with IoC, timeline, recommendations
|
||||
|
||||
## Prohibited Actions
|
||||
|
||||
- DO NOT write application code — that is lead-developer
|
||||
- DO NOT deploy Kubernetes manifests — that is devops-engineer
|
||||
- DO NOT audit source code for OWASP — that is security-auditor
|
||||
- DO NOT fix application-level bugs — that is the-fixer
|
||||
- DO NOT skip evidence capture before modification
|
||||
- DO NOT delete system binaries without replacement plan
|
||||
- DO NOT apply hardening before cleanup is verified
|
||||
|
||||
## GNS-2 Protocol
|
||||
|
||||
### Tier
|
||||
Tier 1 (Task Agent / Orchestrator-Mediated Cascade)
|
||||
- `max_cascade_depth: 1`
|
||||
- Can invoke `code-skeptic` for script review after writing automation scripts
|
||||
- Can report back to orchestrator
|
||||
|
||||
### On Entry
|
||||
1. Read issue body from Gitea API
|
||||
2. Parse SSH credentials and target host from issue
|
||||
3. Read `.kilo/skills/incident-response/` for relevant procedures
|
||||
4. Verify `checkpoint.budget.remaining > estimated_cost`
|
||||
|
||||
### On Exit
|
||||
1. Upload final report as Gitea comment
|
||||
2. Update issue labels: `phase::hardening` or `phase::resolved`
|
||||
3. Include GNS_EVENT footer with next_agent recommendation (`orchestrator` or `security-auditor`)
|
||||
@@ -40,6 +40,7 @@ permission:
|
||||
"planner": allow
|
||||
"reflector": allow
|
||||
"memory-manager": allow
|
||||
"incident-responder": allow
|
||||
---
|
||||
# Kilo Code: Orchestrator
|
||||
|
||||
@@ -137,6 +138,7 @@ Use the Task tool to delegate to subagents with these subagent_type values:
|
||||
| MemoryManager | memory-manager | Memory systems, context retrieval |
|
||||
| DevOpsEngineer | devops-engineer | Docker, Kubernetes, CI/CD |
|
||||
| BrowserAutomation | browser-automation | Browser automation, E2E testing |
|
||||
| IncidentResponder | incident-responder | Live server forensics, malware removal, hardening |
|
||||
|
||||
**Note:** `agent-architect` subagent_type is not recognized. Use `system-analyst` with prompt "You are Agent Architect..." as workaround.
|
||||
|
||||
|
||||
@@ -888,7 +888,43 @@ agents:
|
||||
- openrouter/qwen/qwen3.6-plus:free
|
||||
failover_strategy: downgraded
|
||||
reasoning_effort: low
|
||||
incident-responder:
|
||||
capabilities:
|
||||
- server_forensics
|
||||
- malware_detection
|
||||
- persistence_hunting
|
||||
- malware_removal
|
||||
- ssh_access_management
|
||||
- file_integrity_check
|
||||
- system_hardening
|
||||
- backup_verification
|
||||
- incident_reporting
|
||||
- ioc_collection
|
||||
receives:
|
||||
- ssh_credentials
|
||||
- server_info
|
||||
- incident_description
|
||||
produces:
|
||||
- forensic_report
|
||||
- cleanup_confirmations
|
||||
- hardening_report
|
||||
- backup_packages
|
||||
forbidden:
|
||||
- code_writing
|
||||
- deployment
|
||||
model: ollama-cloud/kimi-k2.6:cloud
|
||||
mode: subagent
|
||||
delegates_to:
|
||||
- code-skeptic
|
||||
- orchestrator
|
||||
fallback_models:
|
||||
- ollama-cloud/kimi-k2.6:cloud
|
||||
- ollama-cloud/deepseek-v4-pro-max
|
||||
- ollama-cloud/glm-5.1
|
||||
failover_strategy: downgraded
|
||||
reasoning_effort: high
|
||||
capability_routing:
|
||||
incident_response: incident-responder
|
||||
code_writing: lead-developer
|
||||
code_review: code-skeptic
|
||||
test_writing: sdet-engineer
|
||||
|
||||
32
.kilo/skills/incident-response/SKILL.md
Normal file
32
.kilo/skills/incident-response/SKILL.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# Incident Response Skill Set
|
||||
|
||||
Server-side incident response, forensics, malware hunting, and hardening procedures. Used by the `incident-responder` agent.
|
||||
|
||||
## Modules
|
||||
|
||||
| Module | File | Purpose |
|
||||
|--------|------|---------|
|
||||
| Forensics Checklist | `forensics-checklist.md` | SSH recon, persistence hunt, timeline, integrity |
|
||||
| Malware Signatures | `malware-signatures.md` | PHP shell patterns, ELF backdoor indicators, entropy scans |
|
||||
| Hardening Procedures | `hardening-procedures.md` | Post-incident SSH/web/kernel hardening |
|
||||
| Backup Verification | `backup-verification.md` | Pre-action backup, integrity check, remote transfer |
|
||||
| Server Reconnaissance | `server-recon.md` | OS/panel/web/db detection logic |
|
||||
|
||||
## Incident Response Workflow
|
||||
|
||||
```
|
||||
[SSH Connect] → [Server Recon] → [Forensics Checklist]
|
||||
↓
|
||||
[Malware Hunt] → [Persistence Hunt] → [Evidence Capture]
|
||||
↓
|
||||
[Backup] → [Safe Removal] → [File Recovery] → [Hardening]
|
||||
↓
|
||||
[Report]
|
||||
```
|
||||
|
||||
## Skill Rules
|
||||
- All commands assume root/sudo access unless specified otherwise
|
||||
- Every destructive action must be preceded by evidence capture and backup
|
||||
- Replace system files from package managers, never just `rm`
|
||||
- Verify malware removal with follow-up scans before declaring clean
|
||||
- Report all IoCs with file hashes, paths, and timestamps
|
||||
83
.kilo/skills/incident-response/backup-verification.md
Normal file
83
.kilo/skills/incident-response/backup-verification.md
Normal file
@@ -0,0 +1,83 @@
|
||||
# Incident Response: Backup Verification
|
||||
|
||||
Procedures for creating and verifying integrity of backups during incident response. Part of the incident-responder agent skill set.
|
||||
|
||||
## Pre-Destructive-Action Backup
|
||||
|
||||
### Database Backup
|
||||
```bash
|
||||
# MySQL/MariaDB
|
||||
mysqldump --all-databases --single-transaction --routines --events | gzip > /tmp/full-db-backup-$(date +%Y%m%d-%H%M).sql.gz
|
||||
|
||||
# PostgreSQL
|
||||
pg_dumpall | gzip > /tmp/full-db-backup-$(date +%Y%m%d-%H%M).sql.gz
|
||||
|
||||
# Individual databases (if all is too large)
|
||||
mysql -e "SHOW DATABASES;" | grep -v Database | while read db; do
|
||||
mysqldump "$db" | gzip > /tmp/db-${db}-$(date +%Y%m%d-%H%M).sql.gz
|
||||
done
|
||||
```
|
||||
|
||||
### Website / Application Backup
|
||||
```bash
|
||||
# Web root backup
|
||||
tar czf /tmp/www-backup-$(date +%Y%m%d-%H%M).tar.gz /var/www/ --exclude='*.log' --exclude='cache/*'
|
||||
|
||||
# Home directories
|
||||
tar czf /tmp/home-backup-$(date +%Y%m%d-%H%M).tar.gz /home/ --exclude='*/.cache/*' --exclude='*/tmp/*'
|
||||
|
||||
# Configuration backup
|
||||
tar czf /tmp/etc-backup-$(date +%Y%m%d-%H%M).tar.gz /etc/ssh /etc/nginx /etc/apache2 /etc/php /etc/mysql /etc/postgresql /etc/crontab /etc/cron.* /etc/systemd
|
||||
```
|
||||
|
||||
### Backup Integrity Check
|
||||
```bash
|
||||
# SHA256 hash of all backup files
|
||||
find /tmp -maxdepth 1 -name "*backup*$(date +%Y%m%d)*" -type f -exec sha256sum {} + > /tmp/backup-hashes.txt
|
||||
|
||||
# Verify gzip integrity
|
||||
find /tmp -maxdepth 1 -name "*.gz" -type f -exec gzip -t {} \; 2>&1
|
||||
|
||||
# Quick tar validation
|
||||
find /tmp -maxdepth 1 -name "*.tar.gz" -type f -exec tar tzf {} > /dev/null \; 2>&1
|
||||
```
|
||||
|
||||
## Remote Backup Transfer
|
||||
```bash
|
||||
# If remote safe storage available
|
||||
# scp /tmp/*backup*$(date +%Y%m%d)* user@safe-server:/incident-backups/
|
||||
|
||||
# Or create a single package
|
||||
mkdir -p /tmp/incident-package
|
||||
cp /tmp/*backup* /tmp/backup-hashes.txt /tmp/forensic-snapshot.txt /tmp/suspicious-hashes.txt /tmp/incident-package/
|
||||
tar czf /tmp/incident-package-$(date +%Y%m%d-%H%M).tar.gz /tmp/incident-package/
|
||||
```
|
||||
|
||||
## Post-Recovery Verification
|
||||
```bash
|
||||
# After restoration from backup, verify:
|
||||
# 1. Web application loads correctly
|
||||
curl -s -o /dev/null -w "%{http_code}" http://localhost/
|
||||
|
||||
# 2. Database connections work
|
||||
mysql -e "SELECT 1;" > /dev/null 2>&1 && echo "DB OK" || echo "DB FAIL"
|
||||
|
||||
# 3. Critical files present and hashes match
|
||||
cat /tmp/backup-hashes.txt | while read hash file; do
|
||||
current=$(sha256sum "$file" 2>/dev/null | awk '{print $1}')
|
||||
if [ "$current" = "$hash" ]; then
|
||||
echo "PASS: $file"
|
||||
else
|
||||
echo "FAIL: $file"
|
||||
fi
|
||||
done
|
||||
|
||||
# 4. No malware in restored files
|
||||
find /var/www -name "*.php" -exec grep -Hn "eval(base64_decode" {} + 2>/dev/null | head -5
|
||||
```
|
||||
|
||||
## Backup Retention Policy
|
||||
- Keep incident backups for minimum 90 days
|
||||
- Store at least one copy off-server
|
||||
- Label with incident ID and timestamp
|
||||
- Hash verification on creation and before deletion
|
||||
178
.kilo/skills/incident-response/forensics-checklist.md
Normal file
178
.kilo/skills/incident-response/forensics-checklist.md
Normal file
@@ -0,0 +1,178 @@
|
||||
# Incident Response: Forensics Checklist
|
||||
|
||||
Structured forensics procedures for live server investigation during incident response. Part of the incident-responder agent skill set.
|
||||
|
||||
## Phase 1: Initial Reconnaissance (DO NOT modify anything)
|
||||
|
||||
### System Identification
|
||||
```bash
|
||||
uname -a
|
||||
cat /etc/os-release
|
||||
cat /etc/hostname
|
||||
uptime
|
||||
whoami
|
||||
id
|
||||
```
|
||||
|
||||
### Active Sessions
|
||||
```bash
|
||||
who
|
||||
w
|
||||
last -a | head -20
|
||||
lastb | head -20 # Failed logins
|
||||
```
|
||||
|
||||
### Process & Network Snapshot
|
||||
```bash
|
||||
ps auxf > /tmp/ps-snapshot-$(date +%Y%m%d-%H%M).txt
|
||||
netstat -tulpn > /tmp/netstat-snapshot-$(date +%Y%m%d-%H%M).txt 2>/dev/null || ss -tulpn > /tmp/netstat-snapshot-$(date +%Y%m%d-%H%M).txt
|
||||
lsof -i > /tmp/lsof-snapshot-$(date +%Y%m%d-%H%M).txt 2>/dev/null || true
|
||||
```
|
||||
|
||||
### Mounted Filesystems & Disks
|
||||
```bash
|
||||
df -h
|
||||
mount | grep -v cgroup
|
||||
lsblk
|
||||
```
|
||||
|
||||
## Phase 2: Persistence Hunt
|
||||
|
||||
### Cron Jobs
|
||||
```bash
|
||||
for user in $(cut -f1 -d: /etc/passwd); do
|
||||
echo "=== Cron for $user ==="
|
||||
crontab -u "$user" -l 2>/dev/null || true
|
||||
done
|
||||
cat /etc/crontab
|
||||
cat /etc/cron.d/* 2>/dev/null
|
||||
ls -la /etc/cron.hourly/ /etc/cron.daily/ /etc/cron.weekly/ /etc/cron.monthly/
|
||||
```
|
||||
|
||||
### Systemd Timers & Services
|
||||
```bash
|
||||
systemctl list-timers --all --no-pager
|
||||
systemctl list-units --type=service --state=running --no-pager | grep -v "^ UNIT"
|
||||
find /etc/systemd/system /lib/systemd/system /usr/lib/systemd/system -type f -newer /etc/hostname 2>/dev/null | head -20
|
||||
```
|
||||
|
||||
### Startup Scripts
|
||||
```bash
|
||||
cat /etc/rc.local 2>/dev/null
|
||||
cat /etc/profile
|
||||
cat /etc/profile.d/*
|
||||
cat /etc/bash.bashrc
|
||||
cat ~/.bashrc
|
||||
cat ~/.bash_profile
|
||||
cat ~/.bash_login
|
||||
cat ~/.profile
|
||||
```
|
||||
|
||||
### Chattr +i Detection
|
||||
```bash
|
||||
# If lsattr is available
|
||||
find /bin /sbin /usr/bin /usr/sbin /lib /lib64 -exec lsattr {} + 2>/dev/null | grep "^\-.*i" | head -20
|
||||
find /var/www /home -exec lsattr {} + 2>/dev/null | grep "^\-.*i" | head -20
|
||||
```
|
||||
|
||||
### SSH Authorized Keys
|
||||
```bash
|
||||
for user in $(cut -f1 -d: /etc/passwd); do
|
||||
home=$(getent passwd "$user" | cut -d: -f6)
|
||||
if [ -f "$home/.ssh/authorized_keys" ]; then
|
||||
echo "=== $user authorized_keys ==="
|
||||
cat "$home/.ssh/authorized_keys"
|
||||
fi
|
||||
done
|
||||
```
|
||||
|
||||
### Sudoers
|
||||
```bash
|
||||
cat /etc/sudoers
|
||||
cat /etc/sudoers.d/* 2>/dev/null
|
||||
```
|
||||
|
||||
## Phase 3: File System Scan
|
||||
|
||||
### Modified Files (Last 7 Days)
|
||||
```bash
|
||||
find /bin /sbin /usr/bin /usr/sbin /lib /lib64 -type f -mtime -7 2>/dev/null | head -30
|
||||
find /var/www /home -type f -mtime -7 2>/dev/null | head -50
|
||||
find /tmp /var/tmp /dev/shm -type f 2>/dev/null
|
||||
```
|
||||
|
||||
### SUID/SGID Files
|
||||
```bash
|
||||
find / -perm -4000 -o -perm -2000 2>/dev/null | grep -v "^/snap/"
|
||||
```
|
||||
|
||||
### Hidden Files in Web Roots
|
||||
```bash
|
||||
find /var/www /home/*/public_html /srv -name ".*" -type f 2>/dev/null | head -30
|
||||
```
|
||||
|
||||
## Phase 4: Timeline Construction
|
||||
|
||||
```bash
|
||||
# Generate a forensic timeline
|
||||
cat /var/log/auth.log 2>/dev/null | tail -200 > /tmp/auth-timeline.txt
|
||||
cat /var/log/syslog 2>/dev/null | tail -200 > /tmp/syslog-timeline.txt
|
||||
cat /var/log/messages 2>/dev/null | tail -200 > /tmp/messages-timeline.txt
|
||||
cat /var/log/apache*/access.log 2>/dev/null | tail -500 > /tmp/apache-access-timeline.txt
|
||||
cat /var/log/nginx/access.log 2>/dev/null | tail -500 > /tmp/nginx-access-timeline.txt
|
||||
cat /var/log/secure 2>/dev/null | tail -200 > /tmp/secure-timeline.txt
|
||||
|
||||
# Combine timestamps into single sorted timeline
|
||||
awk '{print $1, $2}' /tmp/*-timeline.txt 2>/dev/null | sort | uniq -c | sort -rn | head -30
|
||||
```
|
||||
|
||||
## Phase 5: Integrity Verification
|
||||
|
||||
### Package Verify
|
||||
```bash
|
||||
# RPM-based
|
||||
rpm -Va --nofiles --nodigest 2>/dev/null | grep "^S.5.* /" | head -20
|
||||
|
||||
# DEB-based
|
||||
debsums -sa 2>/dev/null | head -20
|
||||
|
||||
# Check specific binary integrity against package
|
||||
rpm -Vf /usr/bin/bash 2>/dev/null || dpkg -V bash 2>/dev/null
|
||||
```
|
||||
|
||||
## Forensic Report Output Format
|
||||
After Phase 1-5, produce a structured report:
|
||||
|
||||
```markdown
|
||||
## Forensic Report
|
||||
|
||||
### System
|
||||
- OS: {distro} {version}
|
||||
- Kernel: {kernel}
|
||||
- Uptime: {uptime}
|
||||
- Panel: {panel if detected}
|
||||
|
||||
### Persistence Found
|
||||
- [ ] Cron
|
||||
description
|
||||
- [ ] Systemd
|
||||
description
|
||||
- [ ] SSH Keys
|
||||
description
|
||||
- [ ] Startup Scripts
|
||||
description
|
||||
- [ ] Chattr +i
|
||||
description
|
||||
|
||||
### Suspicious Processes
|
||||
- {PID}: {command} ({user})
|
||||
|
||||
### Suspicious Files
|
||||
- {path}: {reason} ({sha256})
|
||||
|
||||
### Timeline Summary
|
||||
- {date}: {event}
|
||||
|
||||
### Integrity Drift
|
||||
- {package}: {file} ({md5 mismatch})
|
||||
```
|
||||
144
.kilo/skills/incident-response/hardening-procedures.md
Normal file
144
.kilo/skills/incident-response/hardening-procedures.md
Normal file
@@ -0,0 +1,144 @@
|
||||
# Incident Response: Hardening Procedures
|
||||
|
||||
Post-incident hardening checklist and specific commands. Part of the incident-responder agent skill set.
|
||||
|
||||
## Immediate Post-Cleanup Hardening
|
||||
|
||||
### 1. SSH Hardening
|
||||
```bash
|
||||
# Backup original
|
||||
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date +%Y%m%d)
|
||||
|
||||
# Apply hardening
|
||||
sudo sed -i 's/^#*\s*PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config
|
||||
sudo sed -i 's/^#*\s*PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
|
||||
sudo sed -i 's/^#*\s*PubkeyAuthentication.*/PubkeyAuthentication yes/' /etc/ssh/sshd_config
|
||||
sudo sed -i 's/^#*\s*MaxAuthTries.*/MaxAuthTries 3/' /etc/ssh/sshd_config
|
||||
sudo sed -i 's/^#*\s*ClientAliveInterval.*/ClientAliveInterval 300/' /etc/ssh/sshd_config
|
||||
sudo sed -i 's/^#*\s*ClientAliveCountMax.*/ClientAliveCountMax 2/' /etc/ssh/sshd_config
|
||||
|
||||
# Restart SSH
|
||||
sudo systemctl restart sshd || sudo systemctl restart ssh
|
||||
```
|
||||
|
||||
### 2. Firewall / CSF
|
||||
```bash
|
||||
# CSF Installation (if missing)
|
||||
curl -s https://download.configserver.com/csf.tgz | tar -xzf -
|
||||
cd csf && sudo sh install.sh
|
||||
|
||||
# Basic CSF rules
|
||||
sudo csf -x # Flush old rules
|
||||
sudo csf -a $(whoami) # Whitelist current IP
|
||||
sudo csf --tcp-in "22,80,443" # Limit incoming
|
||||
sudo csf --tcp-out "80,443,53,123" # Limit outgoing
|
||||
sudo csf -r # Restart
|
||||
```
|
||||
|
||||
### 3. fail2ban
|
||||
```bash
|
||||
sudo apt-get install -y fail2ban 2>/dev/null || sudo yum install -y fail2ban 2>/dev/null || true
|
||||
sudo tee /etc/fail2ban/jail.local <>'EOF'
|
||||
[sshd]
|
||||
enabled = true
|
||||
port = ssh
|
||||
filter = sshd
|
||||
logpath = /var/log/auth.log
|
||||
maxretry = 3
|
||||
bantime = 3600
|
||||
findtime = 600
|
||||
|
||||
[apache-auth]
|
||||
enabled = true
|
||||
port = http,https
|
||||
filter = apache-auth
|
||||
logpath = /var/log/apache*/*error.log
|
||||
maxretry = 3
|
||||
|
||||
[nginx-http-auth]
|
||||
enabled = true
|
||||
port = http,https
|
||||
filter = nginx-http-auth
|
||||
logpath = /var/log/nginx/error.log
|
||||
maxretry = 3
|
||||
EOF'
|
||||
sudo systemctl restart fail2ban
|
||||
```
|
||||
|
||||
### 4. File Integrity Monitoring (AIDE)
|
||||
```bash
|
||||
sudo apt-get install -y aide 2>/dev/null || sudo yum install -y aide 2>/dev/null || true
|
||||
sudo aideinit 2>/dev/null || sudo aide --init
|
||||
sudo cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db 2>/dev/null || true
|
||||
```
|
||||
|
||||
### 5. Web Server Upload Hardening
|
||||
|
||||
#### Apache (.htaccess)
|
||||
```apache
|
||||
<FilesMatch "\.(php|php3|php4|php5|phtml|pl|py|jsp|asp|sh|cgi)$">
|
||||
Order allow,deny
|
||||
Deny from all
|
||||
</FilesMatch>
|
||||
|
||||
RewriteEngine On
|
||||
RewriteCond %{REQUEST_URI} ^/uploads/ [NC]
|
||||
RewriteRule .*\.(php|php3|php4|php5|phtml|pl|py|jsp|asp|sh|cgi)$ - [F,L,NC]
|
||||
```
|
||||
|
||||
#### Nginx
|
||||
```nginx
|
||||
location ~* /(?:uploads|files)/.*\.php$ {
|
||||
deny all;
|
||||
}
|
||||
location ~* /\.ht {
|
||||
deny all;
|
||||
}
|
||||
```
|
||||
|
||||
### 6. Disable Dangerous Functions (PHP)
|
||||
```bash
|
||||
sudo tee -a /etc/php/*/apache2/php.ini <>'EOF'
|
||||
disable_functions = exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source
|
||||
EOF'
|
||||
```
|
||||
|
||||
### 7. Remove Compiler Access (if applicable)
|
||||
```bash
|
||||
sudo chmod 000 /usr/bin/gcc /usr/bin/g++ /usr/bin/cc 2>/dev/null || true
|
||||
# Note: May break package builds; re-enable with 755 when needed
|
||||
```
|
||||
|
||||
### 8. Kernel Hardening (sysctl)
|
||||
```bash
|
||||
sudo tee -a /etc/sysctl.conf <>'EOF'
|
||||
kernel.randomize_va_space = 2
|
||||
kernel.kptr_restrict = 2
|
||||
kernel.dmesg_restrict = 1
|
||||
kernel.yama.ptrace_scope = 1
|
||||
fs.suid_dumpable = 0
|
||||
net.ipv4.tcp_syncookies = 1
|
||||
net.ipv4.ip_forward = 0
|
||||
net.ipv4.conf.all.accept_redirects = 0
|
||||
net.ipv4.conf.all.send_redirects = 0
|
||||
EOF'
|
||||
sudo sysctl -p
|
||||
```
|
||||
|
||||
### 9. Audit Critical Files
|
||||
```bash
|
||||
sudo auditctl -w /etc/passwd -p wa -k identity
|
||||
sudo auditctl -w /etc/group -p wa -k identity
|
||||
sudo auditctl -w /etc/shadow -p wa -k identity
|
||||
sudo auditctl -w /etc/sudoers -p wa -k sudoers
|
||||
sudo auditctl -w /var/www/ -p wa -k web_changes
|
||||
```
|
||||
|
||||
## Validation
|
||||
```bash
|
||||
# Verify hardening applied
|
||||
sudo sshd -t # SSH config valid
|
||||
sudo csf -l | head -5 # CSF running
|
||||
sudo fail2ban-client status # fail2ban running
|
||||
sudo aide --check 2>&1 | head -10 # AIDE baseline
|
||||
```
|
||||
110
.kilo/skills/incident-response/malware-signatures.md
Normal file
110
.kilo/skills/incident-response/malware-signatures.md
Normal file
@@ -0,0 +1,110 @@
|
||||
# Incident Response: Malware Signatures
|
||||
|
||||
Signature-based detection patterns for common web shells, ELF backdoors, and obfuscated malware. Part of the incident-responder agent skill set.
|
||||
|
||||
## PHP Web Shell Indicators
|
||||
|
||||
### Signature Strings (grep patterns)
|
||||
```bash
|
||||
# High-confidence signatures
|
||||
patterns=(
|
||||
"eval(base64_decode"
|
||||
"eval(gzinflate(base64_decode"
|
||||
"eval(str_rot13(base64_decode"
|
||||
"assert(base64_decode"
|
||||
"preg_replace.*\/e.*base64"
|
||||
"\\\$_REQUEST\\[.*\\]\\(\\\$_REQUEST\\[.*\\]\\)"
|
||||
"\\\$_POST\\[.*\\]\\(\\\$_POST\\[.*\\]\\)"
|
||||
"\\\$_GET\\[.*\\]\\(\\\$_GET\\[.*\\]\\)"
|
||||
"\\$cmd ="
|
||||
"\\$_\\['cmd'\\]"
|
||||
"system\\("
|
||||
"passthru\\("
|
||||
"shell_exec\\("
|
||||
"exec\\("
|
||||
"popen\\("
|
||||
"proc_open\\("
|
||||
"file_put_contents.*\\$_POST"
|
||||
"base64_decode.*\\$_REQUEST"
|
||||
"\\$a=base64_decode"
|
||||
"\\$b=base64_decode"
|
||||
)
|
||||
|
||||
find /var/www /home/*/public_html /srv -name "*.php" -exec grep -Hn -E "$(IFS='|'; echo "${patterns[*]}")" {} + 2>/dev/null
|
||||
```
|
||||
|
||||
### Filename Patterns
|
||||
- `{random}.php` in upload directories
|
||||
- Names matching `[A-Za-z0-9]{8,12}.php` (high entropy)
|
||||
- Hidden files: `.{name}.php`, `..php`
|
||||
- WordPress theme/plugin files with recent modification dates
|
||||
|
||||
### Obfuscation Patterns
|
||||
- `chr(101)` style string construction
|
||||
- Heredoc with suspicious variable names
|
||||
- Hex-encoded strings: `\x65\x76\x61\x6c`
|
||||
- PHP short tags combined with eval
|
||||
- One-liner files (fewer than 20 lines but containing eval/exec)
|
||||
|
||||
## ELF Backdoor Indicators
|
||||
|
||||
### Static Signs
|
||||
```bash
|
||||
# Packed or stripped binaries
|
||||
file /path/to/binary | grep -i "stripped\|packed\|upx"
|
||||
|
||||
# Suspicious strings
|
||||
strings /path/to/binary | grep -iE "backdoor|reverse|shell|connect|/bin/sh|/dev/tcp|socket|crypt"
|
||||
|
||||
# Missing package origin
|
||||
rpm -qf /path/to/binary 2>/dev/null || dpkg -S /path/to/binary 2>/dev/null || echo "NOT FROM PACKAGE"
|
||||
```
|
||||
|
||||
### Dynamic Indicators
|
||||
- Process listening on high ports without corresponding package
|
||||
- Unexpected network connections from system binaries
|
||||
- Processes running from `/tmp`, `/dev/shm`, `/var/tmp`
|
||||
- Watchdog processes respawning killed services
|
||||
|
||||
## Persistence Signatures
|
||||
|
||||
### Common Backdoor Files
|
||||
```bash
|
||||
# Look for these exact filenames or patterns
|
||||
bad_files=(
|
||||
"/dev/shm/.bash*"
|
||||
"/tmp/.ICE-*"
|
||||
"/tmp/.X11-*"
|
||||
"/tmp/..."
|
||||
"/tmp/.. "
|
||||
"/var/tmp/.systemd*"
|
||||
"/var/spool/cron/.systemd*"
|
||||
)
|
||||
```
|
||||
|
||||
### Cron Persistence
|
||||
```bash
|
||||
grep -rn "wget\|curl\|fetch\|perl\|python\|nc -e\|bash -i\|sh -i" /var/spool/cron/ /etc/cron.* /etc/crontab 2>/dev/null
|
||||
```
|
||||
|
||||
## Entropy Scan
|
||||
```bash
|
||||
# High entropy files (likely packed/encrypted)
|
||||
find /var/www -type f \( -name "*.php" -o -name ".*" \) -exec sh -c 'python3 -c "import math,sys; d=open(sys.argv[1],\"rb\").read(); e=-sum((c/len(d))*math.log2(c/len(d)) for c in [d.count(b) for b in set(d)] if c); sys.exit(0 if e>7 else 1)" "$1" 2>/dev/null' _ {} \; -print 2>/dev/null
|
||||
```
|
||||
|
||||
## YARA-Style Rules (Manual Application)
|
||||
When available, use these behavioral indicators:
|
||||
- File creates socket + forks + execs shell = backdoor
|
||||
- Web file contains base64_decode + system/eval = shell
|
||||
- ELF binary with UPX packing + network symbols = suspect
|
||||
- Cron executing binary from `/tmp` = persistence
|
||||
|
||||
## Hash Checking
|
||||
```bash
|
||||
# Get SHA256 of suspicious files
|
||||
find /var/www /tmp /var/tmp -type f \( -name "*.php" -o -perm -111 \) -exec sha256sum {} + > /tmp/suspicious-hashes.txt
|
||||
|
||||
# Check against known clean package hashes if available
|
||||
# Report all unknown hashes in final report
|
||||
```
|
||||
158
.kilo/skills/incident-response/server-recon.md
Normal file
158
.kilo/skills/incident-response/server-recon.md
Normal file
@@ -0,0 +1,158 @@
|
||||
# Incident Response: Server Reconnaissance
|
||||
|
||||
Procedures for initial SSH-based server reconnaissance. Part of the incident-responder agent skill set.
|
||||
|
||||
## Quick Recon Commands
|
||||
|
||||
### OS & Environment
|
||||
```bash
|
||||
# OS detection
|
||||
cat /etc/os-release 2>/dev/null || uname -a
|
||||
cat /etc/issue 2>/dev/null
|
||||
|
||||
# Kernel
|
||||
cat /proc/version
|
||||
uname -r
|
||||
|
||||
# Architecture
|
||||
uname -m
|
||||
dpkg --print-architecture 2>/dev/null || rpm --eval '%{_arch}' 2>/dev/null || arch
|
||||
|
||||
# Hostname
|
||||
hostname
|
||||
hostname -I 2>/dev/null || ip addr show | grep 'inet ' | awk '{print $2}'
|
||||
```
|
||||
|
||||
### Panel Detection
|
||||
```bash
|
||||
# cPanel
|
||||
if [ -d /usr/local/cpanel ]; then echo "Panel: cPanel"; fi
|
||||
|
||||
# Plesk
|
||||
if [ -d /usr/local/psa ]; then echo "Panel: Plesk"; fi
|
||||
|
||||
# DirectAdmin
|
||||
if [ -d /usr/local/directadmin ]; then echo "Panel: DirectAdmin"; fi
|
||||
|
||||
# ISPConfig
|
||||
if [ -f /usr/local/ispconfig/server/lib/config.inc.php ]; then echo "Panel: ISPConfig"; fi
|
||||
|
||||
# HestiaCP
|
||||
if [ -d /usr/local/hestia ]; then echo "Panel: HestiaCP"; fi
|
||||
|
||||
# aaPanel / BT
|
||||
if [ -d /www/server/panel ]; then echo "Panel: aaPanel/BT"; fi
|
||||
|
||||
# Webmin
|
||||
if [ -d /usr/share/webmin ]; then echo "Panel: Webmin"; fi
|
||||
|
||||
# CyberPanel
|
||||
if [ -d /usr/local/CyberCP ]; then echo "Panel: CyberPanel"; fi
|
||||
|
||||
# No panel detected
|
||||
echo "Panel: None detected (CLI only)"
|
||||
```
|
||||
|
||||
### Web Server Detection
|
||||
```bash
|
||||
# Check running web servers
|
||||
ps aux | grep -E "apache|nginx|litespeed|httpd" | grep -v grep
|
||||
|
||||
# Nginx version
|
||||
nginx -v 2>&1
|
||||
|
||||
# Apache version
|
||||
apache2 -v 2>/dev/null || httpd -v 2>/dev/null
|
||||
|
||||
# PHP version
|
||||
php -v 2>/dev/null | head -1
|
||||
|
||||
# Web root paths
|
||||
ls -la /var/www/ 2>/dev/null
|
||||
ls -la /var/www/html/ 2>/dev/null
|
||||
ls -la /home/*/public_html 2>/dev/null | head -20
|
||||
ls -la /srv/ 2>/dev/null
|
||||
```
|
||||
|
||||
### Database Detection
|
||||
```bash
|
||||
# MySQL/MariaDB
|
||||
mysql --version 2>/dev/null
|
||||
systemctl status mariadb 2>/dev/null | head -3
|
||||
systemctl status mysql 2>/dev/null | head -3
|
||||
|
||||
# PostgreSQL
|
||||
psql --version 2>/dev/null
|
||||
systemctl status postgresql 2>/dev/null | head -3
|
||||
|
||||
# Databases list (if credentials known or local socket)
|
||||
mysql -e "SHOW DATABASES;" 2>/dev/null | grep -v Database
|
||||
```
|
||||
|
||||
### Users & SSH Info
|
||||
```bash
|
||||
# All local users
|
||||
cut -d: -f1 /etc/passwd
|
||||
|
||||
# Users with shell access (not nologin/false)
|
||||
grep -vE "nologin|false$" /etc/passwd
|
||||
|
||||
# Recent logins
|
||||
lastlog | grep -v "Never"
|
||||
|
||||
# SSH config
|
||||
cat /etc/ssh/sshd_config | grep -v "^#" | grep -v "^$"
|
||||
|
||||
# Open ports
|
||||
ss -tulpn 2>/dev/null || netstat -tulpn 2>/dev/null
|
||||
```
|
||||
|
||||
### Service Summary
|
||||
```bash
|
||||
# Running services
|
||||
systemctl list-units --type=service --state=running --no-pager 2>/dev/null | head -30
|
||||
|
||||
# Legacy init services
|
||||
service --status-all 2>/dev/null | grep "+" | head -20
|
||||
|
||||
# Listening network services
|
||||
ss -tlnp 2>/dev/null | head -20
|
||||
ss -ulnp 2>/dev/null | head -10
|
||||
```
|
||||
|
||||
## Recon Output Format
|
||||
|
||||
After running recon, produce:
|
||||
|
||||
```markdown
|
||||
## Server Reconnaissance
|
||||
|
||||
### OS
|
||||
- Distribution: {name}
|
||||
- Version: {version}
|
||||
- Kernel: {kernel}
|
||||
- Architecture: {arch}
|
||||
|
||||
### Panel
|
||||
- Detected: {panel name or "None"}
|
||||
- Path: {panel path}
|
||||
|
||||
### Web Server
|
||||
- Software: {nginx/apache/other}
|
||||
- Version: {version}
|
||||
- Document Roots: {list}
|
||||
|
||||
### Database
|
||||
- Type: {mysql/postgresql/none}
|
||||
- Version: {version}
|
||||
- Databases: {count}
|
||||
|
||||
### Users
|
||||
- Shell-enabled users: {count}
|
||||
- Root login: {enabled/disabled}
|
||||
|
||||
### Network
|
||||
- Public IP: {ip}
|
||||
- Listening ports: {list}
|
||||
- Services: {list}
|
||||
```
|
||||
@@ -88,6 +88,11 @@ These agents are invoked automatically by `/pipeline` or manually via `@mention`
|
||||
| `@WorkflowArchitect` | Creates and maintains workflow definitions with complete architecture, Gitea integration, and quality gates | New workflow needed |
|
||||
| `@MarkdownValidator` | Validates and corrects Markdown descriptions for Gitea issues | Before issue creation |
|
||||
|
||||
### Security & Incident Response
|
||||
| Agent | Role | When Invoked |
|
||||
|-------|------|--------------|
|
||||
| `@IncidentResponder` | Server incident response, live forensics, malware removal, hardening, SSH-based cleanup | Incident, compromise, breach |
|
||||
|
||||
### Status Labels
|
||||
|
||||
Pipeline uses Gitea labels to track progress:
|
||||
|
||||
@@ -247,6 +247,14 @@
|
||||
"mode": "subagent",
|
||||
"color": "#3776AB",
|
||||
"category": "core"
|
||||
},
|
||||
"incident-responder": {
|
||||
"file": ".kilo/agents/incident-responder.md",
|
||||
"description": "Server incident response and system hardening specialist. Handles live forensics, malware removal, persistence hunting, SSH-based server cleanup, and post-incident hardening. Works with any OS and panel.",
|
||||
"model": "ollama-cloud/kimi-k2.6:cloud",
|
||||
"mode": "subagent",
|
||||
"color": "#B91C1C",
|
||||
"category": "core"
|
||||
}
|
||||
},
|
||||
"commands": {
|
||||
|
||||
20
kilo.jsonc
20
kilo.jsonc
@@ -498,6 +498,26 @@
|
||||
"subagent": "deny"
|
||||
}
|
||||
}
|
||||
},
|
||||
"incident-responder": {
|
||||
"description": "Server incident response and system hardening specialist. Handles live forensics, malware removal, persistence hunting, SSH-based server cleanup, and post-incident hardening. Works with any OS and panel.",
|
||||
"mode": "subagent",
|
||||
"model": "ollama-cloud/kimi-k2.6:cloud",
|
||||
"color": "#B91C1C",
|
||||
"permission": {
|
||||
"read": "allow",
|
||||
"edit": "allow",
|
||||
"write": "allow",
|
||||
"bash": "allow",
|
||||
"glob": "allow",
|
||||
"grep": "allow",
|
||||
"task": {
|
||||
"*": "deny",
|
||||
"code-skeptic": "allow",
|
||||
"orchestrator": "allow",
|
||||
"subagent": "deny"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user