CategoriesIdentity

Simple MIM Sync Run Profiles Scheduler using PowerShell and Task Scheduler – GG EZ

Today I’m going to share one weird trick to schedule MIM Run Profiles using PowerShell. Consultants hate me. Let’s get started.

Script

We are going to create two folders. The first folder is where we are going to store the PowerShell script and configuration. The second folder is where we are going to store our logfiles. I will use C:\MIMRunScheduler and C:\MIMRunScheduler\Log.

param([string]$configfile=$(Read-Host -prompt "Configfile"))

### Load Configuration Data ###
[xml]$maconfig=(Get-Content $configfile)
"" > $maconfig.runcycle.logfile
$sourceFolder="C:\MIMRunScheduler\"
### Functions ###
$line = "---------------------------------------------------------------------------------"
function Write-Output-Banner([string]$msg) {
       Write-Output $line,(" "+$msg),$line
    Write-Output $line,(" "+$msg),$line | Add-Content $sourceFolder"Log\$(Get-Date -f yyyy-MM-dd).log"
}

function Write-Output-Text([string]$msg) {
       Write-Output $msg
    Write-Output $msg | Add-Content $sourceFolder"Log\$(Get-Date -f yyyy-MM-dd).log"
}


### Get Management Agent Data ###
$allMA = @(get-wmiobject -class "MIIS_ManagementAgent" -namespace "root\MicrosoftIdentityIntegrationServer" -computername $maconfig.runcycle.computername)
$numOfExecDone = 0


### Main Script ###
do {
       Write-Output-Banner("Execution #:"+(++$numOfExecDone)+" - Date: "+(date))
       foreach($MANextRun in $maconfig.runcycle.ma) {
             $found = $false;
             
             foreach($MA in $allMA) {   
               if(!$found) {
                    if($MA.Name.Equals($MANextRun.name)) {
                           $found=$true;
                           Write-Output-Banner("MA: "+$MA.Name+" [Type: "+$MA.Type+"]")
                           Write-Output-Text(" - Starting Pre-Script: "+$MANextRun.preScript)
                           invoke-expression $MANextRun.preScript | Out-Null
                           Write-Output-Text(" - Done`n")
                           
                           foreach($profileName in $MANextRun.profilesToRun) {
                                  Write-Output-Text(" - Starting Profile: "+$profileName)
                                  $datetimeBefore = Get-Date;
                                  $result = $MA.Execute($profileName);
                                  $datetimeAfter = Get-Date;
                                  $duration = $datetimeAfter - $datetimeBefore;
                                  Write-Output-Text(" - Done with status: "+$result.ReturnValue+" - Duration: "+$duration.Hours+":"+$duration.Minutes+":"+$duration.Seconds+"`n")
                           }
                           
                           Write-Output-Text(" - Starting Post-Script: "+$MANextRun.postScript)
                           invoke-expression $MANextRun.postScript | Out-Null
                           Write-Output-Text(" - Done`n")
                           Start-Sleep -s $MANextRun.waitSeconds
                    }
               }
             }
             if(!$found) { Write-Output-Text("Not found MA name :"+$MANextRun.name); }
       }

       $continue = ($maconfig.runcycle.cycleWaitSeconds -EQ 0) -OR ($numOfExecDone -lt $maconfig.runcycle.numOfExecs) -OR ($maconfig.runcycle.numOfExecs -EQ -1)
       if($continue) { 
             Write-Output-Banner("Sleeping "+$maconfig.runcycle.cycleWaitSeconds+" seconds")
             Start-Sleep -s $maconfig.runcycle.cycleWaitSeconds
       }
} while($continue)

Save the PowerShell script as C:\MIMRunScheduler\MIMRunCycle.ps1.

The PowerShell script accepts an XML configuration file as a parameter and causes the MIM Synchronization Engine runs to be performed. How the runs are performed is described in the configuration file.

Within the PowerShell script, there is a $sourceFolder variable. This is responsible for the location where the log files will reside.

Script Syntax

.\MIMRunCycle.ps1 [-configFile] <location>

-configFile <location>

The <location> refers to the location of the configuration file. The following example shows how this can be done:

-configfile C:\MIMRunScheduler\FULLConfig.XML

NameValue
Required?True
Accept wildcard characters?False
Accept pipeline input?False
PositionNamed

Configuration

We are going to create two additional scripts called C:\MIMRunScheduler\pre.ps1 and C:\MIMRunScheduler\post.ps1. If you want to perform an action right before or after a run, you can use these two scripts. We are going to leave them empty.

<?xml version="1.0" encoding="UTF-8"?>
<runcycle numOfExecs="0" cycleWaitSeconds="15" computerName=".">
   <MA>
      <name>ADMA</name>
      <preScript>C:\MIMRunScheduler\pre.ps1</preScript>
      <profilesToRun>FIFS</profilesToRun>
      <postScript>C:\MIMRunScheduler\post.ps1</postScript>
      <waitSeconds>5</waitSeconds>
   </MA>
   <MA>
      <name>MIMMA</name>
      <preScript>C:\MIMRunScheduler\pre.ps1</preScript>
      <profilesToRun>FIFS</profilesToRun>
      <postScript>C:\MIMRunScheduler\post.ps1</postScript>
      <waitSeconds>5</waitSeconds>
   </MA>
</runcycle>

