Version 5.1.3 🔥

- Replaced Gevent with AsyncIO
- Shares are now logged in the database and can be queried
- You can now press enter while a scan is being performed and CME will
  give you a completion percentage and the number of hosts remaining to
  scan
main
byt3bl33d3r 2020-11-15 16:42:28 -07:00
parent 119e5af997
commit cb5c8855ed
18 changed files with 708 additions and 673 deletions

View File

@ -6,7 +6,6 @@ clean:
rm -f -r build/
rm -f -r bin/
rm -f -r dist/
rm -f -r *.egg-info
find . -name '*.pyc' -exec rm -f {} +
find . -name '*.pyo' -exec rm -f {} +
find . -name '*~' -exec rm -f {} +
@ -16,6 +15,6 @@ clean:
tests:
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics --exclude cme/thirdparty/*,cme/data/*
reqs:
requirements:
poetry export --without-hashes -f requirements.txt -o requirements.txt
poetry export --without-hashes --dev -f requirements.txt -o requirements-dev.txt

View File

@ -1,10 +1,7 @@
from gevent import monkey
import sys
import os
import cme
monkey.patch_all()
thirdparty_modules = os.path.join(os.path.dirname(cme.__file__), 'thirdparty')
for module in os.listdir(thirdparty_modules):

View File

@ -6,8 +6,8 @@ from cme.helpers.logger import highlight
def gen_cli_args():
VERSION = '5.1.1dev'
CODENAME = '3TH@n'
VERSION = '5.1.3dev'
CODENAME = 'U fancy huh?'
p_loader = protocol_loader()
protocols = p_loader.get_protocols()
@ -32,7 +32,7 @@ def gen_cli_args():
formatter_class=RawTextHelpFormatter,
#version='{} - {}'.format(VERSION, CODENAME),
epilog="Ya feelin' a bit buggy all of a sudden?")
epilog="A la mierda el mundo soy una erección ambulante")
parser.add_argument("-t", type=int, dest="threads", default=100, help="set how many concurrent threads to use (default: 100)")
parser.add_argument("--timeout", default=None, type=int, help='max timeout in seconds of each thread (default: None)')

View File

@ -1,8 +1,8 @@
import logging
from os.path import isfile
# from traceback import format_exc
from gevent.lock import BoundedSemaphore
from gevent.socket import gethostbyname
from threading import BoundedSemaphore
from socket import gethostbyname
from functools import wraps
from cme.logger import CMEAdapter
from cme.context import Context

View File

@ -1,7 +1,5 @@
#!/usr/bin/env python3
from gevent.pool import Pool
from gevent import sleep
from cme.logger import setup_logger, setup_debug_logger, CMEAdapter
from cme.helpers.logger import highlight
from cme.helpers.misc import identify_target_file
@ -14,7 +12,13 @@ from cme.loaders.module_loader import module_loader
from cme.servers.http import CMEServer
from cme.first_run import first_run_setup
from cme.context import Context
from concurrent.futures import ThreadPoolExecutor
from pprint import pformat
from decimal import Decimal
import time
import asyncio
import aioconsole
import functools
import configparser
import cme.helpers.powershell as powershell
import cme
@ -26,11 +30,85 @@ import os
import sys
import logging
setup_logger()
logger = CMEAdapter()
async def monitor_threadpool(pool, targets):
logging.debug('Started thread poller')
while True:
try:
text = await aioconsole.ainput("")
if text == "":
pool_size = pool._work_queue.qsize()
finished_threads = len(targets) - pool_size
percentage = Decimal(finished_threads) / Decimal(len(targets)) * Decimal(100)
logger.info(f"completed: {percentage:.2f}% ({finished_threads}/{len(targets)})")
except asyncio.CancelledError:
logging.debug("Stopped thread poller")
break
async def run_protocol(loop, protocol_obj, args, db, target, jitter):
try:
if jitter:
value = random.choice(range(jitter[0], jitter[1]))
logging.debug(f"Doin' the jitterbug for {value} second(s)")
await asyncio.sleep(value)
thread = loop.run_in_executor(
None,
functools.partial(
protocol_obj,
args,
db,
str(target)
)
)
await asyncio.wait_for(
thread,
timeout=args.timeout
)
except asyncio.TimeoutError:
logging.debug("Thread exceeded timeout")
except asyncio.CancelledError:
logging.debug("Stopping thread")
thread.cancel()
async def start_threadpool(protocol_obj, args, db, targets, jitter):
pool = ThreadPoolExecutor(max_workers=args.threads + 1)
loop = asyncio.get_running_loop()
loop.set_default_executor(pool)
monitor_task = asyncio.create_task(
monitor_threadpool(pool, targets)
)
jobs = [
run_protocol(
loop,
protocol_obj,
args,
db,
target,
jitter
)
for target in targets
]
try:
logging.debug("Running")
await asyncio.gather(*jobs)
except asyncio.CancelledError:
print('\n')
logger.info("Shutting down, please wait...")
logging.debug("Cancelling scan")
finally:
monitor_task.cancel()
pool.shutdown(wait=True)
def main():
setup_logger()
logger = CMEAdapter()
first_run_setup(logger)
args = gen_cli_args()
@ -191,25 +269,12 @@ def main():
setattr(protocol_object, 'server', module_server.server)
try:
'''
Open all the greenlet (as supposed to redlet??) threads
Whoever came up with that name has a fetish for traffic lights
'''
pool = Pool(args.threads)
jobs = []
for target in targets:
jobs.append(pool.spawn(protocol_object, args, db, str(target)))
if jitter:
value = random.choice(range(jitter[0], jitter[1]))
logging.debug("Doin' the Jitterbug for {} seconds".format(value))
sleep(value)
for job in jobs:
job.join(timeout=args.timeout)
asyncio.run(
start_threadpool(protocol_object, args, db, targets, jitter)
)
except KeyboardInterrupt:
pass
logging.debug("Got keyboard interrupt")
finally:
if module_server:
module_server.shutdown()

View File

@ -1,7 +1,7 @@
from cme.helpers.powershell import *
from cme.helpers.misc import gen_random_string
from cme.servers.smb import CMESMBServer
from gevent import sleep
from time import sleep
from sys import exit
import os

View File

@ -526,7 +526,11 @@ class smb(connection):
def shares(self):
temp_dir = ntpath.normpath("\\" + gen_random_string())
#hostid,_,_,_,_,_,_ = self.db.get_hosts(filterTerm=self.host)[0]
computer_id = self.db.get_computers(filterTerm=self.host)[0][0]
user_id = self.db.get_user(
self.domain.split('.')[0].upper(),
self.username
)[0][0]
permissions = []
try:
@ -553,7 +557,9 @@ class smb(connection):
pass
permissions.append(share_info)
#self.db.add_share(hostid, share_name, share_remark, read, write)
if share_name != "IPC$":
self.db.add_share(computer_id, user_id, share_name, share_remark, read, write)
self.logger.success('Enumerated shares')
self.logger.highlight('{:<15} {:<15} {}'.format('Share', 'Permissions', 'Remark'))

View File

@ -4,7 +4,7 @@ from impacket.dcerpc.v5 import tsch, transport
from impacket.dcerpc.v5.dtypes import NULL
from impacket.dcerpc.v5.rpcrt import RPC_C_AUTHN_GSS_NEGOTIATE
from cme.helpers.misc import gen_random_string
from gevent import sleep
from time import sleep
class TSCH_EXEC:
def __init__(self, target, share_name, username, password, domain, doKerberos=False, aesKey=None, kdcHost=None, hashes=None):

View File

@ -59,6 +59,19 @@ class database:
FOREIGN KEY(groupid) REFERENCES groups(id)
)''')
db_conn.execute('''CREATE TABLE "shares" (
"id" integer PRIMARY KEY,
"computerid" integer,
"userid" integer,
"name" text,
"remark" text,
"read" boolean,
"write" boolean,
FOREIGN KEY(computerid) REFERENCES computers(id),
FOREIGN KEY(userid) REFERENCES users(id)
UNIQUE(computerid, userid, name)
)''')
#db_conn.execute('''CREATE TABLE "ntds_dumps" (
# "id" integer PRIMARY KEY,
# "computerid", integer,
@ -68,21 +81,72 @@ class database:
# FOREIGN KEY(computerid) REFERENCES computers(id)
# )''')
#db_conn.execute('''CREATE TABLE "shares" (
# "id" integer PRIMARY KEY,
# "hostid" integer,
# "name" text,
# "remark" text,
# "read" boolean,
# "write" boolean
# )''')
def add_share(self, computerid, userid, name, remark, read, write):
cur = self.conn.cursor()
cur.execute("INSERT OR IGNORE INTO shares (computerid, userid, name, remark, read, write) VALUES (?,?,?,?,?,?)", [computerid, userid, name, remark, read, write])
cur.close()
#def add_share(self, hostid, name, remark, read, write):
# cur = self.conn.cursor()
def is_share_valid(self, shareID):
"""
Check if this share ID is valid.
"""
# cur.execute("INSERT INTO shares (hostid, name, remark, read, write) VALUES (?,?,?,?,?)", [hostid, name, remark, read, write])
cur = self.conn.cursor()
cur.execute('SELECT * FROM shares WHERE id=? LIMIT 1', [shareID])
results = cur.fetchall()
cur.close()
# cur.close()
logging.debug(f"is_share_valid(shareID={shareID}) => {len(results) > 0}")
return len(results) > 0
def get_shares(self, filterTerm = None):
cur = self.conn.cursor()
if self.is_share_valid(filterTerm):
cur.execute("SELECT * FROM shares WHERE id=?", [filterTerm])
elif filterTerm:
cur.execute("SELECT * FROM shares WHERE LOWER(name) LIKE LOWER(?)", [f"%{filterTerm}%"])
else:
cur.execute("SELECT * FROM shares")
results = cur.fetchall()
return results
def get_shares_by_access(self, permissions, shareID=None):
cur = self.conn.cursor()
permissions = permissions.lower()
if shareID:
if permissions == "r":
cur.execute("SELECT * FROM shares WHERE id=? AND read=1",[shareID])
elif permissions == "w":
cur.execute("SELECT * FROM shares WHERE id=? write=1", [shareID])
elif permissions == "rw":
cur.execute("SELECT * FROM shares WHERE id=? AND read=1 AND write=1", [shareID])
else:
if permissions == "r":
cur.execute("SELECT * FROM shares WHERE read=1")
elif permissions == "w":
cur.execute("SELECT * FROM shares WHERE write=1")
elif permissions == "rw":
cur.execute("SELECT * FROM shares WHERE read= AND write=1")
results = cur.fetchall()
return results
def get_users_with_share_access(self, computerID, share_name, permissions):
cur = self.conn.cursor()
permissions = permissions.lower()
if permissions == "r":
cur.execute("SELECT userid FROM shares WHERE computerid=(?) AND name=(?) AND read=1", [computerID, share_name])
elif permissions == "w":
cur.execute("SELECT userid FROM shares WHERE computerid=(?) AND name=(?) AND write=1", [computerID, share_name])
elif permissions == "rw":
cur.execute("SELECT userid FROM shares WHERE computerid=(?) AND name=(?) AND read=1 AND write=1", [computerID, share_name])
results = cur.fetchall()
return results
def add_computer(self, ip, hostname, domain, os, dc=None):
"""
@ -111,6 +175,7 @@ class database:
"""
Check if this credential has already been added to the database, if not add it in.
"""
domain = domain.split('.')[0].upper()
user_rowid = None
cur = self.conn.cursor()
@ -370,6 +435,13 @@ class database:
cur.close()
return results
def get_user(self, domain, username):
cur = self.conn.cursor()
cur.execute("SELECT * FROM users WHERE LOWER(domain)=LOWER(?) AND LOWER(username)=LOWER(?)", [domain, username])
results = cur.fetchall()
cur.close()
return results
def is_computer_valid(self, hostID):
"""
Check if this host ID is valid.

View File

@ -55,6 +55,120 @@ class navigator(DatabaseNavigator):
self.print_table(data, title='Hosts')
def display_shares(self, shares):
data = [["ShareID", "Name", "Remark", "Read Access", "Write Access"]]
for share in shares:
shareID = share[0]
computerid = share[1]
name = share[3]
remark = share[4]
users_r_access = self.db.get_users_with_share_access(
computerID=computerid,
share_name=name,
permissions='r'
)
users_w_access = self.db.get_users_with_share_access(
computerID=computerid,
share_name=name,
permissions='w'
)
data.append([shareID, name, remark, f"{len(users_r_access)} User(s)", f"{len(users_w_access)} Users"])
self.print_table(data)
def do_shares(self, line):
filterTerm = line.strip()
if filterTerm == "":
shares = self.db.get_shares()
self.display_shares(shares)
else:
shares = self.db.get_shares(filterTerm=filterTerm)
if len(shares) > 1:
self.display_shares(shares)
elif len(shares) == 1:
share = shares[0]
shareID = share[0]
computerID = share[1]
name = share[3]
remark = share[4]
users_r_access = self.db.get_users_with_share_access(
computerID=computerID,
share_name=name,
permissions='r'
)
users_w_access = self.db.get_users_with_share_access(
computerID=computerID,
share_name=name,
permissions='w'
)
data = [["ShareID", "Name", "Remark"]]
data.append([shareID, name, remark])
self.print_table(data, title='Share')
host = self.db.get_computers(filterTerm=computerID)[0]
data = [['HostID', 'IP', 'Hostname', 'Domain', 'OS', 'DC']]
hostID = host[0]
ip = host[1]
hostname = host[2]
domain = host[3]
os = host[4]
dc = host[5]
data.append([hostID, ip, hostname, domain, os, dc])
self.print_table(data, title='Share Location')
if users_r_access:
data = [['CredID', 'CredType', 'Domain', 'UserName', 'Password']]
for user in users_r_access:
userid = user[0]
creds = self.db.get_credentials(filterTerm=userid)
for cred in creds:
credID = cred[0]
domain = cred[1]
username = cred[2]
password = cred[3]
credtype = cred[4]
data.append([credID, credtype, domain, username, password])
self.print_table(data, title='Users(s) with Read Access')
if users_w_access:
data = [['CredID', 'CredType', 'Domain', 'UserName', 'Password']]
for user in users_w_access:
userid = user[0]
creds = self.db.get_credentials(filterTerm=userid)
for cred in creds:
credID = cred[0]
domain = cred[1]
username = cred[2]
password = cred[3]
credtype = cred[4]
data.append([credID, credtype, domain, username, password])
self.print_table(data, title='Users(s) with Write Access')
def do_groups(self, line):
filterTerm = line.strip()
@ -130,7 +244,7 @@ class navigator(DatabaseNavigator):
data.append([hostID, ip, hostname, domain, os, dc])
self.print_table(data, title='Host(s)')
self.print_table(data, title='Host')
data = [['CredID', 'CredType', 'Domain', 'UserName', 'Password']]
for hostID in hostIDList:

View File

@ -28,7 +28,7 @@
import logging
import os
from gevent import sleep
from time import sleep
from cme.helpers.misc import gen_random_string
from impacket.dcerpc.v5.dcom.oaut import IID_IDispatch, string_to_bin, IDispatch, DISPPARAMS, DISPATCH_PROPERTYGET, \

View File

@ -1,6 +1,6 @@
import logging
import os
from gevent import sleep
from time import sleep
from impacket.dcerpc.v5 import transport, scmr
from impacket.smbconnection import *
from cme.helpers.misc import gen_random_string

View File

@ -1,7 +1,7 @@
import ntpath, logging
import os
from gevent import sleep
from time import sleep
from cme.helpers.misc import gen_random_string
from impacket.dcerpc.v5.dcomrt import DCOMConnection
from impacket.dcerpc.v5.dcom import wmi

View File

@ -5,7 +5,7 @@ import os
import sys
import logging
from http.server import BaseHTTPRequestHandler
from gevent import sleep
from time import sleep
from cme.helpers.logger import highlight
from cme.logger import CMEAdapter

760
poetry.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
[tool.poetry]
name = "crackmapexec"
version = "5.1.1dev"
version = "5.1.3dev"
description = "A swiss army knife for pentesting networks"
authors = ["Marcello Salvati <byt3bl33d3r@pm.com>"]
readme = "README.md"
@ -51,7 +51,6 @@ cmedb = 'cme.cmedb:main'
[tool.poetry.dependencies]
python = "^3.7.0"
gevent = ">=1.2.0"
requests = ">=2.9.1"
requests-ntlm = ">=0.3.0"
bs4 = "^0.0.1"
@ -65,13 +64,14 @@ paramiko = "^2.7.2"
impacket = "^0.9.21"
xmltodict = "^0.12.0"
terminaltables = "^3.1.0"
aioconsole = "^0.3.1"
[tool.poetry.dev-dependencies]
flake8 = "^3.8.2"
pylint = "^2.5.2"
shiv = "^0.3.1"
ipython = "^7.18.1"
flake8 = "*"
pylint = "*"
shiv = "*"
black = "^20.8b1"
[build-system]
requires = ["poetry>=0.12"]

View File

@ -1,85 +1,76 @@
aiowinreg==0.0.3
appnope==0.1.0; sys_platform == "darwin"
asn1crypto==1.4.0
astroid==2.4.2
asysocks==0.0.7
backcall==0.2.0
bcrypt==3.2.0
beautifulsoup4==4.9.1
aioconsole==0.3.1; python_version >= "3.6"
aiowinreg==0.0.3; python_version >= "3.6"
appdirs==1.4.4; python_version >= "3.6"
asn1crypto==1.4.0; python_version >= "3.7"
astroid==2.4.2; python_version >= "3.5"
asysocks==0.0.10; python_version >= "3.7"
bcrypt==3.2.0; python_version >= "3.6"
beautifulsoup4==4.9.3
black==20.8b1; python_version >= "3.6"
bs4==0.0.1
certifi==2020.6.20
cffi==1.14.3
chardet==3.0.4
click==7.1.2
colorama==0.4.3; sys_platform == "win32"
cryptography==3.1
decorator==4.4.2
dnspython==2.0.0
flake8==3.8.3
flask==1.1.2
future==0.18.2
gevent==20.6.2
greenlet==0.4.16; platform_python_implementation == "CPython"
idna==2.10
certifi==2020.11.8; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0"
cffi==1.14.3; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6"
chardet==3.0.4; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0"
click==7.1.2; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6"
colorama==0.4.4; python_version >= "3.5" and python_full_version < "3.0.0" and sys_platform == "win32" or sys_platform == "win32" and python_version >= "3.5" and python_full_version >= "3.5.0"
cryptography==3.2.1; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6"
dnspython==2.0.0; python_version >= "3.6"
flake8==3.8.4; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.4.0")
flask==1.1.2; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6"
future==0.18.2; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version >= "3.6"
idna==2.10; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0"
impacket==0.9.21
importlib-metadata==1.7.0; python_version < "3.8"
ipython==7.18.1
ipython-genutils==0.2.0
isort==5.5.2
itsdangerous==1.1.0
jedi==0.17.2
jinja2==2.11.2
lazy-object-proxy==1.4.3
ldap3==2.8.1
ldapdomaindump==0.9.3
lsassy==2.1.2
markupsafe==1.1.1
mccabe==0.6.1
minidump==0.0.13
minikerberos==0.2.4
importlib-metadata==2.0.0; python_version >= "2.7" and python_full_version < "3.0.0" and python_version < "3.8" or python_full_version >= "3.5.0" and python_version < "3.8"
isort==5.6.4; python_version >= "3.6" and python_version < "4.0"
itsdangerous==1.1.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6"
jinja2==2.11.2; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6"
lazy-object-proxy==1.4.3; python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.5"
ldap3==2.8.1; python_version >= "3.6"
ldapdomaindump==0.9.3; python_version >= "3.6"
lsassy==2.1.3; python_version >= "3.6"
markupsafe==1.1.1; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6"
mccabe==0.6.1; python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.5"
minidump==0.0.13; python_version >= "3.6"
minikerberos==0.2.5; python_version >= "3.7"
msgpack==1.0.0
msldap==0.3.13
msldap==0.3.20; python_version >= "3.7"
mypy-extensions==0.4.3; python_version >= "3.6"
neo4j==4.1.1
netaddr==0.8.0
ntlm-auth==1.5.0
netaddr==0.8.0; python_version >= "3.6"
ntlm-auth==1.5.0; python_version >= "2.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0"
paramiko==2.7.2
parso==0.7.1
pexpect==4.8.0; sys_platform != "win32"
pickleshare==0.7.5
prompt-toolkit==3.0.7
ptyprocess==0.6.0; sys_platform != "win32"
pyasn1==0.4.8
pycodestyle==2.6.0
pycparser==2.20
pycryptodomex==3.9.8
pyflakes==2.2.0
pygments==2.7.1
pylint==2.6.0
pylnk3==0.3.0
pynacl==1.4.0
pyopenssl==19.1.0
pypsrp==0.5.0
pypykatz==0.3.12
pyspnego==0.1.1
pytz==2020.1
requests==2.24.0
pathspec==0.8.1; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6"
prompt-toolkit==3.0.8; python_full_version >= "3.6.1" and python_version >= "3.7"
pyasn1==0.4.8; python_version >= "3.6"
pycodestyle==2.6.0; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0"
pycparser==2.20; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0"
pycryptodomex==3.9.9; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6"
pyflakes==2.2.0; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0"
pylint==2.6.0; python_version >= "3.5"
pylnk3==0.3.0; python_version >= "3"
pynacl==1.4.0; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0"
pyopenssl==19.1.0; python_version >= "3.6"
pypsrp==0.5.0; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.5.0")
pypykatz==0.3.14; python_version >= "3.6"
pyspnego==0.1.3; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0"
pytz==2020.4
regex==2020.11.13; python_version >= "3.6"
requests-ntlm==1.1.0
shiv==0.3.1
six==1.15.0
soupsieve==1.9.6
requests==2.25.0; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.5.0")
shiv==0.4.0; python_version >= "3.6"
six==1.15.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6"
soupsieve==2.0.1; python_version >= "3.5"
termcolor==1.1.0
terminaltables==3.1.0
toml==0.10.1
tqdm==4.49.0
traitlets==5.0.4
typed-ast==1.4.1; implementation_name == "cpython" and python_version < "3.8"
urllib3==1.25.10
wcwidth==0.2.5
werkzeug==1.0.1
winacl==0.0.6
winsspi==0.0.9
wrapt==1.12.1
xmltodict==0.12.0
zipp==3.1.0; python_version < "3.8"
zope.event==4.5.0
zope.interface==5.1.0
toml==0.10.2; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version >= "3.6"
tqdm==4.51.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.2.0" and python_version >= "3.7"
typed-ast==1.4.1; implementation_name == "cpython" and python_version < "3.8" and python_version >= "3.6"
typing-extensions==3.7.4.3; python_version >= "3.6"
urllib3==1.26.2; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version < "4"
wcwidth==0.2.5; python_full_version >= "3.6.1" and python_version >= "3.7"
werkzeug==1.0.1; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6"
winacl==0.1.0; python_version >= "3.7"
winsspi==0.0.9; platform_system == "Windows" and python_version >= "3.7"
wrapt==1.12.1; python_version >= "3.5"
xmltodict==0.12.0; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.4.0")
zipp==3.4.0; python_version >= "3.6" and python_full_version < "3.0.0" and python_version < "3.8" or python_full_version >= "3.5.0" and python_version < "3.8" and python_version >= "3.6"

View File

@ -1,58 +1,55 @@
aiowinreg==0.0.3
asn1crypto==1.4.0
asysocks==0.0.7
bcrypt==3.2.0
beautifulsoup4==4.9.1
aioconsole==0.3.1; python_version >= "3.6"
aiowinreg==0.0.3; python_version >= "3.6"
asn1crypto==1.4.0; python_version >= "3.7"
asysocks==0.0.10; python_version >= "3.7"
bcrypt==3.2.0; python_version >= "3.6"
beautifulsoup4==4.9.3
bs4==0.0.1
certifi==2020.6.20
cffi==1.14.3
chardet==3.0.4
click==7.1.2
cryptography==3.1
dnspython==2.0.0
flask==1.1.2
future==0.18.2
gevent==20.6.2
greenlet==0.4.16; platform_python_implementation == "CPython"
idna==2.10
certifi==2020.11.8; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0"
cffi==1.14.3; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6"
chardet==3.0.4; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0"
click==7.1.2; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6"
cryptography==3.2.1; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6"
dnspython==2.0.0; python_version >= "3.6"
flask==1.1.2; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6"
future==0.18.2; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version >= "3.6"
idna==2.10; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0"
impacket==0.9.21
itsdangerous==1.1.0
jinja2==2.11.2
ldap3==2.8.1
ldapdomaindump==0.9.3
lsassy==2.1.2
markupsafe==1.1.1
minidump==0.0.13
minikerberos==0.2.4
itsdangerous==1.1.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6"
jinja2==2.11.2; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6"
ldap3==2.8.1; python_version >= "3.6"
ldapdomaindump==0.9.3; python_version >= "3.6"
lsassy==2.1.3; python_version >= "3.6"
markupsafe==1.1.1; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6"
minidump==0.0.13; python_version >= "3.6"
minikerberos==0.2.5; python_version >= "3.7"
msgpack==1.0.0
msldap==0.3.13
msldap==0.3.20; python_version >= "3.7"
neo4j==4.1.1
netaddr==0.8.0
ntlm-auth==1.5.0
netaddr==0.8.0; python_version >= "3.6"
ntlm-auth==1.5.0; python_version >= "2.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0"
paramiko==2.7.2
prompt-toolkit==3.0.7
pyasn1==0.4.8
pycparser==2.20
pycryptodomex==3.9.8
pylnk3==0.3.0
pynacl==1.4.0
pyopenssl==19.1.0
pypsrp==0.5.0
pypykatz==0.3.12
pyspnego==0.1.1
pytz==2020.1
requests==2.24.0
prompt-toolkit==3.0.8; python_full_version >= "3.6.1" and python_version >= "3.7"
pyasn1==0.4.8; python_version >= "3.6"
pycparser==2.20; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0"
pycryptodomex==3.9.9; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6"
pylnk3==0.3.0; python_version >= "3"
pynacl==1.4.0; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0"
pyopenssl==19.1.0; python_version >= "3.6"
pypsrp==0.5.0; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.5.0")
pypykatz==0.3.14; python_version >= "3.6"
pyspnego==0.1.3; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0"
pytz==2020.4
requests-ntlm==1.1.0
six==1.15.0
soupsieve==1.9.6
requests==2.25.0; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.5.0")
six==1.15.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6"
soupsieve==2.0.1; python_version >= "3.5"
termcolor==1.1.0
terminaltables==3.1.0
tqdm==4.49.0
urllib3==1.25.10
wcwidth==0.2.5
werkzeug==1.0.1
winacl==0.0.6
winsspi==0.0.9
xmltodict==0.12.0
zope.event==4.5.0
zope.interface==5.1.0
tqdm==4.51.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.2.0" and python_version >= "3.7"
urllib3==1.26.2; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version < "4"
wcwidth==0.2.5; python_full_version >= "3.6.1" and python_version >= "3.7"
werkzeug==1.0.1; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6"
winacl==0.1.0; python_version >= "3.7"
winsspi==0.0.9; platform_system == "Windows" and python_version >= "3.7"
xmltodict==0.12.0; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.4.0")