Mitigating vulnerabilities with identity security posture assessments

Mitigating vulnerabilities with identity security posture assessments

This article is contributed. See the original author and article here.

Imagine the following scenario, after a successful phishing campaign, an attacker finds themselves with an active shell on one of your non-sensitive employee’s devices. Using Living-off-the-Land (LotL) tactics (employing built in tools and commands), the attacker starts identifying their next targets and configuration weaknesses to leverage to comprise them. One such vulnerability might be the infamous print spooler bug.

 

The print spooler bug…

As published on the security conference DerbyCon at (2018), the print spooler bug is a way to gain elevated credentials (a sensitive computer account Kerberos ticket in this case) by exploiting two distinct configurations.

  1. A privileged device with the “print spooler” service running.
  2. A victim device configured for Unconstrained Kerberos delegation.

Using these two configurations in tandem, an attacker can “request” the sensitive device Kerberos ticket using the print spooler service through the victim’s device; and because unconstrained Kerberos delegation is enabled, that request will contain the highly sought-after Kerberos authentication ticket (TGT) that allows the attacker to impersonate the domain controller computer account – pretty bad, right?

 

1 Print spooler bug.png

*Image from https://adsecurity.org/?p=4056

 

What can you do?

As part of Azure ATP, we introduced the Identity Security Posture assessment that automatically looks for these kinds of risky configurations in your on-premises environment. This assessment and the recommendation are now integrated in Microsoft Secure Score, makes creating a mitigation plan for these recommended actions easier than ever. To view the recommendations you can use the following steps:

 

  1. Go to the Microsoft Secure Score portal.
  2. Use filters to show the relevant product or tags.
  3. Locate the relevant improvement actions for mitigating the print spooler bug, create an action plan using the builtin options or click “Manage to find out which entities have risky configurations and what actions are needed to re-configure them to remediate the issue.
 

3 Secure Score controls.png

 

Once mitigated, Microsoft Secure Score will reflect the actions taken by increasing your score and mark these improvement actions as “Completed”.

 

Now, let’s consider another scenario.

 

After mitigating the print spooler bug , you discover another improvement action called “Stop clear text credential exposure”. After clicking the “Manage” button to access the assessment to view additional details, you discover that a sensitive entity and an accompanying device are authenticating over LDAP simple bind. To make matters even worse, the exposed user is also sensitive (belonging to the Domain admin group)

 

4 LDAP Cleartext report.png

 

You then realize that if an attacker can get onto your network, they can “sniff” the transmitted credentials that are in clear text and gain elevated credentials.

To further investigate this case, you will need additional details regarding this type of unsecure communication such as:

  • What processes are causing this behavior?
  • Are any of them part of a critical application?
  • What should I do next?

The hunt is on…

To answer these questions, let’s utilize one of MTP’s cool features called Advanced hunting which is now also enriched with Azure ATP activities alongside other security products such as Microsoft Defender ATP, Cloud App Security and Azure AD, and data from Office 365.

We’ll start by going to the Advanced hunting page in the new M365 security portal and from there, we now have access to all the different types of hunting data available for us, including two main tables relevant for this task:

  1. IdentityLogonEvents – all logon events generated by Azure ATP including the LDAP Cleartext type
  2. DeviceNetworkEvents – All networking events generated by Microsoft Defender ATP including LDAP queries generated toward the domain controllers using port 389.

To get started, we can write a query, joining detected logon sessions and network events from both these tables, resulting in a consolidated result that includes the all the unsecure logon activities and their initiating process names.

 

5 Advanced Hunting.png

 

Using the query result, we can construct a cohesive story:

On Aug 05, Testuser2 used the LDP.exe executable to generate an unsecure authentication using LDAP Simple Bind from Client5.”

We now have the relevant details to create a full remediation plan for this activity, such as simply blocking LDP.exe or configuring the application to require a more secure authentication while blocking insecure authentications at the domain level.

 

Conclusion

And there you have it! Using Azure ATP’s Identity Security Posture assessment with Microsoft Secure Score and Advanced hunting, we can build a simple mitigation plan for our organization’s security weak spots, making it that much harder for the bad guy the get in

 

 

For more information about Identity Security Posture assessments and MTP, see

