欢迎来到starnight_cyber的博客

从ZoomEye API 到 Weblogic 弱口令扫描

参考资料:
ZoomEye API: https://www.zoomeye.org/api/doc
Weblogic-Weakpassword-Scnner: https://github.com/dc3l1ne/Weblogic-Weakpassword-Scnner
Python 调用 ZoomEye API 批量获取目标网站IP: http://www.cnblogs.com/anka9080/p/ZoomEyeAPI.html

本文参考以上资料,经过部分修改,以便于自己使用,现将其分享出来。为了表示对原作者敬意,特将其工作列在文首。

本文涉及两方面的工作,从ZoomEye API获取到想要的IP列表,再用Weblogic 弱口令扫描器对得到的地址进行扫描。

Github传送: ZoomEye

一、从ZoomEye API获取IP地址列表

"首先要说明的是,使用ZoomEye API需要先注册账号,使用方法是先提交账户,密码获得一个唯一的访问令牌(access_token)"

"然后每次调用 API 的时候在 HTTP 的 Headers 里加上格式化后的 access_token 就可以使用了"

  使用python脚本从ZoomEye API 获取到的IP地址数量是有限的,但由于其数量巨大,我们可以得到的便利也是巨大的。且ZoomEye 的爬虫是一直在运行的,搜索得到的结果也是变动的,因此我们可以多注册几个账号...

  

下面是从ZoomEye API 获取IP地址的Demo

# coding: utf-8
# author  : evilclay
# datetime: 20160330
# http://www.cnblogs.com/anka9080/p/ZoomEyeAPI.html
# Modified by : starnight_cyber@foxmail.com
# Time : 2016.12.1

import os
import requests
import json
import time

access_token = ''
ip_list = []

def login():
    """
        输入用户名密码 进行登录操作
    :return: 访问口令 access_token
    """
    user = raw_input('[-] input : username :')
    passwd = raw_input('[-] input : password :')
    data = {
        'username': user,
        'password': passwd
    }

    # dumps 将 python 对象转换成 json 字符串
    data_encoded = json.dumps(data)
    try:
        r = requests.post(url='https://api.zoomeye.org/user/login', data=data_encoded)
        # loads() 将 json 字符串转换成 python 对象
        r_decoded = json.loads(r.text)
        global access_token

        # 获取到账户的access_token
        access_token = r_decoded['access_token']
    except Exception, e:
        print '[-] info : username or password is wrong, please try again '
        exit()


def saveStrToFile(file, str):
    """
        将access_token写如文件中
    :return:
    """
    with open(file, 'w') as output:
        output.write(str)


def saveListToFiles(ip_list):
    '''
    :param ip_list: 使用ZoomEye接口获得的ip列表
    : 会写入到多个文件,保存格式不同,仅ip和 http://ip/console/login/LoginForm.jsp
    : 如http://162.105.205.162/console/login/LoginForm.jsp
    :return:
    '''

    # 以当前运行脚本的时间创建文件,这样就可以保证脚本运行时创建的文件不会重名
    xtime = time.strftime("%Y-%m-%d[%H.%M.%S]")
    ip_list_file = open(xtime + 'ip.txt', 'w')
    url_list_file = open(xtime + 'url.txt', 'w')

    # 将list以一定格式写入到文件中
    for line in ip_list:
        # ip格式
        ip_list_file.write(line + '\n')

        # weblogic 后台登录地址格式
        url_list_file.write('http://' + line + '/console/login/LoginForm.jsp' + '\n')

    # 关闭文件
    ip_list_file.close()
    url_list_file.close()


