Archive

Posts Tagged ‘Certificates’

Replace Tenable Nessus Essentials Self-Signed Certificate

November 29, 2019 Leave a comment

After installing Tenable Nessus Essentials & browsing to the web interface, you get warning about the certificate. The message can vary depending on the name used in the browser to connect (localhost, hostname, etc.)

Your connection is not private. Attackers might be trying to steal your information. NET::ERR_CERT_AUTHORITY_INVALID

This server could not prove that it is.

This is due to it using the built-in self-signed certificate that is generated when Tenable Nessus Essentials is installed.

Windows does not have enough information to verify this certificate

Once logged into the web interface, there isn’t anywhere to replace the certificate being used. I found the link below on how to use a certificate from a certificate authority, but the details are…lacking.
https://docs.tenable.com/nessus/Content/CustomSSLCertificates.htm

So below is what I did to replace the self-signed certificate with one from an internal certificate authority. It’s no one-stop script or function to run but it does the trick. Form follow function people. All the code can be found on my GitHub page. Some code is based off other sources & is credited on the GitHub page.
https://github.com/PonchoHobono/Scripts/blob/master/PowerShell/Certificates/GenerateNessusCertificate.ps1

All the standard disclaimers apply, if you break something that’s on you. Use at your own risk.

  1. Create a DNS entry as needed for the FQDN you are going to use. In my case, I use nessus.laptoplab.net.
  2. Some environment specific variables you will need to change. $CN is the FQDN that will be used to access the web interface. $TemplateName is the name of the template in your CA. $Password is a temporary password used for exporting the certificates.
  3. # Variables to update as needed 
    [string]$CN = "nessus.laptoplab.net"
    [string]$TemplateName = "LabSSLWebCertificateCustom"
    [string]$Password = "P@ssw0rd" 
    
  4. Set some more variables. These you can modify if needed.
  5. # Other Variables
    [string[]]$SAN = "DNS=$CN"
    [string]$Date = Get-Date -Format yyyyMMddhhmmss
    [string]$FriendlyName = """Nessus $Date"""
    [int]$keyLength = 2048
    [string]$NessusCAPath = "C:\ProgramData\Tenable\Nessus\nessus\CA"
    $SecurePassword = ConvertTo-SecureString $Password -AsPlainText -Force
    
    # CA
    $rootDSE = [System.DirectoryServices.DirectoryEntry]'LDAP://RootDSE'
    $searchBase = [System.DirectoryServices.DirectoryEntry]"LDAP://$($rootDSE.configurationNamingContext)"
    $CAs = [System.DirectoryServices.DirectorySearcher]::new($searchBase,'objectClass=pKIEnrollmentService').FindAll()
    If ($CAs.Count -eq 1){
        $CAName = "$($CAs[0].Properties.dnshostname)\$($CAs[0].Properties.cn)"
    } Else {
        $CAName = ""
    }
    If (!$CAName -eq "") {
        $CAName = "$CAName"
    }  
    
  6. Stop the Tenable Nessus service
  7. Stop-Service -Name 'Tenable  
    
  8. Create a variable of the contents for the INF file to be used by certutil.
  9. # INF Template
    $file = @"
    [NewRequest]
    FriendlyName = $FriendlyName
    Subject = "CN=$CN,c=$Country,s=$State,l=$City,o=$Organisation,ou=$Department"
    MachineKeySet = TRUE
    KeyLength = $KeyLength
    KeySpec=1
    Exportable = TRUE
    RequestType = PKCS10
    ProviderName = "Microsoft Enhanced Cryptographic Provider v1.0"
    [RequestAttributes]
    CertificateTemplate = "$TemplateName"
    "@
    
    # SAN Certificate
    If (($SAN).count -eq 1) {
        $SAN = @($SAN -split ',')
    }
    $file += 
    @'
    
    [Extensions]
    ; If your client operating system is Windows Server 2008, Windows Server 2008 R2, Windows Vista, or Windows 7
    ; SANs can be included in the Extensions section by using the following text format. Note 2.5.29.17 is the OID for a SAN extension.
    
    2.5.29.17 = "{text}"
    
    '@
    ForEach ($an in $SAN) {
        $file += "_continue_ = `"$($an)&`"`n"
    } 
    
  10. Prepare a few files.
  11. $inf = Join-Path -Path $env:TEMP -ChildPath "$CN.inf"
    $req = Join-Path -Path $env:TEMP -ChildPath "$CN.req"
    $cer = Join-Path -Path $env:TEMP -ChildPath "$CN.cer" 
    
  12. Populate the INF file.
  13. Set-Content -Path $inf -Value $file 
    
  14. Create a CSR.
  15. Invoke-Expression -Command "certreq -new `"$inf`" `"$req`""
    
  16. Get the private key info for the CSR.
  17. # Private Key
    $CertificateRequest = Get-ChildItem -Path Cert:\LocalMachine\REQUEST | Where-Object {$_.Subject -like "CN=$CN*"} | sort NotBefore | Select-Object -Last 1
    Export-PfxCertificate -Cert $CertificateRequest -Password $SecurePassword -FilePath "$env:TEMP\$CN.pfx"
    
    # Convert PFX to PEM
    Set OPENSSL_CONF=C:\Program Files\OpenSSL-Win64\bin\openssl.cfg
    Set-Location -Path 'C:\Program Files\OpenSSL-Win64\bin'
    Invoke-Expression -Command ".\openssl.exe pkcs12 -in $env:TEMP\$CN.pfx -nocerts -out $env:TEMP\$CN.pem -passin pass:$Password -passout pass:$Password"
    Invoke-Expression -Command ".\openssl.exe rsa -in $env:TEMP\$CN.pem -out $env:TEMP\$CN.key -passin pass:$Password -passout pass:$Password" 2>&1
    Set-Location -Path C:\Temp
    
  18. Submit the CSR to the CA.
  19. Invoke-Expression -Command "certreq -submit -config `"$CAName`" `"$req`" `"$cer`""
    
  20. Retrieve the certificate.
  21. Invoke-Expression -Command "certreq -accept `"$cer`""
    
  22. Export the certificate.
  23. # Export certificate
    $IssuedCertificate = Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object {$_.Subject -like "CN=$CN*"} | sort NotBefore | Select-Object -Last 1
    Export-Certificate -Cert $IssuedCertificate -FilePath "$env:TEMP\$CN`_Issued.cer"
    # Convert to Base64
    certutil -encode "$env:TEMP\$CN`_Issued.cer" "$env:TEMP\$CN`_Issued_Base64.cer"
    
  24. Get the CA’s certificate. This step can vary depending on the PKI infrastructure.
  25. # Get CA Certificate
    # https://www.powershellgallery.com/packages/CertificatePS/1.2/Content/Copy-CertificateToRemote.ps1
    [int]$iteration = 1
    $Chain.Build($IssuedCertificate) | Out-Null
    $ChainElements = $Chain.ChainElements | Select-Object -ExpandProperty Certificate -Skip 1
    ForEach ($ChainElement in $ChainElements) {
        $Iteration++
        $CertificatePath = Join-Path $env:TEMP "$("{0:00}" -f $Iteration).$($ChainElement.Thumbprint).cer"
        $ChainElement | Export-Certificate -FilePath $CertificatePath | Out-Null
        # Convert to Base64
        $Output = certutil -encode "$CertificatePath" "$env:TEMP\$("{0:00}" -f $Iteration).$($ChainElement.Thumbprint)`_Base64.cer"
    } 
    
  26. Copy some of the certificate files to the Nessus Tenable directory. This one can vary as well to get the CA cert copied over. But if you’re reading this, you’re probably able to deduce how to get it copied & named correctly based on this example.
  27. # Update Nessus certificate files
    $Date = Get-Date -Format yyyyMMddhhmmss
    Rename-Item -Path $NessusCAPath\cacert.pem -NewName $NessusCAPath\cacert`_$Date.pem
    Copy-Item -Path $CertificatePath.Replace('.cer','_Base64.cer') -Destination $NessusCAPath\cacert.pem 
    Rename-Item -Path $NessusCAPath\servercert.pem -NewName $NessusCAPath\servercert`_$Date.pem
    Copy-Item -Path $env:TEMP\$CN`_Issued_Base64.cer -Destination $NessusCAPath\servercert.pem -Force
    Rename-Item -Path $NessusCAPath\serverkey.pem -NewName $NessusCAPath\serverkey`_$Date.pem
    Copy-Item -Path $env:TEMP\$CN`.key -Destination $NessusCAPath\serverkey.pem -Force
    
  28. Start the Tenable Nessus service.
  29. Start-Service -Name 'Tenable Nessus'
    
  30. Do a little cleanup. You can of course skip this step if you like & just move all the files generated to a secure location for backup.
  31. $Cleanup = Get-ChildItem -Path $env:TEMP | Where-Object {$_.Name -like "$CN*"}
    Remove-Item -Path $Cleanup.FullName 
    

Now the moment of truth. Browse to the FQDN you configured for the Nessus Tenable web interface. You should not get any certificate warning.

Connection is secure. Your information is provate when it is sent to this site.

No Certificate Templates Could Be Found Error

February 14, 2012 10 comments

I was doing a little Active Directory Certificate Services (AD CS) testing in the lab. I came across the following error when browsing to the web enrollment page, “No certificate templates could be found. You do not have permission to request a certificate from this CA, or an error occurred while accessing the Active Directory.”

Searching around online I found plenty of articles & posts on this error but none of the solutions fixed my issue. After three days of troubleshooting here’s what worked for me.

Being a lab at some point I had changed the Authentication settings in IIS on both CertEnroll & CertSrv to Anonymous Authentication Enabled & Windows Authentication Disabled.

When I changed them back to the defaults which are Anonymous Authentication Disabled & Windows Authentication Enabled I stopped getting the error.

RDP Error Connecting to Server

May 27, 2011 7 comments

One of our Helpdesk personnel got the following error when making an RDP connection from Windows XP SP3 to a Windows Server 2008 R2 server, “Remote Desktop cannot connect to the remote computer because the authentication certificate received from the remote computer is expired or invalid. In some cases, this error might also be caused by a large time discrepency between the client and server computers.”

Since the error suggested it I checked the date, time, & time zone on both the server & client but they are all correct. I tried to RDP to the same server & was able to log in just fine, however I was using Windows 7.

On the server if I open the certificate store in an MMC & browse to the Remote Desktop\Certificates I see that there is a self-signed certificate that expired on 5/3/2011.

If I look at the same store in other 2008 R2 & 2008 SP2 servers they all have a self-signed certificate as well but the expiration dates have not yet passed. It appears as though this certificate should be renewing itself automatically every 6 months but for some reason on this one server it is not. While I could never find any documentation on the mechanics behind this certificate auto-renewing itself the fix is pretty simple. You just need to restart the Remote Desktop Configuration service. The expired certificate will then be renewed.

You will also see an Event ID 1056 in the System log that says, “A new self signed certificate to be used for Terminal Server authentication on SSL connections was generated. The name on this certificate is servername.domain.tld. The SHA1 hash of the certificate is in the event data.”

 

Update: I have also found this same issue on Windows Server 2008 RTM, SP1, and SP2. The same fix applies only the service to restart is Terminal Services Configuration.

%d bloggers like this: