-
Notifications
You must be signed in to change notification settings - Fork 17
/
PluginManager.py
148 lines (124 loc) · 4.78 KB
/
PluginManager.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
'''
代码来源: https://cloud.tencent.com/developer/article/1567791
经过一点小修改后, 可用于vulcat
'''
### 插件式框架
import os
import sys
from imp import find_module
from imp import load_module
from lib.tool import color
class PluginManager(type):
#静态变量配置插件路径
__PluginPath = './payloads/'
#调用时将插件注册
def __init__(self, name, bases, dict):
if not hasattr(self,'AllPlugins'):
self.__AllPlugins = {}
else:
self.RegisterAllPlugin(self)
#设置插件路径
@staticmethod
def SetPluginPath(path):
if os.path.isdir(path):
PluginManager.__PluginPath = path
else:
print(color.red('The "{PATH}" is not a valid path!!!\n\nPlease check config.yaml'.format(PATH=path)))
print(color.reset())
os._exit(1)
@staticmethod
def Whitelist(list, moduleName):
'''
检查该模块是否在 提供的白名单中
在 -> True
不在 -> False
'''
if not list: # * 如果白名单中没有元素, 说明未启用白名单功能, 默认True
return True
for l in list:
if l in moduleName:
return True
return False
#递归检测插件路径下的所有插件,并将它们存到内存中
@staticmethod
def LoadAllPlugin(vulns = []):
pluginPath = PluginManager.__PluginPath
if not os.path.isdir(pluginPath):
raise EnvironmentError
# raise EnvironmentError,'%s is not a directory' % pluginPath
items = os.listdir(pluginPath)
for item in items:
if os.path.isdir(os.path.join(pluginPath, item)):
PluginManager.__PluginPath = os.path.join(pluginPath, item)
PluginManager.LoadAllPlugin(vulns)
else:
if not PluginManager.Whitelist(vulns, item):
continue # * 如果该Payload不在vulns白名单中, 则跳过添加
if item.endswith('.py') and item != '__init__.py':
moduleName = item[:-3]
if moduleName not in sys.modules:
fileHandle, filePath, dect = find_module(moduleName, [pluginPath])
else:
continue
try:
moduleObj = load_module(moduleName, fileHandle, filePath, dect)
except Exception as e:
print(color.red('The POC "{NAME}" is Error!!!'.format(NAME=item)))
print(e)
print(color.reset())
os._exit(1)
finally:
if fileHandle : fileHandle.close()
#返回所有的插件
@property
def AllPlugins(self):
return self.__AllPlugins
#注册插件
def RegisterAllPlugin(self, aPlugin):
pluginName = '.'.join([aPlugin.__module__,aPlugin.__name__])
pluginObj = aPlugin()
self.__AllPlugins[pluginName] = pluginObj
#注销插件
def UnregisterPlugin(self, pluginName):
if pluginName in self.__AllPlugins:
pluginObj = self.__AllPlugins[pluginName]
del pluginObj
#获取插件对象。
def GetPluginObject(self, pluginName = None):
if pluginName is None:
return self.__AllPlugins.values()
else:
result = self.__AllPlugins[pluginName] if pluginName in self.__AllPlugins else None
return result
#根据插件名字,获取插件对象。(提供插件之间的通信)
@staticmethod
def GetPluginByName(pluginName):
if pluginName is None:
return None
else:
for SingleModel in __ALLMODEL__:
plugin = SingleModel.GetPluginObject(pluginName)
if plugin:
return plugin
# * 插件框架的接入点。便于管理各个插件。
# * 各个插件通过继承接入点类,利用Python中metaclass的优势,将插件注册。
# * 接入点中定义了各个插件模块必须要实现的接口。
class Vuln_Scan(object, metaclass=PluginManager):
'''
漏洞检测
'''
def POC(self):
print ('Please write the POC() function')
def EXP(self):
print ('Please write the EXP() function')
def Start(self):
print ('Please write the Start() function')
class Model_Placeholder(object, metaclass=PluginManager):
'''
占位
'''
def ABCDEFGHIJKLMNOPQRSTUVWXYZ(self):
print ('Please write the ABCDEFGHIJKLMNOPQRSTUVWXYZ() function')
__ALLMODEL__ = (Vuln_Scan, Model_Placeholder)