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

Βασικές λειτουργίες
-------------------

Το honeyd μπορεί να προσομοιώσει εώς 216 εικονικά συστήματα . Κάθε ένα από αυτά τα εικονικά συστήματα μπορεί να προσομοιώσει υπηρεσίες που βασίζονται στα πρωτόκολλα SMTP, FTP, HTTP κλπ. Η χρήση του μπορεί να γίνει 

1. Για ερευνητικούς σκοπούς, όπως, για παράδειγμα, για εξόρυξη δεδομένων χρησιμοποιώντας τα στοιχεία που συλλέγονται από τις διάφορες επιθέσεις.
2. Για αντιπερισπασμό απέναντι σε κακόβουλους χάκερ , επιχειρώντας να "κρύψει" αληθινά συστήματα ανάμεσα σε εικονικά. Ο επιτιθέμενος θα αναγκαστεί να σπαταλήσει χρόνο, χρησιμοποιώντας εναλλακτικά μέσα για την ανακάλυψη των αληθινών συστημάτων. Αυτή η διαδικασία μπορεί να δώσει στον διαχειριστή του δικτύου τον απαραίτητο χρόνο για να λάβει τα κατάλληλα αντίμετρα. εφ' όσον διαπιστώσει ύποπτη κίνηση στο δίκτυο.

Τρόπος λειτουργίας
------------------

Η προσομοίωση των συστημάτων γίνεται χρησιμοποιώντας την τεχνική 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 	)
            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

1. ↑
2. ↑  «Αρχειοθετημένο αντίγραφο». Αρχειοθετήθηκε από το πρωτότυπο στις 4 Ιανουαρίου 2011. Ανακτήθηκε στις 16 Ιανουαρίου 2011.
3. ↑  «Αρχειοθετημένο αντίγραφο». Αρχειοθετήθηκε από το πρωτότυπο στις 6 Δεκεμβρίου 2010. Ανακτήθηκε στις 16 Ιανουαρίου 2011.
4. ↑