mirror of https://github.com/desaster/kippo.git
initial import
git-svn-id: https://kippo.googlecode.com/svn/trunk@1 951d7100-d841-11de-b865-b3884708a8e2
This commit is contained in:
commit
2954787fd7
|
@ -0,0 +1,15 @@
|
|||
Kippo
|
||||
|
||||
http://www.rpg.fi/kippo/
|
||||
|
||||
Copyright (C) 2009 Upi Tamminen
|
||||
|
||||
Kippo is a low interaction SSH honeypot intended to become a bit more higher
|
||||
interaction honeypot than an average low interactive honeypot.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Kippo was inspired by Kojoney, http://kojoney.sourceforge.net/
|
||||
-------------------------------------------------------------------------------
|
||||
Thanks for testing, ideas:
|
||||
- Viacheslav Slavinsky
|
||||
-------------------------------------------------------------------------------
|
|
@ -0,0 +1,106 @@
|
|||
import os, time
|
||||
from core.Kippo import HoneyPotCommand
|
||||
from core.fstypes import *
|
||||
|
||||
class command_whoami(HoneyPotCommand):
|
||||
def call(self, args):
|
||||
self.honeypot.writeln(self.honeypot.user.username)
|
||||
|
||||
class command_cat(HoneyPotCommand):
|
||||
def call(self, args):
|
||||
path = self.honeypot.fs.resolve_path(args, self.honeypot.cwd)
|
||||
|
||||
if not path or not self.honeypot.fs.exists(path):
|
||||
self.honeypot.writeln(
|
||||
'bash: cat: %s: No such file or directory' % args)
|
||||
return
|
||||
|
||||
fakefile = './honeyfs/%s' % path
|
||||
if os.path.exists(fakefile) and \
|
||||
not os.path.islink(fakefile) and os.path.isfile(fakefile):
|
||||
f = file(fakefile, 'r')
|
||||
self.honeypot.terminal.write(f.read())
|
||||
f.close()
|
||||
|
||||
class command_cd(HoneyPotCommand):
|
||||
def call(self, args):
|
||||
if not args:
|
||||
args = '/root'
|
||||
|
||||
try:
|
||||
newpath = self.honeypot.fs.resolve_path(args, self.honeypot.cwd)
|
||||
newdir = self.honeypot.fs.get_path(newpath)
|
||||
except:
|
||||
newdir = None
|
||||
|
||||
if newdir is None:
|
||||
self.honeypot.writeln(
|
||||
'bash: cd: %s: No such file or directory' % args)
|
||||
return
|
||||
self.honeypot.cwd = newpath
|
||||
|
||||
class command_rm(HoneyPotCommand):
|
||||
def call(self, args):
|
||||
for f in args.split(' '):
|
||||
path = self.honeypot.fs.resolve_path(f, self.honeypot.cwd)
|
||||
dir = self.honeypot.fs.get_path('/'.join(path.split('/')[:-1]))
|
||||
basename = path.split('/')[-1]
|
||||
contents = [x for x in dir]
|
||||
for i in dir[:]:
|
||||
if i[A_NAME] == basename:
|
||||
if i[A_TYPE] == T_DIR:
|
||||
self.honeypot.writeln(
|
||||
'rm: cannot remove `%s\': Is a directory' % \
|
||||
i[A_NAME])
|
||||
else:
|
||||
dir.remove(i)
|
||||
|
||||
class command_uptime(HoneyPotCommand):
|
||||
def call(self, args):
|
||||
self.honeypot.writeln(
|
||||
' %s up 14 days, 3:53, 0 users, load average: 0.08, 0.02, 0.01' % \
|
||||
time.strftime('%T'))
|
||||
#self.honeypot.writeln('USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT')
|
||||
|
||||
class command_w(HoneyPotCommand):
|
||||
def call(self, args):
|
||||
self.honeypot.writeln(
|
||||
' %s up 14 days, 3:53, 0 users, load average: 0.08, 0.02, 0.01' % \
|
||||
time.strftime('%T'))
|
||||
self.honeypot.writeln('USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT')
|
||||
|
||||
class command_echo(HoneyPotCommand):
|
||||
def call(self, args):
|
||||
self.honeypot.writeln(args)
|
||||
|
||||
class command_quit(HoneyPotCommand):
|
||||
def call(self, args):
|
||||
self.honeypot.terminal.loseConnection()
|
||||
|
||||
class command_clear(HoneyPotCommand):
|
||||
def call(self, args):
|
||||
self.honeypot.terminal.reset()
|
||||
|
||||
class command_vi(HoneyPotCommand):
|
||||
def call(self, args):
|
||||
self.honeypot.writeln('E558: Terminal entry not found in terminfo')
|
||||
|
||||
class command_mount(HoneyPotCommand):
|
||||
def call(self, args):
|
||||
if len(args.strip()):
|
||||
return
|
||||
for i in [
|
||||
'/dev/sda1 on / type ext3 (rw,errors=remount-ro)',
|
||||
'tmpfs on /lib/init/rw type tmpfs (rw,nosuid,mode=0755)',
|
||||
'proc on /proc type proc (rw,noexec,nosuid,nodev)',
|
||||
'sysfs on /sys type sysfs (rw,noexec,nosuid,nodev)',
|
||||
'udev on /dev type tmpfs (rw,mode=0755)',
|
||||
'tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev)',
|
||||
'devpts on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=620)',
|
||||
]:
|
||||
self.honeypot.writeln(i)
|
||||
|
||||
|
||||
class command_nop(HoneyPotCommand):
|
||||
def call(self, args):
|
||||
pass
|
|
@ -0,0 +1,72 @@
|
|||
from core.Kippo import HoneyPotCommand
|
||||
from core.fstypes import *
|
||||
import stat, time
|
||||
|
||||
class command_ls(HoneyPotCommand):
|
||||
|
||||
def uid2name(self, uid):
|
||||
if uid == 0:
|
||||
return 'root'
|
||||
return uid
|
||||
|
||||
def gid2name(self, gid):
|
||||
if gid == 0:
|
||||
return 'root'
|
||||
return gid
|
||||
|
||||
def call(self, args):
|
||||
path = self.honeypot.cwd
|
||||
paths = []
|
||||
if len(args):
|
||||
for arg in args.split():
|
||||
if not arg.startswith('-'):
|
||||
paths.append(self.honeypot.fs.resolve_path(arg,
|
||||
self.honeypot.cwd))
|
||||
if not paths:
|
||||
self.do_ls_l(path)
|
||||
else:
|
||||
for path in paths:
|
||||
self.do_ls_l(path)
|
||||
|
||||
def do_ls_l(self, path):
|
||||
try:
|
||||
files = self.honeypot.fs.list_files(path)
|
||||
except:
|
||||
self.honeypot.writeln(
|
||||
'ls: cannot access %s: No such file or directory' % path)
|
||||
return
|
||||
|
||||
largest = 0
|
||||
if len(files):
|
||||
largest = max([x[A_SIZE] for x in files])
|
||||
|
||||
for file in files:
|
||||
perms = ['-'] * 10
|
||||
|
||||
if file[A_MODE] & stat.S_IRUSR: perms[1] = 'r'
|
||||
if file[A_MODE] & stat.S_IWUSR: perms[2] = 'w'
|
||||
if file[A_MODE] & stat.S_IXUSR: perms[3] = 'x'
|
||||
|
||||
if file[A_MODE] & stat.S_IRGRP: perms[4] = 'r'
|
||||
if file[A_MODE] & stat.S_IWGRP: perms[5] = 'w'
|
||||
if file[A_MODE] & stat.S_IXGRP: perms[6] = 'x'
|
||||
|
||||
if file[A_MODE] & stat.S_IROTH: perms[7] = 'r'
|
||||
if file[A_MODE] & stat.S_IWOTH: perms[8] = 'w'
|
||||
if file[A_MODE] & stat.S_IXOTH: perms[9] = 'x'
|
||||
|
||||
if file[A_TYPE] == T_DIR:
|
||||
perms[0] = 'd'
|
||||
|
||||
perms = ''.join(perms)
|
||||
ctime = time.localtime(file[A_CTIME])
|
||||
|
||||
l = '%s 1 %s %s %s %s %s' % \
|
||||
(perms,
|
||||
self.uid2name(file[A_UID]),
|
||||
self.gid2name(file[A_GID]),
|
||||
str(file[A_SIZE]).rjust(len(str(largest))),
|
||||
time.strftime('%Y-%m-%d %H:%M', ctime),
|
||||
file[A_NAME])
|
||||
|
||||
self.honeypot.writeln(l)
|
|
@ -0,0 +1,35 @@
|
|||
from core.Kippo import HoneyPotCommand
|
||||
from core.fstypes import *
|
||||
import stat, time, urlparse, random
|
||||
|
||||
class command_tar(HoneyPotCommand):
|
||||
|
||||
def call(self, args):
|
||||
if len(args.split()) < 2:
|
||||
self.honeypot.writeln('tar: You must specify one of the `-Acdtrux\' options')
|
||||
self.honeypot.wirteln('Try `tar --help\' or `tar --usage\' for more information.')
|
||||
return
|
||||
|
||||
filename = args.split()[1]
|
||||
|
||||
path = self.honeypot.fs.resolve_path(filename, self.honeypot.cwd)
|
||||
if not path or not self.honeypot.fs.exists(path):
|
||||
self.honeypot.writeln('tar: rs: Cannot open: No such file or directory')
|
||||
self.honeypot.writeln('tar: Error is not recoverable: exiting now')
|
||||
self.honeypot.writeln('tar: Child returned status 2')
|
||||
self.honeypot.writeln('tar: Error exit delayed from previous errors')
|
||||
return
|
||||
|
||||
cwd = self.honeypot.fs.get_path(self.honeypot.cwd)
|
||||
for f in (
|
||||
'tiffany1.jpg',
|
||||
'tiffany3.jpg',
|
||||
'tiffany4.jpg',
|
||||
'tiffany5.jpg',
|
||||
'tiffany6.jpg',
|
||||
'XxX Anal Thunder 5 XxX.AVI',
|
||||
):
|
||||
size = 1000000 + int(random.random() * 4000000)
|
||||
cwd.append((
|
||||
f, T_FILE, 0, 0, size, 33188, time.time(), [], None))
|
||||
self.honeypot.writeln('./%s' % f)
|
|
@ -0,0 +1,43 @@
|
|||
from core.Kippo import HoneyPotCommand
|
||||
from core.fstypes import *
|
||||
import stat, time, urlparse, random
|
||||
|
||||
class command_wget(HoneyPotCommand):
|
||||
|
||||
def call(self, args):
|
||||
if not len(args):
|
||||
self.honeypot.writeln('wget: missing URL')
|
||||
self.honeypot.writeln('Usage: wget [OPTION]... [URL]...')
|
||||
self.honeypot.terminal.nextLine()
|
||||
self.honeypot.writeln('Try `wget --help\' for more options.')
|
||||
return
|
||||
|
||||
# ('http', 'www.google.fi', '/test.txt', '', '', '')
|
||||
url = urlparse.urlparse(args)
|
||||
size = 10000 + int(random.random() * 40000)
|
||||
speed = 50 + int(random.random() * 300)
|
||||
|
||||
output = """
|
||||
--%(stamp)s-- %(url)s
|
||||
Connecting to %(host)s:80... connected.
|
||||
HTTP request sent, awaiting response... 200 OK
|
||||
Length: unspecified [text/html]
|
||||
Saving to: `%(file)s'
|
||||
|
||||
[ <=> ] 6,214 --.-K/s in 0.04s
|
||||
|
||||
%(stamp)s (%(speed)s KB/s) - `%(file)s' saved [%(size)s]
|
||||
|
||||
""" % {
|
||||
'stamp': time.strftime('%Y-%m-%d %T'),
|
||||
'url': args,
|
||||
'file': url[2].split('/')[-1],
|
||||
'host': url[1],
|
||||
'size': size,
|
||||
'speed': speed,
|
||||
}
|
||||
self.honeypot.writeln(output)
|
||||
cwd = self.honeypot.fs.get_path(self.honeypot.cwd)
|
||||
cwd.append((
|
||||
url[2].split('/')[-1],
|
||||
T_FILE, 0, 0, size, 33188, time.time(), [], None))
|
|
@ -0,0 +1,235 @@
|
|||
from twisted.cred import portal, checkers, credentials
|
||||
from twisted.conch import error, avatar, recvline, interfaces as conchinterfaces
|
||||
from twisted.conch.ssh import factory, userauth, connection, keys, session, common
|
||||
from twisted.conch.insults import insults
|
||||
from twisted.application import service, internet
|
||||
from twisted.protocols.policies import TrafficLoggingFactory
|
||||
from twisted.internet import reactor, protocol
|
||||
from twisted.python import log
|
||||
from zope.interface import implements
|
||||
from copy import deepcopy
|
||||
import sys, os, random, pickle, time, stat, copy
|
||||
|
||||
from core import ttylog
|
||||
from core.fstypes import *
|
||||
|
||||
moi = 1
|
||||
|
||||
class HoneyPotProtocol(recvline.HistoricRecvLine):
|
||||
def __init__(self, user, env):
|
||||
self.user = user
|
||||
self.env = env
|
||||
self.cwd = '/root'
|
||||
self.fs = HoneyPotFilesystem(deepcopy(self.env.fs))
|
||||
|
||||
def connectionMade(self):
|
||||
recvline.HistoricRecvLine.connectionMade(self)
|
||||
self.showPrompt()
|
||||
|
||||
# Overriding to prevent terminal.reset()
|
||||
def initializeScreen(self):
|
||||
self.setInsertMode()
|
||||
|
||||
def showPrompt(self):
|
||||
path = self.cwd
|
||||
if path == '/root':
|
||||
path = '~'
|
||||
self.terminal.write('sales:%s# ' % path)
|
||||
|
||||
def getCommandFunc(self, cmd):
|
||||
return getattr(self, 'do_' + cmd, None)
|
||||
|
||||
def getCommand(self, cmd, args):
|
||||
path = None
|
||||
|
||||
if cmd in self.env.commands:
|
||||
return self.env.commands[cmd](self)
|
||||
|
||||
if cmd[0] in ('.', '/'):
|
||||
path = self.fs.resolve_path(cmd, self.cwd)
|
||||
if not self.fs.exists(path):
|
||||
return None
|
||||
else:
|
||||
for i in ['%s/%s' % (x, cmd) for x in \
|
||||
'/bin', '/usr/bin', '/sbin', '/usr/sbin']:
|
||||
if self.fs.exists(i):
|
||||
path = i
|
||||
break
|
||||
if path in self.env.commands:
|
||||
return self.env.commands[path](self)
|
||||
return None
|
||||
|
||||
def lineReceived(self, line):
|
||||
line = line.strip()
|
||||
if line:
|
||||
print 'CMD: %s' % line
|
||||
cmdAndArgs = line.split(' ', 1)
|
||||
cmd = cmdAndArgs[0]
|
||||
args = ''
|
||||
if len(cmdAndArgs) > 1:
|
||||
args = cmdAndArgs[1]
|
||||
obj = self.getCommand(cmd, args)
|
||||
if obj:
|
||||
try:
|
||||
obj.call(args)
|
||||
del obj
|
||||
except Exception, e:
|
||||
print e
|
||||
self.writeln("Segmentation fault")
|
||||
else:
|
||||
self.writeln('bash: %s: command not found' % cmd)
|
||||
self.showPrompt()
|
||||
|
||||
def keystrokeReceived(self, keyID, modifier):
|
||||
ttylog.ttylog_write(self.terminal.ttylog_file, len(keyID),
|
||||
ttylog.DIR_READ, time.time(), keyID)
|
||||
recvline.HistoricRecvLine.keystrokeReceived(self, keyID, modifier)
|
||||
|
||||
def writeln(self, data):
|
||||
self.terminal.write(data)
|
||||
self.terminal.nextLine()
|
||||
|
||||
class HoneyPotCommand(object):
|
||||
def __init__(self, honeypot):
|
||||
self.honeypot = honeypot
|
||||
|
||||
def call(self, *args):
|
||||
self.honeypot.writeln('Hello World!')
|
||||
|
||||
class LoggingServerProtocol(insults.ServerProtocol):
|
||||
def connectionMade(self):
|
||||
print dir(self.transport.session)
|
||||
#print self.transport.session.getHost()
|
||||
#print self.transport.session.getPeer()
|
||||
print self.transport.session.id
|
||||
self.ttylog_file = './log/tty/%s-%s.log' % \
|
||||
(time.strftime('%Y%m%d-%H%M%S'), int(random.random() * 10000))
|
||||
print 'Opening TTY log: %s' % self.ttylog_file
|
||||
ttylog.ttylog_open(self.ttylog_file, time.time())
|
||||
self.ttylog_open = True
|
||||
insults.ServerProtocol.connectionMade(self)
|
||||
|
||||
def write(self, bytes):
|
||||
if self.ttylog_open:
|
||||
ttylog.ttylog_write(self.ttylog_file, len(bytes),
|
||||
ttylog.DIR_WRITE, time.time(), bytes)
|
||||
insults.ServerProtocol.write(self, bytes)
|
||||
|
||||
def connectionLost(self, reason):
|
||||
if self.ttylog_open:
|
||||
ttylog.ttylog_close(self.ttylog_file, time.time())
|
||||
self.ttylog_open = False
|
||||
|
||||
class HoneyPotAvatar(avatar.ConchUser):
|
||||
implements(conchinterfaces.ISession)
|
||||
|
||||
def __init__(self, username, env):
|
||||
avatar.ConchUser.__init__(self)
|
||||
self.username = username
|
||||
self.env = env
|
||||
self.channelLookup.update({'session':session.SSHSession})
|
||||
|
||||
def openShell(self, protocol):
|
||||
serverProtocol = LoggingServerProtocol(HoneyPotProtocol, self, self.env)
|
||||
serverProtocol.makeConnection(protocol)
|
||||
protocol.makeConnection(session.wrapProtocol(serverProtocol))
|
||||
|
||||
def getPty(self, terminal, windowSize, attrs):
|
||||
return None
|
||||
|
||||
def execCommand(self, protocol, cmd):
|
||||
raise NotImplementedError
|
||||
|
||||
def closed(self):
|
||||
pass
|
||||
|
||||
class HoneyPotEnvironment(object):
|
||||
def __init__(self):
|
||||
from core.cmdl import cmdl
|
||||
self.commands = cmdl
|
||||
|
||||
print 'Loading filesystem...',
|
||||
sys.stdout.flush()
|
||||
self.fs = pickle.load(file('fs.pickle'))
|
||||
print 'done'
|
||||
|
||||
class HoneyPotFilesystem(object):
|
||||
def __init__(self, fs):
|
||||
self.fs = fs
|
||||
|
||||
def resolve_path(self, path, cwd):
|
||||
pieces = path.rstrip('/').split('/')
|
||||
|
||||
if path[0] == '/':
|
||||
cwd = []
|
||||
else:
|
||||
cwd = [x for x in cwd.split('/') if len(x) and x is not None]
|
||||
|
||||
while 1:
|
||||
if not len(pieces):
|
||||
break
|
||||
piece = pieces.pop(0)
|
||||
if piece == '..':
|
||||
if len(cwd): cwd.pop()
|
||||
continue
|
||||
if piece in ('.', ''):
|
||||
continue
|
||||
cwd.append(piece)
|
||||
|
||||
return '/%s' % '/'.join(cwd)
|
||||
|
||||
def get_path(self, path):
|
||||
p = self.fs
|
||||
for i in path.split('/'):
|
||||
if not i:
|
||||
continue
|
||||
p = [x for x in p[A_CONTENTS] if x[A_NAME] == i][0]
|
||||
return p[A_CONTENTS]
|
||||
|
||||
def list_files(self, path):
|
||||
return self.get_path(path)
|
||||
|
||||
def exists(self, path):
|
||||
pieces = path.strip('/').split('/')
|
||||
p = self.fs
|
||||
while 1:
|
||||
if not len(pieces):
|
||||
break
|
||||
piece = pieces.pop(0)
|
||||
if piece not in [x[A_NAME] for x in p[A_CONTENTS]]:
|
||||
return False
|
||||
p = [x for x in p[A_CONTENTS] \
|
||||
if x[A_NAME] == piece][0]
|
||||
return True
|
||||
|
||||
class HoneyPotRealm:
|
||||
implements(portal.IRealm)
|
||||
|
||||
def __init__(self):
|
||||
# I don't know if i'm supposed to keep static stuff here
|
||||
self.env = HoneyPotEnvironment()
|
||||
|
||||
def requestAvatar(self, avatarId, mind, *interfaces):
|
||||
if conchinterfaces.IConchUser in interfaces:
|
||||
return interfaces[0], \
|
||||
HoneyPotAvatar(avatarId, self.env), lambda: None
|
||||
else:
|
||||
raise Exception, "No supported interfaces found."
|
||||
|
||||
def getRSAKeys():
|
||||
if not (os.path.exists('public.key') and os.path.exists('private.key')):
|
||||
# generate a RSA keypair
|
||||
print "Generating RSA keypair..."
|
||||
from Crypto.PublicKey import RSA
|
||||
KEY_LENGTH = 1024
|
||||
rsaKey = RSA.generate(KEY_LENGTH, common.entropy.get_bytes)
|
||||
publicKeyString = keys.makePublicKeyString(rsaKey)
|
||||
privateKeyString = keys.makePrivateKeyString(rsaKey)
|
||||
# save keys for next time
|
||||
file('public.key', 'w+b').write(publicKeyString)
|
||||
file('private.key', 'w+b').write(privateKeyString)
|
||||
print "done."
|
||||
else:
|
||||
publicKeyString = file('public.key').read()
|
||||
privateKeyString = file('private.key').read()
|
||||
return publicKeyString, privateKeyString
|
|
@ -0,0 +1,20 @@
|
|||
from commands import base, ls, wget, tar
|
||||
|
||||
cmdl = {
|
||||
'/bin/echo': base.command_echo,
|
||||
'cd': base.command_cd,
|
||||
'/bin/cat': base.command_cat,
|
||||
'/usr/bin/whoami': base.command_whoami,
|
||||
'quit': base.command_quit,
|
||||
'/usr/bin/clear': base.command_clear,
|
||||
'/bin/rm': base.command_rm,
|
||||
'/usr/bin/uptime': base.command_uptime,
|
||||
'/usr/bin/w': base.command_w,
|
||||
'/usr/bin/who': base.command_w,
|
||||
'/usr/bin/vi': base.command_vi,
|
||||
'/usr/bin/vim': base.command_vi,
|
||||
'/bin/mount': base.command_mount,
|
||||
'/bin/ls': ls.command_ls,
|
||||
'/usr/bin/wget': wget.command_wget,
|
||||
'/bin/tar': tar.command_tar,
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
A_NAME, \
|
||||
A_TYPE, \
|
||||
A_UID, \
|
||||
A_GID, \
|
||||
A_SIZE, \
|
||||
A_MODE, \
|
||||
A_CTIME, \
|
||||
A_CONTENTS, \
|
||||
A_TARGET = range(0, 9)
|
||||
T_LINK, \
|
||||
T_DIR, \
|
||||
T_FILE, \
|
||||
T_BLK, \
|
||||
T_CHR, \
|
||||
T_SOCK, \
|
||||
T_FIFO = range(0, 7)
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
# Should be compatible with user mode linux
|
||||
|
||||
import struct, sys
|
||||
|
||||
OP_OPEN, OP_CLOSE, OP_WRITE, OP_EXEC = 1, 2, 3, 4
|
||||
DIR_READ, DIR_WRITE = 1, 2
|
||||
|
||||
def ttylog_write(logfile, len, direction, stamp, data = None):
|
||||
f = file(logfile, 'a')
|
||||
sec, usec = int(stamp), int(1000000 * (stamp - int(stamp)))
|
||||
f.write(struct.pack('iLiiLL', 3, 0, len, direction, sec, usec))
|
||||
f.write(data)
|
||||
f.close()
|
||||
|
||||
def ttylog_open(logfile, stamp):
|
||||
f = file(logfile, 'a')
|
||||
sec, usec = int(stamp), int(1000000 * (stamp - int(stamp)))
|
||||
f.write(struct.pack('iLiiLL', 1, 0, 0, 0, sec, usec))
|
||||
f.close()
|
||||
|
||||
def ttylog_close(logfile, stamp):
|
||||
f = file(logfile, 'a')
|
||||
sec, usec = int(stamp), int(1000000 * (stamp - int(stamp)))
|
||||
f.write(struct.pack('iLiiLL', 2, 0, 0, 0, sec, usec))
|
||||
f.close()
|
|
@ -0,0 +1,50 @@
|
|||
processor : 0
|
||||
vendor_id : GenuineIntel
|
||||
cpu family : 6
|
||||
model : 23
|
||||
model name : Intel(R) Core(TM)2 Duo CPU E8200 @ 2.66GHz
|
||||
stepping : 6
|
||||
cpu MHz : 2133.305
|
||||
cache size : 6144 KB
|
||||
physical id : 0
|
||||
siblings : 2
|
||||
core id : 0
|
||||
cpu cores : 2
|
||||
apicid : 0
|
||||
initial apicid : 0
|
||||
fpu : yes
|
||||
fpu_exception : yes
|
||||
cpuid level : 10
|
||||
wp : yes
|
||||
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx lm constant_tsc arch_perfmon pebs bts rep_good pni monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr sse4_1 lahf_lm
|
||||
bogomips : 4270.03
|
||||
clflush size : 64
|
||||
cache_alignment : 64
|
||||
address sizes : 36 bits physical, 48 bits virtual
|
||||
power management:
|
||||
|
||||
processor : 1
|
||||
vendor_id : GenuineIntel
|
||||
cpu family : 6
|
||||
model : 23
|
||||
model name : Intel(R) Core(TM)2 Duo CPU E8200 @ 2.66GHz
|
||||
stepping : 6
|
||||
cpu MHz : 2133.305
|
||||
cache size : 6144 KB
|
||||
physical id : 0
|
||||
siblings : 2
|
||||
core id : 1
|
||||
cpu cores : 2
|
||||
apicid : 1
|
||||
initial apicid : 1
|
||||
fpu : yes
|
||||
fpu_exception : yes
|
||||
cpuid level : 10
|
||||
wp : yes
|
||||
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx lm constant_tsc arch_perfmon pebs bts rep_good pni monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr sse4_1 lahf_lm
|
||||
bogomips : 4266.61
|
||||
clflush size : 64
|
||||
cache_alignment : 64
|
||||
address sizes : 36 bits physical, 48 bits virtual
|
||||
power management:
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
from twisted.cred import portal, checkers
|
||||
from twisted.conch.ssh import factory, keys
|
||||
from twisted.internet import reactor
|
||||
from core import Kippo
|
||||
|
||||
if __name__ == "__main__":
|
||||
sshFactory = factory.SSHFactory()
|
||||
sshFactory.portal = portal.Portal(Kippo.HoneyPotRealm())
|
||||
|
||||
users = {'root': 'root'}
|
||||
sshFactory.portal.registerChecker(
|
||||
checkers.InMemoryUsernamePasswordDatabaseDontUse(**users))
|
||||
|
||||
pubKeyString, privKeyString = Kippo.getRSAKeys()
|
||||
sshFactory.publicKeys = {
|
||||
'ssh-rsa': keys.Key.fromString(data=pubKeyString)}
|
||||
sshFactory.privateKeys = {
|
||||
'ssh-rsa': keys.Key.fromString(data=privKeyString)}
|
||||
|
||||
reactor.listenTCP(2222, sshFactory)
|
||||
reactor.run()
|
||||
|
||||
# vim: set sw=4 et:
|
|
@ -0,0 +1,61 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import os, pickle, sys, locale
|
||||
from stat import *
|
||||
|
||||
def recurse(root, tree, count = 0):
|
||||
A_NAME, A_TYPE, A_UID, A_GID, A_SIZE, A_MODE, \
|
||||
A_CTIME, A_CONTENTS, A_TARGET = range(0, 9)
|
||||
T_LINK, T_DIR, T_FILE, T_BLK, T_CHR, T_SOCK, T_FIFO = range(0, 7)
|
||||
|
||||
for name in os.listdir(root):
|
||||
path = os.path.join(root, name)
|
||||
if path in (
|
||||
'/root/realfs.txt',
|
||||
'/root/createfs.py',
|
||||
'/root/.bash_history',
|
||||
):
|
||||
continue
|
||||
|
||||
if os.path.islink(path):
|
||||
s = os.lstat(path)
|
||||
else:
|
||||
s = os.stat(path)
|
||||
|
||||
entry = [name, T_FILE, s.st_uid, s.st_gid, s.st_size, s.st_mode, \
|
||||
int(s.st_ctime), [], None]
|
||||
|
||||
if S_ISLNK(s[ST_MODE]):
|
||||
entry[A_TYPE] = T_LINK
|
||||
entry[TARGET] = os.path.realpath(path)
|
||||
elif S_ISDIR(s[ST_MODE]):
|
||||
entry[A_TYPE] = T_DIR
|
||||
if path not in ('/proc', '/sys'):
|
||||
recurse(path, entry[A_CONTENTS])
|
||||
elif S_ISREG(s[ST_MODE]):
|
||||
entry[A_TYPE] = T_FILE
|
||||
elif S_ISBLK(s[ST_MODE]):
|
||||
entry[A_TYPE] = T_BLK
|
||||
elif S_ISCHR(s[ST_MODE]):
|
||||
entry[A_TYPE] = T_CHR
|
||||
elif S_ISSOCK(s[ST_MODE]):
|
||||
entry[A_TYPE] = T_SOCK
|
||||
elif S_ISFIFO(s[ST_MODE]):
|
||||
entry[A_TYPE] = T_FIFO
|
||||
else:
|
||||
sys.stderr.write('We should handle %s' % path)
|
||||
sys.exit(1)
|
||||
|
||||
tree.append(entry)
|
||||
|
||||
if __name__ == '__main__':
|
||||
A_NAME, A_TYPE, A_UID, A_GID, A_SIZE, A_MODE, \
|
||||
A_CTIME, A_CONTENTS, A_TARGET = range(0, 9)
|
||||
T_LINK, T_DIR, T_FILE, T_BLK, T_CHR, T_SOCK, T_FIFO = range(0, 7)
|
||||
|
||||
tree = ['/', T_DIR, 0, 0, 0, 0, 0, [], '']
|
||||
recurse('.', tree[A_CONTENTS], tree[A_CONTENTS])
|
||||
|
||||
sys.stderr.write('Doing stuff\n')
|
||||
|
||||
print pickle.dumps(tree)
|
|
@ -0,0 +1,262 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright (C) 2003 Upi Tamminen <desaster@dragonlight.fi>
|
||||
#
|
||||
# Last update: Mon Sep 15 20:01:15 EEST 2003
|
||||
# * Sessions can now be extracted to a file
|
||||
# * The first data seen is considered 'output'.
|
||||
# If this guess is wrong, the new -i option can be used
|
||||
# * Rewritten to use file positions instead of tty IDs
|
||||
# * Added -f that works like tail -f
|
||||
# * Delays longer than 5 seconds are shortened to 5 seconds
|
||||
#
|
||||
|
||||
import os, sys, time, struct, string, getopt, fcntl, termios
|
||||
|
||||
OP_OPEN, OP_CLOSE, OP_WRITE, OP_EXEC = 1, 2, 3, 4
|
||||
DIR_READ, DIR_WRITE = 1, 2
|
||||
|
||||
def termwidth():
|
||||
return struct.unpack("hhhh",
|
||||
fcntl.ioctl(0, termios.TIOCGWINSZ ,"\000" * 8))[1]
|
||||
|
||||
|
||||
def maxcolumnlen(list, column):
|
||||
maxlen = 0
|
||||
for row in list:
|
||||
if len(row[column]) > maxlen:
|
||||
maxlen = len(row[column])
|
||||
return maxlen
|
||||
|
||||
|
||||
def playlog(fd, pos, settings):
|
||||
|
||||
ssize = struct.calcsize('iLiiLL')
|
||||
currtty, prevtime, prefdir = 0, 0, 0
|
||||
|
||||
fd.seek(int(pos))
|
||||
|
||||
while 1:
|
||||
try:
|
||||
(op, tty, length, dir, sec, usec) = \
|
||||
struct.unpack('iLiiLL', fd.read(ssize))
|
||||
data = fd.read(length)
|
||||
except struct.error:
|
||||
if settings['tail']:
|
||||
prevtime = 0
|
||||
time.sleep(0.1)
|
||||
settings['maxdelay'] = 0
|
||||
continue
|
||||
break
|
||||
|
||||
if currtty == 0: currtty = tty
|
||||
|
||||
if str(tty) == str(currtty) and op == OP_WRITE:
|
||||
# the first stream seen is considered 'output'
|
||||
if prefdir == 0:
|
||||
prefdir = dir
|
||||
# use the other direction
|
||||
if settings['input_only']:
|
||||
prefdir = DIR_READ
|
||||
if dir == DIR_READ: prefdir = DIR_WRITE
|
||||
if dir == prefdir or settings['both_dirs']:
|
||||
curtime = float(sec) + float(usec) / 1000000
|
||||
if prevtime != 0:
|
||||
sleeptime = curtime - prevtime
|
||||
if sleeptime > settings['maxdelay']:
|
||||
sleeptime = settings['maxdelay']
|
||||
if settings['maxdelay'] > 0:
|
||||
time.sleep(sleeptime)
|
||||
prevtime = curtime
|
||||
sys.stdout.write(data)
|
||||
sys.stdout.flush()
|
||||
elif str(tty) == str(currtty) and op == OP_CLOSE:
|
||||
break
|
||||
|
||||
|
||||
def writelog(fd, outfile, pos):
|
||||
|
||||
ssize = struct.calcsize('iLiiLL')
|
||||
currtty, prevtime, prefdir = 0, 0, 0
|
||||
|
||||
try:
|
||||
outfd = open(outfile, 'ab')
|
||||
except IOError:
|
||||
print "Couldn't open the output file!"
|
||||
sys.exit(3)
|
||||
|
||||
fd.seek(int(pos))
|
||||
|
||||
written = 0
|
||||
while 1:
|
||||
try:
|
||||
structdata = fd.read(ssize)
|
||||
op, tty, length, dir, sec, usec = \
|
||||
struct.unpack('iLiiLL', structdata)
|
||||
data = fd.read(length)
|
||||
except struct.error:
|
||||
op = -1
|
||||
|
||||
if currtty == 0: currtty = tty
|
||||
|
||||
if str(tty) == str(currtty):
|
||||
outfd.write(structdata + data)
|
||||
written += len(structdata + data)
|
||||
if op == OP_CLOSE or op == -1:
|
||||
print 'Total %d bytes written' % written
|
||||
break
|
||||
|
||||
|
||||
def showsessions(fd):
|
||||
|
||||
ssize = struct.calcsize('iLiiLL')
|
||||
ttys, chunches, currpos = {}, [], 0
|
||||
|
||||
# no point in reading more...
|
||||
maxglancelen = termwidth()
|
||||
|
||||
while 1:
|
||||
try:
|
||||
structdata = fd.read(ssize)
|
||||
op, tty, length, dir, sec, usec = \
|
||||
struct.unpack('iLiiLL', structdata)
|
||||
data = fd.read(length)
|
||||
except struct.error:
|
||||
op = -1
|
||||
|
||||
if op == OP_OPEN:
|
||||
ttys[tty] = {
|
||||
'pos': currpos,
|
||||
'start': sec,
|
||||
'end': sec,
|
||||
'size': 0,
|
||||
'glance': '',
|
||||
'prefdir': 0,
|
||||
}
|
||||
elif op == OP_CLOSE or op == -1:
|
||||
if ttys.has_key(tty):
|
||||
chunch = ttys[tty]
|
||||
chunch['end'] = sec
|
||||
chunches.append(chunch)
|
||||
del ttys[tty]
|
||||
elif op == OP_WRITE:
|
||||
if ttys[tty]['prefdir'] == 0:
|
||||
ttys[tty]['prefdir'] = dir
|
||||
if dir == ttys[tty]['prefdir']:
|
||||
ttys[tty]['size'] += len(data)
|
||||
if len(ttys[tty]['glance']) <= maxglancelen:
|
||||
ttys[tty]['glance'] += data
|
||||
|
||||
if op == -1:
|
||||
break
|
||||
|
||||
currpos += len(structdata) + length
|
||||
|
||||
# unclosed sessions
|
||||
for tty in ttys.keys():
|
||||
chunch = ttys[tty]
|
||||
chunch['end'] = -1
|
||||
chunches.append(chunch)
|
||||
|
||||
sessions = [['id', 'start', 'end', 'size', 'glance']]
|
||||
|
||||
for chunch in chunches:
|
||||
|
||||
session = [str(chunch['pos'])]
|
||||
|
||||
startdate = time.localtime(chunch['start'])
|
||||
enddate = time.localtime(chunch['end'])
|
||||
|
||||
session.append(time.strftime('%Y-%m-%d %R', startdate))
|
||||
if chunch['end'] == -1:
|
||||
session.append('still open')
|
||||
else:
|
||||
if time.strftime('%Y-%m-%d', enddate) == \
|
||||
time.strftime('%Y-%m-%d', startdate):
|
||||
session.append(time.strftime('%R', enddate))
|
||||
else:
|
||||
session.append(time.strftime('%Y-%m-%d %R', enddate))
|
||||
|
||||
session.append('%s' % chunch['size'])
|
||||
session.append(chunch['glance'].translate(
|
||||
string.maketrans('\t\n\r\x1b', ' ')).strip())
|
||||
|
||||
sessions.append(session)
|
||||
|
||||
maxidlen = maxcolumnlen(sessions, 0) + 1
|
||||
maxstartdatelen = maxcolumnlen(sessions, 1) + 1
|
||||
maxenddatelen = maxcolumnlen(sessions, 2) + 1
|
||||
maxcounterlen = maxcolumnlen(sessions, 3) + 1
|
||||
spaceleft = termwidth() - \
|
||||
(maxidlen + maxstartdatelen + maxenddatelen + maxcounterlen + 5)
|
||||
|
||||
for session in sessions:
|
||||
print '%s %s %s %s %s' % (session[0].ljust(maxidlen),
|
||||
session[1].ljust(maxstartdatelen),
|
||||
session[2].ljust(maxenddatelen),
|
||||
session[3].ljust(maxcounterlen),
|
||||
session[4][:spaceleft])
|
||||
|
||||
print
|
||||
help(brief = 1)
|
||||
|
||||
def help(brief = 0):
|
||||
|
||||
print 'Usage: %s [-bfhi] [-m secs] [-w file] <tty-log-file> [id]\n' % \
|
||||
os.path.basename(sys.argv[0])
|
||||
|
||||
if not brief:
|
||||
|
||||
print ' -f keep trying to read the log until it\'s closed'
|
||||
print ' -m <seconds> maximum delay in seconds, to avoid' + \
|
||||
' boredom or fast-forward\n' + \
|
||||
' to the end. (default is 3.0)'
|
||||
print ' -i show the input stream instead of output'
|
||||
print ' -b show both input and output streams'
|
||||
print ' -w <file> extract the session to a file'
|
||||
print ' -h display this help\n'
|
||||
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
settings = {
|
||||
'tail': 0,
|
||||
'maxdelay': 3.0,
|
||||
'input_only': 0,
|
||||
'both_dirs': 0,
|
||||
'outfile': '',
|
||||
}
|
||||
|
||||
try:
|
||||
optlist, args = getopt.getopt(sys.argv[1:], 'fhibm:w:', ['help'])
|
||||
except getopt.GetoptError, error:
|
||||
print 'Error: %s\n' % error
|
||||
help()
|
||||
|
||||
for o, a in optlist:
|
||||
if o == '-f': settings['tail'] = 1
|
||||
elif o == '-m': settings['maxdelay'] = float(a) # takes decimals
|
||||
elif o == '-i': settings['input_only'] = 1
|
||||
elif o == '-b': settings['both_dirs'] = 1
|
||||
elif o == '-w': settings['outfile'] = a
|
||||
elif o in ['-h', '--help']: help()
|
||||
|
||||
if len(args) < 1: help()
|
||||
|
||||
try:
|
||||
logfd = open(args[0], 'rb')
|
||||
except IOError:
|
||||
print "Couldn't open log file!"
|
||||
sys.exit(2)
|
||||
|
||||
if len(args) > 1:
|
||||
if len(settings['outfile']):
|
||||
writelog(logfd, settings['outfile'], args[1])
|
||||
else:
|
||||
playlog(logfd, args[1], settings)
|
||||
else:
|
||||
showsessions(logfd)
|
||||
|
||||
|
||||
# vim: set sw=4:
|
Loading…
Reference in New Issue