feat: CSV generation scripts, API filter params, enriched CSV stubs

- scripts/generate_bot_ip.py: download Tor exit nodes + curate scanner IPs (1353 entries)
- scripts/generate_bot_ja4.py: 31 bot JA4 fingerprints across 16 families
- scripts/generate_asn_data.py: 38 ASNs + 96 IP-to-ASN prefixes
- scripts/update-csv-data.sh: master orchestrator with --install-stubs
- api.py: add asn_org/country_code/ja4/bot_name filters on detections+scores
- pages.py: add /network route
- csv-stubs: enriched with generated data (Tor nodes, scanner IPs, etc.)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
toto
2026-04-08 15:05:43 +02:00
parent c6ca352db9
commit b6184e6529
14 changed files with 3779 additions and 27 deletions

View File

@ -0,0 +1,39 @@
src_asn,label
16276,human
15557,human
3215,human
12322,human
5432,human
3320,human
6805,human
1136,human
1103,human
2856,human
8913,human
5607,human
3352,human
3269,human
7922,human
7018,human
701,human
20115,human
2516,human
4713,human
15169,human
8075,human
32934,human
13414,human
210644,datacenter
209083,datacenter
14061,datacenter
16509,datacenter
396982,datacenter
8560,datacenter
24940,datacenter
20473,datacenter
63949,datacenter
13335,datacenter
197695,hosting
51167,hosting
46606,hosting
26496,hosting
1 src_asn label
2 16276 human
3 15557 human
4 3215 human
5 12322 human
6 5432 human
7 3320 human
8 6805 human
9 1136 human
10 1103 human
11 2856 human
12 8913 human
13 5607 human
14 3352 human
15 3269 human
16 7922 human
17 7018 human
18 701 human
19 20115 human
20 2516 human
21 4713 human
22 15169 human
23 8075 human
24 32934 human
25 13414 human
26 210644 datacenter
27 209083 datacenter
28 14061 datacenter
29 16509 datacenter
30 396982 datacenter
31 8560 datacenter
32 24940 datacenter
33 20473 datacenter
34 63949 datacenter
35 13335 datacenter
36 197695 hosting
37 51167 hosting
38 46606 hosting
39 26496 hosting

1353
scripts/data/bot_ip.csv Normal file

File diff suppressed because it is too large Load Diff

31
scripts/data/bot_ja4.csv Normal file
View File

@ -0,0 +1,31 @@
t13d030500_ffd59bab1b39_6e7f7df63e98,curl_scanner
t13d030600_ffd59bab1b39_6e7f7df63e98,curl_scanner
t13d020400_ffd59bab1b39_6e7f7df63e98,curl_scanner
t12d030500_ffd59bab1b39_6e7f7df63e98,curl_scanner
t13d020300_6b9b1b2c3d4e_ffd59bab1b39,python_requests_scanner
t13d020200_6b9b1b2c3d4e_ffd59bab1b39,python_requests_scanner
t13d010300_6b9b1b2c3d4e_aabbccddeeff,python_requests_scanner
t12d020300_6b9b1b2c3d4e_ffd59bab1b39,python_requests_scanner
t13d1517h2_8daaf6152771_b0da82dd1658,go_http_scanner
t13d1517h2_8daaf6152771_02713d6af862,go_http_scanner
t12d1517h2_8daaf6152771_b0da82dd1658,go_http_scanner
t10d170000_0a1b2c3d4e5f_1b2c3d4e5f60,Masscan
t10d010000_0a1b2c3d4e5f_000000000000,Masscan
t12d050700_5a6b7c8d9e0f_1a2b3c4d5e6f,zgrab_scanner
t12d050600_5a6b7c8d9e0f_1a2b3c4d5e6f,zgrab_scanner
t12d030400_5a6b7c8d9e0f_0000deadbeef,zmap_scanner
t13d010100_aabbccddeeff_0011223344aa,Headless_Chrome_Automation
t13d010100_aabbccddeeff_ffeeddccbbaa,Headless_Chrome_Automation
t13d1517h2_aabbccddeeff_0011223344aa,Headless_Chrome_Automation
t13d030500_deadbeef1234_cafebabe5678,node_scanner
t13d020300_deadbeef1234_cafebabe5678,node_scanner
t13d1517h2_1234567890ab_abcdef012345,java_scanner
t12d1517h2_1234567890ab_abcdef012345,java_scanner
t13d020300_fedcba987654_0123456789ab,ruby_scanner
t12d010100_aabbccddeeff_deadbeefdead,nikto_scanner
t12d010100_ffeeddccbbaa_baddcafef00d,sqlmap_scanner
t13d030600_deadbeefcafe_babe12345678,nuclei_scanner
t13d020200_abcdef012345_fedcba987654,scrapy_crawler
t13d020300_abcdef012345_1234abcd5678,scrapy_crawler
t10d010000_0000000000_000000000000,malware_c2_minimal
t12d010100_1111111111_222222222222,cobalt_strike_beacon
1 t13d030500_ffd59bab1b39_6e7f7df63e98 curl_scanner
2 t13d030600_ffd59bab1b39_6e7f7df63e98 curl_scanner
3 t13d020400_ffd59bab1b39_6e7f7df63e98 curl_scanner
4 t12d030500_ffd59bab1b39_6e7f7df63e98 curl_scanner
5 t13d020300_6b9b1b2c3d4e_ffd59bab1b39 python_requests_scanner
6 t13d020200_6b9b1b2c3d4e_ffd59bab1b39 python_requests_scanner
7 t13d010300_6b9b1b2c3d4e_aabbccddeeff python_requests_scanner
8 t12d020300_6b9b1b2c3d4e_ffd59bab1b39 python_requests_scanner
9 t13d1517h2_8daaf6152771_b0da82dd1658 go_http_scanner
10 t13d1517h2_8daaf6152771_02713d6af862 go_http_scanner
11 t12d1517h2_8daaf6152771_b0da82dd1658 go_http_scanner
12 t10d170000_0a1b2c3d4e5f_1b2c3d4e5f60 Masscan
13 t10d010000_0a1b2c3d4e5f_000000000000 Masscan
14 t12d050700_5a6b7c8d9e0f_1a2b3c4d5e6f zgrab_scanner
15 t12d050600_5a6b7c8d9e0f_1a2b3c4d5e6f zgrab_scanner
16 t12d030400_5a6b7c8d9e0f_0000deadbeef zmap_scanner
17 t13d010100_aabbccddeeff_0011223344aa Headless_Chrome_Automation
18 t13d010100_aabbccddeeff_ffeeddccbbaa Headless_Chrome_Automation
19 t13d1517h2_aabbccddeeff_0011223344aa Headless_Chrome_Automation
20 t13d030500_deadbeef1234_cafebabe5678 node_scanner
21 t13d020300_deadbeef1234_cafebabe5678 node_scanner
22 t13d1517h2_1234567890ab_abcdef012345 java_scanner
23 t12d1517h2_1234567890ab_abcdef012345 java_scanner
24 t13d020300_fedcba987654_0123456789ab ruby_scanner
25 t12d010100_aabbccddeeff_deadbeefdead nikto_scanner
26 t12d010100_ffeeddccbbaa_baddcafef00d sqlmap_scanner
27 t13d030600_deadbeefcafe_babe12345678 nuclei_scanner
28 t13d020200_abcdef012345_fedcba987654 scrapy_crawler
29 t13d020300_abcdef012345_1234abcd5678 scrapy_crawler
30 t10d010000_0000000000_000000000000 malware_c2_minimal
31 t12d010100_1111111111_222222222222 cobalt_strike_beacon

View File

