forked from fortra/impacket
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathsamedit.py
More file actions
121 lines (94 loc) · 3.97 KB
/
samedit.py
File metadata and controls
121 lines (94 loc) · 3.97 KB
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
#!/usr/bin/env python
# Impacket - Collection of Python classes for working with network protocols.
#
# Copyright (C) 2024 Fortra. All rights reserved.
#
# This software is provided under a slightly modified version
# of the Apache Software License. See the accompanying LICENSE file
# for more information.
#
# Description:
# Simple implementation for replacing a local user's password through
# editing of a copy of the SAM and SYSTEM hives.
#
# It still needs some improvement to handle some scenarios and expanded
# to allow user creation/password setting as it currently only allows
# for the replacing of an existing password for an existing user.
#
# Author:
# Otavio Brito (@Iorpim)
#
# References:
# The code is largely based on previous impacket work, namely
# the secretsdump and winregistry packages. (both by @agsolino)
#
import sys
import codecs
import argparse
import logging
import binascii
from impacket import version, ntlm
from impacket.examples import logger
from impacket.examples.secretsdump import LocalOperations, SAMHashes
try:
input = raw_input
except NameError:
pass
if __name__ == '__main__':
if sys.stdout.encoding is None:
sys.stdout = codecs.getWriter('utf8')(sys.stdout)
print(version.BANNER)
parser = argparse.ArgumentParser(add_help = True, description = "In-place edits a local user's password in a SAM hive file")
parser.add_argument('user', action='store', help='Name of the user account to replace the password')
parser.add_argument('sam', action='store', help='SAM hive file to edit')
parser.add_argument('-password', action='store', help='New password to be set')
parser.add_argument('-hashes', action='store', help='Replace NTLM hash directly (LM hash is optional)')
parser.add_argument('-system', action='store', help='SYSTEM hive file containing the bootkey for password encryption')
parser.add_argument('-bootkey', action='store', help='Bootkey used to encrypt and decrypt SAM passwords')
parser.add_argument('-debug', action='store_true', help='Turn DEBUG output ON')
parser.add_argument('-ts', action='store_true', help='Adds timestamp to every logging output')
if len(sys.argv) < 4:
parser.print_help()
sys.exit(1)
options = parser.parse_args()
logger.init(options.ts)
if options.debug is True:
logging.getLogger().setLevel(logging.DEBUG)
logging.debug(version.getInstallationPath())
else:
logging.getLogger().setLevel(logging.INFO)
if options.system is None and options.bootkey is None:
logging.critical('A SYSTEM hive or bootkey value is required for password changing')
sys.exit(1)
if options.system is not None and options.bootkey is not None:
logging.critical('Only a SYSTEM hive or bootkey value can be supplied')
sys.exit(1)
if options.password is None and options.hashes is None:
logging.critical('A password or hash argument is required')
sys.exit(1)
if options.password is not None and options.hashes is not None:
logging.critical('Only a password or hash argument can be supplied')
sys.exit(1)
if options.bootkey:
bootkey = binascii.unhexlify(options.bootkey)
else:
localOperations = LocalOperations(options.system)
bootkey = localOperations.getBootKey()
hive = SAMHashes(options.sam, bootkey, False)
if options.hashes:
if ':' not in options.hashes:
LMHash = b''
NTHash = binascii.unhexlify(options.hashes)
else:
LMHash, NTHash = [binascii.unhexlify(hash) for hash in options.hashes.split(":")]
if options.password:
LMHash = b''
NTHash = ntlm.NTOWFv1(options.password)
try:
hive.edit(options.user, NTHash, LMHash)
except Exception as e:
if logging.getLogger().level == logging.DEBUG:
import traceback
traceback.print_exc()
logging.error(e)
hive.finish()