home *** CD-ROM | disk | FTP | other *** search
/ ftp.ac-grenoble.fr / 2015.02.ftp.ac-grenoble.fr.tar / ftp.ac-grenoble.fr / pub / slis / security / confickermon / confickermon.py < prev    next >
Text File  |  2009-02-26  |  5KB  |  110 lines

  1. #! /usr/bin/env python
  2. # -*- coding: iso-8859-15 -*-
  3.  
  4. ###############################################################################
  5. ##                                                                           ##
  6. ##     Confickermon.py - Version 0.2.2                                       ##
  7. ##                                                                           ##
  8. ###############################################################################
  9. ##                                                                           ##
  10. ## confickermon.py -- try to detect Conficker worm and friends activities.   ##
  11. ##              all hard stuff made by scapy :                               ##
  12. ##              http://www.secdev.org/projects/scapy/                        ##
  13. ##                                                                           ##
  14. ## Copyright (C) 2009 Luc Milland <luc@ac-grenoble.fr>, AcadΘmie de Grenobl. ##
  15. ##                                                                           ##
  16. ## This program is free software; you can redistribute it and/or modify it   ##
  17. ## under the terms of the GNU General Public License version 2 as            ##
  18. ## published by the Free Software Foundation; version 2.                     ##
  19. ##                                                                           ##
  20. ## This program is distributed in the hope that it will be useful, but       ##
  21. ## WITHOUT ANY WARRANTY; without even the implied warranty of                ##
  22. ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         ##
  23. ## General Public License for more details.                                  ##
  24. ##                                                                           ##
  25. ###############################################################################
  26.  
  27. import sys
  28. import StringIO
  29. import smtplib
  30. from email.MIMEText import MIMEText
  31. from email.Utils import formatdate
  32. from urllib import urlopen
  33. from socket import gethostname
  34. from scapy import *
  35.  
  36. # Some constants you may change :
  37. MAIL_SUBJ = '[confickermon] %s : Alerte CONFICKER'
  38. MAIL_BODY = 'une requete vers %s est partie de %s.'
  39. MAIL_SENDER = 'confickermon@ac-grenoble.fr'
  40. MAIL_DEST = 'slismaster@ac-grenoble.fr'
  41. SMTP_HOST = 'smtp.ac-grenoble.fr'
  42. # Interface to listen to.
  43. # Set it to None to listen to all interfaces or if you don't know the iface name (nt serveurs ?)
  44. IFACE = 'eth1' # zombified lan workstations are our target :)
  45. BLACKLIST_URL = 'http://ftp.ac-grenoble.fr/slis/security/confickermon/last_conficker_bl.txt'
  46.  
  47. # setting scapy.conf.color_theme to noTheme to get reports in clean way
  48. conf.color_theme = NoTheme()
  49.  
  50. # Retrieving list of domains contacted by Confiker
  51. domains = urlopen(BLACKLIST_URL)
  52. domains = [ line.strip() for line in domains.readlines() ]
  53.  
  54. # utils
  55. def domain_from_http_host(load):
  56.     load = load.lower().split()
  57.     if not 'host:' in load:
  58.         return False
  59.     try:
  60.         host = load[load.index('host:') + 1]
  61.     except IndexError:
  62.         return False
  63.     domain = '.'.join(host.split('.')[-2:])
  64.     return domain
  65.  
  66. def mail_it(hostname, src_ip, domain, packet):
  67.     # catching the nice packet.show() print from stdout into variable
  68.     tmp_stdout = StringIO.StringIO()
  69.     sys.stdout = tmp_stdout
  70.     packet.show()
  71.     sys.stdout = sys.__stdout__
  72.     detail = tmp_stdout.getvalue()
  73.     tmp_stdout.close()
  74.     # end catch
  75.     body = MAIL_BODY % (domain, src_ip)
  76.     body = '\nDetail:\n-------\n'.join([body, detail])
  77.     msg = MIMEText(body)                       
  78.     msg['From'] = MAIL_SENDER
  79.     msg['To'] = MAIL_DEST
  80.     msg['Date'] = formatdate(localtime=True)
  81.     msg['Subject'] = MAIL_SUBJ % hostname
  82.     msg['Content-Type'] = 'text/plain; charset=iso-8859-15'
  83.     smtp = smtplib.SMTP(SMTP_HOST)
  84.     smtp.sendmail(MAIL_SENDER, MAIL_DEST, msg.as_string())
  85.     smtp.close()
  86.     return
  87.  
  88. # Processing stuff
  89. def conficker_filter(packet):
  90.     dns_match = packet.haslayer(DNS) \
  91.                 and packet[DNS].qr == 0 \
  92.                 and packet[DNS].qd.qname.strip('.') in domains
  93.     http_match = packet.haslayer(TCP) \
  94.                 and (packet[TCP].dport==80 or packet[TCP].dport==3128) \
  95.                 and packet.haslayer(Raw) \
  96.                 and domain_from_http_host(packet[Raw].load) in domains
  97.     return dns_match or http_match
  98.  
  99. def callback(packet):
  100.     src_ip = packet[IP].src
  101.     domain = packet.haslayer(DNS) and packet[DNS].qd.qname.strip('.') or domain_from_http_host(packet[Raw].load)
  102.     hostname = gethostname()
  103.     mail_it(hostname, src_ip, domain, packet)
  104.     return
  105.  
  106. # go sniff !
  107. if __name__=='__main__':
  108.     sniff(iface=IFACE, lfilter=conficker_filter, prn=callback, store=0)
  109.  
  110.