WINDOWS AUTHENTICATION

Certificate-based Authentication over WinRM

Nairuz Abulhul
R3d Buck3T
Published in
9 min readJun 14, 2023

--

Advanced WinRM Security: Achieving Passwordless Authentication with Certificate-Based Methods

Windows Remote Management (WinRM) is a feature of Windows that allows administrators to manage remote systems — execute commands, manage services, and deploy software.

By default, WinRM uses Basic Authentication to authenticate users; this method is simple to set up and use, but it is not very secure. Usernames and passwords can be easily guessed or stolen, allowing unauthorized users to access remote systems.

For a better secure option, WinRM also supports Certificate-based Authentication that leverages digital certificates to verify users’ identities, ensuring that only authorized entities can access and manage remote systems.

In this blog post, we will explore the concept of certificate-based authentication over WinRM and the configuration steps involved in authenticating from Windows and Linux environments. We will use the HTB Sizzle machine to demonstrate the steps.

Certificate-based Authentication Overview

Certificate-based authentication is a process that verifies the authenticity and integrity of digital certificates. The process involves the certificate authority (CA) issuing a certificate containing information about the holder, such as common name (e.g., domain name), organization, location, and public key of the entity requesting the certificate.

When a user or service attempts to connect, they show their issued certificate; if the certificate is valid, they will grant access, and if not, they won’t. No passwords are required other than the certificates themselves.

Generating Certificates

Now we understand the basics of certificate-based authentication; we will start with the first steps of generating certificates on Windows and Linux environments.

On Linux

To create a certificate on a Linux machine, we need to install the OpenSSL tool with the apt-get command.

sudo apt-get install openssl
Figure 1 — shows installing OpenSSL on Linux — r3d-buck3t
Figure 1 — shows installing OpenSSL on Linux.

Then we generate a private key and certificate signing request, a CSR file running the below OpenSSL command. You will be prompted to provide information about the certificate holder, such as organization details, common name, usually the domain name, and other relevant details.

📌You can skip providing information by pressing enter or typing N/A in the fields.

openssl req -new -newkey rsa:2048 -nodes -keyout private.key -out request.csr
Figures 2 & 3 — show generating CSR and private key files.

On Windows