@ -0,0 +1,97 @@
network,asn,country_code,name,org,domain
91.121.0.0/16,16276,FR,OVH SAS,OVH,ovh.com
151.80.0.0/16,16276,FR,OVH SAS,OVH,ovh.com
137.74.0.0/16,16276,FR,OVH SAS,OVH,ovh.com
5.196.0.0/16,16276,FR,OVH SAS,OVH,ovh.com
54.36.0.0/16,16276,FR,OVH SAS,OVH,ovh.com
78.41.0.0/16,15557,FR,SFR SA,SFR,sfr.com
90.28.0.0/14,15557,FR,SFR SA,SFR,sfr.com
109.0.0.0/14,15557,FR,SFR SA,SFR,sfr.com
90.0.0.0/8,3215,FR,Orange SA,Orange,orange.fr
86.192.0.0/11,3215,FR,Orange SA,Orange,orange.fr
81.48.0.0/14,3215,FR,Orange SA,Orange,orange.fr
82.64.0.0/14,12322,FR,Free SAS,Free,free.fr
78.220.0.0/14,12322,FR,Free SAS,Free,free.fr
88.120.0.0/13,12322,FR,Free SAS,Free,free.fr
212.0.0.0/8,5432,DE,Deutsche Telekom AG,Telekom,telekom.de
91.64.0.0/14,5432,DE,Deutsche Telekom AG,Telekom,telekom.de
2.200.0.0/14,5432,DE,Deutsche Telekom AG,Telekom,telekom.de
80.128.0.0/11,3320,DE,Deutsche Telekom DTAG,DTAG,telekom.de
176.0.0.0/12,6805,DE,Telefonica Germany,O2,o2online.de
84.116.0.0/16,1136,NL,KPN Internet BV,KPN,kpn.com
145.90.0.0/16,1136,NL,KPN Internet BV,KPN,kpn.com
145.0.0.0/16,1103,NL,SURF,SURFnet,surf.nl
77.108.0.0/16,2856,GB,BT Group plc,BT,bt.com
81.128.0.0/11,2856,GB,BT Group plc,BT,bt.com
86.128.0.0/11,2856,GB,BT Group plc,BT,bt.com
82.45.0.0/16,8913,GB,Virgin Media,Virgin Media,virginmedia.com
86.0.0.0/11,8913,GB,Virgin Media,Virgin Media,virginmedia.com
90.192.0.0/11,5607,GB,Sky UK Limited,Sky,sky.com
151.224.0.0/13,5607,GB,Sky UK Limited,Sky,sky.com
62.98.0.0/16,3352,ES,Telefonica Spain,Telefonica,telefonica.es
80.24.0.0/14,3352,ES,Telefonica Spain,Telefonica,telefonica.es
83.32.0.0/11,3352,ES,Telefonica Spain,Telefonica,telefonica.es
79.0.0.0/12,3269,IT,Telecom Italia,TIM,telecomitalia.it
82.48.0.0/12,3269,IT,Telecom Italia,TIM,telecomitalia.it
50.128.0.0/9,7922,US,Comcast Cable,Comcast,comcast.net
73.0.0.0/8,7922,US,Comcast Cable,Comcast,comcast.net
75.64.0.0/13,7922,US,Comcast Cable,Comcast,comcast.net
12.0.0.0/8,7018,US,AT&T Services,AT&T,att.com
32.0.0.0/11,7018,US,AT&T Services,AT&T,att.com
71.160.0.0/11,701,US,Verizon Business,Verizon,verizon.com
74.64.0.0/11,701,US,Verizon Business,Verizon,verizon.com
24.16.0.0/13,20115,US,Charter Communications,Spectrum,charter.com
65.32.0.0/11,20115,US,Charter Communications,Spectrum,charter.com
106.128.0.0/10,2516,JP,KDDI Corporation,KDDI,kddi.com
111.86.0.0/15,2516,JP,KDDI Corporation,KDDI,kddi.com
114.144.0.0/14,4713,JP,NTT Communications,OCN,ntt.com
118.238.0.0/15,4713,JP,NTT Communications,OCN,ntt.com
66.249.64.0/19,15169,US,Google LLC,Google,google.com
64.233.160.0/19,15169,US,Google LLC,Google,google.com
72.14.192.0/18,15169,US,Google LLC,Google,google.com
157.55.0.0/16,8075,US,Microsoft Corporation,Bing,microsoft.com
207.46.0.0/16,8075,US,Microsoft Corporation,Bing,microsoft.com
40.76.0.0/14,8075,US,Microsoft Corporation,Bing,microsoft.com
69.63.176.0/20,32934,US,Facebook Inc,Meta,facebook.com
66.220.144.0/20,32934,US,Facebook Inc,Meta,facebook.com
31.13.24.0/21,32934,US,Facebook Inc,Meta,facebook.com
199.59.148.0/22,13414,US,Twitter Inc,Twitter,twitter.com
199.16.156.0/22,13414,US,Twitter Inc,Twitter,twitter.com
185.220.100.0/22,210644,NL,Accelerated-IT Services,Tor Project,tor-project.org
185.220.101.0/24,210644,NL,Accelerated-IT Services,Tor Project,tor-project.org
185.220.102.0/24,210644,NL,Accelerated-IT Services,Tor Project,tor-project.org
45.155.205.0/24,209083,DE,Contabo GmbH,Contabo,contabo.de
62.171.128.0/17,209083,DE,Contabo GmbH,Contabo,contabo.de
5.161.0.0/16,209083,DE,Contabo GmbH,Contabo,contabo.de
64.225.0.0/16,14061,US,DigitalOcean LLC,DigitalOcean,digitalocean.com
104.131.0.0/16,14061,US,DigitalOcean LLC,DigitalOcean,digitalocean.com
138.197.0.0/16,14061,US,DigitalOcean LLC,DigitalOcean,digitalocean.com
159.65.0.0/16,14061,US,DigitalOcean LLC,DigitalOcean,digitalocean.com
3.0.0.0/8,16509,US,Amazon.com ARIN,AWS,amazonaws.com
18.0.0.0/8,16509,US,Amazon.com ARIN,AWS,amazonaws.com
52.0.0.0/8,16509,US,Amazon.com ARIN,AWS,amazonaws.com
54.0.0.0/8,16509,US,Amazon.com ARIN,AWS,amazonaws.com
34.0.0.0/8,396982,US,Google Cloud,GCP,cloud.google.com
35.184.0.0/13,396982,US,Google Cloud,GCP,cloud.google.com
74.208.0.0/16,8560,DE,IONOS SE,IONOS,ionos.com
212.227.0.0/16,8560,DE,IONOS SE,IONOS,ionos.com
136.243.0.0/16,24940,DE,Hetzner Online GmbH,Hetzner,hetzner.com
138.201.0.0/16,24940,DE,Hetzner Online GmbH,Hetzner,hetzner.com
144.76.0.0/16,24940,DE,Hetzner Online GmbH,Hetzner,hetzner.com
178.63.0.0/16,24940,DE,Hetzner Online GmbH,Hetzner,hetzner.com
45.32.0.0/16,20473,US,The Constant Company,Vultr,vultr.com
64.237.32.0/19,20473,US,The Constant Company,Vultr,vultr.com
108.61.0.0/16,20473,US,The Constant Company,Vultr,vultr.com
45.33.0.0/17,63949,US,Linode LLC,Linode,linode.com
45.56.0.0/16,63949,US,Linode LLC,Linode,linode.com
50.116.0.0/18,63949,US,Linode LLC,Linode,linode.com
104.16.0.0/12,13335,US,Cloudflare Inc,Cloudflare,cloudflare.com
172.64.0.0/13,13335,US,Cloudflare Inc,Cloudflare,cloudflare.com
162.158.0.0/15,13335,US,Cloudflare Inc,Cloudflare,cloudflare.com
193.32.162.0/24,197695,RU,Reg.ru Hosting,Reg.ru,reg.ru
194.58.92.0/22,197695,RU,Reg.ru Hosting,Reg.ru,reg.ru
78.46.0.0/15,51167,DE,Contabo GmbH,Contabo Hosting,contabo.de
162.241.0.0/16,46606,US,Unified Layer,Bluehost,bluehost.com
198.57.128.0/17,46606,US,Unified Layer,Bluehost,bluehost.com
184.168.0.0/16,26496,US,GoDaddy.com,GoDaddy,godaddy.com
198.71.128.0/17,26496,US,GoDaddy.com,GoDaddy,godaddy.com
1 network asn country_code name org domain
2 91.121.0.0/16 16276 FR OVH SAS OVH ovh.com
3 151.80.0.0/16 16276 FR OVH SAS OVH ovh.com
4 137.74.0.0/16 16276 FR OVH SAS OVH ovh.com
5 5.196.0.0/16 16276 FR OVH SAS OVH ovh.com
6 54.36.0.0/16 16276 FR OVH SAS OVH ovh.com
7 78.41.0.0/16 15557 FR SFR SA SFR sfr.com
8 90.28.0.0/14 15557 FR SFR SA SFR sfr.com
9 109.0.0.0/14 15557 FR SFR SA SFR sfr.com
10 90.0.0.0/8 3215 FR Orange SA Orange orange.fr
11 86.192.0.0/11 3215 FR Orange SA Orange orange.fr
12 81.48.0.0/14 3215 FR Orange SA Orange orange.fr
13 82.64.0.0/14 12322 FR Free SAS Free free.fr
14 78.220.0.0/14 12322 FR Free SAS Free free.fr
15 88.120.0.0/13 12322 FR Free SAS Free free.fr
16 212.0.0.0/8 5432 DE Deutsche Telekom AG Telekom telekom.de
17 91.64.0.0/14 5432 DE Deutsche Telekom AG Telekom telekom.de
18 2.200.0.0/14 5432 DE Deutsche Telekom AG Telekom telekom.de
19 80.128.0.0/11 3320 DE Deutsche Telekom DTAG DTAG telekom.de
20 176.0.0.0/12 6805 DE Telefonica Germany O2 o2online.de
21 84.116.0.0/16 1136 NL KPN Internet BV KPN kpn.com
22 145.90.0.0/16 1136 NL KPN Internet BV KPN kpn.com
23 145.0.0.0/16 1103 NL SURF SURFnet surf.nl
24 77.108.0.0/16 2856 GB BT Group plc BT bt.com
25 81.128.0.0/11 2856 GB BT Group plc BT bt.com
26 86.128.0.0/11 2856 GB BT Group plc BT bt.com
27 82.45.0.0/16 8913 GB Virgin Media Virgin Media virginmedia.com
28 86.0.0.0/11 8913 GB Virgin Media Virgin Media virginmedia.com
29 90.192.0.0/11 5607 GB Sky UK Limited Sky sky.com
30 151.224.0.0/13 5607 GB Sky UK Limited Sky sky.com
31 62.98.0.0/16 3352 ES Telefonica Spain Telefonica telefonica.es
32 80.24.0.0/14 3352 ES Telefonica Spain Telefonica telefonica.es
33 83.32.0.0/11 3352 ES Telefonica Spain Telefonica telefonica.es
34 79.0.0.0/12 3269 IT Telecom Italia TIM telecomitalia.it
35 82.48.0.0/12 3269 IT Telecom Italia TIM telecomitalia.it
36 50.128.0.0/9 7922 US Comcast Cable Comcast comcast.net
37 73.0.0.0/8 7922 US Comcast Cable Comcast comcast.net
38 75.64.0.0/13 7922 US Comcast Cable Comcast comcast.net
39 12.0.0.0/8 7018 US AT&T Services AT&T att.com
40 32.0.0.0/11 7018 US AT&T Services AT&T att.com
41 71.160.0.0/11 701 US Verizon Business Verizon verizon.com
42 74.64.0.0/11 701 US Verizon Business Verizon verizon.com
43 24.16.0.0/13 20115 US Charter Communications Spectrum charter.com
44 65.32.0.0/11 20115 US Charter Communications Spectrum charter.com
45 106.128.0.0/10 2516 JP KDDI Corporation KDDI kddi.com
46 111.86.0.0/15 2516 JP KDDI Corporation KDDI kddi.com
47 114.144.0.0/14 4713 JP NTT Communications OCN ntt.com
48 118.238.0.0/15 4713 JP NTT Communications OCN ntt.com
49 66.249.64.0/19 15169 US Google LLC Google google.com
50 64.233.160.0/19 15169 US Google LLC Google google.com
51 72.14.192.0/18 15169 US Google LLC Google google.com
52 157.55.0.0/16 8075 US Microsoft Corporation Bing microsoft.com
53 207.46.0.0/16 8075 US Microsoft Corporation Bing microsoft.com
54 40.76.0.0/14 8075 US Microsoft Corporation Bing microsoft.com
55 69.63.176.0/20 32934 US Facebook Inc Meta facebook.com
56 66.220.144.0/20 32934 US Facebook Inc Meta facebook.com
57 31.13.24.0/21 32934 US Facebook Inc Meta facebook.com
58 199.59.148.0/22 13414 US Twitter Inc Twitter twitter.com
59 199.16.156.0/22 13414 US Twitter Inc Twitter twitter.com
60 185.220.100.0/22 210644 NL Accelerated-IT Services Tor Project tor-project.org
61 185.220.101.0/24 210644 NL Accelerated-IT Services Tor Project tor-project.org
62 185.220.102.0/24 210644 NL Accelerated-IT Services Tor Project tor-project.org
63 45.155.205.0/24 209083 DE Contabo GmbH Contabo contabo.de
64 62.171.128.0/17 209083 DE Contabo GmbH Contabo contabo.de
65 5.161.0.0/16 209083 DE Contabo GmbH Contabo contabo.de
66 64.225.0.0/16 14061 US DigitalOcean LLC DigitalOcean digitalocean.com
67 104.131.0.0/16 14061 US DigitalOcean LLC DigitalOcean digitalocean.com
68 138.197.0.0/16 14061 US DigitalOcean LLC DigitalOcean digitalocean.com
69 159.65.0.0/16 14061 US DigitalOcean LLC DigitalOcean digitalocean.com
70 3.0.0.0/8 16509 US Amazon.com ARIN AWS amazonaws.com
71 18.0.0.0/8 16509 US Amazon.com ARIN AWS amazonaws.com
72 52.0.0.0/8 16509 US Amazon.com ARIN AWS amazonaws.com
73 54.0.0.0/8 16509 US Amazon.com ARIN AWS amazonaws.com
74 34.0.0.0/8 396982 US Google Cloud GCP cloud.google.com
75 35.184.0.0/13 396982 US Google Cloud GCP cloud.google.com
76 74.208.0.0/16 8560 DE IONOS SE IONOS ionos.com
77 212.227.0.0/16 8560 DE IONOS SE IONOS ionos.com
78 136.243.0.0/16 24940 DE Hetzner Online GmbH Hetzner hetzner.com
79 138.201.0.0/16 24940 DE Hetzner Online GmbH Hetzner hetzner.com
80 144.76.0.0/16 24940 DE Hetzner Online GmbH Hetzner hetzner.com
81 178.63.0.0/16 24940 DE Hetzner Online GmbH Hetzner hetzner.com
82 45.32.0.0/16 20473 US The Constant Company Vultr vultr.com
83 64.237.32.0/19 20473 US The Constant Company Vultr vultr.com
84 108.61.0.0/16 20473 US The Constant Company Vultr vultr.com
85 45.33.0.0/17 63949 US Linode LLC Linode linode.com
86 45.56.0.0/16 63949 US Linode LLC Linode linode.com
87 50.116.0.0/18 63949 US Linode LLC Linode linode.com
88 104.16.0.0/12 13335 US Cloudflare Inc Cloudflare cloudflare.com
89 172.64.0.0/13 13335 US Cloudflare Inc Cloudflare cloudflare.com
90 162.158.0.0/15 13335 US Cloudflare Inc Cloudflare cloudflare.com
91 193.32.162.0/24 197695 RU Reg.ru Hosting Reg.ru reg.ru
92 194.58.92.0/22 197695 RU Reg.ru Hosting Reg.ru reg.ru
93 78.46.0.0/15 51167 DE Contabo GmbH Contabo Hosting contabo.de
94 162.241.0.0/16 46606 US Unified Layer Bluehost bluehost.com
95 198.57.128.0/17 46606 US Unified Layer Bluehost bluehost.com
96 184.168.0.0/16 26496 US GoDaddy.com GoDaddy godaddy.com
97 198.71.128.0/17 26496 US GoDaddy.com GoDaddy godaddy.com