* Learn more about Identity security posture assessments.

* Learn more about Microsoft Secure Score

* Azure ATP activities in advanced hunting

 

Or Tsemah, Senior Product Manager, Azure ATP.

Experiencing Data Latency issue in Azure Portal for Many Data Types – 09/03 – Investigating

This article is contributed. See the original author and article here.

Initial Update: Thursday, 03 September 2020 10:34 UTC

We are aware of issues with Data Latency within Application Insights and Log Analytics in West Europe region and are actively investigating. Some customers may experience intermittent data latency, data gaps and incorrect alert activation.

  • Work Around: None
  • Next Update: Before 09/03 14:00 UTC

We are working hard to resolve this issue and apologize for any inconvenience.
-Sandeep


Understanding Pipeline Failures and Error Handling

Understanding Pipeline Failures and Error Handling

This article is contributed. See the original author and article here.

Azure Data Factory orchestration allows conditional logic and enables user to take different based upon outcomes of a previous activity. In total we allows four conditional paths: Upon Success (default pass), Upon Failure, Upon Completion, and Upon Skip. Using different paths allow users to build robust pipelines and incorporates error handling in their ETL/ELT logic.

 

chezcharlie_0-1599116489778.png

Here are two common error handling pattern we see customers use:

  1. TRY-CATCH block. Define the business logic, and only defines Upon Failure path to catch any error from previous activities Pic 1.png
  2. DO-IF-ELSE block. Define the business logic, and depends on the outcome of the activity, enacts either Upon Success path or Upon Failure path

Pic 2.png

Both are valid ways to incorporate error handling into the pipeline. However, upon pipeline execution, they may show different outcomes. Approach #1, TRY-CATCH, shows pipeline succeeds if Upon Failure path clears, where as approach #2, DO-IF-ELSE show pipeline failed if Upon Failure path is enacted.

 

Technical reasons for the difference is that, Azure Data Factory defines pipeline success and failures as follows:

  • Evaluate outcome for all leaves activities. If a leaf activity was skipped, we evaluate its parent activity instead
  • Pipeline result is success if and only if all leaves succeed

Applying the logic to previous examples. 

  1. In approach #1 TRY-CATCH block:
    • when previous activity succeeds: the node activity, Upon Failure, is skipped and its parent node succeeds, so overall pipeline succeeds
    • when previous activity fails: the node activity, Upon Failure, enacted and overall pipeline succeeds if Upon Failure path succeeds
  2. In approach #2 DO-IF-ELSE block:
    • when previous activity succeeds: one node activity, Upon Success, succeeded, and the other node activity, Upon Failure, is skipped and its parent node succeeds; so overall pipeline succeeds
    • when previous activity fails: one node activity, Upon Success, is skipped and its parent node failed; so overall pipeline failed

Here is a table summarizing the difference

Approach Error Handling Defines When Activity Succeeds When Activity Fails
TRY-CATCH Only Upon Failure path Pipeline shows Success Pipeline shows Success
DO-IF-ELSE Upon Failure and Upon Success paths Pipeline shows Success Pipeline shows Failure

 

Service Bus – duplicate detection for partitioned messaging entity

Service Bus – duplicate detection for partitioned messaging entity

This article is contributed. See the original author and article here.

Pre-requirements:

Before we start, please read these document about Duplicate Detection, Partitioned queues and topics and Message Sessions 

 

From the above Pre-requirements, we learn the followings

  • Enabling Duplicate detection helps to ensure that a duplicate message, which has the same message Id cannot be sent into a messaging entity during a specified time.

 

  • Service Bus Partitions enable queues and topics or message entities to be partitioned across multiple message brokers and messaging stores. Enable partitioning the overall throughput will separate to different partition. Partition key can be used in some scenarios, such as sessions or transactions, require messages to be stored in a specific partition.

 

 

  • Microsoft Service Bus Session enable joint and ordered handling of unbounded sequences of messages.  There are two patterns of it , first out and request-response pattern. Any sender can create a session when submitting messages into a topic or queue by setting the SessionId property to some application-defined identifier that is unique to the session.

 

So, from these above knowledges, we know that Azure Service Bus Queue and Topic/Subscription can enable for Duplicate Detection, Partitions and Sessions. But what’s the relationship between them?

