build-phishing-domainset.js 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. const psl = require('psl');
  2. const { processFilterRules } = require('./lib/parse-filter.js');
  3. const fs = require('fs');
  4. const path = require('path');
  5. const WHITELIST_DOMAIN = new Set([]);
  6. const BLACK_TLD = [
  7. '.xyz',
  8. '.top',
  9. '.win',
  10. '.vip',
  11. '.site',
  12. '.space',
  13. '.online',
  14. '.icu',
  15. '.fun',
  16. '.shop',
  17. '.cool',
  18. '.cyou',
  19. '.id'
  20. ];
  21. (async () => {
  22. const domainSet = Array.from(
  23. (
  24. await processFilterRules('https://curbengh.github.io/phishing-filter/phishing-filter-agh.txt')
  25. ).black
  26. );
  27. const domainCountMap = {};
  28. for (let i = 0, len = domainSet.length; i < len; i++) {
  29. const line = domainSet[i];
  30. // starts with #
  31. if (line.charCodeAt(0) === 35) {
  32. continue;
  33. }
  34. if (line.trim().length === 0) {
  35. continue;
  36. }
  37. const domain = line.charCodeAt(0) === 46 ? line.slice(1) : line;
  38. if (line.length > 25) {
  39. const parsed = psl.parse(domain);
  40. if (parsed.input === parsed.tld) {
  41. continue;
  42. }
  43. const apexDomain = parsed.domain
  44. if (WHITELIST_DOMAIN.has(apexDomain)) {
  45. continue;
  46. }
  47. domainCountMap[apexDomain] ||= 0;
  48. domainCountMap[apexDomain] += 1;
  49. }
  50. }
  51. const results = [];
  52. Object.entries(domainCountMap).forEach(([domain, count]) => {
  53. if (
  54. count >= 8
  55. && BLACK_TLD.some(tld => domain.endsWith(tld))
  56. ) {
  57. results.push('.' + domain);
  58. }
  59. });
  60. const filePath = path.resolve(__dirname, '../List/domainset/reject_phishing.conf');
  61. await fs.promises.writeFile(filePath, results.join('\n'), 'utf-8');
  62. })();