从编程角度理解什么是蜜罐

一、蜜罐定义

百度百科:蜜罐技术本质上是一种对攻击方进行欺骗的技术,通过布置一些作为诱饵的主机、网络服务或者信息,诱使攻击方对它们实施攻击,从而可以对攻击行为进行捕获和分析,了解攻击方所使用的工具与方法,推测攻击意图和动机,能够让防御方清晰地了解他们所面对的安全威胁,并通过技术和管理手段来增强实际系统的安全防护能力。

维基百科:蜜罐通常伪装成看似有利用价值的网络、数据、计算机系统,并故意设置了bug,用来吸引黑客攻击。由于蜜罐事实上并未对网络提供任何有价值的服务,所以任何对蜜罐的尝试都是可疑的。蜜罐中还可能装有监控软件,用以监视黑客入侵后的举动。

个人理解:密罐是仿照正常服务对客户端请求进行响应的软件,且一般比正常服务具有更强的操作记录功能。下面我将通过从使用角度和编程角度来讲解这一定义的具体含义。

二、从使用角度理解”仿照“的含义

现具有一个IIS搭建的ftp服务,和一个ftp蜜罐,我们对其进行如下操作:

服务 监听端口 用户 蜜码 文件 测试操作
IIS搭建的ftp服务 21 ls abcd1234 根目录下有一ftp_server.txt文件 登录---查看文件----退出
ftp服务密罐 21212 ls abcd1234 声称自己在根目录下有一ftp_server.txt文件 登录---查看文件----退出

IIS搭建的ftp服务ftp客户端操作截图如下:

ftp服务密罐ftp客户端操作截图如下:

总结如下:

服务类型 数据包 功能是否真正实现 客户端使用感受
IIS搭建的ftp服务 按协议发送 真正实现(比如2.1中的ls是真列出ftp目录中的文件) 正常ftp服务
ftp服务密罐 按协议发送 声称实现(比如2.2中的ls并不是真列出ftp目录中的文件,而是代码设定好的回应) 正常ftp服务

也就是说,在以上操作中,蜜罐”仿照“了正常服务对客户端请求进行响应,导致用户无法区分其是蜜罐还是正常服务。

三、从编程角度理解”仿照“的含义

使用上的”仿照“本质上是代码的”仿照“。此处代码正是上节ftp蜜罐的代码,从代码中我们可以看到蜜罐到底是如何从代码上对正常服务进行仿照的。

(由于代码略长为避免影响后文这里折叠起来。)

import time
import socket
import threading

# 文件传输线程
class myThread (threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)

    def run(self):
        # 被动模式启监听
        while True:
            ftp_data_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
            ftp_data_socket.setblocking(True)
            ftp_data_socket.bind(("10.10.6.91", 8361))
            print("listening")
            ftp_data_socket.listen(2)
            while True:
                try:
                    self.client_socket, addr = ftp_data_socket.accept()
                except:
                    continue

    # 被动模式列文件函数
    def pasv_send_msg(self):
        msg = "07-07-18  01:48PM                 5828 taiwan_ip_modify.txt\r\n"
        self.client_socket.send(msg.encode())
        self.client_socket.close()

    # 主动模式列文件函数
    def port_send_msg(self,port):
        send_file_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        send_file_socket.connect((‘10.10.6.91‘, port))
        msg = "ftp_server.txt\r\n"
        send_file_socket.send(msg.encode())
        send_file_socket.close()