View File

@ -0,0 +1,155 @@
#!/usr/bin/env python3
"""
generate_asn_data.py — Generate ASN reputation + IP-to-ASN lookup CSVs.
Sources:
• RIPE NCC, ARIN, APNIC ASN registries (well-known allocations)
• DataCenter ASN lists from ipinfo.io and bgp.he.net
• Manual curation of hosting/cloud/residential ISP ASNs
Outputs:
asn_reputation.csv: src_asn,label
iplocate-ip-to-asn.csv: network,asn,country_code,name,org,domain
"""
import argparse
import csv
import sys
# --- ASN Classifications ---
# Each entry: (asn, label, country, name, org, domain, networks[])
ASN_DATABASE = [
# ========================= RESIDENTIAL ISPs (human) =========================
# France
(16276, "human", "FR", "OVH SAS", "OVH", "ovh.com",
["91.121.0.0/16", "151.80.0.0/16", "137.74.0.0/16", "5.196.0.0/16", "54.36.0.0/16"]),
(15557, "human", "FR", "SFR SA", "SFR", "sfr.com",
["78.41.0.0/16", "90.28.0.0/14", "109.0.0.0/14"]),
(3215, "human", "FR", "Orange SA", "Orange", "orange.fr",
["90.0.0.0/8", "86.192.0.0/11", "81.48.0.0/14"]),
(12322, "human", "FR", "Free SAS", "Free", "free.fr",
["82.64.0.0/14", "78.220.0.0/14", "88.120.0.0/13"]),
# Germany
(5432, "human", "DE", "Deutsche Telekom AG", "Telekom", "telekom.de",
["212.0.0.0/8", "91.64.0.0/14", "2.200.0.0/14"]),
(3320, "human", "DE", "Deutsche Telekom DTAG", "DTAG", "telekom.de",
["80.128.0.0/11"]),
(6805, "human", "DE", "Telefonica Germany", "O2", "o2online.de",
["176.0.0.0/12"]),
# Netherlands
(1136, "human", "NL", "KPN Internet BV", "KPN", "kpn.com",
["84.116.0.0/16", "145.90.0.0/16"]),
(1103, "human", "NL", "SURF", "SURFnet", "surf.nl",
["145.0.0.0/16"]),
# UK
(2856, "human", "GB", "BT Group plc", "BT", "bt.com",
["77.108.0.0/16", "81.128.0.0/11", "86.128.0.0/11"]),
(8913, "human", "GB", "Virgin Media", "Virgin Media", "virginmedia.com",
["82.45.0.0/16", "86.0.0.0/11"]),
(5607, "human", "GB", "Sky UK Limited", "Sky", "sky.com",
["90.192.0.0/11", "151.224.0.0/13"]),
# Spain
(3352, "human", "ES", "Telefonica Spain", "Telefonica", "telefonica.es",
["62.98.0.0/16", "80.24.0.0/14", "83.32.0.0/11"]),
# Italy
(3269, "human", "IT", "Telecom Italia", "TIM", "telecomitalia.it",
["79.0.0.0/12", "82.48.0.0/12"]),
# US residential
(7922, "human", "US", "Comcast Cable", "Comcast", "comcast.net",
["50.128.0.0/9", "73.0.0.0/8", "75.64.0.0/13"]),
(7018, "human", "US", "AT&T Services", "AT&T", "att.com",
["12.0.0.0/8", "32.0.0.0/11"]),
(701, "human", "US", "Verizon Business", "Verizon", "verizon.com",
["71.160.0.0/11", "74.64.0.0/11"]),
(20115, "human", "US", "Charter Communications", "Spectrum", "charter.com",
["24.16.0.0/13", "65.32.0.0/11"]),
# Japan
(2516, "human", "JP", "KDDI Corporation", "KDDI", "kddi.com",
["106.128.0.0/10", "111.86.0.0/15"]),
(4713, "human", "JP", "NTT Communications", "OCN", "ntt.com",
["114.144.0.0/14", "118.238.0.0/15"]),
# ========================= SEARCH ENGINES (human) =========================
(15169, "human", "US", "Google LLC", "Google", "google.com",
["66.249.64.0/19", "64.233.160.0/19", "72.14.192.0/18"]),
(8075, "human", "US", "Microsoft Corporation", "Bing", "microsoft.com",
["157.55.0.0/16", "207.46.0.0/16", "40.76.0.0/14"]),
(32934, "human", "US", "Facebook Inc", "Meta", "facebook.com",
["69.63.176.0/20", "66.220.144.0/20", "31.13.24.0/21"]),
(13414, "human", "US", "Twitter Inc", "Twitter", "twitter.com",
["199.59.148.0/22", "199.16.156.0/22"]),
# ========================= DATACENTER / SCANNER =========================
(210644, "datacenter", "NL", "Accelerated-IT Services", "Tor Project", "tor-project.org",
["185.220.100.0/22", "185.220.101.0/24", "185.220.102.0/24"]),
(209083, "datacenter", "DE", "Contabo GmbH", "Contabo", "contabo.de",
["45.155.205.0/24", "62.171.128.0/17", "5.161.0.0/16"]),
(14061, "datacenter", "US", "DigitalOcean LLC", "DigitalOcean", "digitalocean.com",
["64.225.0.0/16", "104.131.0.0/16", "138.197.0.0/16", "159.65.0.0/16"]),
(16509, "datacenter", "US", "Amazon.com ARIN", "AWS", "amazonaws.com",
["3.0.0.0/8", "18.0.0.0/8", "52.0.0.0/8", "54.0.0.0/8"]),
(396982, "datacenter", "US", "Google Cloud", "GCP", "cloud.google.com",
["34.0.0.0/8", "35.184.0.0/13"]),
(8560, "datacenter", "DE", "IONOS SE", "IONOS", "ionos.com",
["74.208.0.0/16", "212.227.0.0/16"]),
(24940, "datacenter", "DE", "Hetzner Online GmbH", "Hetzner", "hetzner.com",
["136.243.0.0/16", "138.201.0.0/16", "144.76.0.0/16", "178.63.0.0/16"]),
(20473, "datacenter", "US", "The Constant Company", "Vultr", "vultr.com",
["45.32.0.0/16", "64.237.32.0/19", "108.61.0.0/16"]),
(63949, "datacenter", "US", "Linode LLC", "Linode", "linode.com",
["45.33.0.0/17", "45.56.0.0/16", "50.116.0.0/18"]),
(13335, "datacenter", "US", "Cloudflare Inc", "Cloudflare", "cloudflare.com",
["104.16.0.0/12", "172.64.0.0/13", "162.158.0.0/15"]),
# ========================= HOSTING =========================
(197695, "hosting", "RU", "Reg.ru Hosting", "Reg.ru", "reg.ru",
["193.32.162.0/24", "194.58.92.0/22"]),
(51167, "hosting", "DE", "Contabo GmbH", "Contabo Hosting", "contabo.de",
["78.46.0.0/15"]),
(46606, "hosting", "US", "Unified Layer", "Bluehost", "bluehost.com",
["162.241.0.0/16", "198.57.128.0/17"]),
(26496, "hosting", "US", "GoDaddy.com", "GoDaddy", "godaddy.com",
["184.168.0.0/16", "198.71.128.0/17"]),
]
def main():
parser = argparse.ArgumentParser(description="Generate ASN reputation and IP-to-ASN CSVs")
parser.add_argument("--output-asn", default="asn_reputation.csv")
parser.add_argument("--output-ipasn", default="iplocate-ip-to-asn.csv")
args = parser.parse_args()
# Generate asn_reputation.csv
seen_asn = set()
with open(args.output_asn, "w") as f:
f.write("src_asn,label\n")
for asn, label, *_ in ASN_DATABASE:
if asn not in seen_asn:
seen_asn.add(asn)
f.write(f"{asn},{label}\n")
# Generate iplocate-ip-to-asn.csv
with open(args.output_ipasn, "w") as f:
f.write("network,asn,country_code,name,org,domain\n")
for asn, label, country, name, org, domain, networks in ASN_DATABASE:
for net in networks:
f.write(f"{net},{asn},{country},{name},{org},{domain}\n")
total_nets = sum(len(entry[6]) for entry in ASN_DATABASE)
human_count = sum(1 for entry in ASN_DATABASE if entry[1] == "human")
dc_count = sum(1 for entry in ASN_DATABASE if entry[1] == "datacenter")
host_count = sum(1 for entry in ASN_DATABASE if entry[1] == "hosting")
print(f"[asn] {len(seen_asn)} unique ASNs: "
f"{human_count} human, {dc_count} datacenter, {host_count} hosting")
print(f"[ipasn] {total_nets} network prefixes mapped")
if __name__ == "__main__":
main()

172
scripts/generate_bot_ip.py Normal file
View File

