Ejemplo n.º 1
0
def login(email, password):
    """
    登陆到ZoomEye
    :param email: 账户email
    :param password: 账户password
    :return: None
    """
    data = {'username': email, 'password': password}
    # dumps 将 python 对象转换成 json 字符串
    data_encoded = json.dumps(data)
    try:
        # print('---------------------')
        r = requests.post(url='https://api.zoomeye.org/user/login',
                          data=data_encoded)
        # loads() 将 json 字符串转换成 python 对象
        # print('---------------------')
        r_decoded = json.loads(r.text)
        # print('---------------------')
        info('username : {}\tpasswd : {}'.format(email, password))

        # 获取到账户的access_token
        global access_token
        access_token = r_decoded['access_token']
        write_conf(path.config, 'zoomeye', 'access_token',
                   access_token)  # 写入access_token
        print('#######################################')
    except Exception:
        error(
            'username or password is wrong, please check config file or input')
    pass
Ejemplo n.º 2
0
def set_cmd_opts(args):
    """
    Set data using commandline args
    解析命令行参数设置到cmd_opts中
    :return: None
    """

    # 先检查命令行参数一下是否正确设置
    check_args(args)

    # --update 检查系统更新
    if args.Update:
        update()

    # --list 列出所有的可用脚本信息
    if args.list_scripts:
        show_scripts()

    # --threads 设置线程数
    if args.threads:
        threads = args.threads
        set_threads(threads)

    # --script 加载脚本
    if args.script_name:
        script_name = args.script_name

        # 检查是否存在该脚本
        check_script_existence(script_name)

        # 设置攻击脚本
        cmd_opts.script = script_name
    else:
        cmd_opts.script = ''

    set_targets(args)           # --target 设置攻击目标

    # --limit  设置从api接口获取的数量, 默认限额20
    if args.limit:
        cmd_opts.limit = args.limit
    else:
        cmd_opts.limit = 20

    # --offset 设置偏移量,从相应的api接口查询起始页,默认从第一页开始page=0
    if args.offset:
        cmd_opts.offset = args.offset
    else:
        cmd_opts.offset = 0

    # --query  设置查询语句,query='weblogic country:cn'
    if args.query:
        cmd_opts.query = args.query
        info('query : {}'.format(cmd_opts.query))

    # 查找脚本,模糊查找,列出名字相似或相同的脚本,以便选择
    if args.search_script:
        script_name = args.search_script
        search_script(script_name)
Ejemplo n.º 3
0
def fofa_api():  # TODO 付费获取结果的功能实现
    """
    Get query result from Fofa
    :param query: query string
    :param limit: query amount
    :param offset: start page
    :return: query result
    """
    global email, key

    # load query, limit, offset from cmd_opts
    query = cmd_opts.query
    limit = cmd_opts.limit
    offset = cmd_opts.offset

    # 从配置文件中读取email和key
    try:
        email = read_conf(path.config, 'fofa', 'email')
        key = read_conf(path.config, 'fofa', 'key')
        print('{} - {}'.format(email, key))
        if check(email, key):
            pass
        else:
            raise  # will go to except block
    # 读取手工输入的email和key
    except:
        warning('Automatic authorization failed.')
        email = input("Fofa Email: ").strip()
        key = input("Fofa Key: ").strip()

        if not check(email, key):
            error(
                'Fofa API authorization failed, Please re-run it and enter a valid key.'
            )

    exit()

    query = base64.b64encode(query)

    request = "https://fofa.so/api/v1/search/all?email={0}&key={1}&qbase64={2}".format(
        email, key, query)
    global result
    try:
        response = requests.get(request, timeout=3)
        resp = response.readlines()[0]
        resp = json.loads(resp)
        if resp["error"] is None:
            for item in resp.get('results'):
                result.append(item[0])
            if resp.get('size') >= 100:
                info("{0} items found! just 100 returned....".format(
                    resp.get('size')))
    except:
        sys.exit()
    finally:
        return result
Ejemplo n.º 4
0
def print_args(args):
    """
    输出参数信息,检测参数是否出现问题
    :return: None
    """
    print('---args for : {}'.format(args))
    for k, v in args.items():
        info('{} : {}'.format(k, v))
        time.sleep(0.05)
    print('\r\n\r\n')
Ejemplo n.º 5
0
def init_shodan():
    """
    Init Shodan, read config file to fetch API_KEY
    从配置文件中获取API_KEY
    :return: None
    """

    global API_KEY, api
    API_KEY = read_conf(path.config, 'shodan', 'api_key')
    if API_KEY:
        info(API_KEY)
    else:
        API_KEY = input('please input API_KEY')

    api = shodan.Shodan(API_KEY)  # init
Ejemplo n.º 6
0
def update():
    """
    Update this program
    更新脚本: 直接使用git pull origin master
    :return: None
    """
    info('update program \r\n...')

    try:
        # 使用git 命令更新脚本
        os.system('git pull origin master')
        info('succeed ... ')
    except:
        error('something wrong with "git pull origin master", please try to re-download this repo for update')
    exit()