From the meaning of Duplication detection, we know that there is a MessageId of each message. Definition of MessageId is shown below

“If the queue or topic has the RequiresDuplicateDetection property set to true and the SessionId or PartitionKey properties are not set, then the MessageId property value serves as the partition key”

 

This means the duplicate detection only can work when SessionID or PartitionKey are not be set. Is that a correct statement? Let’s do a test!

 

Test Entities:

 

Queues:

There are three queue I used, testqueue, testqueue2, testqueue3. At first time all of them have 0 messages.

servicebusblog0.png

  • testqueue:  Enable Batched Operation, Requires Duplicate Detection. And set duplicate detection for 10 mins.

 servicebusblog1.png

  • testqueue2: Enable Batched Operation, Requires Duplicate Detection, Requires Session

 servicebusblog2.png

  • testqueue3: Enable Batched Operation, Requires Duplicate Detection, Requires Session, Enable Partition

 servicebusblog3.png

 

My Program:

Here is the code. The different in this program used in each time, just the BrokeredMessage SessionID and PartitionKey that in red color.

The Session ID here set with a random value. From the above document, when enable both Partition key and Session ID, the value of them need to be same. Otherwise Service Bus returns an invalid operation exception.

 

    class Program

    {

        static string connectionString = [ConnectionString];

        static string queueName = “testqueue3”;// testqueue,testqueue2

        static void Main(string[] args)

        {

            MainAsync();

        }

        static void MainAsync()

        {

            QueueClient sendClient = QueueClient.CreateFromConnectionString(connectionString, queueName);

            //create a sender on the queue

 

            var session = Guid.NewGuid().ToString();

            var partitionKey = session;

            sendClient.SendBatch(Enumerable.Range(0, 10).Select(n =>

            {

 

                Console.WriteLine(“test my message n{0}”, session);

                BrokeredMessage test = new BrokeredMessage(“Hello World!”) { SessionId = session, , PartitionKey = session, MessageId = “deadbeef-dead-beef-dead-beef” + n };

 

                return test;

            }

            ));

        }

}

Test Round 1:

To find the message, I sent 10 message each time first.

  • testqueue (Enable Batched Operation, Requires Duplicate Detection):  send 10 messages first, then immediately  send another same 10 messages, it still displays 10 messages.

servicebusblog8.0.png

  • testqueue2(Enable Batched Operation, Requires Duplicate Detection, Requires Session): send 10 messages first, and send another same 10 messages, here also display 10 messages.

servicebusblog7.png

 

  • testqueue3(Enable Batched Operation, Requires Duplicate Detection, Requires Session, Enable Partition): Add new message twice the message count turn to 20.

servicebusblog8.png

You can see in the list there are message with duplicate MessageId.

 servicebusblog9.png

 

Then I checked for same MessageId “deadbeef-dead-beef-dead-beef0” , and I found they have  different Partition Keys.

servicebusblog10.png

 

servicebusblog10.1.png

 

Here are these three queues result in this test.

servicebusblog12.png

 

The above test about messages sent in duplicate detection duration. How about we wait for 10 mins to check after the duplicate detection time?

 

 

 

Test Round 2

 

After 10 mins, I sent 1000 messages again twice. The result shows, testqueue and testqueue2 have 1000 included the 10 messages sent before. For testqueue3, there are 2020 messages.

servicebusblog13.png

 

 

Test Result Summary

  • From the first round test result, it indicates that messages with same MessageId can be detected as duplication in a non-partitioned entity within specified duplicate detection duration (10 mins).

 

  • However with partitioned entity, duplicate messages which has same MessageId may not be detected as duplication due to they can end up in a different partition. In conclusion, messages can only be detected as duplication within the specified duplicate detection duration when they are landed in the same partition, i.e. same partition key

 

 

  • For the second test with 1000 message were sent twice, it indicates that the duplicate duration detect only works for the specified duration. After the duplicate detection period, the Messages with same MessageId can be sent to the same Service Bus messaging entity.

 

 

 

Large-scale Data Analytics with Azure Synapse – Workspaces with CLI

Large-scale Data Analytics with Azure Synapse – Workspaces with CLI

This article is contributed. See the original author and article here.