class ftpd:
    def ftp_server(self):
        ip_addr = socket.gethostbyname(socket.gethostname())
        port = 21212
        data = ""
        # 文件传输线程
        self.thread_file = ""
        # 文件传输模式,port--主动,pasv--被动
        self.file_tran_mode = "port"

        # 启动监听
        server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        # server_socket.setblocking(True)
        server_socket.bind((ip_addr,port))
        server_socket.listen(5)
        while True:
            try:
                # 接收客户端连接
                client_socket,addr = server_socket.accept()
                # client_socket.setblocking(True)
                print(f"accept connect from {addr}")
                msg = "220 Microsoft FTP Service\r\n".encode()
                client_socket.send(msg)
                # 接受客户端请求
                while True:
                    data = client_socket.recv(100)
                    if not data:
                        continue
                    # 处理用户登录指令
                    elif "USER" in data.decode():
                        print(f"data-{data.decode()}")
                        msg = (f"331 Password required for "
                               f"{data.decode()[5:-2]}.\r\n")
                        client_socket.send(msg.encode())
                    # 处理密码验证指令
                    elif "PASS" in data.decode():
                        print(f"data-{data.decode()}")
                        msg = "230 User logged in.\r\n"
                        client_socket.send(msg.encode())
                    # 处理查看系统信息指令
                    elif "SYST" in data.decode():
                        print(f"data-{data.decode()}")
                        msg = "215 Windows_NT\r\n"
                        client_socket.send(msg.encode())
                    # 处理查看当前路径指令
                    elif "PWD" in data.decode():
                        print(f"data-{data.decode()}")
                        msg = ‘257 "/" is current directory.\r\n‘
                        client_socket.send(msg.encode())
                    # 处理编码指令
                    elif "OPTS UTF8" in data.decode():
                        print(f"data-{data.decode()}")
                        msg = "200 OPTS UTF8 command successful - UTF8 encoding now ON.\r\n"
                        client_socket.send(msg.encode())
                    # 处理保持连接指令
                    elif "NOOP" in data.decode():
                        print(f"data-{data.decode()}")
                        msg = "200 NOOP command successful.\r\n"
                        client_socket.send(msg.encode())
                    # 处理退出登录指令
                    elif "QUIT" in data.decode():
                        print(f"data-{data.decode()}")
                        msg = "221 Goodbye.\r\n"
                        client_socket.send(msg.encode())
                        self.thread_file.join()
                        client_socket.close()
                    # 处理切换被动模式指令
                    elif "PASV" in data.decode():
                        print(f"data-{data.decode()}")
                        msg = "227 Entering Passive Mode (10,10,6,93,32,169).\r\n"
                        client_socket.send(msg.encode())
                        if self.thread_file == "" or not self.thread_file.is_alive():
                                self.thread_file = myThread()
                                self.thread_file.start()
                        self.file_tran_mode = "pasv"
                    # 处理切换主动模式指令
                    elif "PORT" in data.decode():
                        print(f"data-{data.decode()}")
                        msg = "200 PORT command successful.\r\n"
                        client_socket.send(msg.encode())
                        if self.thread_file == "" or not self.thread_file.is_alive():
                                self.thread_file = myThread()
                                self.thread_file.start()
                        self.file_tran_mode = "port"
                        tmp = data.decode().strip().replace("\r\n", "")
                        tmp_dict = tmp.split(",")
                        self.port = int(tmp_dict[4]) * 256 + int(tmp_dict[5])
                    # 处理列目录指令,根据当是是主动还是被动模式调用发送函数
                    elif "NLST" in data.decode():
                        print(f"data-{data.decode()}")
                        if self.file_tran_mode == "port":
                            self.thread_file.port_send_msg(self.port)
                            time.sleep(1)
                            msg = "125 Data connection already open; Transfer starting.\r\n"
                            client_socket.send(msg.encode())
                        else:
                            self.thread_file.pasv_send_msg()
                            time.sleep(1)
                        msg = "226 Transfer complete.\r\n"
                        client_socket.send(msg.encode())
                    # 其他指令,未处理
                    else:
                        print(f"data-{data}")
            except:
                print("socket have been close")
                continue

if __name__ == "__main__":
    ftp_server = ftpd()
    ftp_server.ftp_server()

四、其他一些说明

4.1 蜜罐编写思路

密罐是仿照正常服务对客户端请求进行响应的软件,所以我们可以和正常服务开发一样根据服务的协议文档来编写蜜罐。

但是读协议文档往往是很费劲的一件事。我们可以先搭建一个正常的服务,再安装一个客户端,然后使用wireshark拦截客户端与服务端的交互数据包,最后收到什么客户端请求就模仿正常服务返回同样的数据包就可以了。