Save the configuration file as C:\MIMRunScheduler\FULLConfig.xml.

Configuration Syntax

Each configuration file starts with the XML declaration.

<?xml version="1.0" encoding="UTF-8"?>

After that, run cycles (runcycle in XML) can be defined. A runcycle contains three parameters.

<runcycle numOfExecs="0" cycleWaitSeconds="15" computerName=".">
NameDatatypeDescription
numOfExecsInteger0 = perform the run once
-1 = perform the runs in perpetuity
>0 = define how often the runs should be performed
cycleWaitSecondsIntegerTime between performing run cycles in seconds.
computerNameStringSpecify the computer name in FQDN or in NetBIOS on which MIM is installed. Use the value “.” if the PowerShell script is running on the same server on which MIM is installed.

In a runcycle, multiple MA elements (<MA>) can be defined. In each MA element contains the following elements.

   <MA>
      <name>ADMA</name>
      <preScript>C:\MIMRunScheduler\pre.ps1</preScript>
      <profilesToRun>FIFS</profilesToRun>
      <postScript>C:\MIMRunScheduler\post.ps1</postScript>
      <waitSeconds>5</waitSeconds>
   </MA>
NameDatatypeDescription
nameStringSpecify the name of the Management Agent.
preScriptStringSpecify the location of the PowerShell script to be performed before the run.
profilesToRunStringSpecify the run profile of the selected Management Agent from the name element.
postScriptStringSpecify the location of the PowerShell script to be performed after the run.
waitSecondsIntegerSpecify how many seconds to wait between running the Management Agents.

Task Scheduler

Create a new task in Windows Task Scheduler.

In the General tab, ensure that the task is run by a service account with sufficient rights in MIMSync. Furthermore, pay attention to the Local Security PolicyLocal PoliciesUser Rights Management > Log on as a batch job permission.

Go to the Actions tab.

Press New… to create a new action.

Action:Start a program
Program/script:Powershell.exe “C:\MIMRunScheduler\MIMRunCycle.ps1”
Add arguments (optional):-configfile “C:\MIMRunScheduler\FULLConfig.XML”

Click on OK to save.

Side note: In some environments, the PowerShell execution policy is set to restricted so make sure that’s dealt with first with the system administrator and security officer.

Action:Start a program
Program/script:Powershell.exe -ExecutionPolicy Bypass “C:\MIMRunScheduler\MIMRunCycle.ps1”
Add arguments (optional):-configfile “C:\MIMRunScheduler\FULLConfig.XML”
Disclaimer: Use -ExecutionPolicy Bypass at your own discretion. CISO’s hate this one trick.

Save and run the task.

Conclusion

That’s all folks! I really prefer this method of scheduling MIMSync runs because the script is very lightweight and easy to understand. Hope that you can make use of this. Have a good one.

CategoriesIdentity

FIM Service Management Agent (MIMMA) is not responsive and ends with a stopped-server error – [sadness noises]

The stopped-server error is difficult to troubleshoot because of its indistinct error reporting and multiple causes. It is basically saying that something has happened but Microsoft Identity Manager Synchronization Service (MIMSync) doesn’t know what exactly. It is indicating that the error is beyond the scope of MIMSync. We should focus on what the MIMMA is trying to do in order to troubleshoot this correctly.

Let’s take a look at the architecture of MIM in general. The architecture diagram is based on FIM but this still apply to MIM. As for naming convention we’ll continue to use MIMSync and MIMService.

FIM Architecture Diagram by Brad Turner and David Lundell

We can see that the MIMSync is located in the application tier between the MIMService and the database servers. Most of the time the MIMService is also installed on the MIMPortal server but as shown in the diagram, they are two separate entities. This means that if I disable every Microsoft Internet Information Services (IIS) instances that is hosting MIMPortal, MIMService will continue to run as this is a stand-alone web service (Microsoft.ResourceManagement.Service.exe). As for the scope of this problem, we have established that the stopped-server error doesn’t involve MIMPortal nor IIS.

The MIMMA behaves like a SQLMA with additional ECMA/XMA properties. It connects to the database server and to the MIMService’s base address. The export run in particular connects to the MIMService. Should the MIMService endpoint be unavailable, the export will generate the following error.

An error occurred in executing a Web service object request. 
Type: System.ServiceModel.EndpointNotFoundException 

Message: There was no endpoint listening at http://mim.identandy.local:5725/ResourceManagementService/MEX that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.

Stack Trace:    at System.Net.HttpWebRequest.GetRequestStream(TransportContext& context)
   at System.Net.HttpWebRequest.GetRequestStream()
   at System.ServiceModel.Channels.HttpOutput.WebRequestHttpOutput.GetOutputStream()

Inner Exception: Unable to connect to the remote server

Troubleshooting