def apiTest():
    """
        进行 api 使用测试
    :return:
    """
    page = 1        # 表示第几页
    num = 1         # 页数
    index = 1       # 循环下标
    global access_token
    with open('access_token.txt', 'r') as input:
        access_token = input.read()
    # 将 token 格式化并添加到 HTTP Header 中
    headers = {
        'Authorization': 'JWT ' + access_token,
    }

    # 要搜索的字符串
    # query = 'port:80 weblogic country:China'
    query = raw_input('[*] please input search string : ')

    # 设置获取结果的起始页面,对于量比较大的时候比较有用
    page = int(raw_input('[*] please input start page : '))

    # 设置获取的结果页数
    num = int(raw_input('[*] please input number of pages you want to retrieve : '))

    while (True):
        try:
            # 将查询字符串和页数结合在一起构造URL
            searchurl = 'https://api.zoomeye.org/host/search?query=' + query + '&page=' + str(page)
            r = requests.get(url=searchurl, headers=headers)
            print searchurl
            r_decoded = json.loads(r.text)
            # print r_decoded
            # print r_decoded['total']
            for x in r_decoded['matches']:
                print x['ip']
                ip_list.append(x['ip'])
            print '[-] info : count ' + str(index * 10)

        except Exception, e:
            # 若搜索请求超过 API 允许的最大条目限制 或者 全部搜索结束,则终止请求
            if str(e.message) == 'matches':
                print '[-] info : account was break, excceeding the max limitations'
                break
            else:
                print '[-] info : ' + str(e.message)
        else:
            # 判断页数
            if index == num:
                break
            page += 1       # 用于获取下一页的结果
            index += 1
            # 输出提示
            print 'page : ' + str(page) + ' - ' + 'index : ' + str(index)


def main():
    # 访问口令文件不存在则进行登录操作
    if not os.path.isfile('access_token.txt'):
        print '[-] info : access_token file is not exist, please login'
        login()
        # 保存access_token到文件中
        saveStrToFile('access_token.txt', access_token)

    # 从ZoomEye API 获取IP地址列表
    apiTest()

    # 将结果保存到文件中
    saveListToFiles(ip_list)


if __name__ == '__main__':
    main()

 运行:

运行结束后保存了以时间命名的文件

 获取到的IP列表

 Weblogic 后台登录地址形式:

 

这样,我们的第一步就完成了,得到了我们想要的IP地址列表。

二、使用Weblogic-Weakpassword-Scnner 扫描weblogic 后台弱口令

  得到有效的weblogic后台登录地址:

  将第一步得到的url格式的文件,重命名为url.txt, 运行Weblogic-Weakpassword-Scnner 中的spider.py 脚本, 清除无效的url,得到u.txt, 为有效的weblogic 后台登录地址,可以用来暴力破解。

python spider.py

  

  暴力破解:

  运行Weblogic-Weakpassword-Scnner 中的main.py 脚本, 进行暴力破解。

python main.py 100

  

命名为*.txt的文件中,保存了weblogic的后台登录地址,及用户和密码。 

得到IP地址后,不仅仅是可以用来扫描Weblogic后台弱口令,接下来...

最后,附上Top5的弱口令:

weblogic
weblogic123
12345678
11111111
weblogic123456

 

三、ZoomEye Version 2

  在处理上做了些小的修改,之前端口处理有点问题,现已修正...

# -*- coding: utf-8 -*-
# author  : evilclay
# datetime: 20160330
# http://www.cnblogs.com/anka9080/p/ZoomEyeAPI.html
# Modified by : starnight_cyber@foxmail.com
# Time : 2016.12.8

import os
import requests
import json
import time

access_token = ''
ip_list = []
ip_port_list = []

def login():
    """
        输入用户名密码 进行登录操作
    :return: 访问口令 access_token
    """
    user = raw_input('[-] input : username :')
    passwd = raw_input('[-] input : password :')
    data = {
        'username': user,
        'password': passwd
    }

    # dumps 将 python 对象转换成 json 字符串
    data_encoded = json.dumps(data)
    try:
        r = requests.post(url='https://api.zoomeye.org/user/login', data=data_encoded)
        # loads() 将 json 字符串转换成 python 对象
        r_decoded = json.loads(r.text)
        global access_token

        # 获取到账户的access_token
        access_token = r_decoded['access_token']
    except Exception, e:
        print '[-] info : username or password is wrong, please try again '
        exit()


def saveStrToFile(file, str):
    """
        将access_token写如文件中
    :return:
    """
    with open(file, 'w') as output:
        output.write(str)