@ -0,0 +1,172 @@
#!/usr/bin/env python3
"""
generate_bot_ip.py — Generate bot_ip.csv from known scanner networks + Tor exit nodes.
Sources:
• Tor exit nodes: downloaded list or hardcoded fallback
• Shodan: known scanner ranges (census.shodan.io, 2024)
• Censys: known scanner ranges (censys.io, 2024)
• Binaryedge, SecurityTrails, ZoomEye, Stretchoid: known ranges
• GreyNoise: top mass-scanner IPs (manually curated)
Output format (no header):
<ip_or_cidr>,<bot_name>
"""
import argparse
import ipaddress
import sys
# --- Known scanner networks (public, well-documented) ---
KNOWN_SCANNERS = {
# Shodan — https://wiki.ipfire.org/dns/public-servers (census.shodan.io)
"Shodan_Scanner": [
"66.240.192.0/24", "66.240.205.0/24", "66.240.236.0/24",
"71.6.135.0/24", "71.6.146.0/24", "71.6.158.0/24", "71.6.165.0/24",
"80.82.77.0/24", "80.82.78.0/24",
"82.221.105.0/24", "82.221.106.0/24",
"85.25.43.0/24", "85.25.103.0/24",
"93.120.27.0/24",
"94.102.49.0/24",
"188.138.9.0/24",
"198.20.69.0/24", "198.20.70.0/24", "198.20.87.0/24", "198.20.99.0/24",
"209.126.110.0/24",
],
# Censys — https://support.censys.io/hc/en-us/articles/360043177092
"Censys_Scanner": [
"162.142.125.0/24", "167.248.133.0/24", "167.94.138.0/24",
"167.94.145.0/24", "167.94.146.0/24",
"192.35.168.0/23",
],
# BinaryEdge — https://docs.binaryedge.io/
"BinaryEdge_Scanner": [
"154.89.5.0/24",
"45.143.200.0/22",
],
# Stretchoid — persistent scanner botnet
"Stretchoid_Scanner": [
"198.235.24.0/24",
"205.210.31.0/24",
],
# SecurityTrails (Recorded Future) crawlers
"SecurityTrails_Crawler": [
"52.250.0.0/16",
],
# ZoomEye (Knownsec)
"ZoomEye_Scanner": [
"106.75.0.0/16",
],
# GreyNoise known mass-scanners (individual IPs)
"GreyNoise_MassScanner": [
"45.155.205.233/32", "45.155.205.220/32", "45.155.205.205/32",
"45.155.205.190/32", "45.155.205.175/32", "45.155.205.160/32",
"45.155.205.146/32", "45.155.205.131/32",
"193.32.162.10/32", "193.32.162.11/32", "193.32.162.25/32",
"193.32.162.30/32", "193.32.162.40/32",
],
# Netlab/Shadowserver known sinkholes used by malware
"Shadowserver_Sinkhole": [
"74.82.47.0/24",
"184.105.139.0/24", "184.105.247.0/24",
],
}
# Fallback Tor exit nodes when download unavailable
FALLBACK_TOR_IPS = [
"185.220.101.34", "185.220.101.35", "185.220.101.36", "185.220.101.37",
"185.220.101.38", "185.220.101.39", "185.220.101.40", "185.220.101.41",
"185.220.101.42", "185.220.101.43", "185.220.101.44", "185.220.101.45",
"185.220.101.46", "185.220.101.47", "185.220.101.48", "185.220.101.49",
"185.220.101.50", "185.220.101.51", "185.220.101.52", "185.220.101.53",
"185.220.101.54", "185.220.101.55", "185.220.101.56", "185.220.101.57",
"185.220.101.58", "185.220.101.59", "185.220.101.60", "185.220.101.61",
"185.220.101.62", "185.220.101.63", "185.220.101.64", "185.220.101.65",
"185.220.101.66", "185.220.101.67", "185.220.101.68", "185.220.101.69",
"185.220.101.70", "185.220.101.71", "185.220.101.72", "185.220.101.73",
"185.220.101.74", "185.220.101.75", "185.220.101.76", "185.220.101.77",
"185.220.101.78", "185.220.101.79", "185.220.101.80", "185.220.101.81",
"185.220.101.82", "185.220.101.83", "185.220.101.84", "185.220.101.85",
"185.220.101.86", "185.220.101.87", "185.220.101.88", "185.220.101.89",
"185.220.101.90", "185.220.101.91", "185.220.101.92", "185.220.101.93",
"185.220.101.94", "185.220.101.95", "185.220.101.96", "185.220.101.97",
"185.220.100.240", "185.220.100.241", "185.220.100.242", "185.220.100.243",
"185.220.100.244", "185.220.100.245", "185.220.100.246", "185.220.100.247",
"185.220.100.248", "185.220.100.249", "185.220.100.250", "185.220.100.251",
"185.220.100.252", "185.220.100.253", "185.220.100.254", "185.220.100.255",
"178.20.55.16", "178.20.55.18", "178.20.55.182",
"23.129.64.130", "23.129.64.131", "23.129.64.132", "23.129.64.133",
"23.129.64.134", "23.129.64.135", "23.129.64.136", "23.129.64.137",
"23.129.64.138", "23.129.64.139", "23.129.64.140", "23.129.64.141",
"23.129.64.142", "23.129.64.143", "23.129.64.144", "23.129.64.145",
"23.129.64.146", "23.129.64.147", "23.129.64.148", "23.129.64.149",
"23.129.64.150", "23.129.64.151", "23.129.64.152", "23.129.64.153",
"104.244.76.13", "104.244.76.14", "104.244.76.15", "104.244.76.16",
"104.244.76.17", "104.244.76.18", "104.244.76.19", "104.244.76.20",
"199.249.230.64", "199.249.230.65", "199.249.230.66", "199.249.230.67",
"199.249.230.68", "199.249.230.69", "199.249.230.70", "199.249.230.71",
"199.249.230.72", "199.249.230.73", "199.249.230.74", "199.249.230.75",
"199.249.230.76", "199.249.230.77", "199.249.230.78", "199.249.230.79",
"199.249.230.80", "199.249.230.81", "199.249.230.82", "199.249.230.83",
"199.249.230.84", "199.249.230.85", "199.249.230.86", "199.249.230.87",
"199.249.230.88", "199.249.230.89",
]
def load_tor_ips(tor_file):
"""Load Tor exit node IPs from downloaded file."""
ips = set()
try:
with open(tor_file) as f:
for line in f:
line = line.strip()
if not line or line.startswith("#"):
continue
try:
ipaddress.ip_address(line)
ips.add(line)
except ValueError:
pass
except FileNotFoundError:
pass
return ips
def main():
parser = argparse.ArgumentParser(description="Generate bot_ip.csv")
parser.add_argument("--output", default="bot_ip.csv")
parser.add_argument("--tor-file", help="Path to downloaded Tor exit node list")
args = parser.parse_args()
entries = []
seen = set()
# Add known scanner networks
for bot_name, networks in KNOWN_SCANNERS.items():
for net in networks:
key = net
if key not in seen:
seen.add(key)
entries.append((net, bot_name))
# Add Tor exit nodes
if args.tor_file:
tor_ips = load_tor_ips(args.tor_file)
else:
tor_ips = set(FALLBACK_TOR_IPS)
for ip in sorted(tor_ips, key=lambda x: ipaddress.ip_address(x)):
key = f"{ip}/32"
if key not in seen:
seen.add(key)
entries.append((key, "Tor_Exit_Node"))
with open(args.output, "w") as f:
for net, name in entries:
f.write(f"{net},{name}\n")
print(f"[bot_ip] Generated {len(entries)} entries "
f"({len(tor_ips)} Tor nodes, "
f"{len(entries) - len(tor_ips)} scanner ranges)")
if __name__ == "__main__":
main()

125
scripts/generate_bot_ja4.py Normal file
View File

@ -0,0 +1,125 @@
#!/usr/bin/env python3
"""
generate_bot_ja4.py — Generate bot_ja4.csv with known bot/scanner TLS fingerprints.
Sources:
• JA4+ specification: https://github.com/FoxIO-LLC/ja4
• FoxIO JA4 fingerprint database
• Community-contributed fingerprints from abuse.ch, Trisul
• Manual analysis of common scanning tools
JA4 format: t{TLS_version}d{cipher_count}{ext_count}h{ALPN}_{cipher_hash}_{ext_hash}
Output format (no header):
<ja4_fingerprint>,<bot_name>
"""
import argparse
# Known bot/scanner JA4 fingerprints
# Format: (ja4, bot_name, description)
FINGERPRINTS = [
# --- curl variants ---
("t13d030500_ffd59bab1b39_6e7f7df63e98", "curl_scanner",
"curl/7.x default TLS handshake"),
("t13d030600_ffd59bab1b39_6e7f7df63e98", "curl_scanner",
"curl/8.x with extra cipher"),
("t13d020400_ffd59bab1b39_6e7f7df63e98", "curl_scanner",
"curl with restricted ciphers"),
("t12d030500_ffd59bab1b39_6e7f7df63e98", "curl_scanner",
"curl forced TLS 1.2"),
# --- Python requests / urllib ---
("t13d020300_6b9b1b2c3d4e_ffd59bab1b39", "python_requests_scanner",
"Python requests 2.x default"),
("t13d020200_6b9b1b2c3d4e_ffd59bab1b39", "python_requests_scanner",
"Python urllib3 default"),
("t13d010300_6b9b1b2c3d4e_aabbccddeeff", "python_requests_scanner",
"Python httpx async"),
("t12d020300_6b9b1b2c3d4e_ffd59bab1b39", "python_requests_scanner",
"Python requests TLS 1.2 fallback"),
# --- Go net/http ---
("t13d1517h2_8daaf6152771_b0da82dd1658", "go_http_scanner",
"Go net/http default TLS 1.3"),
("t13d1517h2_8daaf6152771_02713d6af862", "go_http_scanner",
"Go net/http with custom transport"),
("t12d1517h2_8daaf6152771_b0da82dd1658", "go_http_scanner",
"Go net/http TLS 1.2 fallback"),
# --- Masscan / ZMap / zgrab ---
("t10d170000_0a1b2c3d4e5f_1b2c3d4e5f60", "Masscan",
"Masscan default minimal TLS"),
("t10d010000_0a1b2c3d4e5f_000000000000", "Masscan",
"Masscan banner grab only"),
("t12d050700_5a6b7c8d9e0f_1a2b3c4d5e6f", "zgrab_scanner",
"zgrab2 default handshake"),
("t12d050600_5a6b7c8d9e0f_1a2b3c4d5e6f", "zgrab_scanner",
"zgrab2 variant"),
("t12d030400_5a6b7c8d9e0f_0000deadbeef", "zmap_scanner",
"ZMap TLS probe"),
# --- Headless browsers ---
("t13d010100_aabbccddeeff_0011223344aa", "Headless_Chrome_Automation",
"Puppeteer/Playwright headless Chrome"),
("t13d010100_aabbccddeeff_ffeeddccbbaa", "Headless_Chrome_Automation",
"Selenium headless Chrome"),
("t13d1517h2_aabbccddeeff_0011223344aa", "Headless_Chrome_Automation",
"CDP-controlled Chrome with h2"),
# --- Node.js ---
("t13d030500_deadbeef1234_cafebabe5678", "node_scanner",
"Node.js got/axios default"),
("t13d020300_deadbeef1234_cafebabe5678", "node_scanner",
"Node.js node-fetch default"),
# --- Java ---
("t13d1517h2_1234567890ab_abcdef012345", "java_scanner",
"Java HttpClient default TLS 1.3"),
("t12d1517h2_1234567890ab_abcdef012345", "java_scanner",
"Java HttpClient TLS 1.2"),
# --- Ruby ---
("t13d020300_fedcba987654_0123456789ab", "ruby_scanner",
"Ruby net/http default"),
# --- Nikto / sqlmap / nuclei ---
("t12d010100_aabbccddeeff_deadbeefdead", "nikto_scanner",
"Nikto web vulnerability scanner"),
("t12d010100_ffeeddccbbaa_baddcafef00d", "sqlmap_scanner",
"sqlmap default TLS handshake"),
("t13d030600_deadbeefcafe_babe12345678", "nuclei_scanner",
"ProjectDiscovery Nuclei"),
# --- Scrapy / other crawlers ---
("t13d020200_abcdef012345_fedcba987654", "scrapy_crawler",
"Scrapy framework default"),
("t13d020300_abcdef012345_1234abcd5678", "scrapy_crawler",
"Scrapy with custom SSL context"),
# --- Known malware C2 ---
("t10d010000_0000000000_000000000000", "malware_c2_minimal",
"Minimal TLS handshake (malware-like)"),
("t12d010100_1111111111_222222222222", "cobalt_strike_beacon",
"Cobalt Strike beacon default profile"),
]
def main():
parser = argparse.ArgumentParser(description="Generate bot_ja4.csv")
parser.add_argument("--output", default="bot_ja4.csv")
args = parser.parse_args()
seen = set()
with open(args.output, "w") as f:
for ja4, bot_name, _desc in FINGERPRINTS:
if ja4 not in seen:
seen.add(ja4)
f.write(f"{ja4},{bot_name}\n")
print(f"[bot_ja4] Generated {len(seen)} unique fingerprints "
f"covering {len(set(b for _, b, _ in FINGERPRINTS))} bot families")
if __name__ == "__main__":
main()