There are multiple causes that could make the stopped-server error occur. I have categorized them as the following four suspects:

  • The MIMService is unreachable. We need to establish what is preventing the connection between MIMSync and MIMService.
    • Check the Windows Services Manager (services.msc) whether or not MIMService is running.
    • If the MIMService isn’t running, check if the service account has sufficient rights.
    • Check the firewall whether or not port 5725 is blocked.
    • Check the connectivity to the MIMService endpoint using a browser. It should display a default WCF services page.
  • The SQL Server is unreachable. We need to confirm that the management agent can connect to the SQL database and server.
    • Check the SQL Server Configuration Manager whether or not SQL Server and the concerning instance are running.
    • Check the firewall if the necessary ports are open.
    • Check the SQL Server Client Network Utility (cliconfg.exe) whether or not the correct network library and server name is being used. Normally I would use TCP/IP with “Dynamically determine port” enabled.
    • Check the SQL Server Management Studio (SSMS) whether or not the service account has login permissions.
  • The SQL Server is unresponsive. We can assume that MIMSync can successfully (or partially) connect to the database server.
    • Check the Event Viewer for SQL timeout exceptions such as “Net SqlClient Data Provider: System.Data.SqlClient.SqlException: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding“.
      • This indicates that there are performance problems that needs to be addressed.
    • Check the Event Viewer for SQL permission exceptions such as “System.Data.SqlClient.SqlException: The EXECUTE permission was denied on the object 'StoredProcedureName', database 'FIMService', schema 'sync'.“.
      • This should be easily fixed by adding the service account to the db_owner role of the FIMService database.
    • Check the Event Viewer for SQL tempdb exceptions such as “Could not allocate space for object ‘dbo.SORT temporary run storage: ***************‘ in database ‘tempdb’ because the ‘PRIMARY’ filegroup is full. Create disk space by deleting unneeded files, dropping objects in the filegroup, adding additional files to the filegroup, or setting autogrowth on for existing files in the filegroup.”.
      • While I haven’t fully established the source of this problem, I have managed to work around this by stopping the MIMSync and MIMService instances and clearing the TempDB’s by either a SQL Server restart or via SQL scripts.
  • The MIMMA, MIMService or SQL Server is taking forever to complete requests. This one is by far the most difficult to troubleshoot.
    • Check if the implementation is following the best practices defined by Microsoft.
    • Check the SQL Server Management Studio (SSMS) to find deadlocks in the FIMService and FIMSynchronization databases.
    • Check the Management Policy Rules (MPR) in MIM Portal to find contradicting rules or erroneous workflows.
    • Check if the server infrastructure is adequately equipped. Ensure that the SQL Server has enough IOPS, memory and CPU to limit bottlenecking.

If you are still experiencing problems, consider getting a MIM health check done by a Microsoft Professional to discover underlying issues that might be the cause of this problem. Contact me for more information.

CategoriesIdentity

Unable to disconnect a connector in MIM – Errors… Errors everywhere.

I was greeted with an ambiguous error that occured in Microsoft Identity Manager (MIM) Synchronization Service Manager. (MIMSync) The error message in question:

[SYNCHRONIZATION SERVICE MANAGER]
Could not find any resources appropriate for the specified culture or the neutral culture.
Make sure Microsoft.DirectoryServices.MetadirectoryServices.UI.PropertySheetBase.MMSErrorMessages.resources" was correctly embedded or linked into assembly "PropertySheetBase" at compile time, or that all the satellite assemblies required are loadable and fully signed. [OK]

Let’s start from the beginning. I was trying to disconnect a connector from the connector space in MIMSync and I was greeted with a warning:

[SYNCHRONIZATION SERVICE MANAGER]
You are about to disconnect an unconfirmed provisioned connector or an object that is a pending import delete. This operation will immediately delete the object from connector space. Do you want to continue? [YES/NO]

Sure, I wanted to make it a disconnector but having the object disappear completely would be a viable alternative as well. I clicked on [YES] and then I was shown the “Could not find any resources…” error. What’s going on? The error indicates as if something is wrong with MIMSync itself but it could also be something entirely else.

Upon looking further I’ve found that the object/connector that I was trying to disconnect is having a synchronization error. The synchronization error was “connector-filter-rule-violation” under the synchronization step: “Connector filter (export)”. Then I generated a Full Synchronization preview and here’s what I’ve found in the preview; under the MIM Service management agent, there’s a match with a defined connection filter rule. This is what is causing all the problems!

I opened the MIM Service management agent (MIMMA) and checked the Connector Filter configuration. I found the matched filter that was causing the problem and I deleted it. I went back to the Metaverse Search and opened the connector I wanted to disconnect. Clicked on Disconnect, another “You are about to disconnect an unconfirmed provisioned…” error, clicked on YES and it’s successfully disconnected! I did not have to perform any Import/Syncs/Exports after deleting the connection filter. After that’s done, I restored the connection filter back on the MIMMA.

Job done. ✅

Update (2021-06-27) I’ve noticed that the “Could not find any resources appropriate…” error is directly related to a synchronization error on a management agent. This is because I’ve seen the error happen again but this time, it wasn’t a “connection-filter-rule-violation” error. So if you could fix the synchronization error on one of the connectors of the object you’re trying to disconnect, that will fix the problem.

CategoriesWindows

How to start any program from the Command Prompt (cmd) or the Run dialog – “Sometimes My Genius… It’s Almost Frightening”

We’ve all been here before. We installed some application e.g. OpenSSL and you want to start the application in a directory other than where the OpenSSL executable is actually located. Bam! Error. You can resolve this by adding the folder where the executable is located to the PATH environment variable.

Error: ‘applicationName’ is not recognized as an internal or external command, operable program or batch file.

PATH

PATH is an environment variable on Unix-like operating systems, DOS, OS/2, and Microsoft Windows, specifying a set of directories where executable programs are located. In general, each executing process or user session has its own PATH setting.

Wikipedia – PATH (variable)

