From 7c6a9827ba4fa11c6044786cd2a9ccf7d0d799cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Bj=C3=B6rklund?= Date: Wed, 20 Nov 2024 15:34:14 +0100 Subject: [PATCH] Add sieves --- .../soc/files/intelmq/sieve/domains.sieve | 30 +++++++ .../soc/files/intelmq/sieve/phishers.sieve | 67 +++++++++++++++ .../soc/files/intelmq/sieve/squatters.sieve | 83 +++++++++++++++++++ .../puppet/modules/soc/manifests/intelmq.pp | 24 ++++-- 4 files changed, 199 insertions(+), 5 deletions(-) create mode 100644 global/overlay/etc/puppet/modules/soc/files/intelmq/sieve/domains.sieve create mode 100644 global/overlay/etc/puppet/modules/soc/files/intelmq/sieve/phishers.sieve create mode 100644 global/overlay/etc/puppet/modules/soc/files/intelmq/sieve/squatters.sieve diff --git a/global/overlay/etc/puppet/modules/soc/files/intelmq/sieve/domains.sieve b/global/overlay/etc/puppet/modules/soc/files/intelmq/sieve/domains.sieve new file mode 100644 index 0000000..96af68d --- /dev/null +++ b/global/overlay/etc/puppet/modules/soc/files/intelmq/sieve/domains.sieve @@ -0,0 +1,30 @@ +// domains.sieve +// This sieve filters out domains under the SUNET umbrella. +// Results are passed on to phishing.sieve and squatters.sieve + +// https://regex101.com/ is a good place to test out regexes + +if :notexists source.fqdn { + drop // Abort processing if we cannot match against it. +} + +// See if domain is anywhere in FQDN. +// Only match when domain is first or between to periods "." +// With chalmers as example: +// Matches: +// chalmers.foo.com +// foo.chalmers.com +// foo.chalmers.bar.com +// No match: +// chalmerss.com +// www_chalmers.com +// Matching is split in two expressions to avoid expensive regexes. +// First see if domain is first in FQDN +// Then see if it it anywhere between two periods ".." +if (source.fqdn =~ '^(arkdes|bornet|bth|chalmers|csbnet|dnlab|du|efs|ehs|esss|fhs|gih|gsix|gu|hb|hh|hhs|hig|his|hkr|hv|irf|johannelund|ju|junet|kau|kb|ki|kkh|kks|kmh|konstfack|konstnarsnamnden|kth|kulturradet|kva|lansstyrelsen|liu|lnu|ltu|lu|maritima|mau|mdfnet|mdh|miun|mittag-leffler|modernamuseet|musikverket|nationalmuseum|ndgf|nordgen|nordiskamuseet|nordu|nrm|oru|polar|raa|riksarkivet|riksdagen|riksutstallningar|rj|rkh|sfhm|sh|shm|sics|sipri|skansen|sll|slu|smhi|sophiahemmet|sp|studentnatet|stupi|su|sunet|svenskaakademien|tekniskamuseet|tillvaxtverket|uhr|uka|umu|uniarts|unimaster|ur|uu|val|varldskulturmuseerna|vinnova|vr)\..*$') + || + (source.fqdn =~ '\.(arkdes|bornet|bth|chalmers|csbnet|dnlab|du|efs|ehs|esss|fhs|gih|gsix|gu|hb|hh|hhs|hig|his|hkr|hv|irf|johannelund|ju|junet|kau|kb|ki|kkh|kks|kmh|konstfack|konstnarsnamnden|kth|kulturradet|kva|lansstyrelsen|liu|lnu|ltu|lu|maritima|mau|mdfnet|mdh|miun|mittag-leffler|modernamuseet|musikverket|nationalmuseum|ndgf|nordgen|nordiskamuseet|nordu|nrm|oru|polar|raa|riksarkivet|riksdagen|riksutstallningar|rj|rkh|sfhm|sh|shm|sics|sipri|skansen|sll|slu|smhi|sophiahemmet|sp|studentnatet|stupi|su|sunet|svenskaakademien|tekniskamuseet|tillvaxtverket|uhr|uka|umu|uniarts|unimaster|ur|uu|val|varldskulturmuseerna|vinnova|vr)\..*$') { + keep // pass everything that could be interesting on to the next sieve +} else { + drop // drop everything that's not remotely interesting +} diff --git a/global/overlay/etc/puppet/modules/soc/files/intelmq/sieve/phishers.sieve b/global/overlay/etc/puppet/modules/soc/files/intelmq/sieve/phishers.sieve new file mode 100644 index 0000000..c6e5002 --- /dev/null +++ b/global/overlay/etc/puppet/modules/soc/files/intelmq/sieve/phishers.sieve @@ -0,0 +1,67 @@ +// phishers.sieve +// This sieve runs after domains.sieve +// It's aimed at catching certs that have a phished domain in the name, excluding certs +// within the actual domain. + +// https://regex101.com/ is a good place to test out regexes + + + +if :notexists source.fqdn { + drop // Abort processing if we cannot match against it. +} + + +// Rule for dropping internal matches. +// That is drop .*. +// login.chalmers.se.test.chalmers.se would be dropped +// login.gu.se.test.chalmers.se will not be dropped +if source.fqdn =~ '^(?:.*\.)*((arkdes|bornet|bth|chalmers|csbnet|dnlab|du|efs|ehs|esss|fhs|gih|gsix|gu|hb|hh|hhs|hig|his|hkr|hv|irf|ju|junet|kau|kb|ki|kkh|kks|kmh|konstfack|konstnarsnamnden|kth|kth|kulturradet|kva|lansstyrelsen|liu|lnu|ltu|lu|maritima|mau|mdfnet|mdh|mdh|miun|mittag-leffler|modernamuseet|musikverket|nationalmuseum|nordiskamuseet|nrm|oru|raa|riksarkivet|riksdagen|riksutstallningar|rj|rkh|sfhm|sh|shm|sics|skansen|sll|slu|smhi|sophiahemmet|sp|studentnatet|stupi|su|su|sunet|svenskaakademien|tekniskamuseet|tillvaxtverket|uhr|uka|umu|uniarts|unimaster|ur|uu|val|varldskulturmuseerna|vinnova|vr)\.se|(ndgf|nordgen|sipri)\.org|nordu\.net|johannelund\.nu)\..*\1$' { + drop // drop internal domains +} + +// This should match any case where is part of the fqdn, but not when its the actual domain. +if source.fqdn =~ '^(.*\.)*((arkdes|bornet|bth|chalmers|csbnet|dnlab|du|efs|ehs|esss|fhs|gih|gsix|gu|hb|hh|hhs|hig|his|hkr|hv|irf|ju|junet|kau|kb|ki|kkh|kks|kmh|konstfack|konstnarsnamnden|kth|kth|kulturradet|kva|lansstyrelsen|liu|lnu|ltu|lu|maritima|mau|mdfnet|mdh|mdh|miun|mittag-leffler|modernamuseet|musikverket|nationalmuseum|nordiskamuseet|nrm|oru|raa|riksarkivet|riksdagen|riksutstallningar|rj|rkh|sfhm|sh|shm|sics|skansen|sll|slu|smhi|sophiahemmet|sp|studentnatet|stupi|su|su|sunet|svenskaakademien|tekniskamuseet|tillvaxtverket|uhr|uka|umu|uniarts|unimaster|ur|uu|val|varldskulturmuseerna|vinnova|vr)\.se|(ndgf|nordgen|sipri)\.org|nordu\.net|johannelund\.nu)\..+$' { +// add source.abuse_contact = 'cert@cert.sunet.se,fors@cert.sunet.se' + add source.abuse_contact = 'cert@cert.sunet.se' + add comment = 'Probable phishing domain cert registered' +} else { + drop +} + +// Drop stuff used by cloud security +// https://docs.microsoft.com/en-us/defender-cloud-apps/troubleshooting-proxy-url +// *.admin-mcas.ms +// *.admin-mcas-df.ms +// *.admin-mcas-gov.us +// *.admin-rs-mcas.ms +// *.admin-rs2-mcas.ms +// *.cas.ms +// *.mcas.ms +// *.mcas-df.ms +// *.mcas-gov.us +// *.rs-mcas.ms +// *.rs2-mcas.ms + +// regex only on whole name before .ms, .ms is Montserrat TLD and not Microsoft TLD and anyone(?) could register for instance foo-mcas.ms + +if source.fqdn =~ '.*\.(?:admin-mcas|admin-mcas-df|admin-mcas-gov|admin-rs-mcas|admin-rs2-mcas|cas|mcas|mcas-df|mcas-gov|rs-mcas|rs2-mcas)\.ms$' { + drop // Microsoft related +} + +// Drop known "good stuff" +if source.fqdn =~ '(fd\.sunet\.se|speedtest\.nordu\.net)\.prod\.hosts\.ooklaserver\.net' { + // Sunet/Nordunet speedtest server + drop +} elif source.fqdn :contains 'fhs.se.gov.br' { + drop // se.gov.br är delstaten Sergipe i brasilien. fhs.se.gov.br verkar ha varit Fundação Hospitalar de Saúde +} elif source.fqdn =~ 'synot\.io$' { + drop // Synotio AB, www.synotio.se. Svenskt webbhotell +} elif source.fqdn =~ 'hemsida\.eu$' { + drop // hemsida.eu är Oderland webhotell. Används innan domän pekats om till Oderland +} + +// Keep everything that has a source.abuse_contact +if :exists source.abuse_contact { + keep +} diff --git a/global/overlay/etc/puppet/modules/soc/files/intelmq/sieve/squatters.sieve b/global/overlay/etc/puppet/modules/soc/files/intelmq/sieve/squatters.sieve new file mode 100644 index 0000000..359e017 --- /dev/null +++ b/global/overlay/etc/puppet/modules/soc/files/intelmq/sieve/squatters.sieve @@ -0,0 +1,83 @@ +// squatters.sieve +// This sieve runs after domains.sieve and aims to catch domain squatting. + +// False positives are plentiful. Especially for "short" domains. +// We don't even care about domains with only two letters like uu.se, these will +// have way too many false positives. + +// https://regex101.com/ is a good place to test out regexes + +if :notexists source.fqdn { + drop // Abort processing if we cannot match against it. +} + +// Rule for dropping real domain certicates. +if source.fqdn =~ '\.(arkdes|bornet|bth|chalmers|csbnet|dnlab|du|efs|ehs|esss|fhs|gih|gsix|gu|hb|hh|hhs|hig|his|hkr|hv|irf|ju|junet|kau|kb|ki|kkh|kks|kmh|konstfack|konstnarsnamnden|kth|kth|kulturradet|kva|lansstyrelsen|liu|lnu|ltu|lu|maritima|mau|mdfnet|mdh|mdh|miun|mittag-leffler|modernamuseet|musikverket|nationalmuseum|nordiskamuseet|nrm|oru|polar|raa|riksarkivet|riksdagen|riksutstallningar|rj|rkh|sfhm|sh|shm|sics|skansen|sll|slu|smhi|sophiahemmet|sp|studentnatet|stupi|su|su|sunet|svenskaakademien|tekniskamuseet|tillvaxtverket|uhr|uka|umu|uniarts|unimaster|ur|uu|val|varldskulturmuseerna|vinnova|vr)\.se$' || source.fqdn =~ '\.(ndgf|nordgen|sipri)\.org$' || source.fqdn =~ '\.(nordu\.net|johannelund\.nu)$' { + drop // drop real domains +} else { + //add source.abuse_contact = 'cert-report@cert.sunet.se,fors@cert.sunet.se' + add source.abuse_contact = 'cert-report@cert.sunet.se' +} + +// Drop stuff used by cloud security +if source.fqdn =~ '.*\.m*cas(-gov.us|\.ms)$' { + drop // +} elif source.fqdn =~ '.*\.admin-mcas.ms$' { + drop +} + +// CN has one of our domain names (.se) embedded. Suspected phishing +if source.fqdn =~ '\.(arkdes|bornet|bth|chalmers|csbnet|dnlab|du|efs|ehs|esss|fhs|gih|gsix|gu|hb|hh|hhs|hig|his|hkr|hv|irf|ju|junet|kau|kb|ki|kkh|kks|kmh|konstfack|konstnarsnamnden|kth|kth|kulturradet|kva|lansstyrelsen|liu|lnu|ltu|lu|maritima|mau|mdfnet|mdh|mdh|miun|mittag-leffler|modernamuseet|musikverket|nationalmuseum|nordiskamuseet|nrm|oru|polar|raa|riksarkivet|riksdagen|riksutstallningar|rj|rkh|sfhm|sh|shm|sics|skansen|sll|slu|smhi|sophiahemmet|sp|studentnatet|stupi|su|su|sunet|svenskaakademien|tekniskamuseet|tillvaxtverket|uhr|uka|umu|uniarts|unimaster|ur|uu|val|varldskulturmuseerna|vinnova|vr)\.se\..*$' { + add comment = 'Probable phishing' + drop // Hanterar i parallel sieve-expert +} + +// CN has one of our domain names (.org) embedded. Suspected phishing +if source.fqdn =~ '\.(ndgf|nordgen|sipri)\.org\..*$' { + add comment = 'Probable phishing domain cert registered' + drop // Hanterar i produktion +} + +// CN has one of our domain names (.net, .nu) embedded. Suspected phishing +if source.fqdn =~ '\.(nordu\.net|johannelund\.nu)\..*$' { + add comment = 'Probable phishing' + drop // Hanterar i produktion +} + +// Keep only thos domains that contains more than three letters. +// These are dropped (bth|du|efs|ehs|fhs|gih|gu|hb|hh|hhs|hig|his|hkr|hv|irf|ju|kau|kb|ki|kkh|kks|kmh|kth|kva|liu|lnu|ltu|lu|mau|mdh|nrm|oru|raa|rj|rkh|sh|shm|sll|slu|sp|su|uhr|uka|umu|ur|uu|val|vr) + +if source.fqdn !~ '.*\.(arkdes|bornet|chalmers|csbnet|dnlab|esss|gsix|johannelund|junet|konstfack|konstnarsnamnden|kulturradet|lansstyrelsen|maritima|mdfnet|miun|mittag-leffler|modernamuseet|musikverket|nationalmuseum|ndgf|nordgen|nordiskamuseet|nordu|polar|riksarkivet|riksdagen|riksutstallningar|sfhm|sics|sipri|skansen|smhi|sophiahemmet|studentnatet|stupi|sunet|svenskaakademien|tekniskamuseet|tillvaxtverket|uniarts|unimaster|varldskulturmuseerna|vinnova)\..*$' { + drop // drop everything that's not remotely interesting +} else { + add comment = 'Possible squatting domain cert registered' +} + +// Chalmers chalmers.se +if source.fqdn =~ '^(.*\.)*chalmers\.(it)$' { + drop + // chalmers.it -> Chalmers IT-studenter +} + +// Nordunet nordu.net +if source.fqdn =~ '^(.*\.)*nordu\.(no)$' { + drop + // nordu.no -> Nord Universitet, Universitetet i Nordland. (nord.no) +} + +// Polarforskningssekretariatet polar.se +if source.fqdn =~ '^(.*\.)*polar\.(aero|co\.at|codes|com|com\.es|in|it|link|me|nu|one|vercel\.app)$' { + drop + // polar.aero -> JSC Polar Airlines, ryssland. Ingen www på polar.aero eller www.polar.aero + // polar.co.at -> POLAR Entfeuchtung & Sanierung GmbH. Österikiskt saneringsföretag + // polar.codes -> Till salu hos dan.com. Senast kollad 2020-12-10 + // polar.com -> Finska Polar Electro. Tillverkar pulsklockor o.dyl. + // polar.com.es -> Till salu via Sedo Domain parking. Senast kollad 2020-12-10 + // polar.in -> Parkerad hos Sedo Domain Parking. Senast kollad 2020-12-10 + // polar.it -> Polar Sunglasses + // polar.link -> Parkerad hos Sedo Domain Parking. Senast kollad 2020-12-10 + // polar.me -> Polar. Kanadensiskt företag inom marketing/advertising. + // polar.nu -> Polar bemanning AB i Nässjö + // polar.one -> Till salu hos dan.com. Senast kollad 2020-12-10 + // polar.vercel.app -> Oklart. Vercel Inc (vercel.com) verkar vara något webapp-företag (Next.js) +} diff --git a/global/overlay/etc/puppet/modules/soc/manifests/intelmq.pp b/global/overlay/etc/puppet/modules/soc/manifests/intelmq.pp index 428ef06..45e8c0b 100644 --- a/global/overlay/etc/puppet/modules/soc/manifests/intelmq.pp +++ b/global/overlay/etc/puppet/modules/soc/manifests/intelmq.pp @@ -78,11 +78,14 @@ class soc::intelmq( ensure => 'latest', } - file { '/opt/intelmq/install': - ensure => directory, - owner => 'intelmq', - group => 'intelmq', - mode => '0755', + $intelmq_dirs ['/opt/intelmq/install', '/opt/intelmq/var', '/opt/intelmq/var/lib', '/opt/intelmq/var/lib/bots', '/opt/intelmq/var/lib/bots/sieve', ] + $intelmq_dirs.each |String $intelmqdir| { + file { $intelmqdir: + ensure => directory, + owner => 'intelmq', + group => 'intelmq', + mode => '0755', + } } file { @@ -179,6 +182,17 @@ class soc::intelmq( creates => '/opt/intelmq/.pgsql-installed', } + $sieve_scripts = ['domains', 'phisers', 'squatters', ] + $sieve_scripts.each |String $sieve| { + file { "/opt/intelmq/var/lib/bots/sieve/${sieve}.sieve": + ensure => file, + owner => 'intelmq', + group => 'intelmq', + mode => '0644', + content => file("soc/intelmq/sieve/${sieve}.sieve", + } + } + file { '/etc/sudoers.d/01_intelmq-api': ensure => file, content => file('soc/intelmq/sudoers-01-intelmq-api'),