POC-T框架学习————5、相关脚本深入学习一

版权声明:严禁将博客中涉及到的技术用于恶意破坏,如果造成法律责任,博主概不负责! https://blog.csdn.net/Fly_hps/article/details/87932317

前言

通过之前的对POC-T框架的了解,我们知道了一些基本目录的分类,以及该框架的整个设计思维以及他的使用,我们如何去扩展该框架,让其变得更加完美,在接下来的几篇文章当中,我们将会对POC-T源代码脚本进行一个深入分析,深入学习它的实现机制。

相关代码分析

1、POC-T.py(框架入口)

versioncheck.py(检查当前python的版本)

cli.py(被调用的main函数,也是正正的程序的入口)

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# project = https://github.com/Xyntax/POC-T
# author = [email protected]

import os.path
import traceback
from lib.parse.cmdline import cmdLineParser
from lib.core.option import initOptions
from lib.controller.loader import loadModule, loadPayloads
from lib.core.common import setPaths, banner, systemQuit, openBrowser
from lib.core.data import paths, conf, logger, cmdLineOptions
from lib.core.enums import EXIT_STATUS
from lib.core.settings import IS_WIN
from lib.core.exception import ToolkitUserQuitException
from lib.core.exception import ToolkitMissingPrivileges
from lib.core.exception import ToolkitSystemException
from lib.controller.engine import run
from thirdparty.colorama.initialise import init as winowsColorInit


def main():
    """
    Main function of POC-T when running from command line.
    """
    try:
        paths.ROOT_PATH = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
        try:
            os.path.isdir(paths.ROOT_PATH)
        except UnicodeEncodeError:
            errMsg = "your system does not properly handle non-ASCII paths. "
            errMsg += "Please move the project root directory to another location"
            logger.error(errMsg)
            raise SystemExit
        setPaths()

        cmdLineOptions.update(cmdLineParser().__dict__)
        initOptions(cmdLineOptions)

        if IS_WIN:
            winowsColorInit()
        banner()

        loadModule()
        loadPayloads()

        run()

        if conf.OPEN_BROWSER:
            openBrowser()

        systemQuit(EXIT_STATUS.SYSETM_EXIT)

    except ToolkitMissingPrivileges, e:
        logger.error(e)
        systemQuit(EXIT_STATUS.ERROR_EXIT)

    except ToolkitSystemException, e:
        logger.error(e)
        systemQuit(EXIT_STATUS.ERROR_EXIT)

    except ToolkitUserQuitException:
        systemQuit(EXIT_STATUS.USER_QUIT)
    except KeyboardInterrupt:
        systemQuit(EXIT_STATUS.USER_QUIT)

    except Exception:
        print traceback.format_exc()
        logger.warning('It seems like you reached a unhandled exception, please report it to author\'s mail:<[email protected]> or raise a issue via:<https://github.com/Xyntax/POC-T/issues/new>.')

if __name__ == "__main__":
    main()

可以从上面的代码中看到main函数当中也是调用了很多通过import导入的脚本文件中的中的函数,之后我们会一一分析。

2、setPaths函数(用于初始化基本物理路径、脚本路径、字典路径)

3、cmdLineParser(用户输入的参数解析)

各种参数匹配:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# project = https://github.com/Xyntax/POC-T
# author = [email protected]

import argparse
import sys
from lib.core.settings import VERSION