Well, that’s still not very clear on what it does. Basically, a PATH is a variable that can be set to directories in which executable programs are located so that it can be started without specifying the entire path to the file. This will work in the Command Prompt (cmd) and in the Run dialog in the Start Menu.

To do this you will have to go to the Environment Variables dialog to add new directories to the PATH variable. You can open Control Panel > System > Advanced > Environment Variables or I prefer the more simple method of running the following command in the Run dialog:

%windir%\System32\rundll32.exe sysdm.cpl,EditEnvironmentVariables

Select the PATH variable in the User variables list and click on Edit…

Click on New and add the directory path of where the executable is located. We will use OpenSSL as an example.

Click on OK to finish.

And we’re done! You’ve successfully added the OpenSSL bin directory, where the OpenSSL executable is located, to the Path variable. Now we can start OpenSSL from the Command Prompt or the Run dialog without specifying the directory path.

OpenSSL is able to start because the directory of where the executable is located is added to the PATH variable
CategoriesSecurity

Crimediggers | Decrypting Base64 messages using RSA private keys – Encrypted Data: (chuckles) I’m in danger.

A friend of mine was doing an online interactive puzzle/game called Crimediggers developed by the Dutch law enforcement agency, and he asked if I could help him with decrypting some encoded messages.. Hmm, interesting!

He already collected the encoded messages and has obtained the private keys. We are not sure which private key belongs to which encoded message.

Encoded Messages

These are the encoded messages in question:

mLkcoaOGPIdIDUnoWdKd0rca66fMWE/bs0YUJWS9waiPrxJQr6KMbL2le/DYtDDKy+cl8EKj0Q1LL9duUpdhszFGYjC98j2tu38lnb3Im5aevhqqo7mds+ZuE2XNtzEJ2dXdSYzhZvzkT6bKKHfFnMr9+WQzUKG9IQiHxg0eBZRvQJFViTY/3aADE11GDs6S4dbvv4sT8MwQva1rGD/Q+d/kAU+av8pRaTlI1fRdESPtHHljkBev7s5fZRJGki1gtwNiInhmajA23x/oSPBTBPzMIR4K5/OIJ2tRCRDmAUvTETNloh6EpOz+vJR+RkbFv6rZIVaxV3yq1dIKYg54hQ==
W1hkk4XxKglKgRo96MQw0glw+O3WpH2OwSy2I+NbWdQ+dYtdJzR1shwCbacCdzF+DNPa07FWhHUE+An6CD8sRPLRyuXR/p8goehgLG3iPma1gyut0VjHyNDIJsJSu4gvnrEcfiWdEYGUKw+NFeYsvDniyOnH/d3BAli8lM8PDxgZjJ6lQ5EZnjQOGS4l2DZWU1lVXfMukK9/5nAO4h41pSCK8ultYFdEk8sdrf3Td2XVp/EIGI9XCwTAZ8H2+XP/eCO4ecgN3GRjttkdQYUhqvlnCaHpsQyNCGzJQpAOycAj/GDTtQ+EoSfVtEAnmOCZRFk12fy8PL+XnUEI/SwIQg==
UdMsi/STSeUBkVUucCBJWwbUzzF0v8bay0suQg9WvBglwZFoGgAVK48d8AWIhEa1euqkF8O2lv4Sprihlzt+HFNEcf1QADyOTZpK+O9PrtEie9o48TbEaFbxSUImepBzLF2/YxSbKhfGYUNb+4MfOn7r0mLmFeslCNQoH/ZfNW76QZ5/0z0HPZOWCCfAEM6n/L7ERh77h4pemGz8UYLTw12TsBNaNeA4vzqNVTtLnzUpcrFrwJrnBOPjw78Ce/jN/8BNhc+PKwvSQw2yqdAUly6+dUq2W/VEuCK3Q+/ilqtRgu5KZBDlarHgMVeS+Sn0dNleiqB0sPUV5O/PPjGE2A==
UxWL9nhlgZUxdbQDMYs6rDcoqHpSKOPN9c32I2+F4pv3FcxNtUh8TcoF0TBe2MoitglYRsRXIKdVl1MmVQUnb9L+QWSaNlgI/GkI9gXrtUIpS6ZluyJzTzKwwh47BKW7d/3YlrenbL0f8PYy7y2JcZK7gJLcp2AJVNkFAlgKZWdcjjvqdY2GoB7GDtztMSqjM27Zs0DgSv3p6QIqJuWMe3eCQhdMGASBcShItd+wQd1z/3nNvmY5Mk5xC7RahIMi4UZitSgLb6cLKfNmIrre9mDZwnHJxpCtLmgh54pW8ACEpo2qfW/dcAa4dtQebwo7HcpixMzcj7rGon0l+pg5HQ==

From these four messages we can establish a couple of things:

  1. Modern encryption algorithms usually outputs into random bytes and yet this message seems to be formatted in a plain text format. This suggests that some kind of binary-to-text encoding have been applied.
  2. The messages seems to be formatted in Base64 because the content resembles a ASCII string and ends with two == symbols.

Let’s check if the messages are indeed Base64. Using regular expression (RegEx) we can determine that the text could have been a Base64 value. However, even if the message passes the RegEx, this does not mean that the decoded content is valid encrypted content. That’s the beauty of encryption! If we assume that it’s encrypted using modern algorithms, we can’t really know for sure that the file is encrypted because it should look randomized.

