_botnet.py 3.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. This file is part of the UFONet project, https://ufonet.03c8.net
  5. Copyright (c) 2013/2026 | psy <epsylon@riseup.net>
  6. You should have received a copy of the GNU General Public License along
  7. with UFONet; if not, write to the Free Software Foundation, Inc., 51
  8. Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  9. """
  10. import ipaddress, os
  11. PLACEHOLDER_NETS = [
  12. ipaddress.ip_network("203.0.113.0/24"),
  13. ipaddress.ip_network("192.0.2.0/24"),
  14. ipaddress.ip_network("198.51.100.0/24"),
  15. ]
  16. def is_placeholder(entry):
  17. s = entry.strip()
  18. if not s:
  19. return True
  20. if s.startswith('<TBD:') and s.endswith('>'):
  21. return True
  22. if s.startswith(('http://', 'https://')):
  23. from urllib.parse import urlparse
  24. host = urlparse(s).hostname or ''
  25. else:
  26. host = s.split(':', 1)[0].split('/', 1)[0]
  27. try:
  28. ip = ipaddress.ip_address(host)
  29. except ValueError:
  30. return False
  31. for net in PLACEHOLDER_NETS:
  32. if ip in net:
  33. return True
  34. return False
  35. def load_botnet_file(path):
  36. if not os.path.exists(path):
  37. return [], False, False
  38. with open(path, encoding='utf-8', errors='replace') as f:
  39. entries = [l.strip() for l in f.readlines() if l.strip()]
  40. if not entries:
  41. return [], True, False
  42. all_placeholder = all(is_placeholder(e) for e in entries)
  43. return entries, False, all_placeholder
  44. GUIDANCE = {
  45. "open-redirect": "Find real 'zombies' via dorking: ./ufonet -s 'page.php?url=' (or --auto-search / --sd botnet/dorks.txt)",
  46. "dns": "Use any public open DNS resolver (1.1.1.1, 8.8.8.8) or a known recursive server in your scope.",
  47. "ntp": "Use pool.ntp.org, time.cloudflare.com, time.google.com, or a misconfigured NTPv2 server in your scope.",
  48. "snmp": "Scan UDP/161 in your authorized scope (community='public'). Dorking will NOT find these.",
  49. "memcached": "Scan UDP/11211 in your authorized scope (e.g. masscan/zmap). Dorking will NOT find these.",
  50. "cldap": "Scan UDP/389 in your authorized scope (Active Directory hosts replying to anonymous searchRequest). Dorking will NOT find these.",
  51. "ssdp": "Scan UDP/1900 in your authorized scope (UPnP-exposed routers). Dorking will NOT find these.",
  52. "chargen": "Extremely rare today. Scan UDP/19 in your authorized scope. Dorking will NOT find these.",
  53. "qotd": "Extremely rare today. Scan UDP/17 in your scope. Dorking will NOT find these.",
  54. "tftp": "Scan UDP/69 in your authorized scope. Dorking will NOT find these.",
  55. "wsdisco": "Scan UDP/3702 in your scope (printers, IP cameras). Dorking will NOT find these.",
  56. "coap": "Scan UDP/5683 in your scope (IoT). Dorking will NOT find these.",
  57. "mssql": "Scan UDP/1434 in your scope (SQL Server browser). Dorking will NOT find these.",
  58. "arms": "Scan UDP/3283 in your scope (Apple Remote Desktop). Dorking will NOT find these.",
  59. "plex": "Scan UDP/32414 in your scope (Plex GDM). Dorking will NOT find these.",
  60. "netbios": "Scan UDP/137 in your scope. Dorking will NOT find these.",
  61. "ripv1": "Scan UDP/520 in your scope (legacy router). Dorking will NOT find these.",
  62. "middlebox": "Identify censorship middleboxes via probing (CN/IR/RU/etc.). See the Geneva paper. Dorking will NOT find these.",
  63. "reflector": "Populate with real reflectors from your authorized scope. Dorking does NOT usually find these protocols.",
  64. }
  65. def warn_placeholders(label, file_path, kind="reflector"):
  66. print("[Info] [AI] [" + label + "] No real entries in botnet/" + os.path.basename(file_path) + " -> [Skipping]")