def cmdLineParser():
    parser = argparse.ArgumentParser(description='powered by cdxy <mail:[email protected]> ',
                                     usage='python POC-T.py -s bingc -aZ "port:8080"',
                                     add_help=False)

    engine = parser.add_argument_group('ENGINE')
    engine.add_argument('-eT', dest="engine_thread", default=False, action='store_true',
                        help='Multi-Threaded engine (default choice)')

    engine.add_argument('-eG', dest="engine_gevent", default=False, action='store_true',
                        help='Gevent engine (single-threaded with asynchronous)')

    engine.add_argument('-t', metavar='NUM', dest="thread_num", type=int, default=10,
                        help='num of threads/concurrent, 10 by default')

    script = parser.add_argument_group('SCRIPT')

    script.add_argument('-s', metavar='NAME', dest="script_name", type=str, default='',
                        help='load script by name (-s jboss-rce) or path (-s ./script/jboss.py)')

    target = parser.add_argument_group('TARGET')

    target.add_argument('-iS', metavar='TARGET', dest="target_single", type=str, default='',
                        help="scan a single target (e.g. www.wooyun.org)")
    target.add_argument('-iF', metavar='FILE', dest="target_file", type=str, default='',
                        help='load targets from targetFile (e.g. ./data/wooyun_domain)')
    target.add_argument('-iA', metavar='START-END', dest="target_array", type=str, default='',
                        help='generate array from int(start) to int(end) (e.g. 1-100)')
    target.add_argument('-iN', metavar='IP/MASK', dest="target_network", type=str, default='',
                        help='generate IP from IP/MASK. (e.g. 127.0.0.0/24)')

    api = parser.add_argument_group('API')
    api.add_argument('-aZ', '--zoomeye', metavar='DORK', dest="zoomeye_dork", type=str, default='',
                     help='ZoomEye dork (e.g. "zabbix port:8080")')
    api.add_argument('-aS', '--shodan', metavar='DORK', dest="shodan_dork", type=str, default='',
                     help='Shodan dork.')
    api.add_argument('-aG', '--google', metavar='DORK', dest="google_dork", type=str, default='',
                     help='Google dork (e.g. "inurl:admin.php")')
    api.add_argument('-aF', '--fofa', metavar='DORK', dest="fofa_dork", type=str, default='',
                     help='FoFa dork (e.g. "banner=users && protocol=ftp")')
    api.add_argument('--limit', metavar='NUM', dest="api_limit", type=int, default=10,
                     help='Maximum searching results (default:10)')
    api.add_argument('--offset', metavar='OFFSET', dest="api_offset", type=int, default=0,
                     help="Search offset to begin getting results from (default:0)")
    api.add_argument('--search-type', metavar='TYPE', dest="search_type", action="store", default='host',
                     help="[ZoomEye] search type used in ZoomEye API, web or host (default:host)")
    api.add_argument('--gproxy', metavar='PROXY', dest="google_proxy", action="store", default=None,
                     help="[Google] Use proxy for Google (e.g. \"sock5 127.0.0.1 7070\" or \"http 127.0.0.1 1894\"")

    output = parser.add_argument_group('OUTPUT')

    output.add_argument('-o', metavar='FILE', dest="output_path", type=str, default='',
                        help='output file path&name. default in ./output/')
    output.add_argument('-oF', '--no-file', dest="output_file_status", default=True, action='store_false',
                        help='disable file output')
    output.add_argument('-oS', '--no-screen', dest="output_screen_status", default=True, action='store_false',
                        help='disable screen output')

    misc = parser.add_argument_group('MISC')

    misc.add_argument('--single', dest="single_mode", default=False, action='store_true',
                      help='exit after finding the first victim/password.')
    misc.add_argument('--show', dest="show_scripts", default=False, action='store_true',
                      help='show available script names in ./script/ and exit')
    misc.add_argument('--browser', dest="open_browser", default=False, action='store_true',
                      help='Open notepad or web browser to view report after task finished.')

    system = parser.add_argument_group('SYSTEM')

    system.add_argument('-v', '--version', action='version', version=VERSION,
                        help="show program's version number and exit")
    system.add_argument('-h', '--help', action='help',
                        help='show this help message and exit')
    system.add_argument('--update', dest="sys_update", default=False, action='store_true',
                        help='update POC-T from github source')

    if len(sys.argv) == 1:
        sys.argv.append('-h')
    args = parser.parse_args()
    return args

4、initOptions(参数选项初始化)

检查更新

线程与协程(-eT\-eG)

插件(验证逻辑)

target

API

结果输出

5、banner信息

6、loadModule(引入POC需要的安装模块)

7、loadPayloads(引入payloads)

8、run(运行处理,获得处理结果)

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# project = https://github.com/Xyntax/POC-T
# author = [email protected]


import threading
import time
import traceback
from lib.core.data import th, conf, logger
from lib.core.common import dataToStdout
from lib.utils.console import getTerminalSize
from lib.utils.versioncheck import PYVERSION
from lib.core.enums import POC_RESULT_STATUS, ENGINE_MODE_STATUS


def initEngine():
    th.thread_mode = True if conf.ENGINE is ENGINE_MODE_STATUS.THREAD else False
    th.module_name = conf.MODULE_NAME
    th.f_flag = conf.FILE_OUTPUT
    th.s_flag = conf.SCREEN_OUTPUT
    th.output = conf.OUTPUT_FILE_PATH
    th.thread_count = th.threads_num = th.THREADS_NUM
    th.single_mode = conf.SINGLE_MODE
    th.scan_count = th.found_count = 0
    th.console_width = getTerminalSize()[0] - 2
    th.is_continue = True
    th.found_single = False
    th.start_time = time.time()
    setThreadLock()
    msg = 'Set the number of concurrent: %d' % th.threads_num
    logger.success(msg)