^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)?$

We can confirm that each of the four messages are a full match with the RegEx above. Now we need to convert those Base64 encoded messages back to file.

Why? Because we need the original encrypted file to decrypt using the private keys. We can’t apply the private key directly to the Base64 encoded messages. You’ll get a error like:

RSA operation error
19200:error:0406506C:rsa routines:rsa_ossl_private_decrypt:data greater than mod len:crypto\rsa\rsa_ossl.c:401:

The private key should be applied to the output that was generated during the encryption process and not on the Base64 encoded version of it.

Just some additional information…

There’s a lot of ways to do this but since I’m primarily on Windows, I’ll do this with PowerShell. The following script need two variables: $path and $message. The $path variable is where the output of the file will be exported. The $message variable contains the Base64 encoded message. Both variables will be passed into a FromBase64String function.

The FromBase64String method is designed to process a single string that contains all the data to be decoded. Converts the specified string, which encodes binary data as base-64 digits, to an equivalent 8-bit unsigned integer array.

Just some additional information…
$path = 'C:\Temp\encrypted1.bin'
$message = 'mLkcoaOGPIdIDUnoWdKd0rca66fMWE/bs0YUJWS9waiPrxJQr6KMbL2le/DYtDDKy+cl8EKj0Q1LL9duUpdhszFGYjC98j2tu38lnb3Im5aevhqqo7mds+ZuE2XNtzEJ2dXdSYzhZvzkT6bKKHfFnMr9+WQzUKG9IQiHxg0eBZRvQJFViTY/3aADE11GDs6S4dbvv4sT8MwQva1rGD/Q+d/kAU+av8pRaTlI1fRdESPtHHljkBev7s5fZRJGki1gtwNiInhmajA23x/oSPBTBPzMIR4K5/OIJ2tRCRDmAUvTETNloh6EpOz+vJR+RkbFv6rZIVaxV3yq1dIKYg54hQ=='
$bytes = [Convert]::FromBase64String($message)
[IO.File]::WriteAllBytes($path, $bytes)

We will execute this script four times, each time with a different encoded message. In the end, we will have 4 encrypted files that needs to be decrypted.

Private Keys

Now that we have our encoded messages sorted out, let’s go and take a look at the private keys. The private keys are bundled up in a single file looking like this:

-----BEGIN RSA PRIVATE KEY-----
***
-----END RSA PRIVATE KEY-----
-----BEGIN RSA PRIVATE KEY-----
***
-----END RSA PRIVATE KEY-----
-----BEGIN RSA PRIVATE KEY-----
***
-----END RSA PRIVATE KEY-----

This tells us that we are dealing with an RSA private key. We can confirm this by performing the following command in OpenSSL.

openssl rsa –noout –check –in $privateKey | openssl md5

The $privateKey variable is used in the “-in” parameter for the input of the private key. It expects a path to the private key file.

If OpenSSL outputs anything else than “RSA key ok” then the key is invalid. In this specific scenario, the private keys are all valid RSA private keys. I will post the private keys in the second page of this post since there are 10 private keys in the bundle. Now I am going to split up each segment into separate files.

Be sure to include —-BEGIN RSA PRIVATE KEY—- and —–END RSA PRIVATE KEY—– in the text when separating the private keys from the bundle.

Important!

This means that I end up with 10 files looking like this:

-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA3qyBdDzhyyftmxd/FjRHbgtlRnMh8pcBHJVhUe9FNTRsftrF
+9sX2kSoGKSDpmbD0TMckwj8dpWRfVvA5f7xNcPzVlG7HX8FQeIcQjnTFhkWwuNa
LfGD4IXswc82vyYLdW6B5njEKi4I35CkGuOGRqohUuSeiXTlZ6ZaO5HYXZGJ7yCI
1/UGTl5IFuvdqpymqe55egSXN/XrH3Uym5p5Sqh/xtls51ZRl0hMIJZsMVQLb0nf
TrdXWCLfnlmElso5aA02+gi41Ax9c6AreRltXATDQGgFJR9qNs4SE4olJ95shJra
kBnQayNFGrNkDEX4uW48vJ4c2KzRQF1Ujr2irwIDAQABAoIBAGzPjT7Y1Vlp/IDy
HWcjSthqdyXS8v7RbXijQnhAXOhf4rimfWLSMDi3nhDUq4Rv6TZcLJVpKb1k30CL
yppZV1N3mnxO2gnS3SXRsQ9npE/DGM1JPfL/dvsLVqNqd402sRjEVHPkBa+66Rke
XCLLlf0H+9q+3v26grOApc1AOqOVppbYFez7m06RtFWJ2pz3jwk7t0gHYEaBf710
IVwWcLw9OnkX/xo/dwHoBOHfp+0UJ0W83F11Pp4GiE5DoFoS7FYIKa++RrRonJOB
UpgCzr+8yarlZaztCZk0cUS/ck1G9KkDQ4qE1ZG2Cnsd6TS2JlxEEGavQyjy4/Q1
U2IBk9ECgYEA85pb4NqiuCcM8E0ReRRX1yR9yoURJPsbFo2FTz4GNydefqzIovrN
uE5p47E44Y4dtiemcJ+sAntNiXDXriZkOE0QZe90ynHIdOcGpuvWK5A2LnMc82iS
sMv5vd8bzeWX0I/z9C3A/hzjJVSuKbysU9PHE4jhSjPKR+yVHcaY+CcCgYEA6gF7
3e5MByK6r3ZI7enDHrN4XoqtPh6PbmkGq/22LWFw2SeKD3nFTSIXQt+LopjR2Uwt
hAIwv+mvpLfQz59ud2fFhqkBokcf2pF179E9CCQLtM2vNeG3B/It6UE9QkDmGeGs
5hkfBJkXVJhRJl6aAuJjXE7lIvaxTb20gTFpzjkCgYAX0KRg1B8KT88FAxPNOX7o
6oldriqh6eaZCtbYi2DCLZggXDX1MP3BofDaMK415tXiw/eSlRmU2IcZA64iOWCc
3HPY81MAo6UMQLW2xeGXOq8BVYGkDjohDJ/qvxARzftMiXY5DewLK7nNIX0xWV+j
hlW1BDG6Nlv1MhzV319/CwKBgA+dO7uqS+5p9dUBaopdf8SLqyt7y2WKun1eirBt
RHuwtcv3pHG16WFlNfIjYnjeA5qhR6Q4VTJpEGxIS6me9MsI5JhArLg8ULbP3/O5
nX3ukc1lsBxDTGg+U6vty32hQPlXIqdT48r1wCXH6BpMU7B/lKuzI/z6Qwhx8Rpx
xqKZAoGBAJxwngBgwHMuDToAuypPgVx2Vpt5xbuY+Vwed+iiiV85OD4LzkO+yK08
C7mXTOAMzGWYpcEwx7JoxuV/SW45L5pMvoxVEtrVbwF3qAv/FiDivPW8Y8HNOQQb
/qjtTvKFOlajksvYvfZCZJo7nW/MVJE8qYBbNHtJOhMAHVXzZfeh
-----END RSA PRIVATE KEY-----

Solution

We have established that the messages are Base64 encoded and that they need to be converted back to their original encrypted files. Now we can perform decryption using one of the private keys. The following command is used to perform decryption using OpenSSL and RSA and it requires 3 variables.

openssl rsautl -decrypt -in $encrypted -out $output -inkey $privateKey

The $encrypted variable is used in the “-in” parameter for the input of the encrypted file. It expects a path to the encrypted file.

The $output variable is used in the “-out” parameter for the output for the decrypted file. It expects a path to a decrypted file that will be generated.

The $privateKey variable is used in the “-inkey” parameter for the input of the private key. It expects a path to the private key file.

Remember that we had 4 encrypted files and 10 private keys in total? We have to match the corresponding private key to the encrypted file. If we are dealing with a large amount of encrypted files and private keys I would create a for-loop to try each key with each encrypted file. OpenSSL will generate an error when I use an incorrect private key such as:

Attempting to decrypt an encrypted file with an invalid private key with OpenSSL
RSA operation error
7640:error:0407109F:rsa routines:RSA_padding_check_PKCS1_type_2:pkcs decoding error:crypto\rsa\rsa_pk1.c:251:
7640:error:04065072:rsa routines:rsa_ossl_private_decrypt:padding check failed:crypto\rsa\rsa_ossl.c:491:

When OpenSSL doesn’t generate any errors then it managed to decrypt the encrypted file with the private key.

Successfully decrypted an encrypted file with the corresponding private key with OpenSSL
$encrypted = 'C:\Temp\encrypted1.bin'
$output = 'C:\Temp\output.file'
$privateKey = 'C:\Temp\key6.key'

openssl rsautl -decrypt -in $encrypted -out $output -inkey $privateKey

Upon checking the output.file as specified in the $output variable we can find that it contains a message upon opening in Notepad.

Opening the decrypted file in Notepad results in a message for the player

We got lucky that it’s a text file! Since we don’t have any information regarding the file extension we would have to perform some kind of content analysis or reading the file header to determine what kind of file we are dealing with. And there we have it! There are many different ways to go about this. I just like the simplicity of OpenSSL and PowerShell.

CategoriesSecurity

Creating a Certificate Signing Request (CSR) with multiple Subject Alternative Names (SAN) using OpenSSL – Wait, it’s all secure? Always has been.

Introduction

When you want to use digital certificates (also known als public key certificate) to establish a secure connection between computers, you will need to create a certificate signing request. A certificate is most commonly used for SSL/TLS, which is to provide confidentiality and integrity between two communicating applications.

The Subject Alternative Name (SAN or subjectAltName) is a field which allows you to define additional host names to be secured by a single certificate (also known as a Multi-Domain Certificate). For example, this can be useful when you have many domains/subdomains that needs to be secured. In terms of finances and pragmatism, you may not want to purchase different certificates as this might get expensive or having multiple certificates can be bothersome to implement.

You might be thinking, this sounds like a wildcard certificate! You’re not wrong as both type of certificates are quite similar. Both SAN and wildcard certificates allows you to secure multiple (sub)domains. However, a wildcard certificate cannot protect both identandy.com and identandy.org as the top-level domain (TLD) is different. A wildcard certificate only protects the primary domain (as defined in the Common Name) and any subdomains. Plus, wildcard certificates shouldn’t be used anymore since it’s deprecated as shown in section 7.2 of RFC 6125.

7.2. Wildcard Certificates This document states that the wildcard character ‘*’ SHOULD NOT be included in presented identifiers but MAY be checked by application clients (mainly for the sake of backward compatibility with deployed infrastructure).