Ejemplo n.º 7
0
def init_zoomeye():
    """
    初始化zoomeye, 读取配置文件
    :return: None
    """
    global access_token, email, password
    email = read_conf(path.config, 'zoomeye', 'email')
    password = read_conf(path.config, 'zoomeye', 'password')
    access_token = read_conf(path.config, 'zoomeye', 'access_token')

    # 输出读取的配置文件信息
    info('zoomeye infomation \nemail : {} \npassword : {}\naccess_token : {}\n'
         ''.format(email, password, access_token))

    pass
Ejemplo n.º 8
0
def getIp(query, page):
    """
    Fect data from Shodan api
    :param query: query string
    :param page: page number
    :return: None
    """
    info('page : {}'.format(page))
    try:
        results = api.search(query, page=page)
        for result in results['matches']:
            ip_port = '{}:{}'.format(result['ip_str'], result['port'])
            iplist.append(ip_port)
    except:
        pass
    pass
Ejemplo n.º 9
0
def init_censys():
    """
    Init censys, read UID and SECRET from config file
    :return:
    """
    global UID, SECRET
    # email = read_conf(path.config, 'zoomeye', 'email')
    UID = read_conf(path.config, 'censys', 'UID')
    SECRET = read_conf(path.config, 'censys', 'SECRET')

    if UID and SECRET:
        info('UID : {} SECRET:{}'.format(UID, SECRET))
    else:
        warning(
            'please refer to this url : {} and fill in UID and SECRET'.format(
                'https://www.censys.io/account/api'))
Ejemplo n.º 10
0
def start():
    """
    start to exploit
    :return: None
    """
    # 输出参数, 检查下是否有问题
    # print_args(cmd_opts)
    # print_args(scripts)

    # 完成engined的一些初始化工作
    initialize()

    info('concurrent threads : {}'.format(statistic.thread_num))

    run()
    pass
Ejemplo n.º 11
0
def apiTest(query, offset, pages):
    """
    Fetch data : 获取数据
    :param query: 查询语句
    :param offset: 起始页
    :param pages: 页数
    :return: None
    """
    global access_token
    headers = {
        'Authorization': 'JWT ' + access_token,
    }
    flag = True  # 用来标记是否输出资源信息
    for i in range(pages):
        page = offset + i

        try:
            url = 'https://api.zoomeye.org/host/search?query=' + query + '&page=' + str(
                page)

            r = requests.get(url=url, headers=headers)
            r_decoded = json.loads(r.text)

            # 输出一次查询的结果总数
            if flag:
                info('Total result : {}'.format(r_decoded['total']))
                flag = False

            info('url : {}'.format(url))

            # 解析出ip:port 添加到结果列表
            for x in r_decoded['matches']:
                ip_port = '{}:{}'.format(x['ip'], x['portinfo']['port'])
                print(ip_port)
                # result.append(ip_port)
                result.add(ip_port)

        except Exception as e:
            # 如果发生异常,其它先不用管,把获取的数据返回
            return result
            if str(e.message) == 'matches':
                warning('account was break, excceeding the max limitations')
            else:
                warning(str(e.message))
Ejemplo n.º 12
0
def get_resource_info():
    """
    获取跟ZoomEye资源相关信息: 用户类型和用户所剩的查询额度
    :return: None
    """
    global access_token
    headers = {
        'Authorization': 'JWT ' + access_token,
    }
    try:
        url = 'https://api.zoomeye.org/resources-info'
        r = requests.get(url=url, headers=headers)
        info('url : {}'.format(url))
        r_decoded = json.loads(r.text)
        info('plan : {} | resources available : {}'.format(
            r_decoded['plan'], r_decoded['resources']['search']))
    except Exception as e:
        error(str(e.message))
    pass
Ejemplo n.º 13
0
def run():
    """
    开始扫描任务, 漏洞利用
    :return: None
    """

    # 线程数量
    threads_num = cmd_opts.threads

    # 线程list,放在一个list方便管理
    thread_list = []

    # 加载攻击模块,放在外面作为参数传递给线程,这样在线程里就不用每次都去加载了,提高批量检测时的效率,因为是同一个payload
    module = load_module(cmd_opts.script)

    # 输出模块信息
    info('using : {}'.format(module))

    # 存放存在漏洞的主机
    statistic.succeed = set()

    print('\n---------- Exploiting ----------\n')

    # 创建线程
    for i in range(threads_num):
        t = threading.Thread(target=scan, args=(module, ), name=str(i))
        thread_list.append(t)

    # 启动线程
    for t in thread_list:
        t.setDaemon(True)
        t.start()

    # 等待线程终止
    for t in thread_list:
        t.join()

    print('\n--- The following are vulnerable ---\n')
    for line in statistic.succeed:
        print(line)

    # 将结果写入文件
    save_result()
