Home

Awesome

概述

实现一个高交互的SSH蜜罐有方式有多种:

市面上已经有这么多开源的SSH蜜罐了,我为什么还要再造个轮子呢,理由如下:

技术架构

笔者在之前的文章《自制攻击欺骗防御系统》中介绍过完整的架构,整个系统由以下几个模块组成:

本文只讲SSH高交互蜜罐的实现。

SSH高交互蜜罐的Docker实现

docker中默认的openssh服务没有记录bash命令及ssh密码的功能,需要修改bash及openssh的源码并重新编译到Docker中,以下为Dockerfile的内容:

FROM debian:jessie

RUN export DEBIAN_FRONTEND='noninteractive' && \
    apt-get update -qq && \
    apt-get install -qqy --no-install-recommends openssh-server rsyslog wget patch make gcc curl libc6-dev net-tools vim && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/* /tmp/* && \
    mkdir -p /softs/bash-4.3.30-active-syslog/ && mkdir -p /home/test

COPY softs/ /softs/

RUN chmod +x /softs/bash-4.3.30-active-syslog/install-bash-syslog.sh
RUN chmod +x /softs/install_ssh.sh

WORKDIR /softs/bash-4.3.30-active-syslog/
RUN ["/bin/bash", "./install-bash-syslog.sh"]

WORKDIR /softs/
RUN ["/bin/bash", "./install_ssh.sh"]

EXPOSE 22/tcp

COPY entrypoint.sh /etc/systemd/system/

COPY Shanghai /etc/localtime

RUN chmod +x /etc/systemd/system/entrypoint.sh

ENTRYPOINT ["/etc/systemd/system/entrypoint.sh"]

完成后的Docker镜像封装脚本的地址为https://github.com/netxfly/docker_ssh_honeypot/blob/master/install.sh

执行sh -x ./install.sh后经过一段时间的等待后,会直接封装一个Openssh镜像并启动。

测试截图

openssh的密码破解记录如下:

bash的命令执行记录如下:

如果允许攻击者登录到蜜罐中,还需要修改蜜罐的IP地址和主机名,防止攻击者一登录成功就识别出来;其次要做好ACL,防止攻击者通过蜜罐作为跳板攻击内网中其他系统。

仿真系统的守护进程实现

仿真系统的守护进程的作用是实时监控Docker服务产生的数据,并格式化后发送到server端中进行检测,通过插件的形式,可以支持多种服务的日志格式化,然后将格式化的日志通过http协议发送到server端。

func main() {
	logs := make(map[string]string)
	logs["vsftpd-server"] = settings.VsftpLog
	logs["openssh-server"] = settings.SshLog
	logs["history"] = settings.HistLog
	logs["rsync"] = settings.RsyncLog
	logs["mysql-server"] = settings.MysqlLog
	logs["redis-server"] = settings.RedisLog
	logs["mongodb-server"] = settings.MongodbLog

	// logger.Log.Infoln("Log config info:", settings.APIURL, settings.KEY, settings.MODE)

	for tag, fileName := range logs {
		logger.Log.Printf("Tag: %v, path: %v, Truncate: %v", tag, fileName, os.Truncate(fileName, 0))

		if settings.MODE == "syslog" {
			// go util.MonitorLog(tag, fileName)
		} else {
			go util.CheckLog(tag, fileName)
		}
	}

	for {
		time.Sleep(3 * time.Second)
	}
}

SSH密码破解检测插件的实现如下:

  1. 通过正则匹配中破解密码的记录并格式化
  2. 确定为破解行为的记录,通过http接口传到server中

package plugins

import (
	"regexp"
	"time"
	"os"
	"net/http"
	"net/url"
	"encoding/json"

	"cloud-honeypot/sandbox_log/models"
	"cloud-honeypot/sandbox_log/settings"
	"cloud-honeypot/sandbox_log/misc"
	"cloud-honeypot/sandbox_log/logger"
)

var (
	RegexpSSH *regexp.Regexp
	err       error
)

func init() {
	RegexpSSH, err = regexp.Compile(`Honeypot: Username: (.+?) Password: (.+?), from: (.+?), result: (.+?)`)
}

func Check(tag, content string) (checkResult models.CheckResult, result bool) {
	switch tag {
	case "openssh-server":
		checkResult, result = CheckSSH(content, tag)
	}
	if result {
		logger.Log.Infof("from ip: %v, user: %v, password: %v, result: %v", checkResult.Ip,
			checkResult.Username, checkResult.Password, checkResult.Status)
	}
	return checkResult, result
}

func SaveResult(checkResult models.CheckResult, result bool) {
	if result {
		content, _ := json.Marshal(checkResult)
		t := time.Now().Format("2006-01-02 15:04:05")
		apiData := models.APIDATA{}
		apiData.Tag = checkResult.Tag
		apiData.Content = string(content)
		apiData.Hostname, _ = os.Hostname()
		data, err := json.Marshal(apiData)
		if err == nil {
			_, err = http.PostForm(settings.APIURL, url.Values{"timestamp": {t},
				"secureKey": {misc.MakeSign(t, settings.KEY)}, "data": {string(data)}})
		}
	}
}

server端接到数据后做相应的处理后入库,并在管理端中展示,例如: