本文最后更新于:2019 , 十一月 17日 星期日, 9:05 晚上

网上现在有很多类似的框架,甚至架构已经十分完善的(MSF,Pocsuite3),那我为啥还要重复造造轮子呢?

写了这么多的exp,放在那里很混乱,方便管理与更新

在写框架时,遇到了很多之前不曾想过的问题,在其他的框架的分析时,学到了很多

每次的编写,都是为了以后能够制作

总结:学到了就是我的了


大体结构

  • lib:存储核心文件
  • poc:存储 poc/exp 文件
  • main.py:启动脚本

Code

颜色与banner

文件:lib\common.py

  • 控制端颜色输出:使用库colorama

至于为什么不使用其他的,因为我看着脑壳痛,拿个最简单的来使用吧

from colorama import Fore,Style,init

def Color(Conversion,color,Info=''):
    init(autoreset=True)

    if color == "red":
        print(Fore.RED + Conversion + Fore.WHITE + Info)
    elif color == "green":
        print(Fore.GREEN + Conversion + Fore.WHITE + Info)
    elif color == "yellow":
        print(Fore.YELLOW + Conversion + Fore.WHITE + Info)
    elif color == "blue":
        print(Fore.BLUE + Conversion + + Fore.WHITE + Info)
    else:
        print(Fore.RED + "Eroor:Not color")

  • banner:网上有在线的文字转banner
from colorama import Fore,Style,init

# 转换颜色
def Color(Conversion,color,Info=''):
    init(autoreset=True)

    if color == "red":
        print(Fore.RED + Conversion + Fore.WHITE + Info)
    elif color == "green":
        print(Fore.GREEN + Conversion + Fore.WHITE + Info)
    elif color == "yellow":
        print(Fore.YELLOW + Conversion + Fore.WHITE + Info)
    elif color == "blue":
        print(Fore.BLUE + Conversion + + Fore.WHITE + Info)
    else:
        print(Fore.RED + "Eroor:Not color")

# banner
def banner():
    def banner():
    banner = '''
     ______ _____ _____ _______ _    _ 
    |  ____|  __ \_   _|__   __| |  | | 
    | |__  | |  | || |    | |  | |__| |
    |  __| | |  | || |    | |  |  __  |
    | |____| |__| || |_   | |  | |  | |
    |______|_____/_____|  |_|  |_|  |_|

            Author: {}
    '''.format("只因不值得")
    print(Fore.RED + banner)
    print(Style.RESET_ALL)
  • main.py文件进行调用
from lib.common import banner

def main():
    banner()


if __name__ == "__main__":
    main()

加载模块 – 动态加载

两种方法:

  • __import__():自带函数进行加载

  • importlib:第三方模块进行加载

文件:Registry.py

在这里我选择了使用第三方模块进行加载

import importlib.util
import importlib.machinery
from lib.common import Color

# 从本地导入模块
def load_file_modules(file_path):
    """
    需要加载完整的文件路径
    """
    if '' not in importlib.machinery.SOURCE_SUFFIXES:
        importlib.machinery.SOURCE_SUFFIXES.append('')

    try:
        module_file_path = file_path # file_path
        # print(module_file_path) 文件路径
        module_name = file_path.stem
        # print(module_name) 文件名
        spec = importlib.util.spec_from_file_location(module_name,module_file_path)
        module = importlib.util.module_from_spec(spec)
        spec.loader.exec_module(module)
        # print(dir(module))
        return module
    except:
        error_msg = "Load module '{0}' failed! ".format(file_path)
        Color(error_msg,"red")

加载完模块之后,可以使用getattr调用脚本的函数之类

Tab补全

其实写这个框架很久了,一直卡在这个功能这里

尤其是:readline模块,看的我脑壳痛,想自定义tab提示与补全,搞不定。。。肝了很久放弃ing

最后还是使用九世搞得:prompt_toolkit模块

在进行tab补全的时候,顺便把分隔命令一起写了吧。。。

文件:lib/command.py

from prompt_toolkit import PromptSession,shortcuts
from prompt_toolkit.completion import Completer,Completion,FuzzyCompleter