On the Windows side, we also need to install the OpenSSL program, which can be obtained from the Shining Light Production site (https://slproweb.com/products/Win32OpenSSL.html).

Then, we run the installer and follow the on-screen instructions to complete the installation. Once done, open a command prompt as an administrator and run the below command.

.\openssl.exe  req -newkey rsa:2048 -nodes -keyout private.key -out request.csr

The command will prompt you to provide some information for the certificate, and then it will generate a private key and a CSR file once completed.

Figure 4 — shows generating a certificate on Windows. R3dbuck3t blog
Figure 4 — shows generating a certificate on Windows.

Signing Certificate with CA

After generating the two files — request.csr and private.key; we will use a Certificate Authority to sign our request.

In the example of the Sizzle machine, the CA is the Active Directory Certificate Service (AD CS) with an enabled Web Enrollment service. The web interface allows authorized users to submit certificate requests for signing.

There are four (4) main templates:

  • User: A certificate template that allows users to request and receive certificates for various purposes, such as secure email, client authentication, or code signing.
  • Basic EFS (Encrypting File System): A certificate template for encrypting files and folders on Windows systems.
  • UserCert: A generic certificate template in AD CS.
  • SSL: A certificate template for an SSL connection between a web server and a client browser.

To use the AD CS web interface, we need to open a web browser and navigate to the URL of the AD CS server. In the Sizzle machine, it is at https://10.10.10.103/certsrv”. Then, we log in to the web interface using valid Active Directory credentials.

Figure 5 — shows logging into the Certificate Authority Web Interface (AD CS). R3dbuck3t
Figure 5 — shows logging into the Certificate Authority Web Interface (AD CS).

Once logged in, we can request a certificate by clicking on the “Request a Certificate” link, then “Advanced Certificate Request,” to submit the certificate request we generated earlier.

Figure 6 — shows the user requesting a certificate. R3dbuck3t
Figure 6 — shows the user requesting a certificate.
Figure 7- shows the user selecting “Advanced Certificate Request”. R3dbuck3t
Figure 7— shows the user selecting “Advanced Certificate Request”.

In the “Submit a Certificate Request or Renewal Request” page, we paste the base64 contents of the request.csr file in the text field of “Saved Requests”, and click Submit.

Figure 8- shows the base64 certificate. R3dbuck3t
Figure 8- shows the base64 certificate.
Figure 9 — shows the user pasting the base64 certificate request in the Saved Request field. R3dbuck3t
Figure 9 — shows the user pasting the base64 certificate request in the Saved Request field.

If the AD CS accepts the request, it will issue an authentication certificate encoded in DER and Base64 formats. In this case, it doesn’t matter which encoding to choose; both are fine.

Usually, the best encoding format for a certificate depends on the specific use case. If the certificate needs to be read by humans, then Base64 is a better option. If the certificate needs to be stored in a small space or security is a concern, then DER is the option to use.

Below I chose the Base64 encoded format and clicked on the “Download Certificate” link that generates and downloads a file called certnew.cer

Figure 10 — shows the CA issues a certificate encoded in DEF and Base64 formats. R3duck3t
Figure 10 — shows the CA issues a certificate encoded in DEF and Base64 formats.

Authenticating with Certificates

On Linux

To authenticate with certificates over WinRM on Linux, we can use Evil-WirRM or WinRM shell.

Evil-Winrm

Evil-WinRM is a tool that provides a command-line interface for managing remote Windows systems over the network. It leverages the WinRM protocol to connect with a target Windows machine and gain access. It is similar to how SSH on Linux systems.

To authenticate using certificates, we can use the options -c for the signed certificate, -k to pass our user private key, and -S to enable SSL.

evil-winrm -S -i 10.10.10.103 -u amanda -p Ashare1972 -c certnew.cer -k private.key
Figure 11 — shows authenticating to the Sizzle machine using a self-signed certificate. r3dbuck3t
Figure 11 — shows authenticating to the Sizzle machine using a self-signed certificate.

WinRM Shell

WinRM Shell is a Ruby script by Alamot that allows us to connect to Windows machines and execute PowerShell commands. To use the script, we need to install WinRM gem first.

gem install winrm

We copy the script and update it locally to include the endpoint URL to the WSMan service, client certificate (certnew.cer), and the user’s private key.

require 'winrm'

#Append necessary changes in winrm_shell.rb
conn = WinRM::Connection.new(
endpoint: 'https://10.10.10.103:5986/wsman' ,
transport: :ssl,
:client_cert => 'certnew.cer' , # from the server
:client_key => 'private.key' , # private key
:no_ssl_peer_verification => true)

command=""

conn.shell(:powershell) do |shell|
until command == "exit\n" do
output = shell.run("-join($id,'PS ',$(whoami),'@',$env:computername,' ',$((gi $pwd).Name),'> ')")
print(output.output.chomp)
command = gets
output = shell.run(command) do |stdout, stderr|
STDOUT.print stdout
STDERR.print stderr
end
end
puts "Exiting with code #{output.exitcode}"
end

📌 Note: WSMan and WinRM are different technologies; WSMan is the protocol for accessing and managing resources over a network. While WinRM is a Windows-specific implementation of the WS-Man protocol.

Then, run the script; as seen below, we could authenticate to the machine.

ruby winrm_shell.rb
Figure 12 — shows the user authenticated to the machine with the WinRM shell. r3dbuck3t
Figure 12 — shows the user authenticated to the machine with the WinRM shell.

On Windows

In the Windows environment, the private key and signed certificate must be combined in a PFX format to get imported into the Windows Certificate Store.

To achieve this, run the following command to export the files with the pkcs12 option for the PFX format. This format refers to the Public Key Cryptography Standard #12 or PFX, commonly used for exporting and importing certificates in a portable and secure manner.

.\openssl.exe' pkcs12 -export -out certificate.pfx -inkey private.key -in certnew.cer
Figure 13 — shows converting the certificate to PFX format. r3dbuck3t
Figure 13 — shows converting the certificate to PFX format.

Next, double-click on the converted pfx file to import it. We can specify the store location as the current user or the local machine; it won’t make a difference here.

Generally, the main difference between storing a certificate on the current user or local machine is the level of access required to use the certificate. Only that user can access a certificate when stored on the current user. This can be useful for certificates for personal purposes, such as web browsing.

On the other hand, storing the certificate on the local machine allows all computer users to access it. This can be useful for certificates for shared resources, such as a VPN.

Figures 14 &15 — show the steps of importing a certificate to the Windows Certificate Store.

After selecting the certificate to import, type the password you entered when generating the PFX file, then click next and select the store location for the certificate to be chosen automatically. Then click Finish to complete the importing steps.

Figures 15, 16 & 17 — show the steps of importing a certificate to the Windows Certificate Store.

Now we have the certificate imported, we need to get its Thumbprint ID that is required for the WinRM authentication. Since we stored the certificate on the current user location, we go to “Manager User certificates,” and Click on Personal and Certificates. If you stored it on Local Machine, go to “Manage Computer Certificates” instead.

In the Certificate details, scroll down to Thumbprint ID, and copy that ID on the side to use later when connecting to the machine.

Figures 18 & 19 — show the Certificate Thumbprint at the Manger User Certificate location.

The next step is configuring WinRM; open a PowerShell terminal as administrator and run the below command.

 winrm quickconfig
Figure 20- shows configuring WinRM on a Windows machine. r3dbuck3t
Figure 20— shows configuring WinRM on a Windows machine.

Verify the service is running with the Get-Service command and add our machine to the TrustedHosts. The asterisk * in the second command allows us to configure WinRM to allow connections from any host. Of course, we can specify only our machine to be trusted, but for ease, I selected to run it with *.

#check the service status
Get-Service WinRM

#add the machine to trusted hosts
winrm set winrm/config/client '@{TrustedHosts="*"}'
Figure 21- shows adding a machine to TrustedHosts. r3dbuck3t
Figure 21— shows adding a machine to TrustedHosts.

If you want to select only your machine, you can run the Set-Item command and provide your machine name or IP address.


Set-Item WSMan:\localhost\Client\TrustedHosts -Value <TrustedHost>

To connect to the machine, create a new PowerShell session with PSSession and provide the computer name/ IP address and the certificate thumbprint.

#no checks are needed because the machine we connect to is the HTB machine
$sessionOption = New-PSSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck

enter-pssession -ComputerName 10.10.10.103 -SessionOption $sessionOption -CertificateThumbprint 9ccd95dc498eace8e59396b8408d7b7d5811ed4a

As seen below, we are able to connect to the remote machine using WinRM.

Figure 22 -shows authenticating to the remote machine using the imported certificate over WinRM. r3dbuck3t.
Figure 22 -shows authenticating to the remote machine using the imported certificate over WinRM.

Throughout this blog post, we explored the necessary steps to set up and configure certificate-based authentication using the example of the HTB Sizzle machine. We went through the fundamentals of generating certificates and using them for authentication over WinRM.

That’s all for today, thanks!

--

--

Nairuz Abulhul
R3d Buck3T

I spend 70% of the time reading security stuff and 30% trying to make it work !!! aka Pentester [+] Publication: R3d Buck3T