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.