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 >
Wrap
Text File
|
2009-02-26
|
5KB
|
110 lines
#! /usr/bin/env python
# -*- coding: iso-8859-15 -*-
###############################################################################
## ##
## Confickermon.py - Version 0.2.2 ##
## ##
###############################################################################
## ##
## confickermon.py -- try to detect Conficker worm and friends activities. ##
## all hard stuff made by scapy : ##
## http://www.secdev.org/projects/scapy/ ##
## ##
## Copyright (C) 2009 Luc Milland <luc@ac-grenoble.fr>, AcadΘmie de Grenobl. ##
## ##
## This program is free software; you can redistribute it and/or modify it ##
## under the terms of the GNU General Public License version 2 as ##
## published by the Free Software Foundation; version 2. ##
## ##
## This program is distributed in the hope that it will be useful, but ##
## WITHOUT ANY WARRANTY; without even the implied warranty of ##
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ##
## General Public License for more details. ##
## ##
###############################################################################
import sys
import StringIO
import smtplib
from email.MIMEText import MIMEText
from email.Utils import formatdate
from urllib import urlopen
from socket import gethostname
from scapy import *
# Some constants you may change :
MAIL_SUBJ = '[confickermon] %s : Alerte CONFICKER'
MAIL_BODY = 'une requete vers %s est partie de %s.'
MAIL_SENDER = 'confickermon@ac-grenoble.fr'
MAIL_DEST = 'slismaster@ac-grenoble.fr'
SMTP_HOST = 'smtp.ac-grenoble.fr'
# Interface to listen to.
# Set it to None to listen to all interfaces or if you don't know the iface name (nt serveurs ?)
IFACE = 'eth1' # zombified lan workstations are our target :)
BLACKLIST_URL = 'http://ftp.ac-grenoble.fr/slis/security/confickermon/last_conficker_bl.txt'
# setting scapy.conf.color_theme to noTheme to get reports in clean way
conf.color_theme = NoTheme()
# Retrieving list of domains contacted by Confiker
domains = urlopen(BLACKLIST_URL)
domains = [ line.strip() for line in domains.readlines() ]
# utils
def domain_from_http_host(load):
load = load.lower().split()
if not 'host:' in load:
return False
try:
host = load[load.index('host:') + 1]
except IndexError:
return False
domain = '.'.join(host.split('.')[-2:])
return domain
def mail_it(hostname, src_ip, domain, packet):
# catching the nice packet.show() print from stdout into variable
tmp_stdout = StringIO.StringIO()
sys.stdout = tmp_stdout
packet.show()
sys.stdout = sys.__stdout__
detail = tmp_stdout.getvalue()
tmp_stdout.close()
# end catch
body = MAIL_BODY % (domain, src_ip)
body = '\nDetail:\n-------\n'.join([body, detail])
msg = MIMEText(body)
msg['From'] = MAIL_SENDER
msg['To'] = MAIL_DEST
msg['Date'] = formatdate(localtime=True)
msg['Subject'] = MAIL_SUBJ % hostname
msg['Content-Type'] = 'text/plain; charset=iso-8859-15'
smtp = smtplib.SMTP(SMTP_HOST)
smtp.sendmail(MAIL_SENDER, MAIL_DEST, msg.as_string())
smtp.close()
return
# Processing stuff
def conficker_filter(packet):
dns_match = packet.haslayer(DNS) \
and packet[DNS].qr == 0 \
and packet[DNS].qd.qname.strip('.') in domains
http_match = packet.haslayer(TCP) \
and (packet[TCP].dport==80 or packet[TCP].dport==3128) \
and packet.haslayer(Raw) \
and domain_from_http_host(packet[Raw].load) in domains
return dns_match or http_match
def callback(packet):
src_ip = packet[IP].src
domain = packet.haslayer(DNS) and packet[DNS].qd.qname.strip('.') or domain_from_http_host(packet[Raw].load)
hostname = gethostname()
mail_it(hostname, src_ip, domain, packet)
return
# go sniff !
if __name__=='__main__':
sniff(iface=IFACE, lfilter=conficker_filter, prn=callback, store=0)