Kusto Tor Exit Nodes Table
Description
This data represents Tor exit nodes.
Source
Taken from the publically available resource on the Tor Projects own site https://check.torproject.org/torbulkexitlist
Why should I use this data?
It’s a small dataset and high fidelity given it comes from the Tor Project themselves. It is useful to find Tor nodes within existing datasets and represents a snapshot of the Tor environment on a given time.
Updates
Daily at around 0300UTC although source data is updated more regularly.
Schema
Column Name | Data Type | Notes |
---|---|---|
IPAddress | string | The given IP address |
Source | string | Where this was obtained |
Description | string | Description of what this is, eg Exit node on Tor |
Base Kusto Table
externaldata (IpAddress:string, Source:string, Description:string) ['https://firewalliplists.gypthecat.com/lists/kusto/kusto-tor-exit.csv.zip'] with (ignoreFirstRecord=true)
Base Kusto Function
let TorExitNodes = externaldata (IpAddress:string, Source:string, Description:string) ['https://firewalliplists.gypthecat.com/lists/kusto/kusto-tor-exit.csv.zip'] with (ignoreFirstRecord=true)
Self Contained Kusto
// Test randomly generated IP addresses will likely return no results
//*** Variables start
let NumberOfIPsToTest = 100;
//*** Variables end
let TorExitNodes = (externaldata (IpAddress:string, Source:string, Description:string)
['https://firewalliplists.gypthecat.com/lists/kusto/kusto-tor-exit.csv.zip']
with (ignoreFirstRecord=true));
let IPsTesting = materialize(
range Position from 1 to (NumberOfIPsToTest) step 1 //Generate x random IP Addresses for testing
| extend IpAddress = strcat(toint(rand(255)), '.', toint(rand(255)), '.', toint(rand(255)), '.', toint(rand(255))));
IPsTesting
| join kind=leftouter (TorExitNodes) on $left.IpAddress == $right.IpAddress
| order by Position asc
// What Tor Exit nodes are in a given country?
// *** Variables start
let CountriesOfInterest = dynamic(['FR', 'ZA']); //France and South Africa
// *** Variabled end
let TorExitNodes = (externaldata (IpAddress:string, Source:string, Description:string)
['https://firewalliplists.gypthecat.com/lists/kusto/kusto-tor-exit.csv.zip']
with (ignoreFirstRecord=true));
let CIDRRanges = (externaldata (CIDRCountry:string, CIDR:string, CIDRSource:string) //Table containing CIDR to ISO Country codes
['https://firewalliplists.gypthecat.com/lists/kusto/kusto-cidr-countries-simple.csv.zip']
with (ignoreFirstRecord=true));
TorExitNodes
| evaluate ipv4_lookup(CIDRRanges, IpAddress, CIDR, return_unmatched=true)
| where CIDRCountry in (CountriesOfInterest)
| order by parse_ipv4(IpAddress) asc
// What countries have the most Tor exit nodes?
let TorExitNodes = (externaldata (IpAddress:string, Source:string, Description:string)
['https://firewalliplists.gypthecat.com/lists/kusto/kusto-tor-exit.csv.zip']
with (ignoreFirstRecord=true));
let CIDRRanges = (externaldata (CIDRCountry:string, CIDR:string, CIDRCountryName:string, CIDRContinent:string, CIDRContinentName:string, CIDRSource:string)
['https://firewalliplists.gypthecat.com/lists/kusto/kusto-cidr-countries.csv.zip']
with (ignoreFirstRecord=true));
TorExitNodes
| evaluate ipv4_lookup(CIDRRanges, IpAddress, CIDR, return_unmatched=true)
| summarize NumberOfExitNodes = array_length(make_set(IpAddress)), ExitNodes = make_set(IpAddress) by CIDRCountryName
| order by NumberOfExitNodes desc
MDE Example
let TorExitNodes = externaldata (IpAddress:string, Source:string, Description:string) ['https://firewalliplists.gypthecat.com/lists/kusto/kusto-tor-exit.csv.zip'] with (ignoreFirstRecord=true);
DeviceLogonEvents
| where RemoteIPType != 'Private'
| where ActionType == 'LogonSuccess'
| evaluate ipv4_lookup(TorExitNodes, RemoteIP, IpAddress, return_unmatched=false)
Sentinel & Azure Log Analytics Example
Coming soon.