def saveListToFiles(ip_list):
    '''
    :param ip_list: 使用ZoomEye接口获得的ip列表
    : 会写入到多个文件,保存格式不同,仅ip和 http://ip/console/login/LoginForm.jsp
    : 如http://162.105.205.162/console/login/LoginForm.jsp
    :return:
    '''

    # 以当前运行脚本的时间创建文件,这样就可以保证脚本运行时创建的文件不会重名
    xtime = time.strftime("%Y-%m-%d[%H.%M.%S]")
    ip_list_file = open(xtime + 'ip.txt', 'w')
    ip_port_list_file = open(xtime + 'ip:port.txt', 'w')

    # 将ip以一定格式写入到文件中
    for line in ip_list:
        ip_list_file.write(line + '\n')

    #  将ip,port写入文件中
    for line in ip_port_list:
        ip_port_list_file.write(line + '\n')

    # 关闭文件
    ip_list_file.close()
    ip_port_list_file.close()


def apiTest():
    """
        进行 api 使用测试
    :return:
    """
    page = 1        # 表示第几页
    num = 1         # 页数
    index = 1       # 循环下标
    global access_token
    with open('access_token.txt', 'r') as input:
        access_token = input.read()
    # 将 token 格式化并添加到 HTTP Header 中
    headers = {
        'Authorization': 'JWT ' + access_token,
    }

    # 要搜索的字符串
    # query = 'port:80 weblogic country:China'
    query = raw_input('[*] please input search string : ')

    # 设置获取结果的起始页面,对于量比较大的时候比较有用
    page = int(raw_input('[*] please input start page : '))

    # 设置获取的结果页数
    num = int(raw_input('[*] please input number of pages you want to retrieve : '))

    while (True):
        try:
            # 将查询字符串和页数结合在一起构造URL
            searchurl = 'https://api.zoomeye.org/host/search?query=' + query + '&page=' + str(page)
            r = requests.get(url=searchurl, headers=headers)
            print searchurl
            r_decoded = json.loads(r.text)
            # print r_decoded
            # print r_decoded['total']
            for x in r_decoded['matches']:
                print x['ip'], x['portinfo']['port']
                ip_list.append(x['ip'])
                ip_port_list.append(x['ip'] + ', ' + str(x['portinfo']['port']))
            print '[-] info : count ' + str(index * 10)

        except Exception, e:
            # 若搜索请求超过 API 允许的最大条目限制 或者 全部搜索结束,则终止请求
            if str(e.message) == 'matches':
                print '[-] info : account was break, excceeding the max limitations'
                break
            else:
                print '[-] info : ' + str(e.message)
        finally:
            # 判断页数
            if index == num:
                break
            page += 1       # 用于获取下一页的结果
            index += 1
            # 输出提示
            print 'page : ' + str(page) + ' - ' + 'index : ' + str(index)


def main():
    # 访问口令文件不存在则进行登录操作
    if not os.path.isfile('access_token.txt'):
        print '[-] info : access_token file is not exist, please login'
        login()
        # 保存access_token到文件中
        saveStrToFile('access_token.txt', access_token)

    # 从ZoomEye API 获取IP地址列表
    apiTest()

    # 将结果保存到文件中
    saveListToFiles(ip_list)


if __name__ == '__main__':
    main()

三、ZoomEye Version 3 [2018.1.8更新]

直接贴代码吧:

#!/usr/bin/python
# encoding: utf-8
import requests as req
import json
import optparse
import time
import sys
import os

