随着物联网设备越来越普及,大部分物联网设备接入公网但却缺乏有效管理,因此希望能够快速获取物公网上联网设备的相关信息,但是在实验环境下,几台计算机使用传统的链接方式去扫描设备效率太低,为了能够达到这个目的,本文介绍了一个多线程telnet快速扫描器,可以快速地实现telnet物联网设备的密码扫描,并将扫描结果存入库中。
总体架构
1.数据输出/syn泛洪发包,可配置扫描信息
2.信息收集及处理/数据嗅探及过滤
3.多线程scanner/多线程通信
4.命令交互状态机/状态机实现,交互过程
5.数据输出/数据入库
数据探测
Xml文件配置
程序使用xml格式配置读取待扫描的ip地址段信息
写成xml的主要一开始是因为要扫描一个固定地域的ip地址段,正好使用python可以很方便的解析网页上的内容,所以就将网络上的ip段信息处理成xml格式,方便以后读取。
过程中使用的是xrange生成器,主要是怕生成的ip地址过大,占用过多内存。
syn泛洪
为了加快扫描速度,避免等待无用链接,使用scapy从第三层开始构造syn端口探测包并从特定的端口(例如:2222)大量发送出去,采用先回应先处理的原则,极大的缩短了扫描时间。
使用scapy可以很方便的构造数据包,如上图,大量的构造syn数据包。使用scapy的时候注意需要root权限,同时需要注意当前工作目录下的文件名,有可能因为文件名的原因导致scapy无法正常工作。
信息收集
Sniffer
调用scapy中的sniff函数监听数据包,使用bpf过滤规则,过滤特定端口(port:2222),ack响应的数据包,并将数据包的来源ip存入一个FIFO队列(队列默认大小为:100),这是为了避免当收到服务器端的重传ack包,导致处理该ip多次造成效率上的浪费
Queue才是真正的产出队列,而ip_prompt_queue只是为了避免重复探测同一个的一个先进先出队列,如果ip在FIFO队列当中,则代表该ip已经被探测过了直接略过。
由于sniffer线程是阻塞监听不会退出的所以在一开始将这个线程设置为daemon线程,当没有其他线程时,程序退出,而不会阻塞在sniffer。
多线程
采用消费-生产的多线程工作模式,使用spewr线程向外泛洪syn数据包,使用sniffer线程监听并分析数据包,使用多个scanner<线程来并行处理扫描到的ip地址。
使用一个线程标志位exitFlag来通知线程退出,spewer线程结束发包之后会将exitFlag置1,这时主线程将会循环检测接收数据包的最后时间,如果在30秒内没有监听到数据包,则判断探测过程已经完成没有后续的产出了同时将exitFlag置2,scanner线程将会检查queue当中是否有数据,如果没有数据且exitFlag等于2或3,则表示没有破解目标线程开始退出,同时将exitFlag置3,通知主线程开始退出。
命令交互状态机
为了避免逻辑的单一造成的漏扫之类的实例发生,放弃了使用单一的if-else 或者while-which的逻辑结构,进而采用有限状态机的编程方法,实现对telnet协议更好的交互,交互过程中scanner将会从一个优先级队列当中取出硬编码的用户名-密码对,来对设备进行暴力破解
持有状态机的父类
使用pexpect开始数据交互
数据输出
使用MySQL数据库,将成功探测得到的结果存入数据库,存入数据库之前还将添加ip归属地等信息
使用mysql.sql脚本,创建数据库及数据表,注意由于使用了归属地等中文信息,因此建库和建表的时候要设置好响应的字符集才不会导致乱码。设置ip的UNIQUE键,避免重复表项。
使用方法
1.操作环境linux
2.使用apt-get或者yum安装mysql数据库
3.下载pip安装程序(https://pypi.python.org/pypi/pip),按照说明安装
4.使用pip命令安装pexpect,MySQL-python,17monip,scapy等(如:pip install pexpect)
5.进入mysql数据库,source */mysql.sql 执行脚本创建数据库和数据表
6.使用 python scanner.py 10 运行程序
项目代码:https://github.com/scu-igroup/telnet-scanner
本文转自d1net(转载)