Honeyd



Περιγραφή 
Το honeyd είναι ένα ανοιχτού κώδικα, χαμηλής διαδραστικότητας εικονικό honeypot που επιτρέπει την δημιουργία εικονικών συστημάτων σε ένα δίκτυο. Τα εικονικά αυτά συστήματα μπορούν να προσομοιώσουν διαφόρων τύπων λειτουργικά συστήματα καθώς και ένα μεγάλο αριθμό από υπηρεσίες που αυτά παρέχουν. Δημιουργός του είναι ο Niels Provos.

Βασικές λειτουργίες 
Το honeyd μπορεί να προσομοιώσει εώς 216 εικονικά συστήματα  . Κάθε ένα από αυτά τα εικονικά συστήματα μπορεί να προσομοιώσει υπηρεσίες που βασίζονται στα πρωτόκολλα SMTP, FTP, HTTP κλπ. Η χρήση του μπορεί να γίνει 
 Για ερευνητικούς σκοπούς, όπως, για παράδειγμα, για εξόρυξη δεδομένων χρησιμοποιώντας τα στοιχεία που συλλέγονται από τις διάφορες επιθέσεις.
 Για αντιπερισπασμό απέναντι σε κακόβουλους χάκερ , επιχειρώντας να "κρύψει" αληθινά συστήματα ανάμεσα σε εικονικά. Ο επιτιθέμενος θα αναγκαστεί να σπαταλήσει χρόνο, χρησιμοποιώντας εναλλακτικά μέσα για την ανακάλυψη των αληθινών συστημάτων. Αυτή η διαδικασία μπορεί να δώσει στον διαχειριστή του δικτύου τον απαραίτητο χρόνο για να λάβει τα κατάλληλα αντίμετρα. εφ' όσον διαπιστώσει ύποπτη κίνηση στο δίκτυο.

Τρόπος λειτουργίας 
Η προσομοίωση των συστημάτων γίνεται χρησιμοποιώντας την τεχνική ARP spoofing. Τo honeyd μπορεί να ρυθμιστεί ώστε να καλύπτει το εύρος όλων των αχρησιμοποίητων IP διευθύνσεων στο δίκτυο.

Παράδειγμα αρχείου ρυθμίσεων 
Χρησιμοποιώντας το παρακάτω αρχείο ρυθμίσεων, το honeyd προσομοιώνει ένα σύστημα Windows , που έχει ανοιχτά τα TCP port 25 kai 139. Συγκεκριμένα για το port 25 (SMTP) έχουμε ενεργοποιήσει ένα python script που αναποκρίνεται προσομοιώνοντας ένα υποσύνολο των εντολών του πρωτοκόλλου SMTP κατά το RFC821

 create template
 set template personality "Microsoft Windows XP Professional SP1"
 add template tcp port 25 "python /tmp/smtp.py"
 add template tcp port 139 open
 set template default tcp action block
 set template uid 65534 gid 65534
 
 create default
 set default default tcp action block
 set default default udp action block
 set default default icmp action block
 
 bind 10.0.0.8 template

Script υπηρεσιών για το Honeyd 
Τα απλής μορφής script υπηρεσιών για το honeyd μπορούν να γραφούν σε μια scripting γλώσσα (Python, Perl, Bash script κλπ) . Συνήθως υλοποιούνται ως state machines, δέχονται δεδομένα από το standard input (stdin) και ανταποκρίνονται γράφοντας στο stadard output (stdout). To stderr μπορεί να χρησιμοποιηθεί για καταγραφή συμβάντων (logging) από την εκάστοτε εικονική υπηρεσία.

