Microsoft Sentinel – Kusto queries for Killnet and geo lookup

Yesterday, many Norwegian websites were targeted in a DDoS attack by an activist group called Killnet as you can read more about here –> Norway hit with cyberattack, temporarily suspending service (yahoo.com)

Killnet does primarily DDoS attacks using either flooding with POST or GET operations on layer 7 or TCP SYN flood attacks on layer 4. You can read a bit more about how they operate here –> https://www.forescout.com/resources/analysis-of-killnet-report/

One interesting scenario is that Killnet differentiated on services that were hosted on AWS compared to those with regular non cloud endpoints, where with AWS where you have services that are hosted behind Cloudfront you have built-in layer 4 protection TCP SYN flood attacks, therefore they used layer seven attacks for those endpoints.

SYN flood DDoS attack | Cloudflare

If you have a set of services hosted in Microsoft Azure, you will need to use a couple of services to be able to block these types of attacks. DDoS Standard is required if you want to stop TCP SYN flood attacks with a high volume against your services in Azure –> Types of attacks Azure DDoS Protection Standard mitigates | Microsoft Docs

If you want to protect yourself against HTTP Flood attacks you need to use Azure Application Gateway with the WAF feature enabled. This allows you to have Geo-blocking rules or request method blocking if an IP address has more than X number of attempts per minute.  The problem with geo-based blocking is two-fold.

1: The WAF engine still needs to process the connection (allow/block/log)
2: DDoS attacks are from multiple locations, so can make it difficult to lock down access.

However, with the DDoS attacks that were happening yesterday, a couple of customers asked me to help with figuring out if:

1: If Killnet known Indicator IPs were accessing their services?

2: How much traffic is originating from which country? 

Many services are running in Azure behind an Azure Application Gateway which I then used as an example to create these two queries against our Log Analytics Workspace.

1: If Killnet known Indicator IPs were accessing services?

This Query is just using the IP indicators from the report I linked to earlier in this blog post and just looks for those IPs against the Azure Application Gateway diagnostics log table.

let killnet = datatable(ioc:string)
[
'5.2.69.50',
'92.255.85.237',
'92.255.85.135 ',
'173.212.250.114',
'144.217.86.109',
'156.146.34.193',
'162.247.74.200',
'164.92.218.139',
'171.25.193.25',
'171.25.193.78',
'185.100.87.133',
'185.100.87.202',
'185.129.61.9',
'185.220.100.241',
'185.220.100.248',
'185.220.100.250',
'185.220.100.252',
'185.220.100.255',
'185.220.101.15',
'185.220.101.35',
'185.220.102.242',
'185.220.102.243',
'185.220.102.253',
'185.56.80.65',
'185.83.214.69',
'185.100.87.133',
'185.67.82.114',
'185.129.61.9',
'195.206.105.217'
];
AzureDiagnostics
| where clientIP_s in (killnet)
| extend ioc = clientIP_s
| project TimeGenerated, ioc, Resource, requestUri_s, userAgent_s
| summarize count() by ioc

if successful and there are some hits on the IP traffic it will look like this.

2: How much traffic is originating from which country? 

This Kusto Query goes into the Azure Diagnostics table where the Application Gateway is logging diagnostics data and looks at the clientIP_s which is an attribute that used to mark the source IP that is coming in. It is also using an external datasource which is used to collect IPv4 address and using the ipv4_lookup to check if there is a match.

let geoData =
materialize (externaldata(network:string,geoname_id:string,continent_code:string,continent_name:string,
country_iso_code:string,country_name:string,is_anonymous_proxy:string,is_satellite_provider:string)
[@"https://raw.githubusercontent.com/datasets/geoip2-ipv4/master/data/geoip2-ipv4.csv"] with
(ignoreFirstRecord=true, format="csv"));let ip = AzureDiagnostics
| summarize count() by clientIP_s;ip
| evaluate ipv4_lookup(geoData, clientIP_s, network)
| project clientIP_s, network, count_, country_iso_code, country_name
| sort by count_ desc

You can of course change this to look at any other table as long as you change the table name and which IP attribute that is used in that table. If you are using the example above the result should look like this.

Now with this information, I can now define customer Application Gateway rules that can be used to block out different countries based on traffic patterns or block out certain IP addresses if needed.

Here are also some Terraform examples on how to define these custom rules, using for instance to block out Russia from WAF rules which are associated with an application gateway.

 

resource "azurerm_web_application_firewall_policy" "example" {
  name                = "example-wafpolicy"
  resource_group_name = azurerm_resource_group.example.name
  location            = azurerm_resource_group.example.location

  custom_rules {
    name      = "Rule1"
    priority  = 1
    rule_type = "MatchRule"

    match_conditions {
      match_variables {
        variable_name = "RemoteAddr"
      }

      operator           = "GeoMatch"
      negation_condition = false
      match_values       = ["RU"]
    }

    action = "Block"
  }


Leave a Reply

Scroll to Top