Tuesday, September 22, 2015
The security device (smart card) could not be used. Additional details may be available in the system event log. Please report this error to your administrator.
[virtual smartcard]
"The security device could not be used. Additional details may be available in the system event log. Please report this error to your administrator."
[physical card]
"This smart card could not be used. Additional details may be available in the system even log. Please report this error to your administrator."
I ran into this sporadically on a range of machines after a 2012R2 rollout. In the event logs on the systems, a variety of smartcard logon event id 5 messages:
1) An error occurred while retrieving a digital certificate from the inserted smart card. The handle is invalid.
2) An error occurred while decrypting a message: The handle is invalid.
3) An error occurred while retrieving some provider parameter: The handle is invalid.
All having "The handle is invalid" as part of the error. After opening a case with microsoft and doing some low level tracing of the logons, they found a timeout in the smartcard crypto provider. The default for this is 1.5 seconds. After adjusting it to 5 or more seconds, the errors went away.
This is configured at HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Defaults\Provider\Microsoft Base Smart Card Crypto Provider\TransactionTimeoutMilliseconds as a DWORD. A reboot is required for this to take effect. The key can be used on other OS's as well.
I did continue to have problems with at least one machine after this, however the errors were different and quite varied. This system was on a bad network working with highly variable response times and 10% packet loss. On this same type of link, 2008R2 was more reliable for smartcard logons in comparison to 2012R2. So its always good to have some password logon backups to smartcard logons over slow links.
Wednesday, July 17, 2013
ADFS SCOM: Configuration Database unavailable
Thursday, December 27, 2012
"System detected a possible attempt to compromise security" Enter network password popup comes up on 2008R2
1) Dns registration failed (secure DDNS)
2) Group policy processing failed: Event 1053 "Could not resolve the user name"
3) LSASRV 40960 events with authentication errors to various kerberos services such as domain controllers LDAP/ SPNS, and cifs/ for the DFS namespace.
4) TerminalServices error 1067, Cannot registery TERMSRV Service Principal Name
5) When joining the domain and changing primary dns suffix "Changing the primary domain DNS name of this computer failed." "A Directory service error has occurred"
6) Klist shows no kerberos tickets
When I looked at this in netmon, all of the Kerberos transactions for TGT requests would receive a preauthentication required error from the KDC (domain controller) and it wasn't following up on that. After trying to dig around for information related to that, and any possible Kerberos settings that might impact this, I could find nothing. I looked in the registry for LSA settings and found LMCompatibilityLevel at 1. After changing this to a 2, everything started to work fine. From the Microsoft description of NT Compatibility levels, I don't see how this would impact Kerberos transactions, but apparently there may be some correlation. This fix worked for a short while, however everything broke again soon after. Later investigation found the Kerberos encryption types had been restricted to AES only, which was not compatible with the domain. After enabling RC4-HMAC, the problems went away. I have seen related issues on other machines where neither of these two should have been the problem. So perhaps there are many causes.
Wednesday, November 24, 2010
GPO software restrictions
Hash Rule: Crypto hash of the binary file
Certificate: A software publisher certificate that was used to digitally sign the file
Path: The file path or registry path to the file
Zone: What internet zone is used.
These types of rules can help to guard against predictable malware or certain versions of applications. The problem is that they are frequently very easy to get around.
Hash Rule (avoiding blacklist)
Lets assume our block rule covers txdns.
C:\Users\nl\Downloads>md5sum txdns.exe
f59a3d8e94f0f61130874fd794c38aa7 *txdns.exe
Using a hash rule to block something like this requires some considerations. First, every version and every patch level will have a unique hash. For applications that are frequently updating, you will never be able to keep up with them. If you have a file that has limited versions and no further development, it is still trivial to bypass this. Most files will have some text strings inside the executable. If we open txdns.exe with a hex editor, and immediately we see a string "This program cannot be run in DOS mode". We can change the T in This to lower case without effecting the program.
C:\Users\nl\Downloads>md5sum txdns.exe
42e19fdaeda1a12f21af5512396f37b9 *txdns.exe
Here we can see our hash is radically different than the original. A GPO administrator can't get around this with their blacklists. So what would blacklisting a hash be useful for? There may be a rare case where you encounter a specific and non mutating virus/malware that is in your organization. If you can throw up a hash rule and have systems update group policy, you can help to reduce the spread by this type of policy.
Certificate rules
It would be a bit rare to blacklist something that is signed. Many exe files won't be signed. If they are, and you have a specific one to block, you can look in the file properties to see the signature, and extract the certificate. Load this into a rule to block the software. This may work for something like Stuxnet that is reported to be signed by several stolen certs. Certificate rules would be primarily used in white listing mode, but again many exe's are not signed, or they may be signed with many certs. If you go looking through Microsoft software and downloads you will find either no signing or multiple certs used. Trying to keep up with external vendors' signed applications would take a lot of effort. If you were white listing a limited number of apps for a smaller set of machines, then this may be a useful method for one rule of your whole GPO.
Path rules
Getting path rules to work well in a blacklisting scenario would require a well locked down system to start with. Targeting a specific file using a standard install path would be pointless as the application could be moved or installed to a non standard location. If a user did not have access to create files and folders outside of their own home directory, you could blacklist everything in their profile to prevent execution of all code and scripts. Path rules allow for wildcards. So if you specify c:\documents and settings\*, no executable files can be run in this folder or any subfolders. This also includes attempts to access these files/folders using 8.3 format directory names. In the main policy settings, you can specify the extensions of files to protect against. You can try renaming the extension of a file such as file.exe to file.1 and trying to run it from cmd.exe. This will attempt to execute the file, but the system still sees it as the appropriate file type and blocks it. So, in general, if you need your systems to be extremely locked down, path rules can be a powerful addition.
The software restriction policy mechanism is being replaced by applocker, which is available in windows 7. It is possible to use both in policies, but only the newer OS's can process the applocker rules. I have yet to look at applocker, and I hope it is a step in the right direction for security and manageability.
Tuesday, March 30, 2010
Tired of looking up security codes in events?
function decode-krbTktOpts([string]$code) {
#code provided is in hex format
if (-not($code -match "0x\d{8}")) {
write-error "Invalid entry sent to decode-krbTktOpts function : value was : $code"
return $null
}
##########
#Ticket options are 32 bits of flags. Code comes in as hex. Only bits 0-1,3-5,16-17,20,23,25-31 are used
##########
$results = new-object collections.arraylist
$code = [convert]::toint32($code.substring($code.indexof("x")+1), 16)
if ($code -and 1) {
$results.add("Validate") >$null
} else if ($code -and 2) {
$results.add("Renew") >$null
} else if ($code -and 8) {
$results.add("EncTktInSKey") >$null
} else if ($code -and 16) {
$results.add("RenewableOK") >$null
} else if ($code -and 32) {
$results.add("DisableTransitedCheck") >$null
} else if ($code -and 65536) {
$results.add("Canonicalize") >$null
} else if ($code -and 131072) {
$results.add("CNameInAddlTkt") >$null
} else if ($code -and 1048576) {
$results.add("OptHardwareAuth") >$null
} else if ($code -and 8388608) {
$results.add("Renewable") >$null
} else if ($code -and 33554432) {
$results.add("AllowPostDate") >$null
} else if ($code -and 67108864) {
$results.add("Proxy") > $null
} else if ($code -and 134217728) {
$results.add("Proxiable") > $null
} else if ($code -and 268435456) {
$results.add("Forwarded") > $null
} else if ($code -and 536870912) {
$results.add("Forwardable") > $null
}
return $results
}
function decode-LogonErrorCode([string]$code) {
#decode 32 bit microsoft logon error codes from Hex format (32 bit)
if (-not($code -match "0x\d{8}")) {
write-error "Invalid entry sent to decode-krbTktOpts function : value was : $code"
return $null
}
switch($code.tolower()) {
"0x0" { return "Successful login" }
"0xC0000064" { return "The specified user does not exist" }
"0xC000006A" { return "The value provided as the current password is not correct" }
"0xC000006C" { return "Password policy not met" }
"0xC000006D" { return "The attempted logon is invalid due to a bad user name"}
"0xC000006E" { return "User account restriction has prevented successful login"}
"0xC000006F" { return "The user account has time restrictions and may not be logged onto at this time"}
"0xC0000070" { return "The user is restricted and may not log on from the source workstation"}
"0xC0000071" { return "The user account's password has expired"}
"0xC0000072" { return "The user account is currently disabled"}
"0xC000009A" { return "Insufficient system resources"}
"0xC0000193" { return "The user's account has expired"}
"0xC0000224" { return "User must change his password before he logs on the first time"}
"0xC0000234" { return "The user account has been automatically locked" }
default {return "Unknown code provided, unable to translate" }
}
}
function decode-krbErrCode([string]$code) {
#code provided is required to be in the hex format provided in the system event logs ex: 0x2
if (-not($code -match "x")) {
#if we receive something in invalid format, try to convert to hex
if ($code -match "\d+") {
$code = "0x" + [string]::format("{0:x}",$code)
} else {
write-error "Invalid entry sent to decode-krbErrCode function : value was : $code"
return $null
}
}
switch($code.tolower()) {
"0x0" { return ("KDC_ERR_NONE","No Error") }
"0x1" { return ("KDC_ERR_NAME_EXP","Clients entry in Database has Expired") }
"0x2" { return ("KDC_ERR_SERVICE_EXP","Servers entry in Database has Expired") }
"0x3" { return ("KDC_ERR_BAD_PVNO","Request protocol version number not supported") }
"0x4" { return ("KDC_ERR_C_OLD_MAST_KVNO","Client's key encrypted in old master key") }
"0x5" { return ("KDC_ERR_S_OLD_MAST_KVNO","Servers key encrypted in old master key") }
"0x6" { return ("KDC_ERR_C_PRINCIPAL_UNKNOWN","Client not found in Kerberos Database") }
"0x7" { return ("KDC_ERR_S_PRINCIPAL_UNKNOWN","Server not found in Kerberos Database") }
"0x8" { return ("KDC_ERR_PRINCIPAL_NOT_UNIQUE","Multiple principal entries in database") }
"0x9" { return ("KDC_ERR_NULL_KEY", "The client or server has a null key") }
"0xa" { return ("KDC_ERR_CANNOT_POSTDATE", "Ticket not eligible for postdating") }
"0xb" { return ("KDC_ERR_NEVER_VALID","Requested start time is later than end time") }
"0xc" { return ("KDC_ERR_POLICY","KDC policy rejects request") }
"0xd" { return ("KDC_ERR_BADOPTION","KDC cannot accomodate requested option") }
"0xe" { return ("KDC_ERR_ETYPE_NOSUPP","Kerberos server has no support for this encryption type") }
"0xf" { return ("KDC_ERR_SUMTYPE_NOSUPP","Kerberos server has no support for checksum type") }
"0x10" { return ("KDC_ERR_PADATA_TYPE_NOSUPP","Kerberos server has no support for PADATA type") }
"0x11" { return ("KDC_ERR_TRTYPE_NOSUPP", "Kerberos server has no support for transited type") }
"0x12" { return ("KDC_ERR_CLIENT_REVOKED","Clients credentials have been revoked") }
"0x13" { return ("KDC_ERR_SERVICE_REVOKED","Credentials for server have been revoked") }
"0x14" { return ("KDC_ERR_TGT_REVOKED","TGT has been revoked") }
"0x15" { return ("KDC_ERR_CLIENT_NOTYET","Client not yet valid") }
"0x16" { return ("KDC_ERR_SERVICE_NOTYET", "Server not yet valid") }
"0x17" { return ("KDC_ERR_KEY_EXPIRED", "Password has expired - change password to reset") }
"0x18" { return ("KDC_ERR_PREAUTH_FAILED","Preauthentication is invalid, bad password") }
"0x19" { return ("KDC_ERR_PREAUTH_REQUIRED","Additional Preauthentication required") }
"0x1f" { return ("KRB_AP_ERR_BAD_INTEGRITY","Integrity check on decrypted field failed") }
"0x20" { return ("KRB_AP_ERR_TKT_EXPIRED","Ticket expired")}
"0x21" { return ("KRB_AP_ERR_TKT_NYV","Ticket not yet valid")}
"0x22" { return ("KRB_AP_ERR_REPEAT","Request is a replay")}
"0x23" { return ("KRB_AP_ERR_NOT_US","The ticket isn't for us")}
"0x24" { return ("KRB_AP_ERR_BADMATCH", "Ticket and authenticator do not match") }
"0x25" { return ("KRB_AP_ERR_SKEW", "Clock skew is too big")}
"0x26" { return ("KRB_AP_ERR_BADADDR", "Incorrect net address") }
"0x27" { return ("KRB_AP_ERR_BADVERSION", "Protocol version mismatch") }
"0x28" { return ("KRB_AP_ERR_MSG_TYPE", "Invalid message type") }
"0x29" { return ("KRB_AP_ERR_MODIFIED", "Message stream modified") }
"0x2a" { return ("KRB_AP_ERR_BADORDER", "Message out of order") }
"0x2c" { return ("KRB_AP_ERR_BADKEYVER","Specified version of key is not available") }
"0x2d" { return ("KRB_AP_ERR_NOKEY", "Service key not available") }
"0x2e" { return ("KRB_AP_ERR_MUT_FAIL", "Mutual authentication failed") }
"0x2f" { return ("KRB_AP_ERR_BADDIRECTION", "Incorrect message direction") }
"0x30" { return ("KRB_AP_ERR_METHOD", "Alternative authentication method required") }
"0x31" { return ("KRB_AP_ERR_BADSEQ", "Incorrect sequence number in message") }
"0x32" { return ("KRB_AP_ERR_INAPP_CKSUM", "Inappropriate type of checksum in message") }
"0x3c" { return ("KRB_ERR_GENERIC", "Generic error") }
"0x3d" { return ("KRB_ERR_FIELD_TOOLONG","Field is too long for this implementation") }
default { return ("Invalid code", "not in RFC") }
}
}
Friday, March 26, 2010
Auditing Kerberos Delegation
In the last few weeks I was doing some audits in my environment for accounts that were trusted for delegation. I thought I would share some LDAP searches with everyone, using Joe's great ADFIND tool. For those that are not too familiar with delegation, there are two different bits in the UserAccountControl attribute that are related to delegation. These are TRUSTED_FOR_DELEGATION (0x80000) which uses kerberos forwardable tickets, and TRUSTED_TO_AUTH_FOR_DELEGATION (0x1000000) which allows the delegated person/computer to request a ticket on a user's behalf. Both of these options should be used with extreme caution when the accounts are unconstrained, the second option even more so. If systems that are delegated in an unconstrained manner get compromised, anyone accessing them is basically giving up their account for any purpose to the compromised machine.
Finding all unconstrained delegated computer and user accounts, ignoring domain controllers.
adfind -h DCservername -b dc=mydomain,dc=com -s subtree -bit -f "(&(|(objectcategory=user)(objectcategory=computer))(|(userAccountControl:OR:=16777216)(userAccountControl:OR:=524288))(!(iscriticalsystemobject=TRUE))(!(msds-allowedtodelegateto=*)))" -t 9000 distinguishedname serviceprincipalname useraccountcontrol
Finding all constained delegated computer and user accounts, ignoring domain controllers.
adfind -h DCservername -b dc=mydomain,dc=com -s subtree -bit -f "(&(|(objectcategory=user)(objectcategory=computer))(|(userAccountControl:OR:=16777216)(userAccountControl:OR:=524288))(!(iscriticalsystemobject=TRUE))(msds-allowedtodelegateto=*))" -t 9000 distinguishedname serviceprincipalname useraccountcontrol
Wednesday, January 13, 2010
Microsoft Annotated netmon traces for common activity
This is a great time saver...so again, thanks.