比如我这里实现的ftp蜜罐,就是通过先用IIS搭建ftp服务,然后使用windows自带的客户端,再然后使用wireshark拦截到如下数据包,最后编码模仿IIS的ftp服务进行响应实现的。

4.2 蜜罐的分类

根据”仿照“的程度可以分为以下三类密罐:

低交互蜜罐:只是声称功能已经实现但实际没实现很容易看出破绽的蜜罐。比如我这里对get等指令都未做处理,用户很多命令都执行不了就会产生怀疑,所以只能算是一个低交互蜜罐。

高交互蜜罐:声称功能实现且大多功能让攻击者使用起来感觉就和真的服务没区别的密罐。比如我这里的ftp服务如果在现在基上对get等其他指令都做处理那就可以成为一个高交互蜜罐。

实系统蜜罐:真的实现所有服务功能的蜜罐。比如如果我这里的程序不是对指令做假的回应而是真真正正实现ftp的功能那就是一个实系统蜜罐。

但一般情况下实系统蜜罐并不是真自己从头去写,而是采用安装有漏洞版本辅以其他手段完成监控的方式。比如安装有漏洞版本的vsftpd加通过流量镜像进行监控的形式实现。

在常规介绍中蜜罐一般只指低交互蜜罐和高交互蜜罐,但在实际部署中为了提高逼真程度、让攻击者不疑有他地使用自己的攻击手段攻击系统经常直接部署实系统蜜罐。

4.3 蜜网

密网就是所有密罐的总和。我总怀疑密网和H5一样是销售制造的新名词,不过叫密码确实更能体现蜜罐系统的整体性,所以也不算一无是处:

在搭建密罐系统时,为了更强的诱捕能力,通常会不只单独部署一个密罐而经常是使用多台设备安装多个密罐,比如这台启ftp蜜罐那台启smtp蜜罐等。

在搭建密罐系统时,为了营造更逼真环境,通常会使用实系统蜜罐,而实系统蜜罐意味着真实的系统意味着真实的漏洞意味着机器可能真会被攻破,所以通常会将蜜罐系统放在独立的网络环境中。

在搭建蜜罐系统时,更了方便性,通常会有角色分工,比如有统一的流量监控主机和日志监控主机。

原文地址:https://www.cnblogs.com/lsdb/p/9651729.html

时间: 2024-08-23 04:47:40

从编程角度理解什么是蜜罐的相关文章

转:如何学习SQL(第二部分:从关系角度理解SQL)

转自:http://blog.163.com/[email protected]/blog/static/285720652010950825538/ 6. 从关系角度理解SQL 6.1. 关系和表 众所周知,我们目前所用的数据库,通常都是关系数据库.关系自然在其中处于关键位置.初学数据库原理的人可能会很困惑关系和表是什么联系,如果没有清楚的理解,很可能会认为关系这个概念没有实际意义,只会引起混淆.其实这两组概念只是由于理论界与技术界的着重点不同.前者需要用一个专业的.没有歧义的概念来进行理论探

二 从 GPU 的角度理解并行计算

前言 本文从使用 GPU 编程技术的角度来了解计算中并行实现的方法思路. 并行计算中需要考虑的三个重要问题 1. 同步问题 在操作系统原理的相关课程中我们学习过进程间的死锁问题,以及由于资源共享带来的临界资源问题等,这里不做累述. 2. 并发度 有一些问题属于 “易并行” 问题:如矩阵乘法.在这类型问题中,各个运算单元输出的结果是相互独立的,这类问题能够得到很轻松的解决 (通常甚至调用几个类库就能搞定问题). 然而,若各个运算单元之间有依赖关系,那问题就复杂了.在 CUDA 中,块内的通信通过共

对JAVA多线程 并发编程的理解

对JAVA多线程并发编程的理解 Java多线程编程关注的焦点主要是对单一资源的并发访问,本文从Java如何实现支持并发访问的角度,浅析对并发编程的理解,也算是对前段时间所学的一个总结. 线程状态转换 Java语言定义了5中线程状态,在任何一个时间点,一个线程只能有且只有其中一种状态,这5中状态分别是: ?  新建(New):创建后尚未启动的线程处于这种状态 ?  运行(Runable):Runable包括了操作系统线程状态中的Running和Ready,也就是处于此状态的线程可能正在执行,也有可

