Query Details

Hunting For Malicious Click Fix Cases From Airports

Query

**Hunting for Malicious ClickFix cases executed from Airports**

**Description**: A few months ago, I shared a post about the risks of users signing in from airport networks. These can easily be spoofed by malicious actors setting up fake Wi-Fi hotspots to harvest user credentials and other sensitive data.
Now, a new case has been reported involving users clicking on fraudulent Wi-Fi portals that trick them into executing a “connect” action to what appears to be a legitimate network.
These are essentially click-fix attacks, so I’m updating my KQL query to capture all types of DeviceEvents triggered from airport latitude and longitude locations. This should help identify a wider range of suspicious activities originating in such environments.

```
let Airport_Data = externaldata(AirportName:string, maxLatitude: decimal, minLatitude:decimal, maxLongitude:decimal, minLongitude:decimal,iata:string, country: string,maxlatindicator:int)[@"https://raw.githubusercontent.com/Sergio-Albea-Git/Threat-Hunting-KQL-Queries/refs/heads/main/Security-Lists/Airport_polygon.csv"] with (format="csv", ignoreFirstRecord=True);
DeviceNetworkEvents
| where InitiatingProcessFileName has_any("powershell.exe", "curl.exe", "wget.exe", "Invoke-WebRequest")
| where RemoteUrl has_any(".png", ".html", ".htm") or RemotePort == 443 or RemotePort == 80
| extend geo = geo_info_from_ip_address(LocalIP) | extend Country  = tostring(geo.country), Latitude = tostring(geo.latitude),Longitude = tostring(geo.longitude)
| extend Latitude0 = todecimal(Latitude), Longitude0 = todecimal(Longitude)
| extend IntegerPart = toint(Latitude0)
| join kind=inner (Airport_Data) on $left.IntegerPart == $right.maxlatindicator
| where Latitude0 < minLatitude and Latitude0 < maxLatitude and Longitude0 > minLongitude and Longitude0  < maxLongitude
| summarize make_set(AirportName),  make_set(country),dcount(AirportName) by ActionType,RemoteIP,InitiatingProcessCommandLine,RemoteUrl, Country
```

Explanation

This KQL query is designed to detect potentially malicious activities occurring at airports by analyzing device network events. Here's a simplified breakdown of what the query does:

  1. Load Airport Data: The query starts by importing a dataset containing information about airports, including their names, latitude and longitude boundaries, and other identifiers. This data is sourced from an external CSV file.

  2. Filter Device Events: It then filters device network events to find those initiated by specific processes known for network interactions, such as "powershell.exe", "curl.exe", "wget.exe", and "Invoke-WebRequest". These processes can be used to execute network requests and are often scrutinized for suspicious activity.

  3. Check Network Requests: The query further narrows down the events by looking for network requests that involve common web content types (like ".png", ".html", ".htm") or standard web ports (443 for HTTPS and 80 for HTTP).

  4. Geolocation Information: For each event, it retrieves geolocation information based on the local IP address, extracting the country, latitude, and longitude.

  5. Match with Airport Locations: The query then matches these geolocated events with the airport data to identify events occurring within the geographical boundaries of airports.

  6. Summarize Results: Finally, it summarizes the results by listing the airports and countries involved, counting distinct occurrences by action type, remote IP, command line used to initiate the process, and the remote URL accessed.

In essence, this query helps identify suspicious network activities that originate from airport locations, potentially indicating malicious attempts to exploit airport Wi-Fi networks.

Details

Sergio Albea profile picture

Sergio Albea

Released: September 12, 2025

Tables

DeviceNetworkEvents

Keywords

DeviceNetworkEvents

Operators

letexternaldatawithwherehas_anyorextendtostringtodecimaltointjoinon<>summarizemake_setdcountby

Actions