forked from BC-SECURITY/Empire
-
Notifications
You must be signed in to change notification settings - Fork 0
/
powershell_template.py
152 lines (124 loc) · 5.66 KB
/
powershell_template.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
149
150
151
152
from __future__ import print_function
from builtins import str
from builtins import object
from lib.common import helpers
class Module(object):
def __init__(self, mainMenu, params=[]):
# Metadata info about the module, not modified during runtime
self.info = {
# Name for the module that will appear in module menus
'Name': 'Invoke-Something',
# List of one or more authors for the module
'Author': ['@yourname'],
# More verbose multi-line description of the module
'Description': ('description line 1 '
'description line 2'),
'Software': 'SXXXX',
'Techniques': ['TXXXX', 'TXXXX'],
# True if the module needs to run in the background
'Background': False,
# File extension to save the file as
'OutputExtension': None,
# True if the module needs admin rights to run
'NeedsAdmin': False,
# True if the method doesn't touch disk/is reasonably opsec safe
'OpsecSafe': True,
# The language for this module
'Language': 'powershell',
# The minimum PowerShell version needed for the module to run
'MinLanguageVersion': '2',
# List of any references/other comments
'Comments': [
'comment',
'http://link/'
]
}
# Any options needed by the module, settable during runtime
self.options = {
# Format:
# value_name : {description, required, default_value}
'Agent': {
# The 'Agent' option is the only one that MUST be in a module
'Description': 'Agent to grab a screenshot from.',
'Required' : True,
'Value' : ''
},
'Command': {
'Description': 'Command to execute',
'Required' : True,
'Value' : 'test'
}
}
# Save off a copy of the mainMenu object to access external
# functionality like listeners/agent handlers/etc.
self.mainMenu = mainMenu
# During instantiation, any settable option parameters are passed as
# an object set to the module and the options dictionary is
# automatically set. This is mostly in case options are passed on
# the command line.
if params:
for param in params:
# Parameter format is [Name, Value]
option, value = param
if option in self.options:
self.options[option]['Value'] = value
def generate(self, obfuscate=False, obfuscationCommand=""):
# The PowerShell script itself, with the command to invoke for
# execution appended to the end. Scripts should output everything
# to the pipeline for proper parsing.
#
# If you're planning on storing your script in module_source as a ps1,
# or if you're importing a shared module_source, use the first
# method to import it and the second to add any additional code and
# launch it.
#
# If you're just going to inline your script, you can delete the first
# method entirely and just use the second. The script should be
# stripped of comments, with a link to any original reference script
# included in the comments.
#
# First method: Read in the source script from module_source
moduleSource = self.mainMenu.installPath + "/data/module_source/..."
if obfuscate:
helpers.obfuscate_module(moduleSource=moduleSource, obfuscationCommand=obfuscationCommand)
moduleSource = moduleSource.replace("module_source", "obfuscated_module_source")
try:
f = open(moduleSource, 'r')
except:
print(helpers.color("[!] Could not read module source path at: " + str(moduleSource)))
return ""
moduleCode = f.read()
f.close()
# If you'd just like to import a subset of the functions from the
# module source, use the following:
# script = helpers.generate_dynamic_powershell_script(moduleCode, ["Get-Something", "Set-Something"])
script = moduleCode
# Second method: For calling your imported source, or holding your
# inlined script. If you're importing source using the first method,
# ensure that you append to the script variable rather than set.
#
# The script should be stripped of comments, with a link to any
# original reference script included in the comments.
#
# If your script is more than a few lines, it's probably best to use
# the first method to source it.
#
# script += """
script = """
function Invoke-Something {
}
Invoke-Something"""
scriptEnd = ""
# Add any arguments to the end execution of the script
for option, values in self.options.items():
if option.lower() != "agent":
if values['Value'] and values['Value'] != '':
if values['Value'].lower() == "true":
# if we're just adding a switch
scriptEnd += " -" + str(option)
else:
scriptEnd += " -" + str(option) + " " + str(values['Value'])
if obfuscate:
scriptEnd = helpers.obfuscate(psScript=scriptEnd, installPath=self.mainMenu.installPath, obfuscationCommand=obfuscationCommand)
script += scriptEnd
return script