Ejemplo n.º 14
0
def zoomeye_api():
    """
    Use ZoomEye to fetch data and return back
    调用ZoomEye接口,获取数据并返回
    :return:
    """
    # print('fetch result from zoomeye')

    # 从配置文件中获取zoomeye账户信息:登陆需要使用的邮箱和密码
    init_zoomeye()

    global email, password, access_token

    # 如果配置文件中有
    if not access_token:
        # 如果配置文件中,存在email和password字段,则使用该字段登陆zoomeye, 获取access_token
        if email and password:
            login(email, password)
        else:
            email = input('please input email : ')
            password = input('please input password : '******'==>access_token : {}'.format(access_token))

    # 查看资源信息
    get_resource_info()

    # 设置查询参数: 查询语句,起始页和页数
    query = cmd_opts.query
    offset = cmd_opts.offset

    # 设置更为合理的查询页数,其实无所谓啦
    pages = int(cmd_opts.limit / 20)
    if pages * 20 != cmd_opts.limit:
        pages += 1

    # 获取数据
    apiTest(query, offset, pages)

    # 返回
    return result
Ejemplo n.º 15
0
def getIp(query, page):
    """
    Fetch ip:port by given query and page
    :param query: query string
    :param page: page number
    :return: None
    """
    info('page : {}'.format(page))
    data = {"query": query, "page": page, "fields": ["ip", "protocols"]}
    try:
        res = requests.post(API_URL + "/search/ipv4",
                            data=json.dumps(data),
                            auth=(UID, SECRET))
    except:
        pass
    try:
        results = res.json()
    except:
        pass

    if res.status_code != 200:
        print("error occurred: %s" % results["error"])
        sys.exit(1)

    # print(json.dumps(results))
    tmp = []
    # actually, censys is not very accurate, because we can not get a specific port when we search
    # eg: "weblogic", censys will give serveral ports that is open on this machine
    # so, we have to add it all
    for result in results["results"]:
        for i in result["protocols"]:
            tmp.append(result["ip"] + ':' + i)

    # remove http/https from the end
    for line in tmp:
        ip_port = line[:line.find('/')]
        iplist.append(ip_port)
        print(ip_port)
    pass
Ejemplo n.º 16
0
def check():
    """
    Check Authorization
    :param email: email address
    :param key: api key
    :return: login succeed or not | that is True or False
    """
    global email, key
    if email and key:
        auth_url = "https://fofa.so/api/v1/info/my?email={0}&key={1}".format(
            email, key)
        info(auth_url)
        try:
            response = requests.get(auth_url, timeout=3)
            if response.status_code == 200:
                return True
            else:
                warning(response.text)
                return False
        except:
            return False
    return False
Ejemplo n.º 17
0
def set_targets(args):
    """
    Set remote target
    设置目标
    :param args: 目标target, 来自命令行参数
    :return: None
    """

    # 目标队列
    statistic.queue = queue.Queue()

    # 单个url
    if args.target_url:
        cmd_opts.target_mode = 'SINGLE'
        cmd_opts.target = args.target_url
        info('target : {}'.format(cmd_opts.target))
        statistic.queue.put(cmd_opts.target)

    # 从文件中读取
    elif args.target_file:
        cmd_opts.target_mode = 'FILE'
        cmd_opts.target = read_file(args.target_file)
        for line in cmd_opts.target:
            print(line)
            statistic.queue.put(line)

    # 从ZoomEye 获取
    elif args.ZoomEye:
        cmd_opts.target_mode = 'ZoomEye'
        info('fetch targets using ZoomEye Api')

        # statistic.queue.put(zoomeye-api)
        # 从ZoomEye获取的ip:port列表,保存一份到文件中,以备日后之用
        result = zoomeye_api()
        save_ip_port(result)

        info('There are {} hosts to test!'.format(len(result)))

        # 将ip:port放入到待检测的队列中
        for line in result:
            statistic.queue.put(line)

    # 从Shodan 获取
    elif args.Shodan:
        cmd_opts.target_mode = 'Shodan'
        info('fetch targets using Shodan Api')

        # statistic.queue.put(shodan-api)
        result = shodan_api()
        info('There are {} hosts to test!'.format(len(result)))

        for line in result:
            statistic.queue.put(line)
        statistic.queue.put('127.0.0.1')            # shodan未经测试,要钱啊,故添加一个临时的127.0.0.1

    # 从Censys获取
    elif args.Censys:
        cmd_opts.target_mode = 'censys'
        info('fetch targets using Censys Api')

        # statistic.queue.put(censys-api)
        result = censys_api()

        info('{} to test!'.format(len(result)))

        for line in result:
            statistic.queue.put(line)
        statistic.queue.put('127.0.0.1')            # censys 讲道理,获取的结果不准确
    elif args.Fofa:
        cmd_opts.target_mode = 'fofa'
        info('fetch targets using Fofa Api')

        # statistic.queue.put(fofa-api)
        result = fofa_api()

        info('{} to test!'.format(len(result)))

        for line in result:
            statistic.queue.put(line)
        statistic.queue.put('127.0.0.1')  # censys 讲道理,获取的结果不准确,

    else:
        cmd_opts.target_mode = ''
        cmd_opts.target = ''
        pass
    pass