class Console_command(Completer):
    def __init__(self):
        self.hostname = "Clover" # 标识符
        self.global_cmd = ["help", "use", "exit", "search", "version", "clear"]
        self.module_cmd = ["run", "back", "set","list","show"]
        self.module_cmd.extend(self.global_cmd) # 全部命令
        self.poc_paths = [] # 模块路径

    # 分隔命令
    def parse_line(self,line):
        """
        :return: 命令,参数
        """
        command, _, arg = line.strip().partition(" ")
        return command, arg.strip()

    # tab补全
    def get_completions(self, document, complete_event,*args, **kwargs):
        if "use" in str(document):
            for poc in self.poc_paths:
                yield Completion(poc,start_position=0)
        else:
            for command in self.module_cmd:
                yield  Completion(command,start_position=0)

判断当前输入的行中str(document),是否有我们定义的关键字,如果有,则返回我们设定

执行命令

from prompt_toolkit import PromptSession,shortcuts
from prompt_toolkit.completion import Completer,Completion,FuzzyCompleter


class Console_command(Completer):
    def __init__(self):
        self.hostname = "Clover" # 标识符
        self.global_cmd = ["help", "use", "exit", "search", "version", "clear"]
        self.module_cmd = ["run", "back", "set","list","show"]
        self.module_cmd.extend(self.global_cmd) # 全部命令
        self.poc_paths = [] # 模块路径

    # 分隔命令
    def parse_line(self,line):
        """
        :return: 命令,参数
        """
        command, _, arg = line.strip().partition(" ")
        return command, arg.strip()

    # tab补全
    def get_completions(self, document, complete_event,*args, **kwargs):
        if "use" in str(document):
            for poc in self.poc_paths:
                yield Completion(poc,start_position=0)
        else:
            for command in self.module_cmd:
                yield  Completion(command,start_position=0)

    # 执行命令
    def get_command_handler(self,command):
        try:
            get_command = getattr(self,"command_{}".format(command))
        except:
            Color("Unknown Command: ","red","{}".format(command))
        return get_command

通过getattr执行我们当前脚本的函数

如:当我们在终端输入

shell > use

在我们后端,执行的方式就是:getattr(self,command_use)执行当前类中的command_use方法

所以,我们的大体的执行命令,定义的使用应该以,command_命令

运行框架

文件:lib\command.py

from prompt_toolkit import PromptSession,shortcuts
from prompt_toolkit.completion import Completer,Completion,FuzzyCompleter


class Console_command(Completer):
    def __init__(self):
        self.hostname = "Clover" # 标识符
        self.global_cmd = ["help", "use", "exit", "search", "version", "clear"]
        self.module_cmd = ["run", "back", "set","list","show"]
        self.module_cmd.extend(self.global_cmd) # 全部命令
        self.poc_paths = [] # 模块路径

    # 分隔命令
    def parse_line(self,line):
        """
        :return: 命令,参数
        """
        command, _, arg = line.strip().partition(" ")
        return command, arg.strip()

    # tab补全
    def get_completions(self, document, complete_event,*args, **kwargs):
        if "use" in str(document):
            for poc in self.poc_paths:
                yield Completion(poc,start_position=0)
        else:
            for command in self.module_cmd:
                yield  Completion(command,start_position=0)

    # 执行命令
    def get_command_handler(self,command):
        try:
            get_command = getattr(self,"command_{}".format(command))
        except:
            Color("Unknown Command: ","red","{}".format(command))
        return get_command

    # 运行
    def start(self):
        session = PromptSession()
        while True:
            try:
                command,args = self.parse_line(session.prompt(self.prompt+" > ",completer=FuzzyCompleter(Console_command())))
                command = command.lower()
                if not command:
                    continue
                command_run = self.get_command_handler(command)
                command_run(args)
            except Exception as e:
                pass
  • 文件:main.py
from lib.Command import Console_command
from lib.common import banner

def main():
    banner()
    command = Console_command()
    command.start()

if __name__ == "__main__":
    main()


命令例子

文件:lib\command.py

  • version
# 版本号
def command_version(self,*args, **kwargs):
    Version = "vserion: 0.01 \n"
    Color(Version,"red")
  • exit
# 退出
def command_exit(self,*args, **kwargs):
    Color("[-] Exit...","red")
    exit(0)

这里,只弄了两个最简易的例子,其他的,就请各位自己尝试编写看看

这个初次框架,尝试的是单例模式,可以根据各自的需要改成多线程模式!


结尾

一个框架的威力,取决于exp的数量与质量

但是,编写一个适合自己使用的框架,是在造灰机的过程中是必不可少的过程


Python      Python

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!

先知文章爬虫
PHP传值方式绕过D盾