Το παράδειγμα που ακολουθεί είναι γραμμένο σε Python και προσομοιώνει μια υπηρεσία SMTP

 /*
  * Copyright (c) 2011 Lekkas Kwstas <kwstasl@gmail.com>
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
  *
  * 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.
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
  *
  * 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.
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 import sys
 import time
 import re
 
 
 DATE = time.strftime("%a, %d %b %Y %H:%M:%S +0200", time.localtime())
 DOMAIN = 'test.org'
 RCPTTO = 0
 MAILFROM = 0
 DATA = 0
 CRLF='\r\n'
 mail = ''
 list = []
 
 sys.stdout.write('220 test.org ESMTP Sendmail 8.13.8/8.13.8; '+DATE+CRLF)
 sys.stdout.flush();
 
 while True:
         input = sys.stdin.readline()
         input.strip()   # strip white spaces
         input_case = input  # keep case sensitive input
         input = input.upper()
         list = input.split()
     
         if len(list) == 0 and DATA == 1:
             mail = mail + CRLF
 
         elif len(list) == 0:
             sys.stdout.write('500 5.5.1 Command unrecognized: ""'+CRLF)
             sys.stdout.flush()
 
         elif list[0] == 'QUIT' and DATA == 0:
             sys.stdout.write('221 2.0.0 '+DOMAIN+' closing connection'+CRLF)
             sys.stdout.flush()
             sys.exit(0)
 
         elif list[0] == 'HELO' and DATA == 0:
             if len(list) == 1:
                 sys.stdout.write('501 5.0.0 helo requires domain address'+CRLF)
                 sys.stdout.flush()
 
             else:
                 sys.stdout.write('250-'+DOMAIN+' Hello '+list[1]+', pleased to meet you'+CRLF)
                 sys.stdout.flush()
         
         elif list[0] == 'EHLO' and DATA == 0:
             if len(list) == 1:
                 sys.stdout.write('501 5.0.0 helo requires domain address'+CRLF)
                 sys.stdout.flush()
 
             else:
                 sys.stdout.write('250-'+DOMAIN+' Hello '+list[1]+', pleased to meet you'+CRLF)
                 sys.stdout.write('250-ENHANCEDSTATUSCODES'+CRLF)
                 sys.stdout.write('250-PIPELINING'+CRLF)
                 sys.stdout.write('250-EXPN'+CRLF)
                 sys.stdout.write('250-VERB'+CRLF)
                 sys.stdout.write('250-8BITMIME'+CRLF)
                 sys.stdout.write('250-SIZE 10000000'+CRLF)
                 sys.stdout.write('250-DSN'+CRLF)
                 sys.stdout.write('250-ETRN'+CRLF)
                 sys.stdout.write('250-DELIVERBY'+CRLF)
                 sys.stdout.write('250 HELP'+CRLF)
         	sys.stdout.flush()
 
         elif list[0] == 'NOOP' and DATA == 0:
             sys.stdout.write('250 2.0.0 OK'+CRLF)
             sys.stdout.flush()
             
         elif list[0] == 'HELP' and DATA == 0:
             pr = sys.stdout.write
             sys.stdout.write('214-2.0.0 This is sendmail'+CRLF)
             sys.stdout.write('214-2.0.0 Topics:'+CRLF)
             sys.stdout.write('214-2.0.0      HELO    EHLO	MAIL	RCPT    DATA'+CRLF)
             sys.stdout.write('214-2.0.0      RSET    NOOP	QUIT	HELP    VRFY'+CRLF)
             sys.stdout.write('214-2.0.0      EXPN    VERB	ETRN	DSN     AUTH'+CRLF)
             sys.stdout.write('214-2.0.0      STARTTLS'+CRLF)
             sys.stdout.write('214-2.0.0 For more info use "HELP <topic>".'+CRLF)
             sys.stdout.write('214-2.0.0 To report bugs in the implementation see'+CRLF)
             sys.stdout.write('214-2.0.0 	http://www.sendmail.org/email-addresses.html'+CRLF)
             sys.stdout.write('214-2.0.0 For local information send email to Postmaster at your site.'+CRLF)
             sys.stdout.write('214 2.0.0 End of HELP info'+CRLF)
             sys.stdout.flush()
 
         elif list[0] == 'RSET' and DATA == 0:
             MAILFROM = 0
             RCPTTO = 0
             
         elif list[0] == 'MAIL' and DATA == 0:
             p = re.compile('MAIL(\s)+FROM(\s)*:(\s)*.+@.+[.].+(\r)*\n')
             if MAILFROM == 1:
                 sys.stdout.write('503 5.5.0 Sender already specified')
                 sys.stdout.flush()
             elif p.match(input) != None:  # we have a match
                 addrl = input_case.split(':')
                 addr = addrl[1]
                 addr = addr.strip()
                 sys.stdout.write('250 2.1.0 '+addr+'... Sender ok'+CRLF)
                 sys.stdout.flush()
                 MAILFROM = 1
             else:
                 MAILFROM = 0
                 er = ""
                 if len(list) > 1:
                     er = list[1]
                 else:
                     er = ""
                 sys.stdout.write('501 5.5.2 Syntax error in parameters scanning "'+er+'"'+CRLF)
                 sys.stdout.flush()
             
         elif list[0] == 'RCPT' and DATA == 0:
             p = re.compile('RCPT(\s)+TO(\s)*:(\s)*.+@.+[.].+(\r)*\n')
             if p.match(input) != None:  # we have a match
                 addrl = input_case.split(':')
                 addr = addrl[1]
                 addr = addr.strip()
                 sys.stdout.write('250 2.1.5 '+addr+'... Recipient ok'+CRLF)
                 sys.stdout.flush()
                 RCPTTO = 1
             else:
                 RCPTTO = 0
                 er = ""
                 if len(list) > 1:
                     er = list[1]
                 else:
                     er = ""
                 sys.stdout.write('501 5.5.2 Syntax error in parameters scanning "'+er+'"'+CRLF)
                 sys.stdout.flush()
             
 
         elif list[0] == 'DATA' and DATA == 0:
             if MAILFROM == 0:
                 sys.stdout.write('503 5.0.0 Need MAIL command'+CRLF)
                 sys.stdout.flush()
             elif RCPTTO == 0:
                 sys.stdout.write('503 5.0.0 Need RCPT (recipient)'+CRLF)
                 sys.stdout.flush()
             else:
                 sys.stdout.write('354 Enter mail, end with "." on a line by itself'+CRLF)
                 sys.stdout.flush()
                 DATA = 1
                 
         else:
             p = re.compile('[.](\r)*\n')
             if DATA == 1 and p.match(input) == None:
                 mail = mail + input_case
             elif DATA == 1 and p.match(input) != None:  # we have a '.' by itself
                 sys.stdout.write('250 2.0.0 oBV492kc002213 Message accepted for delivery'+CRLF)
                 sys.stdout.flush()
                 DATA = 0
                 RCPTTO = 0
                 MAILFROM = 0
                 sys.stderr.write('---- MAIL START ---- '+CRLF)
 		sys.stderr.write(mail) 				# logging
                 sys.stderr.write('---- MAIL END ----'+CRLF)
                 sys.stderr.flush()
                 mail = ""
             else:
                sys.stdout.write('500 5.5.1 Command unrecognized: ""'+CRLF)
                sys.stdout.flush()

Notes 

Ασφάλεια υπολογιστών
Ελεύθερο λογισμικό