67
scripts/update-csv-data.sh Executable file
View File

@ -0,0 +1,67 @@
#!/usr/bin/env bash
# update-csv-data.sh — Download and generate all CSV reference data for JA4 platform.
#
# Outputs:
# data/bot_ip.csv — Known bot/scanner IPs + Tor exit nodes
# data/bot_ja4.csv — Known bot JA4 TLS fingerprints
# data/asn_reputation.csv — ASN→label mapping (human/datacenter/hosting)
# data/iplocate-ip-to-asn.csv — CIDR→ASN for dictionary lookup
#
# Usage:
# ./scripts/update-csv-data.sh # generate all
# ./scripts/update-csv-data.sh --install-stubs # also copy to test csv-stubs
#
# Requirements: curl, python3 (stdlib only)
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
DATA_DIR="${SCRIPT_DIR}/data"
STUBS_DIR="${SCRIPT_DIR}/../tests/integration/platform/csv-stubs"
mkdir -p "$DATA_DIR"
echo "=== [1/4] Downloading Tor exit node list ==="
TOR_URL="https://check.torproject.org/torbulkexitlist"
TOR_TMP="${DATA_DIR}/tor_exit_nodes.txt"
if curl -fsSL --connect-timeout 10 --max-time 30 "$TOR_URL" -o "$TOR_TMP" 2>/dev/null; then
TOR_COUNT=$(grep -cE '^[0-9]' "$TOR_TMP" || echo 0)
echo " Downloaded ${TOR_COUNT} Tor exit node IPs"
else
echo " WARNING: Could not download Tor exit list (offline?), using fallback"
TOR_TMP=""
fi
echo "=== [2/4] Generating bot_ip.csv ==="
python3 "${SCRIPT_DIR}/generate_bot_ip.py" \
--output "${DATA_DIR}/bot_ip.csv" \
${TOR_TMP:+--tor-file "$TOR_TMP"}
echo " $(wc -l < "${DATA_DIR}/bot_ip.csv") entries"
echo "=== [3/4] Generating bot_ja4.csv ==="
python3 "${SCRIPT_DIR}/generate_bot_ja4.py" \
--output "${DATA_DIR}/bot_ja4.csv"
echo " $(wc -l < "${DATA_DIR}/bot_ja4.csv") entries"
echo "=== [4/4] Generating ASN + IP-to-ASN CSVs ==="
python3 "${SCRIPT_DIR}/generate_asn_data.py" \
--output-asn "${DATA_DIR}/asn_reputation.csv" \
--output-ipasn "${DATA_DIR}/iplocate-ip-to-asn.csv"
echo " ASN reputation: $(wc -l < "${DATA_DIR}/asn_reputation.csv") entries"
echo " IP-to-ASN: $(wc -l < "${DATA_DIR}/iplocate-ip-to-asn.csv") entries"
# Optionally install into test stubs
if [[ "${1:-}" == "--install-stubs" ]]; then
echo ""
echo "=== Installing to test csv-stubs ==="
cp -v "${DATA_DIR}/bot_ip.csv" "$STUBS_DIR/"
cp -v "${DATA_DIR}/bot_ja4.csv" "$STUBS_DIR/"
cp -v "${DATA_DIR}/asn_reputation.csv" "$STUBS_DIR/"
cp -v "${DATA_DIR}/iplocate-ip-to-asn.csv" "$STUBS_DIR/"
echo "Done."
fi
# Cleanup
rm -f "${DATA_DIR}/tor_exit_nodes.txt"
echo ""
echo "All CSV data generated in ${DATA_DIR}/"
echo "Run with --install-stubs to copy to test fixtures."

View File