One of the challenges of large scale data analysis is being able to get the value from data with least effort. Doing that often involves multiple stages: provisioning infrastructure, accessing or moving data, transforming or filtering data, analyzing and learning from data, automating the data pipelines, connecting with other services that provide input or consume the output data, and more. There are quite a few tools available to solve these questions, but it’s usually difficult to have them all in one place and easily connected.

 

If this article was helpful or interesting to you, follow @lenadroid on Twitter.

 

Introduction

This is the first article in this series, which will cover what Azure Synapse is and how to start using it with Azure CLI. Make sure your Azure CLI is installed and up-to-date, and add a synapse extension if necessary:

$ az extension add --name synapse

 

What is Azure Synapse?
In Azure, we have Synapse Analytics service, which aims to provide managed support for distributed data analysis workloads with less friction. If you’re coming from GCP or AWS background, Azure Synapse alternatives in other clouds are products like BigQuery or Redshift. Azure Synapse is currently in public preview.

 

Serverless and provisioned capacity
In the world of large-scale data processing and analytics, things like autoscale clusters and pay-for-what-you-use has become a must-have. In Azure Synapse, you can choose between serverless and provisioned capacity, depending on whether you need to be flexible and adjust to bursts, or have a predictable resource load.

 

Native Apache Spark support
Apache Spark has demonstrated its power in data processing for both batch and real-time streaming models. It offers a great Python and Scala/Java support for data operations at large scale. Azure Synapse provides built-in support for data analytics using Apache Spark. It’s possible to create an Apache Spark pool, upload Spark jobs, or create Spark notebooks for experimenting with the data.

 

SQL support
In addition to Apache Spark support, Azure Synapse has excellent support for data analytics with SQL.

 

Other features
Azure Synapse provides smooth integration with Azure Machine Learning and Spark ML. It enables convenient data ingestion and export using Azure Data Factory, which connects with many Azure and independent data input and output sources. Data can be effectively visualized with PowerBI.

At Microsoft Build 2020, Satya Nadella announced Synapse Link functionality that will help get insights from real-time transactional data stored in operational databases (e.g. Cosmos DB) with a single click, without the need to manage data movement.

 

Get started with Azure Synapse Workspaces using Azure CLI

Prepare the necessary environment variables:

$ StorageAccountName='<come up with a name for your storage account>'
$ ResourceGroup='<come up with a name for your resource group>'
$ Region='<come up with a name of the region, e.g. eastus>'
$ FileShareName='<come up with a name of the storage file share>'
$ SynapseWorkspaceName='<come up with a name for Synapse Workspace>'
$ SqlUser='<come up with a username>'
$ SqlPassword='<come up with a secure password>'

Create a resource group as a container for your resources:

$ az group create --name $ResourceGroup --location $Region

Create a Data Lake storage account:

$ az storage account create 
  --name $StorageAccountName 
  --resource-group $ResourceGroup 
  --location $Region 
  --sku Standard_GRS 
  --kind StorageV2

The output of this command will be similar to:

{- Finished ..
  "accessTier": "Hot",
  "creationTime": "2020-05-19T01:32:42.434045+00:00",
  "customDomain": null,
  "enableAzureFilesAadIntegration": null,
  "enableHttpsTrafficOnly": false,
  "encryption": {
    "keySource": "Microsoft.Storage",
    "keyVaultProperties": null,
    "services": {
      "blob": {
        "enabled": true,
        "lastEnabledTime": "2020-05-19T01:32:42.496550+00:00"
      },
      "file": {
        "enabled": true,
        "lastEnabledTime": "2020-05-19T01:32:42.496550+00:00"
      },
      "queue": null,
      "table": null
    }
  },
  "failoverInProgress": null,
  "geoReplicationStats": null,
  "id": "/subscriptions/<subscription-id>/resourceGroups/Synapse-test/providers/Microsoft.Storage/storageAccounts/<storage-account-name>",
  "identity": null,
  "isHnsEnabled": null,
  "kind": "StorageV2",
  "lastGeoFailoverTime": null,
  "location": "eastus",
  "name": "<storage-account-name>",
  "networkRuleSet": {
    "bypass": "AzureServices",
    "defaultAction": "Allow",
    "ipRules": [],
    "virtualNetworkRules": []
  },
  "primaryEndpoints": {
    "blob": "https://<storage-account-name>.blob.core.windows.net/",
    "dfs": "https://<storage-account-name>.dfs.core.windows.net/",
    "file": "https://<storage-account-name>.file.core.windows.net/",
    "queue": "https://<storage-account-name>.queue.core.windows.net/",
    "table": "https://<storage-account-name>.table.core.windows.net/",
    "web": "https://<storage-account-name>.z13.web.core.windows.net/"
  },
  "primaryLocation": "eastus",
  "provisioningState": "Succeeded",
  "resourceGroup": "<resource-group-name>",
  "secondaryEndpoints": null,
  "secondaryLocation": "westus",
  "sku": {
    "capabilities": null,
    "kind": null,
    "locations": null,
    "name": "Standard_GRS",
    "resourceType": null,
    "restrictions": null,
    "tier": "Standard"
  },
  "statusOfPrimary": "available",
  "statusOfSecondary": "available",
  "tags": {},
  "type": "Microsoft.Storage/storageAccounts"
}