从别人的角度理解这个世界——Leo鉴书80

本书是比较系统介绍博弈论的书,写得通俗易懂,翻译也文从字顺.最为难得的是书里主要用有趣的事例说话,而且考虑到理解的难度先用"10个策略故事"在第一章为读者热身,之后才逐步展开."从别人的角度理解这个世界"是本书的主旨之一,从写法上两位作者写作时无疑首先做到了. 人生就是由一场接着一场不同的博弈组成的,小到明天出门准备穿什么衣服,大到企业甚至国家竞争策略的制定都是博弈的过程.当然,其中有些是单重零和博弈(就玩一次,只有一方最终胜出),有些是多重非零和博弈(玩很多次,最

Android Volley完全解析(四),带你从源码的角度理解Volley

转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/17656437 经过前三篇文章的学习,Volley的用法我们已经掌握的差不多了,但是对于Volley的工作原理,恐怕有很多朋友还不是很清楚.因此,本篇文章中我们就来一起阅读一下Volley的源码,将它的工作流程整体地梳理一遍.同时,这也是Volley系列的最后一篇文章了. 其实,Volley的官方文档中本身就附有了一张Volley的工作流程图,如下图所示. 多数朋友突然看到一张这样

引用别人对编程的理解,挺好

编程对我来说是工作,同时也是我的爱好.喜欢自己的工作,我想我是幸福的人吧.我工作这么多年,唯一真正觉得自己干的好的工作其实也就是编程.而我对编程的理解,我觉得我现在也有资格谈谈自己的理解了.我对编程的理解,说的简单一些,其实就是实用.创新或者探索不是我的工作,我没有受过正规的大学教育,对学术那一套看不太上,我明白我之所以还能够胜任编程的工作更多的靠的是自己的天分以及头脑的聪明,教育对我来说可能有一些潜移默化的影响,但是我心里面明白,我不喜欢那些教育的方式,从而也没有很好的接受过教育对我的帮助,现

一站式学习Java网络编程 全面理解BIO/NIO/AIO

第1章 [开宗明义]网络编程三剑客BIO.NIO.AIO网络编程是RPC的奠基,RPC编程贯穿了程序员生涯的始终.本章首先分析为什么要学网络编,本课为谁设计,然后介绍课程内容主线脉络,让大家清晰知道本课程并非光说不练的假把式,而是处处有实战,实战项目步步优化,最后通过综合项目巩固所学.... 第2章 网络层的解析与协议本章首先对网络中涉及的网络链路层的解析进行讲解,进一步引出网络基本协议知识.使学员了解分层思想,对三种协议的定位及作用有所了解. 第3章 解读java.io专业术语也可以变得生动精

从相亲的角度理解 K8S 的 Node Affinity, Taints 与 Tolerations

这是昨天晚上阅读园子里的2篇 k8s 博文时产生的想法,在随笔中记录一下. 这2篇博文是 K8S调度之节点亲和性 与 K8S调度之Taints and Tolerations . 如果我们把 node 当作女方,pod 当作南方,scheduler 当作媒人,从相亲的角度理解这3个概念,不仅豁然开朗,而且很容易记住. node affinity 就是女方告诉媒人自己喜欢什么类型的男生,介绍这些类型的男生给她. taints 就是女方告诉媒人自己有哪些缺点,不能容忍这些缺点的男生请走开. tole

一站式学习Java网络编程 全面理解BIO/NIO/AIO完整版

一站式学习Java网络编程 全面理解BIO/NIO/AIO 资源获取链接:点击获取完整教程 网络层编程,是每一个开发者都要面对的技术.课程为解决大家学习网络层知识的难题,以创新性的“对比式学习”搭建网络编程课程,课程主线清晰(网络层基础铺垫-->java网络编程前置技术讲解-->阻塞式编程BIO-->非阻塞式编程NIO-->异步编程AIO-->综合实战)适合每一位需要理解网络编程的同学们学习.以“项目驱动”为导向的学习,与企业刚需灵魂契合. 适合人群 网络编程作为编程者的必备