IISCrypto breaking RDP on Windows 10/Server 2019 and SQL Server 2022/2019 when disabling insecure TLS version

My company recently had a penetration test and part of the findings was the fact we had insecure cipher suites. I was the lucky one tasked with removing old cipher suites and TLS versions.

I fired up IISCrypto on my secondary Windows Server 2022 Domain Controller, built out a IISCrypto plan, applied, tested it and exported it as a reg file. Then I powered up Group Policy Manager and created a GPO to disable the old cipher suites. I was nervous doing this, but I knew we only used Server 2016, 2019, 2022, and Windows 10/11, so I didn’t expect many issues since they are all mostly new. And if I did have an issue, all I would have to do is open IISCrypto and revert the changes on things that broke.

First, I applied to the GPO to workstations. All of which are Windows 10 and Windows 11. As I’m sure you know, these changes don’t take effect until after a reboot, so it was a quiet few days. But after the weekend updates applied, that’s when things heated up.

The first report was SQL Server 2019 AND SQL Server 2022 was unable to log in, even locally. When they attempted to login, they got the simple sounding error “Internal connection fatal error. Error state: 15, Token : 23 (System.Data)”

The next report was the fact that a basic Remote Desktop (RDP) would fail when connecting into a device that the GPO has been applied to. It would display the error “An internal error has occurred”.

None of these error messages was helpful. The thing that really blew my mind was that Windows Server 2016 did not have an issue at all. Windows Server 2022/Windows 11 didn’t either. But Server 2019 and Windows 10 did. Why would Server 2016 be fine but 2019 fail when telling it to use more modern cipher suites?

As soon as a developer complained that their local SQL instance didn’t work, I thought don’t worry, I got this. I powered up IISCrypto on their PC and hit server defaults and rebooted. And… It did not fix it. I tried selecting EVERYTHING! Nothing would work.

After MANY MANY hours trying to figure out why developers with Windows 10 kept getting errors, I still could not find the cause. It wasn’t until I started going line by line in the registry file wondering why the changes wasn’t reverting with IISCrypto.

Then it CLICKED! Windows 10 and Server 2019 does NOT support TLS 1.3. Not at all. IISCrypto KNEW that. So when I told IISCrypto to revert changes, it knew Server 2019/2016 didn’t support TLS 1.3, so it didn’t attempt to revert that. It left the reg key for TLS 1.3 in place. So now Windows 10/Server 2019 thinks it supported TLS 1.3, when in reality it doesn’t. When it tried to negotiate the encryption, it said “I support TLS 1.3″ and so did the other side. So they tried to speak in TLS 1.3, but the RDP/SQL server couldn’t walk the walk. Instead, it failed with ‘Internal error”.

After removing the TLS 1.3 registry change, rebooted, everything worked perfectly.

Long story short, DO NOT use a server 2022/Windows 11 IISCrpyto Reg file on Windows Server 2019 or Windows 10. If you did, REVERT THAT REGISTRY CHANGE NOW!!

The real question I have – why does Server 2019 break down, while 2016 does not? Its like Server 2019 is only partially aware of TLS 1.3 while Server 2016 just ignores it. Sounds like a bug to me!

I hope this saves you the many hours I spent trying to find the answer! I saw where several other people asked and there never was an answer. Let me know if this helps you! Below is the error messages we were getting:

===================================

Cannot connect to localhost.

===================================

Internal connection fatal error. Error state: 15, Token : 23 (System.Data)