def singleMode():
    th.is_continue = False
    th.found_single = True


def scan():
    while 1:
        if th.thread_mode: th.load_lock.acquire()
        if th.queue.qsize() > 0 and th.is_continue:
            payload = str(th.queue.get(timeout=1.0))
            if th.thread_mode: th.load_lock.release()
        else:
            if th.thread_mode: th.load_lock.release()
            break
        try:
            # POC在执行时报错如果不被处理,线程框架会停止并退出
            status = th.module_obj.poc(payload)
            resultHandler(status, payload)
        except Exception:
            th.errmsg = traceback.format_exc()
            th.is_continue = False
        changeScanCount(1)
        if th.s_flag:
            printProgress()
    if th.s_flag:
        printProgress()

    changeThreadCount(-1)


def run():
    initEngine()
    if conf.ENGINE is ENGINE_MODE_STATUS.THREAD:
        for i in range(th.threads_num):
            t = threading.Thread(target=scan, name=str(i))
            setThreadDaemon(t)
            t.start()
        # It can quit with Ctrl-C
        while 1:
            if th.thread_count > 0 and th.is_continue:
                time.sleep(0.01)
            else:
                break

    elif conf.ENGINE is ENGINE_MODE_STATUS.GEVENT:
        from gevent import monkey
        monkey.patch_all()
        import gevent
        while th.queue.qsize() > 0 and th.is_continue:
            gevent.joinall([gevent.spawn(scan) for i in xrange(0, th.threads_num) if
                            th.queue.qsize() > 0])

    dataToStdout('\n')

    if 'errmsg' in th:
        logger.error(th.errmsg)

    if th.found_single:
        msg = "[single-mode] found!"
        logger.info(msg)


def resultHandler(status, payload):
    if not status or status is POC_RESULT_STATUS.FAIL:
        return
    elif status is POC_RESULT_STATUS.RETRAY:
        changeScanCount(-1)
        th.queue.put(payload)
        return
    elif status is True or status is POC_RESULT_STATUS.SUCCESS:
        msg = payload
    else:
        msg = str(status)
    changeFoundCount(1)
    if th.s_flag:
        printMessage(msg)
    if th.f_flag:
        output2file(msg)
    if th.single_mode:
        singleMode()


def setThreadLock():
    if th.thread_mode:
        th.found_count_lock = threading.Lock()
        th.scan_count_lock = threading.Lock()
        th.thread_count_lock = threading.Lock()
        th.file_lock = threading.Lock()
        th.load_lock = threading.Lock()


def setThreadDaemon(thread):
    # Reference: http://stackoverflow.com/questions/190010/daemon-threads-explanation
    if PYVERSION >= "2.6":
        thread.daemon = True
    else:
        thread.setDaemon(True)


def changeFoundCount(num):
    if th.thread_mode: th.found_count_lock.acquire()
    th.found_count += num
    if th.thread_mode: th.found_count_lock.release()


def changeScanCount(num):
    if th.thread_mode: th.scan_count_lock.acquire()
    th.scan_count += num
    if th.thread_mode: th.scan_count_lock.release()


def changeThreadCount(num):
    if th.thread_mode: th.thread_count_lock.acquire()
    th.thread_count += num
    if th.thread_mode: th.thread_count_lock.release()


def printMessage(msg):
    dataToStdout('\r' + msg + ' ' * (th.console_width - len(msg)) + '\n\r')


def printProgress():
    msg = '%s found | %s remaining | %s scanned in %.2f seconds' % (
        th.found_count, th.queue.qsize(), th.scan_count, time.time() - th.start_time)
    out = '\r' + ' ' * (th.console_width - len(msg)) + msg
    dataToStdout(out)


def output2file(msg):
    if th.thread_mode: th.file_lock.acquire()
    f = open(th.output, 'a')
    f.write(msg + '\n')
    f.close()
    if th.thread_mode: th.file_lock.release()

9、openBrowser(在浏览器中打开)

9、systemquit(退出系统)

猜你喜欢

转载自blog.csdn.net/Fly_hps/article/details/87932317