Instructions

  1. Ensure that you have the latest version of OpenSSL installed.
  2. Create a new text file using your favorite simple text editor and name it request.config.
  3. Copy the following text to the request.config file and change the C\ST\L\O\OU\CN\DNS.* attributes accordingly. Go to chapter Definitions and Examples for more information regarding these attributes.

Syntax of a request.config file:

[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no
[req_distinguished_name]
C = <countryName>
ST = <stateOrProvinceName>
L = <localityName>
O = <organizationName>
OU = <organizationalUnit>
CN = <commonName>
[v3_req]
keyUsage = keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = <hostName>
DNS.2 = <hostName>

Example of a request.config file:

[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no
[req_distinguished_name]
C = NL
ST = Noord-Holland
L = Amsterdam
O = Identandy
OU = Public Relations
CN = identandy.com
[v3_req]
keyUsage = keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = identandy.com
DNS.2 = subdomain.identandy.com
DNS.3 = identandy.net
  1. Ensure that there aren’t any whitespaces at the beginning or the end of the lines.
  2. Start the following command to create the certificate signing request.

Syntax of an OpenSSL command to create a CSR:

openssl req -new -out <csr_file> -newkey rsa:2048 -nodes -sha256 -keyout <private_key> -config <request.config>

Example of an OpenSSL command to create a CSR:

openssl req -new -out identandy_com.csr -newkey rsa:2048 -nodes -sha256 -keyout identandy_com_private.key -config request.config
  1. After executing the OpenSSL command you will be greeted with the following message and your CSR (identandy_com.csr) and private key (identandy_com_private.key) have been created.
Generating a RSA private key
....+++++
......+++++
writing new private key to 'identandy_com_private.key'
-----
  1. Start the following command to verify the certificate signing request
openssl req -text -noout -verify -in identandy_com.csr

verify OK
Certificate Request:
    Data:
        Version: 1 (0x0)
        Subject: C = NL, ST = Noord-Holland, L = Amsterdam, O = Identandy, OU = Public Relations, CN = identandy.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Modulus:
                    00:ba:9e:94:bc:0b:36:35:18:3c:1d:f8:9b:34:47:
                    a6:a0:05:6c:18:29:06:f8:5e:e4:0a:45:42:4b:db:
                    58:1e:56:dd:c5:cb:7b:e1:c8:3c:0b:89:f8:9c:dd:
                    9c:5a:bd:9e:8b:7c:4b:5e:00:cb:71:02:9f:78:af:
                    d5:de:41:d2:7e:97:36:08:28:75:b1:ff:5b:ac:87:
                    17:d3:4b:23:7f:27:42:7c:34:f5:d9:58:94:b6:f4:
                    42:06:02:27:61:ea:54:09:d5:b9:31:b0:72:a2:17:
                    a4:95:61:3d:e7:81:2f:cc:cf:52:f0:e9:05:89:3b:
                    68:59:4f:17:21:58:d1:e5:e0:32:1c:03:cb:43:25:
                    60:1f:a3:b7:49:c3:07:d5:0a:77:9a:fc:d5:02:32:
                    d8:18:d9:84:9c:e1:69:cd:b4:d3:6a:3c:6c:43:0d:
                    22:29:1e:f9:07:58:e0:0b:50:d1:77:04:41:bd:7c:
                    45:c7:ad:45:15:3e:b6:48:d7:bc:9b:b1:56:32:2e:
                    02:23:7a:c9:20:6c:f5:10:87:f6:e2:b7:2b:6a:a6:
                    9b:a0:3c:2e:49:87:8c:89:37:5b:8e:cf:e4:06:1f:
                    8e:dc:90:71:78:9d:2c:2c:1c:bd:dc:db:a7:64:ac:
                    7d:a6:1a:d9:f7:cc:78:69:13:f6:7f:98:52:97:65:
                    a5:4f
                Exponent: 65537 (0x10001)
        Attributes:
        Requested Extensions:
            X509v3 Key Usage:
                Key Encipherment, Data Encipherment
            X509v3 Extended Key Usage:
                TLS Web Server Authentication
            X509v3 Subject Alternative Name:
                DNS:identandy.com, DNS:subdomain.identandy.com, DNS:identandy.net
    Signature Algorithm: sha256WithRSAEncryption
         37:39:f8:4d:c2:71:c6:30:74:4f:de:dd:21:92:56:5e:55:bf:
         f4:80:cb:fa:0c:25:34:48:c5:be:77:5a:4e:f6:b7:3c:bf:40:
         8e:40:35:58:2a:e6:63:f6:5f:95:c8:bc:1b:c5:da:e2:d7:04:
         12:44:cd:0a:95:13:5b:87:a9:a4:d0:91:f8:d9:2f:e1:8e:a1:
         76:ea:60:cc:cd:a3:34:75:cb:ad:cd:f5:63:10:33:69:3a:fc:
         b4:4e:89:b8:e9:42:0b:af:62:4a:08:ac:0d:b8:fb:e1:3c:fe:
         ee:92:46:5e:e9:22:41:b0:68:93:a6:56:b1:6b:f4:c1:eb:54:
         a9:c9:5b:c7:e0:de:17:57:3e:79:90:eb:13:dd:12:c1:52:2c:
         75:e5:7f:13:73:8a:82:67:b2:66:3f:8a:fd:e6:04:4b:08:11:
         a2:b0:03:9f:cb:a8:41:fc:4a:ea:21:c7:1c:68:b9:65:6b:61:
         0a:b3:14:52:b5:c7:51:68:6f:d0:e8:f3:cf:cf:ff:af:27:7e:
         9b:ef:7a:10:ab:2e:48:4e:7a:49:4b:10:b7:6d:92:11:f2:e1:
         99:92:f1:c5:bc:6e:32:e7:d9:48:3a:66:f4:31:26:a2:e5:87:
         d9:de:39:0e:40:87:3c:b7:d3:e7:60:ca:9a:4f:1a:3d:f0:43:
         6f:32:f5:a5

And there you have it! That’s all you need to do to generate a CSR using OpenSSL. I hope that you have find it useful and if you have any questions leave a comment below.

Definitions and Examples

Confidentiality is the concept of the measures used to ensure the protection of the secrecy of data, objects, or resources. The goal of confidentiality protection is to prevent or minimize unauthorized access to data. Confidentiality focuses security measures on ensuring that no one other than the intended recipient of a message receives it or is able to read it. Confidentiality protection provides a means for authorized users to access and interact with resources, but it actively prevents unauthorized users from doing so. A wide range of security controls can provide protection for confidentiality, including, but not limited to, encryption, access controls, and steganography.

Integrity is the concept of protecting the reliability and correctness of data. Integrity protection prevents unauthorized alterations of data. It ensures that data remains correct, unaltered, and preserved. Properly implemented integrity protection provides a means for authorized changes while protecting against intended and malicious unauthorized activities (such as viruses and intrusions) as well as mistakes made by authorized users (such as mistakes and oversights).

Country Name (CN) Use the two-letter country code based on ISO 3166-1 alpha-2. Example: NL

State or Province (S) Spell out the state completely; do not abbreviate the state or province name. Example: Noord-Holland

Locality or City (L) Spell out the city or town name completely; do not abbreviate the locality or city name. Example: Amsterdam

Organization (O) If the company or department has an &, @, or any other symbol, the symbol must be spelled out or omitted. Example: XY & Z Corporation would be XYZ Corporation or XY and Z Corporation. 

Organizational Unit (OU)  The Organizational Unit (OU) field is the name of the department or organization unit making the request.

Common Name (CN) The Common Name (CN), also known as the Fully Qualified Domain Name (FQDN), is the characteristic value within a Distinguished Name. Example: identandy.com

CategoriesWindows Update

Windows Update 2020 July – DNS is as leaky as a basket

Microsoft released a patch for CVE-2020-1350, a Critical Remote Code Execution (RCE) vulnerability in Windows DNS Server that is classified as a ‘wormable’ vulnerability and has a CVSS base score of 10.0.

Let’s start with the vulnerability also known as SIGRed. According to the researcher Sagi Tzadik from Checkpoint Research, this bug existed for over 17 years and it’s an integer overflow vulnerability. What does this all mean?

The DNS service (dns.exe) in Microsoft Windows Server fails to validate a 16-bit register for a SIG Record. An attacker can exploit this and because the DNS Service runs under the SYSTEM context, remote code execution is a possibility or even granting Domain Administrator rights. The CVSS score of 10.0 means that this must be patched as soon as possible. As of writing, Microsoft confirms that the vulnerability hasn’t been exploited yet but I’m sure that this will change soon. A proof-of-concept has shown that this vulnerability can be exploited remotely through an HTTP payload to non-chromium browsers.

Affected Systems

  • Windows Server 2008 for 32-bit Systems Service Pack 2
  • Windows Server 2008 for 32-bit Systems Service Pack 2 (Server Core)
  • Windows Server 2008 for x64-based Systems Service Pack 2
  • Windows Server 2008 for x64-based Systems Service Pack 2 (Server Core)
  • Windows Server 2008 R2 for x64-based Systems Service Pack 1
  • Windows Server 2008 R2 for x64-based Systems Service Pack 1 (Server Core)
  • Windows Server 2012
  • Windows Server 2012 (Server Core)
  • Windows Server 2012 R2
  • Windows Server 2012 R2 (Server Core)
  • Windows Server 2016
  • Windows Server 2016 (Server Core)
  • Windows Server 2019
  • Windows Server 2019 (Server Core)
  • Windows Server version 1909 (Server Core)
  • Windows Server version 1903 (Server Core)
  • Windows Server version 2004 (Server Core)

Mitigation

It is highly recommended to patch the affected Windows DNS Servers to prevent the exploitation of this vulnerability as soon as possible. The July update should already been made available in Microsoft Update and WSUS. See Microsoft’s Security Update Guide for more information regarding which security update you need. A system reboot is required after installing the update.

Workaround

You can define a maximum length of a DNS message over TCP in the registry. Make sure to restart the DNS Service for the registry change to take effect.

Subkey: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\DNS\Parameters 
Value: TcpReceivePacketSize 
Type: DWORD 
Value data: 0xFF00

You can also do the same by running the following command in an elevated command prompt.

reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\DNS\Parameters" /v "TcpReceivePacketSize" /t REG_DWORD /d 0xFF00 /f
net stop DNS && net start DNS

After applying the patch, you can remove the workaround by removing the TcpReceivePacketSize value and its corresponding data.