class ZoomEye:

    def __init__(self):
        self.initParameter()
        username = 'zl15@foxmail.com'
        password = 'liu120808'
        self.account = {'username': username,'password': password}
        self.headers = {'Authorization': 'JWT ' + self.getToken()}

    def search(self):
        self.isFIle(self.options.file)
        queryType = self.options.type
        queryStr = self.options.query
        try:
            result = req.get('https://api.zoomeye.org/'+ queryType + '/search?query=' + queryStr + '&page=1', \
                    headers=self.headers, timeout = 15)
        except:
            print "Error exit..."
            sys.exit()
        if result.status_code != 200:
            print "error: ",
            print result.content
            print "exit..."
            sys.exit()
        resultDict = json.loads(result.content)
        # print result.content #获取第一页的所有结果
        pages = self.getPageNum(int(resultDict['total']))
        print 'There are %d pages to fetch' % pages

        userAgent = {'user-agent': 'Mozilla/5.0(iPad; U; CPU OS 3_2_1 like Mac OS X; en-us)AppleWebKit/\
            531.21.10(KHTML, like Gecko)Mobile/7B405'}
        self.headers['user-agent'] = userAgent

        start = time.time()
        starPage = 0
        for i in xrange(starPage, pages, 1):
            targetList = []
            try:
                result = req.get('https://api.zoomeye.org/' + queryType +'/search?query='+ queryStr +'&page='+\
                    str(i+1), headers=self.headers, timeout=15)
                # print "Get page " + str(i+1) + " info ..."
                now = time.time()
                print '[ %d / %d ] ==> time elapse %s s ...' % (i, pages, int(now - start))
            except:
                print "Page " + str(i) + " ,  Error exit..."
                # sys.exit()
                continue
            if result.status_code != 200:
                print "error: ",
                print result.content
                print "exit..."
                sys.exit()
                # print result.content #每页的结果
            self.getFileContent(targetList, result.content)
            self.writeTofile(self.options.file, targetList)
        print "The result in " + self.options.file

    def getFileContent(self, targetList, result):
        result = json.loads(result)
        # print result
        if self.options.type == 'web':
            for eachResult in result['matches']:
                # print eachResult
                # 获取目标站点
                targetList.append(eachResult['site'])
            print targetList
            return targetList
        for eachResult in result['matches']:
            # targetList.append(eachResult['ip'] + ':' + str(eachResult['portinfo']['port']))
            ip_port = eachResult['ip'] + ':' + str(eachResult['portinfo']['port'])
            print ip_port
            targetList.append(ip_port)
        return targetList

    def getPageNum(self, total):
        if total == 0:
            print "No result, exit.."
            sys.exit()
        page = total/10
        if total%10 == 0:
            return page
        return page + 1

    def getToken(self):
        token = req.post('https://api.zoomeye.org/user/login',json.dumps(self.account)).content
        print token
        return json.loads(token)['access_token']

    def writeTofile(self, filename, targetList):
        with open(filename, 'a') as f:
            for eachTarget in targetList:
                f.write(eachTarget + "\n")
                time.sleep(0.2)

    def isFIle(self,filename):
        if not os.path.isfile(filename):
            return
        print 'result file is exists, continue ?',
        choice = raw_input("(y/n): ")
        if choice.lower() == 'n':
            print 'Please rename filename, exit ...'
            sys.exit()
        if choice.lower() == 'y':
            return
        else:
            return self.isFIle(filename)

    def initParameter(self):
        usage = '''
         _____                     _____
        |__  /___   ___  _ __ ___ | ____|   _  ___
          / // _ \ / _ \| '_ ` _ \|  _|| | | |/ _
         / /| (_) | (_) | | | | | | |__| |_| |  __/
        /____\___/ \___/|_| |_| |_|_____\__, |\___|
                                        |___/
            '''
        parser = optparse.OptionParser(usage = usage)
        parser.add_option("-t", "--type",
                          default='web',
                          help='''Search type like host ,web  (e.g. "https://api.zoomeye.org/host/\
                                  search?query=port:21")''')

        parser.add_option("-q", "--query",
                          help="What you search is your need")

        parser.add_option("-f", "--file",
                          help="The file will save result's IP or domain")

        (self.options, args) = parser.parse_args()
        if self.options.query == None or self.options.file == None:
            print parser.print_help()
            print "Please Completed  parameters, you can show -h to get help"
            sys.exit()
        else:
            print usage


if __name__ == '__main__':
    ZE = ZoomEye()
    try:
        ZE.search()
    except KeyboardInterrupt:
        print "Ctrl + C exit..."
        sys.exit()

 

posted @ 2016-12-02 21:52  starnight_cyber  阅读(2454)  评论(0编辑  收藏  举报