kaungsithu19/A-Hybrid-Honeypot-Framework-for-Malware-Detection-and-Attacker-Behavioral-Profiling GitHub: kaungsithu19/A-Hybrid-Honeypot-Framework-for-Malware-Detection-and-Attacker-Behavioral-Profiling
整合 Dionaea 与 Cowrie 双蜜罐并接入 Splunk SIEM 的混合威胁检测框架,为资源受限的组织提供实时攻击行为捕获与可视化分析能力。
Stars: 1 | Forks: 0
# 蜜罐技术栈 — Dionaea (Docker) + Cowrie (git) + Splunk
蜜罐 ova - Google Drive [**链接**](https://drive.google.com/file/d/1uX5hL92TqnWefq1jnd0Ar8gtchOAMt-l/view?usp=sharing) 👈
**主机名/IP**
* **蜜罐 VM (Dionaea + Cowrie):** `HNP_IP=192.168.56.150` (用户 `kst`)
* **Splunk VM (Search Head/Indexer):** `SPLUNK_IP=192.168.56.151`
* 如果你的网络环境不同,请在命令中自行调整这些配置。
## 0) 快速开始(我日常运行的命令)
```
cd /opt/cowrie
source /opt/kst-env/bin/activate
./bin/cowrie start
cd /opt/dionaea
sudo docker compose down
sudo docker compose up -d
```
暴露的端口:
* **Dionaea:** 21 (FTP), 80 (HTTP), 443 (HTTPS)
* **Cowrie:** 2222 (SSH/Telnet 蜜罐)
* **iptables DNAT:** 将 **22 → 2222** 转发 (Cowrie)
## 1) 系统准备 (蜜罐 VM)
```
sudo adduser kst
sudo usermod -aG docker kst
sudo apt update && sudo apt install -y \
git python3-venv python3-dev build-essential \
libssl-dev libffi-dev wget curl jq iptables-persistent \
docker.io docker-compose-plugin
# 启用 docker
sudo systemctl enable --now docker
```
### UFW(可选但推荐)
```
sudo apt install -y ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 21/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 2222/tcp
sudo ufw enable
```
## 2) 在 virtualenv 中运行 Cowrie (通过 git)
### 安装
```
sudo mkdir -p /opt/cowrie
sudo chown -R kst:kst /opt/cowrie
cd /opt
# cowrie 的 venv
python3 -m venv /opt/kst-env
# 克隆 cowrie
git clone https://github.com/cowrie/cowrie.git /opt/cowrie
# 安装 deps
source /opt/kst-env/bin/activate
cd /opt/cowrie
pip install --upgrade pip wheel
pip install -r requirements.txt
```
### 配置 Cowrie
```
cp etc/cowrie.cfg.dist etc/cowrie.cfg
# 认证:为测试添加弱 creds
cat <<'EOF' >> etc/userdb.txt
root:123456
admin:password
guest:guest
EOF
```
编辑 `etc/cowrie.cfg` 的最基础必要项:
```
[honeypot]
hostname = fileserver
log_path = var/log/cowrie
[ssh]
enabled = true
listen_endpoints = tcp:2222:interface=0.0.0.0
[telnet]
enabled = false
[backend_pool]
# 默认的 fake FS 即可;如有需要可添加 decoy 文件
```
### systemd 服务(用于实现开机自启)
```
sudo tee /etc/systemd/system/cowrie.service >/dev/null <<'EOF'
[Unit]
Description=Cowrie SSH/Telnet Honeypot
After=network.target
[Service]
User=kst
WorkingDirectory=/opt/cowrie
Environment="VIRTUAL_ENV=/opt/kst-env"
Environment="PATH=/opt/kst-env/bin:/usr/local/bin:/usr/bin:/bin"
ExecStart=/opt/cowrie/bin/cowrie start
ExecStop=/opt/cowrie/bin/cowrie stop
Restart=on-failure
Type=forking
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now cowrie
```
## 3) 重定向真实 SSH (22) → Cowrie (2222)
**(A) 使用 iptables-persistent**
```
# 如有需要清除现有的
# sudo iptables -t nat -F
sudo iptables -t nat -A PREROUTING -p tcp --dport 22 -j REDIRECT --to-ports 2222
sudo iptables-save | sudo tee /etc/iptables/rules.v4
sudo netfilter-persistent save
sudo netfilter-persistent reload
```
**(B) 取消重定向(临时)**
```
sudo iptables -t nat -L --line-numbers
# 找到针对 dpt:22 REDIRECT 到 :2222 的 PREROUTING 规则并按编号删除
sudo iptables -t nat -D PREROUTING 1
sudo netfilter-persistent save
```
## 4) Dionaea (Docker Compose)
```
sudo mkdir -p /opt/dionaea/data /opt/dionaea/log
sudo chown -R kst:kst /opt/dionaea
cat > /opt/dionaea/docker-compose.yml <<'YML'
services:
dionaea:
image: dtagdevsec/dionaea:latest
container_name: dionaea
restart: unless-stopped
network_mode: host
# host mode so ports 21/80/443 are bound directly
volumes:
- /opt/dionaea/data:/opt/dionaea/var/dionaea
- /opt/dionaea/log:/opt/dionaea/var/log
environment:
- TZ=UTC
# if you prefer bridge, bind ports explicitly:
# ports:
# - "21:21"
# - "80:80"
# - "443:443"
YML
```
启动/停止:
```
cd /opt/dionaea
sudo docker compose up -d
# 稍后
sudo docker compose down
```
Dionaea 将监听 **21/80/443** 端口。日志会持久化保存在 `/opt/dionaea/data` 和 `/opt/dionaea/log` 中。
## 5) Splunk(运行于 SPLUNK\_IP)
最简步骤 (Ubuntu):
```
# 获取 .deb
wget -O splunk.deb 'https://download.splunk.com/products/splunk/releases/latest/linux/splunk-linux-2.6-amd64.deb'
sudo dpkg -i splunk.deb
sudo /opt/splunk/bin/splunk enable boot-start --accept-license --answer-yes
sudo /opt/splunk/bin/splunk start
# 在提示时设置管理员密码
```
在浏览器打开 UI:`http://SPLUNK_IP:8000`。
### 启用数据接收(可选的 UF 路径)
* 如果从蜜罐使用 Universal Forwarder,请在 Splunk 上开放 **9997** 端口:
* Settings → Forwarding and receiving → **Configure receiving** → 添加 **9997**
### 启用 HTTP Event Collector (HEC)(可选)
* Settings → Data inputs → **HTTP Event Collector** → Enable → 创建 token(妥善保存 token)。
## 6) 将日志接入 Splunk
从以下常用方案中选择 **一种**:
### A) 在蜜罐 VM 上使用 Universal Forwarder(文件监控)
```
# 在 honeypot 上 (HNP_IP)
wget -O splunkforwarder.deb 'https://download.splunk.com/products/universalforwarder/releases/latest/linux/splunkforwarder-linux-2.6-amd64.deb'
sudo dpkg -i splunkforwarder.deb
sudo /opt/splunkforwarder/bin/splunk start --accept-license
# 指向 Splunk indexer
sudo /opt/splunkforwarder/bin/splunk add forward-server SPLUNK_IP:9997 -auth admin:YOURPASS
# inputs:Cowrie 和 Dionaea
sudo tee /opt/splunkforwarder/etc/system/local/inputs.conf >/dev/null <<'EOF'
[monitor:///opt/cowrie/var/log/cowrie/cowrie.json]
sourcetype = cowrie
index = main
[monitor:///opt/cowrie/var/log/cowrie/cowrie.log]
sourcetype = cowrie
index = main
disabled = true
[monitor:///opt/dionaea/var/dionaea/log/*]
sourcetype = dionaea
index = main
EOF
sudo /opt/splunkforwarder/bin/splunk restart
```
### B) 通过 syslog/HEC 读取(进阶)
* 使用简单的 Python 发送器或 `splunk-logger` 将 cowrie 事件发送到 HEC。(由于你已经有了正常工作的文件监控仪表板,这里可以跳过。)
## 7) 字段提取(可选的 props/transforms 配置)
如果你希望 Splunk 在索引时(或通过搜索时提取)自动为 Dionaea FTP 和 Cowrie 命令提取字段,你可以在 **Search Head** 上使用 **Search-Time** 的 `props.conf` 配置段:
`$SPLUNK_HOME/etc/system/local/props.conf`
```
[dionaea]
TRUNCATE=0
SHOULD_LINEMERGE=false
LINE_BREAKER=([\r\n]+)
MAX_EVENTS=10000
[cowrie]
TRUNCATE=0
SHOULD_LINEMERGE=false
LINE_BREAKER=([\r\n]+)
KV_MODE=json
```
## 8) 实用的 SPL(仪表板与搜索)
### 8.1 Dionaea — FTP 凭据(表格/时间线)
```
sourcetype=dionaea earliest=-24h "ftp"
| rex field=_raw "(?i)b'USER\s+(?
[^'\\r\\n]+)"
| rex field=_raw "(?i)b'PASS\s+(?[^'\\r\\n]+)"
| where isnotnull(ftp_user) OR isnotnull(ftp_pass)
| table _time ftp_user ftp_pass source
| sort 0 _time
```
```
sourcetype=dionaea earliest=-7d "ftp"
| rex max_match=1 field=_raw "(?i)b'USER\s+(?[^'\r\n]+)"
| rex max_match=1 field=_raw "(?i)b'PASS\s+(?[^'\r\n]+)"
| search ftp_user OR ftp_pass
| table _time ftp_user ftp_pass source
```
**标准化处理(去除 CR/LF):**
```
sourcetype=dionaea earliest=-7d "ftp"
| rex max_match=1 field=_raw "(?i)b'USER\s+(?[^'\r\n]+)"
| rex max_match=1 field=_raw "(?i)b'PASS\s+(?[^'\r\n]+)"
| eval ftp_user=trim(replace(ftp_user_raw,"\\r|\\n",""))
| eval ftp_pass=trim(replace(ftp_pass_raw,"\\r|\\n",""))
| where isnotnull(ftp_user) OR isnotnull(ftp_pass)
| table _time ftp_user ftp_pass source
| sort 0 _time
```
**FTP 时间线:**
```
sourcetype=dionaea earliest=-7d "ftp"
| rex field=_raw "processing line b'(?[A-Z]{3,5})"
| timechart span=5m count by ftp_command
```
### 8.2 Dionaea — HTTP 请求(已解析)
```
sourcetype=dionaea earliest=-7d "http.py"
| rex max_match=1 field=_raw "b'(?GET|POST|HEAD|OPTIONS|PUT|DELETE|PATCH)\s+(?[^\s']+)\s+HTTP/(?\d\.\d)"
| rex max_match=1 field=_raw "b'host:\s*(?[^'\r\n]+)"
| rex max_match=1 field=_raw "b'user-agent:\s*(?[^'\r\n]+)"
| bin _time span=1s
| stats latest(method) as method latest(url) as url latest(host) as host latest(user_agent) as user_agent by _time source
| where isnotnull(method) OR isnotnull(host) OR isnotnull(user_agent)
| sort 0 _time
```
### 8.3 Cowrie — 凭据爆破汇总
```
sourcetype="cowrie-too_small"
| stats count by Username Password
| sort - count
```
(如果你的实际 sourcetype 是 `cowrie`,请使用该名称。)
### 8.4 Cowrie — 命令情报(你的基础集合)
```
sourcetype=cowrie Command=*
| stats count by Command
| sort - count
```
```
sourcetype=cowrie Command=*
| timechart count by Command
```
```
sourcetype=cowrie Command=*
| top Command
```
```
sourcetype=cowrie Command=*
| table _time src Command
```
## 9) 现成的仪表板(直接粘贴到 Splunk 中)
### 9.1 **Dionaea — FTP 凭据概览** (XML)
```
Dionaea — FTP Credentials Overview
Time Range
-7d@d now
FTP Attempt Volume Over Time
[^'\r\n]+)"
| rex max_match=1 field=_raw "(?i)b'PASS\s+(?[^'\r\n]+)"
| eval ftp_user=trim(replace(ftp_user_raw,"\r|\n",""))
| eval ftp_pass=trim(replace(ftp_pass_raw,"\r|\n",""))
| where isnotnull(ftp_user) OR isnotnull(ftp_pass)
| bin _time span=1h
| stats count by _time
| sort 0 _time
]]>
$time_tok.earliest$
$time_tok.latest$
line
right
Attempts
Parsed FTP Usernames and Passwords (Dionaea)
[^'\r\n]+)"
| rex max_match=1 field=_raw "(?i)b'PASS\s+(?[^'\r\n]+)"
| eval ftp_user=trim(replace(ftp_user_raw,"\r|\n",""))
| eval ftp_pass=trim(replace(ftp_pass_raw,"\r|\n",""))
| where isnotnull(ftp_user) OR isnotnull(ftp_pass)
| table _time ftp_user ftp_pass source
| sort 0 _time
]]>
$time_tok.earliest$
$time_tok.latest$
20
Top FTP Usernames (Top 10)
[^'\r\n]+)"
| eval ftp_user=trim(replace(ftp_user_raw,"\r|\n",""))
| where isnotnull(ftp_user)
| stats count by ftp_user
| sort - count
| head 10
]]>
$time_tok.earliest$
$time_tok.latest$
bar
```
### 9.2 **Cowrie — 凭据爆破 — 洞察** (XML)
```
Cowrie Credential Spray — Insights
Time range
-7d@d now
Min Count (filter) 1
Total Attempts
$time_tok.earliest$ $time_tok.latest$
Attempts
Unique Usernames
$time_tok.earliest$ $time_tok.latest$
Distinct
Unique Passwords
$time_tok.earliest$ $time_tok.latest$
Distinct
Attempt volume over time
$time_tok.earliest$ $time_tok.latest$
line
Top Username–Password pairs (Top 15)
$time_tok.earliest$ $time_tok.latest$
column
15
All Username–Password pairs (filtered by Min Count)
= tonumber("$min_tok$")
| rename count as Attempts pct as "Share (%)"
| fields Username Password Attempts "Share (%)"
]]>
$time_tok.earliest$ $time_tok.latest$
20
2
```
### 9.3 **Dionaea — HTTP 请求仪表板** (XML)
```
Dionaea — HTTP Requests Dashboard
Overview of HTTP/HTTPS requests captured by Dionaea.
Time Range
-24h@h now
GET|POST|HEAD|OPTIONS|PUT|DELETE|PATCH)\s+(?[^\s']+)\s+HTTP/(?\d\.\d)"
| rex max_match=1 field=_raw "b'host:\s*(?[^'\r\n]+)"
| rex max_match=1 field=_raw "b'user-agent:\s*(?[^'\r\n]+)"
| bin _time span=1s
| stats latest(method) as method latest(url) as url latest(host) as host latest(user_agent) as user_agent by _time source
| where isnotnull(method) OR isnotnull(host) OR isnotnull(user_agent)
]]>
$time_tok.earliest$
$time_tok.latest$
Total Requests | stats count as total
Unique URLs | stats dc(url) as unique_urls
Unique User-Agents | stats dc(user_agent) as unique_agents
Requests Over Time | timechart span=5m count column
HTTP Methods Distribution | stats count by method | sort - count pie
Top Host Headers | stats count by host | sort - count | head 10
Top User-Agents | stats count by user_agent | sort - count | head 10
Parsed HTTP Requests (Latest)
| eval Host=host, Method=method, URL=url, User_Agent=user_agent | fields _time Host Method URL User_Agent source | sort 0 - _time
```
### 9.4 **Cowrie — 命令情报** (XML)
```
Cowrie — Command Intelligence
Time Range -7d@d now
Command filter (wildcards OK) *
Min Count (filter) 1
Total Commands
sourcetype=cowrie Command=* | search Command="$cmd_tok$" | stats count
$time_tok.earliest$ $time_tok.latest$
Unique Commands
sourcetype=cowrie Command=* | search Command="$cmd_tok$" | stats dc(Command) as unique_commands
$time_tok.earliest$ $time_tok.latest$
Unique IPs
sourcetype=cowrie Command=* | search Command="$cmd_tok$" | stats dc(src) as unique_ips
$time_tok.earliest$ $time_tok.latest$
Top Commands (by count)
sourcetype=cowrie Command=* | search Command="$cmd_tok$"
| stats count by Command
| where isnotnull(Command) AND len(Command) > 0
| sort - count
| where count >= tonumber("$min_tok$")
| head 15
$time_tok.earliest$ $time_tok.latest$
column
0
none
Command Usage Over Time (Top 8)
sourcetype=cowrie Command=* | search Command="$cmd_tok$" | timechart count by Command limit=8
$time_tok.earliest$ $time_tok.latest$
line
Top Commands — Count & Share
sourcetype=cowrie Command=* | search Command="$cmd_tok$" | top Command limit=20
$time_tok.earliest$ $time_tok.latest$
20
2
Events — Time, Source, Command
sourcetype=cowrie Command=* | search Command="$cmd_tok$" | table _time src Command | sort 0 _time
$time_tok.earliest$ $time_tok.latest$
20
```
## 10) 快速评估 / 测试命令
**从另一台 Kali 机器上**运行以下命令(将 IP 替换为 `HNP_IP`):
* **Nmap banner/端口检查**
nmap -sV -p 21,80,443,22,2222 192.168.56.150
* **FTP 脚本测试 (Dionaea)**
echo -e "USER anonymous\nPASS test@test.com\nFEAT\nLIST\nQUIT\n" | nc -nv 192.168.56.150 21
* **HTTP 探测 (Dionaea)**
curl -i http://192.168.56.150/
curl -I http://192.168.56.150/
* **SSH 凭据爆破 (Cowrie)**
for u in root admin test; do
sshpass -p "1234" ssh -o StrictHostKeyChecking=no -o ConnectTimeout=5 $u@192.168.56.150 "echo test"
done
# 注意:OpenSSH 使用 'ConnectTimeout'(大写 T);'ConnectionTimeout' 是无效的。
事件应该会出现在 Splunk 的 `sourcetype=dionaea` 和 `sourcetype=cowrie` 下,并填充到上述仪表板中。
## 11) 运维管理
```
# Cowrie 日志
ls -lah /opt/cowrie/var/log/cowrie
# Dionaea 日志
ls -lah /opt/dionaea/log
ls -lah /opt/dionaea/data
# 重启服务
sudo systemctl restart cowrie
cd /opt/dionaea && sudo docker compose restart
```
标签: Docker, 威胁情报, 安全防御评估, 开发者工具, 自定义DNS解析器, 蜜罐, 证书利用, 请求拦截, 逆向工具