Here's a program I'm writing.
-- MikeOrr
code
baitd.py -- Tell intruders to go to hell.
Baitd is a server that pretends to speak several popular protocols (ssh,
telnet, http, smtp, dns) but sends nonsense responses and logs all input. It's bait for script kiddies who are attempting to crack the system, and also amusement as you analyze the logs. Of course it cannot coexist with a "real" service on the same port, but you can run it instead of unneeded services, or move the real services to other ports and have your legitimate users use those ports.
USAGE: baitd.py [options] [ip-or-domain:port:bait ...]
OPTIONS:
--daemon : Fork and run in background. (requires --pidfile)
--stop : Stop a running daemon. (requires --pidfile)
--pidfile : Filename to write the daemon process ID to.
--user : Run as this user.
--group : Run as this group.
ip-or-domain:port:protocol:bait
Which interfaces/ports to listen to, and which bait to use for each.
'protocol' describes the type of client expected:
telnet (literal) (default), ssh (SSL encoded), http, https, smtp, domain ...
Note that some are interactive, some are one-shot (one request/response),
others are non-interactive (one-shot request with no input data)
BAITS:
timeout : Timeout on every request.
hell : Send "Go to hell!" after every request.
eliza : Run the classic AI psychologist.
random15M : Send 15 MB of random data (accepts any #, units "K" and "b")
fortune : Send an offensive fortune ("fortune -O" command)
chameleon : Choose one of the other baits at random
honeypot : <Support other honeypot algorithms?>
CONFIGURATION FILE (Python module syntax):
logger : 'logging.logger' object for server activity. (Not user input.)
logdir : Directory to put logged user input, filenames "DATE_TIME_PORT".
access_log : Access log in CSV format.
baits : Dict of bait objects to map command-line args.
listen : Map these args instead of command line.
Default configuration is logger=<sys.stderr>, logdir=None, access_log=None, baits=<TODO>, listen=None. If 'DEBUG' environment variable is not empty, log level is set to DEBUG, else WARN.
ACCESS LOG:
2005-09-04 20:56:54, 127.0.0.1, 22 (port), username, password, bait, bytes received, bytes sent
- Rewrite log later with domains?
- Just log connections and forget about bytes received/sent?
- Write one log with connections, a second with bytes, a third with domains?
PHASE 1:
- Write the baits (except Eliza).
- Get server to work in foreground with telnet.
PHASE 2:
- Get server to work in foreground with ssh.
PHASE 3 (will prioritize later):
- Implement Eliza.
- Logging.
- Daemonize.
- Port to Twisted and support other protocols. baits module:
"""baits
"""
import random
from subprocess import PIPE, Popen
class Bait(object):
def __call__(self, data):
raise NotImplementedError("subclass responsibility")
class Timeout(Bait):
def __call__(self, data):
return ''
class Hell(Bait):
def __call__(self, data):
return "Go to hell!"
class Eliza(Bait):
def __call__(self, data):
raise NotImplementedError()
class Random(Bait):
#size = 15 * 1024 * 1024 # 15 Megabytes
size = 1024 # 1 KB
chunk_size = 1024 # 1 KB
def __call__(self, data):
chunk_size = self.chunk_size
remaining = self.size
while remaining > 0:
count = min(chunk_size, remaining)
remaining -= count
return os.urandom(count)
class Fortune(Bait):
command = "fortune -o"
def __call__(self, data):
return Popen(self.command, mode='r', bufsize=-1, stdout=PIPE).stdout
class Chameleon(Bait):
classes = [Timeout, Hell, Random, Fortune]
def __new__(klass):
return random.choice(klass.classes)()
baitmap = {
'timeout': Timeout,
'hell': Hell,
#'eliza': Eliza,
'random': Random,
'fortune': Fortune
}