Retrieve the storage account key:

$ StorageAccountKey=$(az storage account keys list 
  --account-name $StorageAccountName 
  | jq -r '.[0] | .value')

Retrieve Storage Endpoint URL:

$ StorageEndpointUrl=$(az storage account show 
  --name $StorageAccountName 
  --resource-group $ResourceGroup 
  | jq -r '.primaryEndpoints | .dfs')

You can always check what your storage account key and endpoint are by looking at them, if you’d like:

$ echo "Storage Account Key: $StorageAccountKey"
$ echo "Storage Endpoint URL: $StorageEndpointUrl"

Create a fileshare:

$ az storage share create 
  --account-name $StorageAccountName 
  --account-key $StorageAccountKey 
  --name $FileShareName

Create a Synapse Workspace:

$ az synapse workspace create 
  --name $SynapseWorkspaceName 
  --resource-group $ResourceGroup 
  --storage-account $StorageAccountName 
  --file-system $FileShareName 
  --sql-admin-login-user $SqlUser 
  --sql-admin-login-password $SqlPassword 
  --location $Region

The output of the command should show the successful creation:

{- Finished ..
  "connectivityEndpoints": {
    "dev": "https://<synapse-workspace-name>.dev.azuresynapse.net",
    "sql": "<synapse-workspace-name>.sql.azuresynapse.net",
    "sqlOnDemand": "<synapse-workspace-name>-ondemand.sql.azuresynapse.net",
    "web": "https://web.azuresynapse.net?workspace=%2fsubscriptions%<subscription-id>%2fresourceGroups%2fS<resource-group-name>%2fproviders%2fMicrosoft.Synapse%2fworkspaces%<synapse-workspace-name>"
  },
  "defaultDataLakeStorage": {
    "accountUrl": "https://<storage-account-name>.dfs.core.windows.net",
    "filesystem": "<file-share-name>"
  },
  "id": "/subscriptions/<subscription-id>/resourceGroups/<resource-group-name>/providers/Microsoft.Synapse/workspaces/<synapse-workspace-name>",
  "identity": {
    "principalId": "<principal-id>",
    "tenantId": "<tenant-id>",
    "type": "SystemAssigned"
  },
  "location": "eastus",
  "managedResourceGroupName": "<managed-tesource-group-id>",
  "name": "<synapse-workspace-name>",
  "provisioningState": "Succeeded",
  "resourceGroup": "<resource-group-name>",
  "sqlAdministratorLogin": "<admin-login>",
  "sqlAdministratorLoginPassword": <admin-password>,
  "tags": null,
  "type": "Microsoft.Synapse/workspaces",
  "virtualNetworkProfile": null
}

After you successfully created these resources, you should be able to go to Azure Portal, and navigate to the resource called $SynapseWorkspaceName within $ResourceGroup resource group. You should see a similar page:

lenadroid_0-1599094247688.png

 

What’s next?

You can now load data and experiment with it in Synapse Data Studio, create Spark or SQL pools and run analytics queries, connect to PowerBI and visualize your data, and many more.

 

Stay tuned for next articles to learn more! Thanks for reading!

 

If this article was interesting to you, follow @lenadroid on Twitter.