------------------------------
Program Location:

   at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
   at System.Data.SqlClient.SqlInternalConnectionTds.CompleteLogin(Boolean enlistOK)
   at System.Data.SqlClient.SqlInternalConnectionTds.AttemptOneLogin(ServerInfo serverInfo, String newPassword, SecureString newSecurePassword, Boolean ignoreSniOpenTimeout, TimeoutTimer timeout, Boolean withFailover, Boolean isFirstTransparentAttempt, Boolean disableTnir)
   at System.Data.SqlClient.SqlInternalConnectionTds.LoginNoFailover(ServerInfo serverInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString connectionOptions, SqlCredential credential, TimeoutTimer timeout)
   at System.Data.SqlClient.SqlInternalConnectionTds.OpenLoginEnlist(TimeoutTimer timeout, SqlConnectionString connectionOptions, SqlCredential credential, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance)
   at System.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, SqlCredential credential, Object providerInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString userConnectionOptions, SessionData reconnectSessionData, DbConnectionPool pool, String accessToken, Boolean applyTransientFaultHandling, SqlAuthenticationProviderManager sqlAuthProviderManager)
   at System.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions)
   at System.Data.ProviderBase.DbConnectionFactory.CreateNonPooledConnection(DbConnection owningConnection, DbConnectionPoolGroup poolGroup, DbConnectionOptions userOptions)
   at System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection)
   at System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
   at System.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
   at System.Data.SqlClient.SqlConnection.TryOpenInner(TaskCompletionSource`1 retry)
   at System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry)
   at System.Data.SqlClient.SqlConnection.Open()
   at Microsoft.SqlServer.Management.SqlStudio.Explorer.ObjectExplorerService.ValidateConnection(UIConnectionInfo ci, IServerType server)
   at Microsoft.SqlServer.Management.UI.ConnectionDlg.Connector.ConnectionThreadUser()

Install Azure Web App Extension using PowerShell

Our company has been using Cloud Services (classic) for some time now and I was tasked with migrating our application to Azure Web Apps. Our company used a MSI to install the New Relic agent as part of the Cloud Services startup. When we switched to Web Apps, I setup our Azure Web Apps to install the New Relic extension. What I did not know at the time was the fact that when you create a staging slot using the PowerShell command New-AzWebAppSlot, extensions are not carried over.

I had to devise a way for our deployment process to be able to create a new staging slot and still be able to install New Relic before swapping slots. Turns out, this is not documented very well by Microsoft or anyone really at the time of writing this.

Below are the methods I use to install new relic (or any extension) on an Azure Web app. If you are trying to install New Relic – the extension name is “NewRelic.Azure.WebSites.Extension”. If you are looking for the name of another extension, I have provided instructions on how to get that name below.

New-AzResource -ResourceType "Microsoft.Web/sites/siteextensions" -ResourceGroupName RGNAME -ResourceName "WEBAPPNAME/EXTENSIONNAME" -ApiVersion '2018-02-01' -Force


If you are trying to install the extension on a slot (such as a staging slot), use this command. I could not find a way to deploy to the production slot/staging slot using the same command. If you can find a way, please let me know in the comment section!

New-AzResource -ResourceType "Microsoft.Web/sites/slots/siteextensions" -ResourceGroupName RGNAME -ResourceName "WEBAPPNAME/SLOTNAME/EXTENSIONNAME" -ApiVersion '2018-02-01' -Force

Find extension name

To find the extension name, we will use Kudo to get that!

  1. Open the Azure Portal and navigate to your Web App
  2. In the sidebar, click Advanced Tools and click Go. This should open a new Tab to the Kudo interface.
  3. You should see a heading called REST API. Under there, you will find Site Extensions: installed | feed
  4. If you have the app installed on this web ap, you can click installed and you will see the information for just what you have installed. If you do not have it installed, you can click feed and see all the installable extensions that the Azure Portal lets you install.
  5. You should now see JSON data for the extensions. Find your extension and look for its id. The ID is what you need to put into the above PowerShell command (without the extra quotes.

How to Join a Windows 11 Computer to an Active Directory Domain

If you want to manage your Windows 11 devices centrally and apply security policies, group policies, and other settings, you need to join them to an Active Directory domain. In this blog post, I will show you how to join a Windows 11 computer to an on-premises Active Directory domain using different methods.

Requirements and Preparations

Before you join your Windows 11 computer to a domain, you need to meet some basic requirements and make some preparations:

  • Your computer must have a Pro, Education, Pro for Workstations, or Enterprise edition of Windows 11. Home editions do not support domain join. However, you can purchase a Home to Pro upgrade license.
  • Your computer must be connected to a local network and be able to access at least one domain controller. You can check the network connectivity and DNS settings of your computer by using the ipconfig /all command in PowerShell or Command Prompt.
  • Your computer must be able to resolve the domain name and ping the domain controller. For example, if your domain name is woshub.loc, you can use the command ping woshub.loc to test the name resolution and network connectivity.
  • Your computer’s local time must be within five minutes of the domain controller’s time. This is required for Kerberos authentication. You can check the time settings of your computer by using the Get-Date command in PowerShell or the date and time commands in Command Prompt.
  • Your computer must have a unique and meaningful name that will be used in the domain. You can change the computer name by using the classic Control Panel (sysdm.cpl) or PowerShell (Rename-Computer -NewName "wks-tst1"). You need to restart your computer after changing the name.
  • You must have a user account with delegated administrative permissions to join computers to the domain. This can be a regular user account (by default, any domain user can join up to 10 devices) or a privileged domain administrator account.

Joining Windows 11 to a Domain Using System Properties

The classic way of joining a Windows computer to a domain is by using the System Properties dialog box. Here are the steps:

  1. Open Control Panel and click on System and Security > System.
  2. Click on Change settings under Computer name, domain, and workgroup settings.
  3. Click on Change under To rename this computer or change its domain or workgroup, click Change.
  4. Select Domain under Member of and enter your domain name (e.g., woshub.loc).
  5. Click OK and enter your user name and password when prompted.
  6. Click OK again when you see the message Welcome to the woshub.loc domain.
  7. Restart your computer.

Joining Windows 11 to a Domain Using Settings App

Another way of joining a Windows 11 computer to a domain is by using the Settings app. Here are the steps:

  1. Open Settings and click on Accounts > Access work or school > Connect.
  2. Click on Join this device to a local Active Directory domain under Advanced options.
  3. Enter your domain name (e.g., woshub.loc) and click Next.
  4. Enter your user name and password when prompted and click OK.
  5. Click Next when you see the message Welcome to the woshub.loc domain.
  6. Restart your computer.

Joining Windows 11 to a Domain Using PowerShell

You can also join a Windows 11 computer to a domain using PowerShell commands. Here are the steps:

  1. Open PowerShell as an administrator.
  2. Use the Add-Computer cmdlet to join your computer to the domain. For example:
Add-Computer -DomainName "woshub.loc" -Credential "woshub\administrator" -Restart

This command will prompt you for the password of the administrator account and then join your computer to the woshub.loc domain and restart it.

  1. Alternatively, you can use the Join-Domain cmdlet from the ActiveDirectory module (you need to install it first by using Install-WindowsFeature RSAT-AD-PowerShell). For example:
Join-Domain -Name "woshub.loc" -Credential "woshub\administrator" -Restart

This command will do the same thing as the previous one.

Applying User GPO Settings to a Computer

Today, I wanted to apply some Group Policy settings to users who login to certain computers in an OU. More specifically, I wanted to create a Scheduled Task for users who log into servers. I have found in my research that this is technically called Loopback Processing of Group Policy. Using this feature of Group Policies, you can apply a User based GPO to users who log into applied computers.

The first thing I did was build out my Group Policy like I wanted, just like a normal GPO. I created some Scheduled Tasks that would run as the user and would be created when they login.

Next, I turned on the setting that applied the GPO to Users as well. Navigate to Computer Configuration – Policies – Administrative Templates – System – Group Policy.

Screenshot of Group Policy GPO folder filtered

From within there, you will find the policy labeled: Configure user Group Policy loopback processing mode. Set that setting to enabled. Below is the Help Section of the group policy setting. Here is a link to the related Microsoft article. You may want to do more research before you turn this setting on, as I only tested it in my Home Lab. It could have more far-reaching changes that I am unaware of.

A screenshot of the GPO item Configure user Group Policy loopback processing mode

This policy setting directs the system to apply the set of Group Policy objects for the computer to any user who logs on to a computer affected by this setting. It is intended for special-use computers, such as those in public places, laboratories, and classrooms, where you must modify the user setting based on the computer that is being used.

By default, the user’s Group Policy Objects determine which user settings apply. If this setting is enabled, then, when a user logs on to this computer, the computer’s Group Policy Objects determine which set of Group Policy Objects applies.

If you enable this setting, you can select one of the following modes from the Mode box:

“Replace” indicates that the user settings defined in the computer’s Group Policy Objects replace the user settings normally applied to the user.

“Merge” indicates that the user settings defined in the computer’s Group Policy Objects and the user settings normally applied to the user are combined. If the settings conflict, the user settings in the computer’s Group Policy Objects take precedence over the user’s normal settings.

If you disable this setting or do not configure it, the user’s Group Policy Objects determines which user settings apply.

Note: This setting is effective only when both the computer account and the user account are in at least Windows 2000 domains.

Sophos XG Firewall Windows DHCP Server not getting IP Addresses

I recently setup Sophos XG Firewall in my Home Lab and setup vlans, firewall rules, DHCP relays to point to my Windows DHCP Server, etc. The whole 9 yards. After I had everything working, I decided to add in the rest of my VLANS and create relays so they all worked without a hitch. After doing this, something that should not have effected other already working VLANs, nothing was getting DHCP addresses. Not even ones that was working.

I spent MANY hours trying to figure out why. I tried changing all of my firewall rules to any-any, etc. Nothing was working. After looing in the logs, I noticed this:

Firewallmessageid="02002" log_type="Firewall" log_component="Appliance Access" log_subtype="Denied" status="Deny" con_duration="0" fw_rule_id="0" policy_type="0" user="" user_group="" web_policy_id="0" ips_policy_id="0" appfilter_policy_id="0" app_name="" app_risk="0" app_technology="" app_category="" in_interface="Port1.21" out_interface="" src_mac="68:b5:99:6f:b5:fe" src_ip="10.124.216.41" src_country="" dst_ip="10.124.219.254" dst_country="" protocol="UDP" src_port="67" dst_port="67" packets_sent="0" packets_received="0" bytes_sent="0" bytes_received="0" src_trans_ip="" src_trans_port="0" dst_trans_ip="" dst_trans_port="0" src_zone_type="" src_zone="" dst_zone_type="" dst_zone="" con_direction="" con_id="" virt_con_id="" hb_status="No Heartbeat" message="" appresolvedby="Signature"

I was getting a block by the firewall rule 0 on Appliance Access as Denied. But why? A – it shouldn’t be a firewall rule blocking it because I put in an Any-Any rule. I tried changing everything. But it came down to one.. simple.. thing.. Here is my setup so you can understand the issue.

The Setup

  • VLAN 110 – 192.168.0.0/24 – Networking equipment
    • Sophos XG Firewall – IP 192.168.0.5
  • VLAN 111 – 192.168.1.0/24 – Servers
    • Windows AD/DNS/DHCP Server – 192.168.1.10
  • VLAN 112 – 192.168.2.0/24 Clients (No IP address)
    • Laptop
    • Cellphone

In Sophos, Windows DHCP, I setup DHCP subnets for all three vlans. Then in Sophos, I setup a DHCP relay just the Clients VLAN.

It worked! I was getting IP addresses assigned to the Clients.

The Issue

Then I decided to setup VLANs for every subnet and made quite a few other changes to get it to that perfect lab I was hoping for. I looked up and noticed all my Chromecasts was saying they couldn’t get an IP. I checked and sure enough, it was no longer dishing out IP addresses.

The Resolution

After much trial and error, I found that the fact I put a DHCP relay on the subnet the DHCP server was on, it was causing all the DHCP requests to fail.

Someone may have a better understanding of it and can explain better in the comments, but what my assumption is, when the DHCP request goes out, it gets blasted to the entire vlan to find a DHCP server by blasting out to port 67/68 UDP in search of a DHCP server. The gateway at 192.168.2.1 forwards this to the 192.168.1.0/24 vlan and it receives the blast on that subnet for the response, and blasts that back out to the requesting vlan.

If you put in a DHCP relay on the same subet as the DHCP server, then when it tries to “blast” the response back, the gateway takes that requests and tries to re-blast it in the same subnet. This causes a malformed loop and causes the request to fail. Thus removing the DHCP relay on the VLAN the DHCP server is in should fix this.

Please let me know if you have a better understanding of the cause or if this helps you!

Change Default SSH Port Number

SSH Command line

By default, SSH runs on port 22, and most scripts attack that port by brute force to attempt to gain access to your server. One way to stop script kiddies from brute forcing your SSH server so often is by changing the default port that OpenSSH uses. You must remember this port number and change all your connections that use SSH to the new port number. Continue reading “Change Default SSH Port Number”

Automatically backup pictures on Android With OneDrive

OneDrive Logo

The past few days I have been getting calls regarding people’s phones not working right. The number one worry – I need my pictures. The way a phone’s internal storage works, if the phone will not come on, there is not much of a way to recover your pictures if they are not on an SD Card. Which leaves the question of how do I keep from loosing my pictures if my phone quits working? The answer – cloud storage. Continue reading “Automatically backup pictures on Android With OneDrive”