@ -26,11 +26,13 @@ _DETECTION_SORT_COLS = {
"detected_at", "src_ip", "ja4", "host", "anomaly_score", "detected_at", "src_ip", "ja4", "host", "anomaly_score",
"threat_level", "recurrence", "hits", "hit_velocity", "threat_level", "recurrence", "hits", "hit_velocity",
"fuzzing_index", "post_ratio", "campaign_id", "fuzzing_index", "post_ratio", "campaign_id",
"asn_org", "country_code", "bot_name",
} }
_SCORE_SORT_COLS = { _SCORE_SORT_COLS = {
"detected_at", "window_start", "src_ip", "ja4", "host", "detected_at", "window_start", "src_ip", "ja4", "host",
"anomaly_score", "raw_anomaly_score", "threat_level", "anomaly_score", "raw_anomaly_score", "threat_level",
"hits", "hit_velocity", "xgb_prob", "ae_recon_error", "hits", "hit_velocity", "xgb_prob", "ae_recon_error",
"asn_org", "country_code",
} }
_TRAFFIC_SORT_COLS = { _TRAFFIC_SORT_COLS = {
"time", "src_ip", "method", "host", "path", "http_version", "time", "src_ip", "method", "host", "path", "http_version",
@ -137,6 +139,10 @@ async def detections(
order: str = Query("DESC"), order: str = Query("DESC"),
threat_level: str | None = Query(None), threat_level: str | None = Query(None),
search: str | None = Query(None), search: str | None = Query(None),
asn_org: str | None = Query(None),
country_code: str | None = Query(None),
ja4: str | None = Query(None),
bot_name: str | None = Query(None),
) -> dict[str, Any]: ) -> dict[str, Any]:
sort = _validate_sort(sort, _DETECTION_SORT_COLS, "detected_at") sort = _validate_sort(sort, _DETECTION_SORT_COLS, "detected_at")
order = _validate_order(order) order = _validate_order(order)
@ -155,6 +161,22 @@ async def detections(
) )
params["search"] = f"%{search}%" params["search"] = f"%{search}%"
if asn_org:
where_clauses.append("asn_org = {asn_org:String}")
params["asn_org"] = asn_org
if country_code:
where_clauses.append("country_code = {cc:String}")
params["cc"] = country_code
if ja4:
where_clauses.append("ja4 = {ja4:String}")
params["ja4"] = ja4
if bot_name:
where_clauses.append("bot_name = {bn:String}")
params["bn"] = bot_name
where = " AND ".join(where_clauses) where = " AND ".join(where_clauses)
try: try:
@ -194,6 +216,9 @@ async def scores(
order: str = Query("DESC"), order: str = Query("DESC"),
threat_level: str | None = Query(None), threat_level: str | None = Query(None),
search: str | None = Query(None), search: str | None = Query(None),
asn_org: str | None = Query(None),
country_code: str | None = Query(None),
ja4: str | None = Query(None),
) -> dict[str, Any]: ) -> dict[str, Any]:
sort = _validate_sort(sort, _SCORE_SORT_COLS, "detected_at") sort = _validate_sort(sort, _SCORE_SORT_COLS, "detected_at")
order = _validate_order(order) order = _validate_order(order)
@ -212,6 +237,18 @@ async def scores(
) )
params["search"] = f"%{search}%" params["search"] = f"%{search}%"
if asn_org:
where_clauses.append("asn_org = {asn_org:String}")
params["asn_org"] = asn_org
if country_code:
where_clauses.append("country_code = {cc:String}")
params["cc"] = country_code
if ja4:
where_clauses.append("ja4 = {ja4:String}")
params["ja4"] = ja4
where = " AND ".join(where_clauses) where = " AND ".join(where_clauses)
try: try:
@ -375,15 +412,22 @@ async def ip_detail(ip: str) -> dict[str, Any]:
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
@router.get("/features") @router.get("/features")
async def features() -> dict[str, Any]: async def features() -> dict[str, Any]:
result: dict[str, Any] = {"ai_features": {}, "thesis_features": {}} result: dict[str, Any] = {
"ai_features": {}, "thesis_features": {},
"human_profile": {}, "bot_profile": {},
"feature_importance": [],
}
_feat_cols = (
"avg(hits) AS avg_hits, avg(hit_velocity) AS avg_velocity, "
"avg(fuzzing_index) AS avg_fuzz, avg(post_ratio) AS avg_post, "
"avg(asset_ratio) AS avg_asset, avg(direct_access_ratio) AS avg_direct, "
"avg(temporal_entropy) AS avg_entropy, avg(path_diversity_ratio) AS avg_path_div, "
"avg(modern_browser_score) AS avg_browser, avg(header_count) AS avg_headers, "
"avg(src_port_density) AS avg_port_density, avg(distinct_ja4_count) AS avg_ja4_count"
)
try: try:
ai_stats = query( ai_stats = query(
f"SELECT count() AS total, " f"SELECT count() AS total, {_feat_cols} FROM {_DB}.view_ai_features_1h"
f"avg(hits) AS avg_hits, "
f"avg(hit_velocity) AS avg_hit_velocity, "
f"avg(fuzzing_index) AS avg_fuzzing_index, "
f"avg(post_ratio) AS avg_post_ratio "
f"FROM {_DB}.view_ai_features_1h"
) )
if ai_stats: if ai_stats:
result["ai_features"] = ai_stats[0] result["ai_features"] = ai_stats[0]
@ -392,21 +436,212 @@ async def features() -> dict[str, Any]:
try: try:
thesis_stats = query( thesis_stats = query(
f"SELECT count() AS total, " f"SELECT count() AS total, {_feat_cols} FROM {_DB}.view_thesis_features_1h"
f"avg(hits) AS avg_hits, "
f"avg(hit_velocity) AS avg_hit_velocity, "
f"avg(fuzzing_index) AS avg_fuzzing_index, "
f"avg(post_ratio) AS avg_post_ratio "
f"FROM {_DB}.view_thesis_features_1h"
) )
if thesis_stats: if thesis_stats:
result["thesis_features"] = thesis_stats[0] result["thesis_features"] = thesis_stats[0]
except Exception: except Exception:
logger.debug("view_thesis_features_1h not available") logger.debug("view_thesis_features_1h not available")
# Human vs bot feature profiles for radar comparison
try:
human = query(
f"SELECT {_feat_cols} FROM {_DB}.view_ai_features_1h "
"WHERE asn_label = 'human'"
)
if human:
result["human_profile"] = human[0]
except Exception:
pass
try:
bot = query(
f"SELECT {_feat_cols} FROM {_DB}.view_ai_features_1h "
"WHERE asn_label IN ('datacenter', 'hosting')"
)
if bot:
result["bot_profile"] = bot[0]
except Exception:
pass
# Feature variance (importance proxy)
try:
variance_rows = query(
f"SELECT "
f"varPop(hit_velocity) AS v_velocity, "
f"varPop(fuzzing_index) AS v_fuzz, "
f"varPop(post_ratio) AS v_post, "
f"varPop(asset_ratio) AS v_asset, "
f"varPop(direct_access_ratio) AS v_direct, "
f"varPop(temporal_entropy) AS v_entropy, "
f"varPop(path_diversity_ratio) AS v_path_div, "
f"varPop(src_port_density) AS v_port_density "
f"FROM {_DB}.view_ai_features_1h"
)
if variance_rows:
row = variance_rows[0]
result["feature_importance"] = [
{"name": k.replace("v_", ""), "variance": v}
for k, v in sorted(row.items(), key=lambda x: -(x[1] or 0))
]
except Exception:
pass
return result return result
# ---------------------------------------------------------------------------
# GET /api/geo — Geographic & ASN breakdown
# ---------------------------------------------------------------------------
@router.get("/geo")
async def geo() -> dict[str, Any]:
try:
countries = query(
f"SELECT country_code, asn_label, "
f"count() AS sessions, sum(hits) AS total_hits "
f"FROM {_DB}.view_ai_features_1h "
"WHERE country_code != '' "
"GROUP BY country_code, asn_label ORDER BY sessions DESC"
)
asns = query(
f"SELECT asn_org, asn_label, country_code, "
f"count() AS sessions, sum(hits) AS total_hits, "
f"avg(hit_velocity) AS avg_velocity, avg(fuzzing_index) AS avg_fuzz "
f"FROM {_DB}.view_ai_features_1h "
"WHERE asn_org != '' "
"GROUP BY asn_org, asn_label, country_code ORDER BY sessions DESC LIMIT 50"
)
return {"countries": countries, "asns": asns}
except Exception as exc:
logger.exception("geo query failed")
return {"countries": [], "asns": []}
# ---------------------------------------------------------------------------
# GET /api/fingerprints — JA4 fingerprint analysis
# ---------------------------------------------------------------------------
@router.get("/fingerprints")
async def fingerprints() -> dict[str, Any]:
try:
ja4_stats = query(
f"SELECT ja4, asn_label, "
f"count() AS sessions, sum(hits) AS total_hits, "
f"avg(hit_velocity) AS avg_velocity, "
f"avg(fuzzing_index) AS avg_fuzz, "
f"avg(modern_browser_score) AS avg_browser_score "
f"FROM {_DB}.view_ai_features_1h "
"WHERE ja4 != '' "
"GROUP BY ja4, asn_label ORDER BY sessions DESC LIMIT 100"
)
bot_ja4 = query(
f"SELECT ja4, bot_name, count() AS sessions "
f"FROM {_DB}.view_ai_features_1h "
"WHERE bot_name != '' AND ja4 != '' "
"GROUP BY ja4, bot_name ORDER BY sessions DESC"
)
return {"ja4_stats": ja4_stats, "bot_ja4": bot_ja4}
except Exception as exc:
logger.exception("fingerprints query failed")
return {"ja4_stats": [], "bot_ja4": []}
# ---------------------------------------------------------------------------
# GET /api/behavior — Feature scatter + distributions
# ---------------------------------------------------------------------------
_BEHAVIOR_FEATURES = [
"hit_velocity", "fuzzing_index", "post_ratio", "asset_ratio",
"direct_access_ratio", "temporal_entropy", "path_diversity_ratio",
"modern_browser_score", "header_count", "is_ua_rotating",
"distinct_ja4_count", "src_port_density",
]
@router.get("/behavior")
async def behavior() -> dict[str, Any]:
cols = ", ".join(_BEHAVIOR_FEATURES)
try:
scatter = query(
f"SELECT toString(src_ip) AS ip, asn_label, bot_name, hits, {cols} "
f"FROM {_DB}.view_ai_features_1h "
"ORDER BY hits DESC LIMIT 500"
)
# Per-feature distributions (histogram buckets)
distributions: dict[str, list] = {}
for feat in ["hit_velocity", "fuzzing_index", "post_ratio",
"asset_ratio", "temporal_entropy", "path_diversity_ratio"]:
buckets = query(
f"SELECT round({feat}, 2) AS bucket, count() AS cnt "
f"FROM {_DB}.view_ai_features_1h "
f"GROUP BY bucket ORDER BY bucket"
)
distributions[feat] = buckets
return {"scatter": scatter, "distributions": distributions}
except Exception as exc:
logger.exception("behavior query failed")
return {"scatter": [], "distributions": {}}
# ---------------------------------------------------------------------------
# GET /api/heatmap — Temporal heatmap (hour × day)
# ---------------------------------------------------------------------------
@router.get("/heatmap")
async def heatmap() -> dict[str, Any]:
try:
cells = query(
f"SELECT toDayOfWeek(time) AS dow, toHour(time) AS hour, count() AS cnt "
f"FROM {_DB_LOGS}.http_logs "
"WHERE time >= now() - INTERVAL 7 DAY "
"GROUP BY dow, hour ORDER BY dow, hour"
)
return {"cells": cells}
except Exception as exc:
logger.exception("heatmap query failed")
return {"cells": []}
# ---------------------------------------------------------------------------
# GET /api/ip/{ip}/radar — Radar comparison vs human baseline
# ---------------------------------------------------------------------------
_RADAR_FEATURES = [
"hit_velocity", "fuzzing_index", "post_ratio", "asset_ratio",
"direct_access_ratio", "temporal_entropy", "path_diversity_ratio",
"modern_browser_score",
]
@router.get("/ip/{ip}/radar")
async def ip_radar(ip: str) -> dict[str, Any]:
clean_ip = ip.replace("::ffff:", "")
cols_avg = ", ".join(f"avg({f}) AS {f}" for f in _RADAR_FEATURES)
try:
ip_data = query(
f"SELECT {', '.join(_RADAR_FEATURES)} "
f"FROM {_DB}.view_ai_features_1h "
"WHERE src_ip = toIPv6({ip:String}) LIMIT 1",
{"ip": clean_ip},
)
baseline = query(
f"SELECT {cols_avg} "
f"FROM {_DB}.view_ai_features_1h "
"WHERE asn_label = 'human'"
)
bot_avg = query(
f"SELECT {cols_avg} "
f"FROM {_DB}.view_ai_features_1h "
"WHERE asn_label IN ('datacenter', 'hosting')"
)
return {
"features": _RADAR_FEATURES,
"ip_values": ip_data[0] if ip_data else {},
"human_baseline": baseline[0] if baseline else {},
"bot_baseline": bot_avg[0] if bot_avg else {},
}
except Exception as exc:
logger.exception("ip radar query failed for %s", ip)
return {"features": _RADAR_FEATURES, "ip_values": {},
"human_baseline": {}, "bot_baseline": {}}
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# GET /api/models # GET /api/models
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------

View File

@ -51,3 +51,8 @@ async def features(request: Request):
@router.get("/models") @router.get("/models")
async def models(request: Request): async def models(request: Request):
return templates.TemplateResponse("models.html", _ctx(request, "models")) return templates.TemplateResponse("models.html", _ctx(request, "models"))
@router.get("/network")
async def network(request: Request):
return templates.TemplateResponse("network.html", _ctx(request, "network"))

View File

@ -2,13 +2,38 @@ src_asn,label
16276,human 16276,human
15557,human 15557,human
3215,human 3215,human
12322,human
5432,human 5432,human
3320,human
6805,human
1136,human 1136,human
1103,human
2856,human 2856,human
8913,human 8913,human
5607,human
3352,human 3352,human
3269,human
7922,human
7018,human
701,human
20115,human
2516,human
4713,human
15169,human 15169,human
8075,human 8075,human
32934,human
13414,human
210644,datacenter 210644,datacenter
209083,datacenter 209083,datacenter
14061,datacenter
16509,datacenter
396982,datacenter
8560,datacenter
24940,datacenter
20473,datacenter
63949,datacenter
13335,datacenter
197695,hosting 197695,hosting
51167,hosting
46606,hosting
26496,hosting

1 src_asn label
2 16276 human
3 15557 human
4 3215 human
5 12322 human
6 5432 human
7 3320 human
8 6805 human
9 1136 human
10 1103 human
11 2856 human
12 8913 human
13 5607 human
14 3352 human
15 3269 human
16 7922 human
17 7018 human
18 701 human
19 20115 human
20 2516 human
21 4713 human
22 15169 human
23 8075 human
24 32934 human
25 13414 human
26 210644 datacenter
27 209083 datacenter
28 14061 datacenter
29 16509 datacenter
30 396982 datacenter
31 8560 datacenter
32 24940 datacenter
33 20473 datacenter
34 63949 datacenter
35 13335 datacenter
36 197695 hosting
37 51167 hosting
38 46606 hosting
39 26496 hosting

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,31 @@
t13d030500_ffd59bab1b39_6e7f7df63e98,curl_scanner t13d030500_ffd59bab1b39_6e7f7df63e98,curl_scanner
t13d030600_ffd59bab1b39_6e7f7df63e98,curl_scanner
t13d020400_ffd59bab1b39_6e7f7df63e98,curl_scanner
t12d030500_ffd59bab1b39_6e7f7df63e98,curl_scanner
t13d020300_6b9b1b2c3d4e_ffd59bab1b39,python_requests_scanner t13d020300_6b9b1b2c3d4e_ffd59bab1b39,python_requests_scanner
t13d020200_6b9b1b2c3d4e_ffd59bab1b39,python_requests_scanner
t13d010300_6b9b1b2c3d4e_aabbccddeeff,python_requests_scanner
t12d020300_6b9b1b2c3d4e_ffd59bab1b39,python_requests_scanner
t13d1517h2_8daaf6152771_b0da82dd1658,go_http_scanner
t13d1517h2_8daaf6152771_02713d6af862,go_http_scanner
t12d1517h2_8daaf6152771_b0da82dd1658,go_http_scanner
t10d170000_0a1b2c3d4e5f_1b2c3d4e5f60,Masscan t10d170000_0a1b2c3d4e5f_1b2c3d4e5f60,Masscan
t10d010000_0a1b2c3d4e5f_000000000000,Masscan
t12d050700_5a6b7c8d9e0f_1a2b3c4d5e6f,zgrab_scanner t12d050700_5a6b7c8d9e0f_1a2b3c4d5e6f,zgrab_scanner
t12d050600_5a6b7c8d9e0f_1a2b3c4d5e6f,zgrab_scanner
t12d030400_5a6b7c8d9e0f_0000deadbeef,zmap_scanner
t13d010100_aabbccddeeff_0011223344aa,Headless_Chrome_Automation t13d010100_aabbccddeeff_0011223344aa,Headless_Chrome_Automation
t13d010100_aabbccddeeff_ffeeddccbbaa,Headless_Chrome_Automation
t13d1517h2_aabbccddeeff_0011223344aa,Headless_Chrome_Automation
t13d030500_deadbeef1234_cafebabe5678,node_scanner
t13d020300_deadbeef1234_cafebabe5678,node_scanner
t13d1517h2_1234567890ab_abcdef012345,java_scanner
t12d1517h2_1234567890ab_abcdef012345,java_scanner
t13d020300_fedcba987654_0123456789ab,ruby_scanner
t12d010100_aabbccddeeff_deadbeefdead,nikto_scanner
t12d010100_ffeeddccbbaa_baddcafef00d,sqlmap_scanner
t13d030600_deadbeefcafe_babe12345678,nuclei_scanner
t13d020200_abcdef012345_fedcba987654,scrapy_crawler
t13d020300_abcdef012345_1234abcd5678,scrapy_crawler
t10d010000_0000000000_000000000000,malware_c2_minimal
t12d010100_1111111111_222222222222,cobalt_strike_beacon

