随着物联网设备越来越普及,大部分物联网设备接入公网但却缺乏有效管理,因此希望能够快速获取物公网上联网设备的相关信息,但是在实验环境下,几台计算机使用传统的链接方式去扫描设备效率太低,为了能够达到这个目的,本文介绍了一个多线程telnet快速扫描器,可以快速地实现telnet物联网设备的密码扫描,并将扫描结果存入库中。

总体架构

1.数据输出/syn泛洪发包,可配置扫描信息

2.信息收集及处理/数据嗅探及过滤

3.多线程scanner/多线程通信

4.命令交互状态机/状态机实现,交互过程

5.数据输出/数据入库

数据探测

Xml文件配置

程序使用xml格式配置读取待扫描的ip地址段信息

xml.png

写成xml的主要一开始是因为要扫描一个固定地域的ip地址段,正好使用python可以很方便的解析网页上的内容,所以就将网络上的ip段信息处理成xml格式,方便以后读取。

过程中使用的是xrange生成器,主要是怕生成的ip地址过大,占用过多内存。

syn泛洪

为了加快扫描速度,避免等待无用链接,使用scapy从第三层开始构造syn端口探测包并从特定的端口(例如:2222)大量发送出去,采用先回应先处理的原则,极大的缩短了扫描时间。

syn.png

使用scapy可以很方便的构造数据包,如上图,大量的构造syn数据包。使用scapy的时候注意需要root权限,同时需要注意当前工作目录下的文件名,有可能因为文件名的原因导致scapy无法正常工作。

信息收集

Sniffer

调用scapy中的sniff函数监听数据包,使用bpf过滤规则,过滤特定端口(port:2222),ack响应的数据包,并将数据包的来源ip存入一个FIFO队列(队列默认大小为:100),这是为了避免当收到服务器端的重传ack包,导致处理该ip多次造成效率上的浪费

sniffer.png

Queue才是真正的产出队列,而ip_prompt_queue只是为了避免重复探测同一个的一个先进先出队列,如果ip在FIFO队列当中,则代表该ip已经被探测过了直接略过。

由于sniffer线程是阻塞监听不会退出的所以在一开始将这个线程设置为daemon线程,当没有其他线程时,程序退出,而不会阻塞在sniffer。

sni_th.png

多线程

采用消费-生产的多线程工作模式,使用spewr线程向外泛洪syn数据包,使用sniffer线程监听并分析数据包,使用多个scanner<线程来并行处理扫描到的ip地址。

thread.png

使用一个线程标志位exitFlag来通知线程退出,spewer线程结束发包之后会将exitFlag置1,这时主线程将会循环检测接收数据包的最后时间,如果在30秒内没有监听到数据包,则判断探测过程已经完成没有后续的产出了同时将exitFlag置2,scanner线程将会检查queue当中是否有数据,如果没有数据且exitFlag等于2或3,则表示没有破解目标线程开始退出,同时将exitFlag置3,通知主线程开始退出。

命令交互状态机

为了避免逻辑的单一造成的漏扫之类的实例发生,放弃了使用单一的if-else 或者while-which的逻辑结构,进而采用有限状态机的编程方法,实现对telnet协议更好的交互,交互过程中scanner将会从一个优先级队列当中取出硬编码的用户名-密码对,来对设备进行暴力破解

connection.png

持有状态机的父类

con_state.png

使用pexpect开始数据交互

数据输出

使用MySQL数据库,将成功探测得到的结果存入数据库,存入数据库之前还将添加ip归属地等信息

mysql.png

使用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

下图是扫描的结果图:

result.png

* 原创作者:scu-igroup