1 t13d030500_ffd59bab1b39_6e7f7df63e98 curl_scanner
2 t13d030600_ffd59bab1b39_6e7f7df63e98 curl_scanner
3 t13d020400_ffd59bab1b39_6e7f7df63e98 curl_scanner
4 t12d030500_ffd59bab1b39_6e7f7df63e98 curl_scanner
5 t13d020300_6b9b1b2c3d4e_ffd59bab1b39 python_requests_scanner
6 t13d020200_6b9b1b2c3d4e_ffd59bab1b39 python_requests_scanner
7 t13d010300_6b9b1b2c3d4e_aabbccddeeff python_requests_scanner
8 t12d020300_6b9b1b2c3d4e_ffd59bab1b39 python_requests_scanner
9 t13d1517h2_8daaf6152771_b0da82dd1658 go_http_scanner
10 t13d1517h2_8daaf6152771_02713d6af862 go_http_scanner
11 t12d1517h2_8daaf6152771_b0da82dd1658 go_http_scanner
12 t10d170000_0a1b2c3d4e5f_1b2c3d4e5f60 Masscan
13 t10d010000_0a1b2c3d4e5f_000000000000 Masscan
14 t12d050700_5a6b7c8d9e0f_1a2b3c4d5e6f zgrab_scanner
15 t12d050600_5a6b7c8d9e0f_1a2b3c4d5e6f zgrab_scanner
16 t12d030400_5a6b7c8d9e0f_0000deadbeef zmap_scanner
17 t13d010100_aabbccddeeff_0011223344aa Headless_Chrome_Automation
18 t13d010100_aabbccddeeff_ffeeddccbbaa Headless_Chrome_Automation
19 t13d1517h2_aabbccddeeff_0011223344aa Headless_Chrome_Automation
20 t13d030500_deadbeef1234_cafebabe5678 node_scanner
21 t13d020300_deadbeef1234_cafebabe5678 node_scanner
22 t13d1517h2_1234567890ab_abcdef012345 java_scanner
23 t12d1517h2_1234567890ab_abcdef012345 java_scanner
24 t13d020300_fedcba987654_0123456789ab ruby_scanner
25 t12d010100_aabbccddeeff_deadbeefdead nikto_scanner
26 t12d010100_ffeeddccbbaa_baddcafef00d sqlmap_scanner
27 t13d030600_deadbeefcafe_babe12345678 nuclei_scanner
28 t13d020200_abcdef012345_fedcba987654 scrapy_crawler
29 t13d020300_abcdef012345_1234abcd5678 scrapy_crawler
30 t10d010000_0000000000_000000000000 malware_c2_minimal
31 t12d010100_1111111111_222222222222 cobalt_strike_beacon

View File

@ -1,14 +1,97 @@
network,asn,country_code,name,org,domain network,asn,country_code,name,org,domain
91.121.0.0/16,16276,FR,OVH SAS,OVH,ovh.com 91.121.0.0/16,16276,FR,OVH SAS,OVH,ovh.com
151.80.0.0/16,16276,FR,OVH SAS,OVH,ovh.com
137.74.0.0/16,16276,FR,OVH SAS,OVH,ovh.com
5.196.0.0/16,16276,FR,OVH SAS,OVH,ovh.com
54.36.0.0/16,16276,FR,OVH SAS,OVH,ovh.com
78.41.0.0/16,15557,FR,SFR SA,SFR,sfr.com 78.41.0.0/16,15557,FR,SFR SA,SFR,sfr.com
90.28.0.0/14,15557,FR,SFR SA,SFR,sfr.com
109.0.0.0/14,15557,FR,SFR SA,SFR,sfr.com
90.0.0.0/8,3215,FR,Orange SA,Orange,orange.fr 90.0.0.0/8,3215,FR,Orange SA,Orange,orange.fr
86.192.0.0/11,3215,FR,Orange SA,Orange,orange.fr
81.48.0.0/14,3215,FR,Orange SA,Orange,orange.fr
82.64.0.0/14,12322,FR,Free SAS,Free,free.fr
78.220.0.0/14,12322,FR,Free SAS,Free,free.fr
88.120.0.0/13,12322,FR,Free SAS,Free,free.fr
212.0.0.0/8,5432,DE,Deutsche Telekom AG,Telekom,telekom.de 212.0.0.0/8,5432,DE,Deutsche Telekom AG,Telekom,telekom.de
91.64.0.0/14,5432,DE,Deutsche Telekom AG,Telekom,telekom.de
2.200.0.0/14,5432,DE,Deutsche Telekom AG,Telekom,telekom.de
80.128.0.0/11,3320,DE,Deutsche Telekom DTAG,DTAG,telekom.de
176.0.0.0/12,6805,DE,Telefonica Germany,O2,o2online.de
84.116.0.0/16,1136,NL,KPN Internet BV,KPN,kpn.com 84.116.0.0/16,1136,NL,KPN Internet BV,KPN,kpn.com
145.90.0.0/16,1136,NL,KPN Internet BV,KPN,kpn.com
145.0.0.0/16,1103,NL,SURF,SURFnet,surf.nl
77.108.0.0/16,2856,GB,BT Group plc,BT,bt.com 77.108.0.0/16,2856,GB,BT Group plc,BT,bt.com
81.128.0.0/11,2856,GB,BT Group plc,BT,bt.com
86.128.0.0/11,2856,GB,BT Group plc,BT,bt.com
82.45.0.0/16,8913,GB,Virgin Media,Virgin Media,virginmedia.com 82.45.0.0/16,8913,GB,Virgin Media,Virgin Media,virginmedia.com
86.0.0.0/11,8913,GB,Virgin Media,Virgin Media,virginmedia.com
90.192.0.0/11,5607,GB,Sky UK Limited,Sky,sky.com
151.224.0.0/13,5607,GB,Sky UK Limited,Sky,sky.com
62.98.0.0/16,3352,ES,Telefonica Spain,Telefonica,telefonica.es 62.98.0.0/16,3352,ES,Telefonica Spain,Telefonica,telefonica.es
80.24.0.0/14,3352,ES,Telefonica Spain,Telefonica,telefonica.es
83.32.0.0/11,3352,ES,Telefonica Spain,Telefonica,telefonica.es
79.0.0.0/12,3269,IT,Telecom Italia,TIM,telecomitalia.it
82.48.0.0/12,3269,IT,Telecom Italia,TIM,telecomitalia.it
50.128.0.0/9,7922,US,Comcast Cable,Comcast,comcast.net
73.0.0.0/8,7922,US,Comcast Cable,Comcast,comcast.net
75.64.0.0/13,7922,US,Comcast Cable,Comcast,comcast.net
12.0.0.0/8,7018,US,AT&T Services,AT&T,att.com
32.0.0.0/11,7018,US,AT&T Services,AT&T,att.com
71.160.0.0/11,701,US,Verizon Business,Verizon,verizon.com
74.64.0.0/11,701,US,Verizon Business,Verizon,verizon.com
24.16.0.0/13,20115,US,Charter Communications,Spectrum,charter.com
65.32.0.0/11,20115,US,Charter Communications,Spectrum,charter.com
106.128.0.0/10,2516,JP,KDDI Corporation,KDDI,kddi.com
111.86.0.0/15,2516,JP,KDDI Corporation,KDDI,kddi.com
114.144.0.0/14,4713,JP,NTT Communications,OCN,ntt.com
118.238.0.0/15,4713,JP,NTT Communications,OCN,ntt.com
66.249.64.0/19,15169,US,Google LLC,Google,google.com 66.249.64.0/19,15169,US,Google LLC,Google,google.com
64.233.160.0/19,15169,US,Google LLC,Google,google.com
72.14.192.0/18,15169,US,Google LLC,Google,google.com
157.55.0.0/16,8075,US,Microsoft Corporation,Bing,microsoft.com 157.55.0.0/16,8075,US,Microsoft Corporation,Bing,microsoft.com
185.220.0.0/16,210644,NL,Accelerated-IT Services,Tor Project,tor-project.org 207.46.0.0/16,8075,US,Microsoft Corporation,Bing,microsoft.com
40.76.0.0/14,8075,US,Microsoft Corporation,Bing,microsoft.com
69.63.176.0/20,32934,US,Facebook Inc,Meta,facebook.com
66.220.144.0/20,32934,US,Facebook Inc,Meta,facebook.com
31.13.24.0/21,32934,US,Facebook Inc,Meta,facebook.com
199.59.148.0/22,13414,US,Twitter Inc,Twitter,twitter.com
199.16.156.0/22,13414,US,Twitter Inc,Twitter,twitter.com
185.220.100.0/22,210644,NL,Accelerated-IT Services,Tor Project,tor-project.org
185.220.101.0/24,210644,NL,Accelerated-IT Services,Tor Project,tor-project.org
185.220.102.0/24,210644,NL,Accelerated-IT Services,Tor Project,tor-project.org
45.155.205.0/24,209083,DE,Contabo GmbH,Contabo,contabo.de 45.155.205.0/24,209083,DE,Contabo GmbH,Contabo,contabo.de
62.171.128.0/17,209083,DE,Contabo GmbH,Contabo,contabo.de
5.161.0.0/16,209083,DE,Contabo GmbH,Contabo,contabo.de
64.225.0.0/16,14061,US,DigitalOcean LLC,DigitalOcean,digitalocean.com
104.131.0.0/16,14061,US,DigitalOcean LLC,DigitalOcean,digitalocean.com
138.197.0.0/16,14061,US,DigitalOcean LLC,DigitalOcean,digitalocean.com
159.65.0.0/16,14061,US,DigitalOcean LLC,DigitalOcean,digitalocean.com
3.0.0.0/8,16509,US,Amazon.com ARIN,AWS,amazonaws.com
18.0.0.0/8,16509,US,Amazon.com ARIN,AWS,amazonaws.com
52.0.0.0/8,16509,US,Amazon.com ARIN,AWS,amazonaws.com
54.0.0.0/8,16509,US,Amazon.com ARIN,AWS,amazonaws.com
34.0.0.0/8,396982,US,Google Cloud,GCP,cloud.google.com
35.184.0.0/13,396982,US,Google Cloud,GCP,cloud.google.com
74.208.0.0/16,8560,DE,IONOS SE,IONOS,ionos.com
212.227.0.0/16,8560,DE,IONOS SE,IONOS,ionos.com
136.243.0.0/16,24940,DE,Hetzner Online GmbH,Hetzner,hetzner.com
138.201.0.0/16,24940,DE,Hetzner Online GmbH,Hetzner,hetzner.com
144.76.0.0/16,24940,DE,Hetzner Online GmbH,Hetzner,hetzner.com
178.63.0.0/16,24940,DE,Hetzner Online GmbH,Hetzner,hetzner.com
45.32.0.0/16,20473,US,The Constant Company,Vultr,vultr.com
64.237.32.0/19,20473,US,The Constant Company,Vultr,vultr.com
108.61.0.0/16,20473,US,The Constant Company,Vultr,vultr.com
45.33.0.0/17,63949,US,Linode LLC,Linode,linode.com
45.56.0.0/16,63949,US,Linode LLC,Linode,linode.com
50.116.0.0/18,63949,US,Linode LLC,Linode,linode.com
104.16.0.0/12,13335,US,Cloudflare Inc,Cloudflare,cloudflare.com
172.64.0.0/13,13335,US,Cloudflare Inc,Cloudflare,cloudflare.com
162.158.0.0/15,13335,US,Cloudflare Inc,Cloudflare,cloudflare.com
193.32.162.0/24,197695,RU,Reg.ru Hosting,Reg.ru,reg.ru 193.32.162.0/24,197695,RU,Reg.ru Hosting,Reg.ru,reg.ru
194.58.92.0/22,197695,RU,Reg.ru Hosting,Reg.ru,reg.ru
78.46.0.0/15,51167,DE,Contabo GmbH,Contabo Hosting,contabo.de
162.241.0.0/16,46606,US,Unified Layer,Bluehost,bluehost.com
198.57.128.0/17,46606,US,Unified Layer,Bluehost,bluehost.com
184.168.0.0/16,26496,US,GoDaddy.com,GoDaddy,godaddy.com
198.71.128.0/17,26496,US,GoDaddy.com,GoDaddy,godaddy.com

1 network asn country_code name org domain
2 91.121.0.0/16 16276 FR OVH SAS OVH ovh.com
3 151.80.0.0/16 16276 FR OVH SAS OVH ovh.com
4 137.74.0.0/16 16276 FR OVH SAS OVH ovh.com
5 5.196.0.0/16 16276 FR OVH SAS OVH ovh.com
6 54.36.0.0/16 16276 FR OVH SAS OVH ovh.com
7 78.41.0.0/16 15557 FR SFR SA SFR sfr.com
8 90.28.0.0/14 15557 FR SFR SA SFR sfr.com
9 109.0.0.0/14 15557 FR SFR SA SFR sfr.com
10 90.0.0.0/8 3215 FR Orange SA Orange orange.fr
11 86.192.0.0/11 3215 FR Orange SA Orange orange.fr
12 81.48.0.0/14 3215 FR Orange SA Orange orange.fr
13 82.64.0.0/14 12322 FR Free SAS Free free.fr
14 78.220.0.0/14 12322 FR Free SAS Free free.fr
15 88.120.0.0/13 12322 FR Free SAS Free free.fr
16 212.0.0.0/8 5432 DE Deutsche Telekom AG Telekom telekom.de
17 91.64.0.0/14 5432 DE Deutsche Telekom AG Telekom telekom.de
18 2.200.0.0/14 5432 DE Deutsche Telekom AG Telekom telekom.de
19 80.128.0.0/11 3320 DE Deutsche Telekom DTAG DTAG telekom.de
20 176.0.0.0/12 6805 DE Telefonica Germany O2 o2online.de
21 84.116.0.0/16 1136 NL KPN Internet BV KPN kpn.com
22 145.90.0.0/16 1136 NL KPN Internet BV KPN kpn.com
23 145.0.0.0/16 1103 NL SURF SURFnet surf.nl
24 77.108.0.0/16 2856 GB BT Group plc BT bt.com
25 81.128.0.0/11 2856 GB BT Group plc BT bt.com
26 86.128.0.0/11 2856 GB BT Group plc BT bt.com
27 82.45.0.0/16 8913 GB Virgin Media Virgin Media virginmedia.com
28 86.0.0.0/11 8913 GB Virgin Media Virgin Media virginmedia.com
29 90.192.0.0/11 5607 GB Sky UK Limited Sky sky.com
30 151.224.0.0/13 5607 GB Sky UK Limited Sky sky.com
31 62.98.0.0/16 3352 ES Telefonica Spain Telefonica telefonica.es
32 80.24.0.0/14 3352 ES Telefonica Spain Telefonica telefonica.es
33 83.32.0.0/11 3352 ES Telefonica Spain Telefonica telefonica.es
34 79.0.0.0/12 3269 IT Telecom Italia TIM telecomitalia.it
35 82.48.0.0/12 3269 IT Telecom Italia TIM telecomitalia.it
36 50.128.0.0/9 7922 US Comcast Cable Comcast comcast.net
37 73.0.0.0/8 7922 US Comcast Cable Comcast comcast.net
38 75.64.0.0/13 7922 US Comcast Cable Comcast comcast.net
39 12.0.0.0/8 7018 US AT&T Services AT&T att.com
40 32.0.0.0/11 7018 US AT&T Services AT&T att.com
41 71.160.0.0/11 701 US Verizon Business Verizon verizon.com
42 74.64.0.0/11 701 US Verizon Business Verizon verizon.com
43 24.16.0.0/13 20115 US Charter Communications Spectrum charter.com
44 65.32.0.0/11 20115 US Charter Communications Spectrum charter.com
45 106.128.0.0/10 2516 JP KDDI Corporation KDDI kddi.com
46 111.86.0.0/15 2516 JP KDDI Corporation KDDI kddi.com
47 114.144.0.0/14 4713 JP NTT Communications OCN ntt.com
48 118.238.0.0/15 4713 JP NTT Communications OCN ntt.com
49 66.249.64.0/19 15169 US Google LLC Google google.com
50 64.233.160.0/19 15169 US Google LLC Google google.com
51 72.14.192.0/18 15169 US Google LLC Google google.com
52 157.55.0.0/16 8075 US Microsoft Corporation Bing microsoft.com
53 185.220.0.0/16 207.46.0.0/16 210644 8075 NL US Accelerated-IT Services Microsoft Corporation Tor Project Bing tor-project.org microsoft.com
54 40.76.0.0/14 8075 US Microsoft Corporation Bing microsoft.com
55 69.63.176.0/20 32934 US Facebook Inc Meta facebook.com
56 66.220.144.0/20 32934 US Facebook Inc Meta facebook.com
57 31.13.24.0/21 32934 US Facebook Inc Meta facebook.com
58 199.59.148.0/22 13414 US Twitter Inc Twitter twitter.com
59 199.16.156.0/22 13414 US Twitter Inc Twitter twitter.com
60 185.220.100.0/22 210644 NL Accelerated-IT Services Tor Project tor-project.org
61 185.220.101.0/24 210644 NL Accelerated-IT Services Tor Project tor-project.org
62 185.220.102.0/24 210644 NL Accelerated-IT Services Tor Project tor-project.org
63 45.155.205.0/24 209083 DE Contabo GmbH Contabo contabo.de
64 62.171.128.0/17 209083 DE Contabo GmbH Contabo contabo.de
65 5.161.0.0/16 209083 DE Contabo GmbH Contabo contabo.de
66 64.225.0.0/16 14061 US DigitalOcean LLC DigitalOcean digitalocean.com
67 104.131.0.0/16 14061 US DigitalOcean LLC DigitalOcean digitalocean.com
68 138.197.0.0/16 14061 US DigitalOcean LLC DigitalOcean digitalocean.com
69 159.65.0.0/16 14061 US DigitalOcean LLC DigitalOcean digitalocean.com
70 3.0.0.0/8 16509 US Amazon.com ARIN AWS amazonaws.com
71 18.0.0.0/8 16509 US Amazon.com ARIN AWS amazonaws.com
72 52.0.0.0/8 16509 US Amazon.com ARIN AWS amazonaws.com
73 54.0.0.0/8 16509 US Amazon.com ARIN AWS amazonaws.com
74 34.0.0.0/8 396982 US Google Cloud GCP cloud.google.com
75 35.184.0.0/13 396982 US Google Cloud GCP cloud.google.com
76 74.208.0.0/16 8560 DE IONOS SE IONOS ionos.com
77 212.227.0.0/16 8560 DE IONOS SE IONOS ionos.com
78 136.243.0.0/16 24940 DE Hetzner Online GmbH Hetzner hetzner.com
79 138.201.0.0/16 24940 DE Hetzner Online GmbH Hetzner hetzner.com
80 144.76.0.0/16 24940 DE Hetzner Online GmbH Hetzner hetzner.com
81 178.63.0.0/16 24940 DE Hetzner Online GmbH Hetzner hetzner.com
82 45.32.0.0/16 20473 US The Constant Company Vultr vultr.com
83 64.237.32.0/19 20473 US The Constant Company Vultr vultr.com
84 108.61.0.0/16 20473 US The Constant Company Vultr vultr.com
85 45.33.0.0/17 63949 US Linode LLC Linode linode.com
86 45.56.0.0/16 63949 US Linode LLC Linode linode.com
87 50.116.0.0/18 63949 US Linode LLC Linode linode.com
88 104.16.0.0/12 13335 US Cloudflare Inc Cloudflare cloudflare.com
89 172.64.0.0/13 13335 US Cloudflare Inc Cloudflare cloudflare.com
90 162.158.0.0/15 13335 US Cloudflare Inc Cloudflare cloudflare.com
91 193.32.162.0/24 197695 RU Reg.ru Hosting Reg.ru reg.ru
92 194.58.92.0/22 197695 RU Reg.ru Hosting Reg.ru reg.ru
93 78.46.0.0/15 51167 DE Contabo GmbH Contabo Hosting contabo.de
94 162.241.0.0/16 46606 US Unified Layer Bluehost bluehost.com
95 198.57.128.0/17 46606 US Unified Layer Bluehost bluehost.com
96 184.168.0.0/16 26496 US GoDaddy.com GoDaddy godaddy.com
97 198.71.128.0/17 26496 US GoDaddy.com GoDaddy godaddy.com