move filesystem related stuff to core/fs.py

git-svn-id: https://kippo.googlecode.com/svn/trunk@40 951d7100-d841-11de-b865-b3884708a8e2
This commit is contained in:
desaster
2009-11-21 11:51:23 +00:00
parent 9c93742f45
commit 902b0ce29e
7 changed files with 146 additions and 135 deletions

View File

@ -3,7 +3,7 @@
import os, time import os, time
from core.honeypot import HoneyPotCommand from core.honeypot import HoneyPotCommand
from core.fstypes import * from core.fs import *
from twisted.internet import reactor from twisted.internet import reactor
import config import config

View File

@ -2,7 +2,7 @@
# See the COPYRIGHT file for more information # See the COPYRIGHT file for more information
from core.honeypot import HoneyPotCommand from core.honeypot import HoneyPotCommand
from core.fstypes import * from core.fs import *
import stat, time import stat, time
commands = {} commands = {}

View File

@ -2,7 +2,7 @@
# See the COPYRIGHT file for more information # See the COPYRIGHT file for more information
from core.honeypot import HoneyPotCommand from core.honeypot import HoneyPotCommand
from core.fstypes import * from core.fs import *
from commands import dice from commands import dice
import time, random, tarfile, os import time, random, tarfile, os
@ -26,7 +26,8 @@ class command_tar(HoneyPotCommand):
path = self.fs.resolve_path(filename, self.honeypot.cwd) path = self.fs.resolve_path(filename, self.honeypot.cwd)
if not path or not self.honeypot.fs.exists(path): if not path or not self.honeypot.fs.exists(path):
self.writeln('tar: rs: Cannot open: No such file or directory') self.writeln('tar: %s: Cannot open: No such file or directory' % \
filename)
self.writeln('tar: Error is not recoverable: exiting now') self.writeln('tar: Error is not recoverable: exiting now')
self.writeln('tar: Child returned status 2') self.writeln('tar: Child returned status 2')
self.writeln('tar: Error exit delayed from previous errors') self.writeln('tar: Error exit delayed from previous errors')
@ -34,9 +35,19 @@ class command_tar(HoneyPotCommand):
f = self.fs.getfile(path) f = self.fs.getfile(path)
if not f[A_REALFILE]: if not f[A_REALFILE]:
self.writeln('tar: this does not look like a tar archive')
self.writeln('tar: skipping to next header')
self.writeln('tar: error exit delayed from previous errors')
return return
try:
t = tarfile.open(f[A_REALFILE]) t = tarfile.open(f[A_REALFILE])
except:
self.writeln('tar: this does not look like a tar archive')
self.writeln('tar: skipping to next header')
self.writeln('tar: error exit delayed from previous errors')
return
for f in t: for f in t:
dest = self.fs.resolve_path(f.name.strip('/'), self.honeypot.cwd) dest = self.fs.resolve_path(f.name.strip('/'), self.honeypot.cwd)
if verbose: if verbose:
@ -47,8 +58,7 @@ class command_tar(HoneyPotCommand):
self.fs.mkdir(dest, 0, 0, 4096, f.mode, f.mtime) self.fs.mkdir(dest, 0, 0, 4096, f.mode, f.mtime)
elif f.isfile(): elif f.isfile():
self.fs.mkfile(dest, 0, 0, f.size, f.mode, f.mtime) self.fs.mkfile(dest, 0, 0, f.size, f.mode, f.mtime)
self.honeypot.commands[dest] = \ self.honeypot.commands[dest] = random.choice(dice.clist)
random.choice(dice.clist)
else: else:
print 'tar: skipping [%s]' % f.name print 'tar: skipping [%s]' % f.name
commands['/bin/tar'] = command_tar commands['/bin/tar'] = command_tar

View File

@ -2,7 +2,7 @@
# See the COPYRIGHT file for more information # See the COPYRIGHT file for more information
from core.honeypot import HoneyPotCommand from core.honeypot import HoneyPotCommand
from core.fstypes import * from core.fs import *
from twisted.web import client from twisted.web import client
from twisted.internet import reactor from twisted.internet import reactor
import stat, time, urlparse, random, re import stat, time, urlparse, random, re

126
core/fs.py Normal file
View File

@ -0,0 +1,126 @@
# Copyright (c) 2009 Upi Tamminen <desaster@gmail.com>
# See the COPYRIGHT file for more information
import os, time
A_NAME, \
A_TYPE, \
A_UID, \
A_GID, \
A_SIZE, \
A_MODE, \
A_CTIME, \
A_CONTENTS, \
A_TARGET, \
A_REALFILE = range(0, 10)
T_LINK, \
T_DIR, \
T_FILE, \
T_BLK, \
T_CHR, \
T_SOCK, \
T_FIFO = range(0, 7)
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):
f = self.getfile(path)
if f is not False:
return True
def update_realfile(self, f, realfile):
if not f[A_REALFILE] and os.path.exists(realfile) and \
not os.path.islink(realfile) and os.path.isfile(realfile) and \
f[A_SIZE] < 25000000:
print 'Updating realfile to %s' % realfile
f[A_REALFILE] = realfile
def realfile(self, f, path):
self.update_realfile(f, path)
if f[A_REALFILE]:
return f[A_REALFILE]
return None
def getfile(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 p
def mkfile(self, path, uid, gid, size, mode, ctime = None):
if ctime is None:
ctime = time.time()
dir = self.get_path(os.path.dirname(path))
outfile = os.path.basename(path)
if outfile in [x[A_NAME] for x in dir]:
dir.remove([x for x in dir if x[A_NAME] == outfile][0])
dir.append([outfile, T_FILE, uid, gid, size, mode, ctime, [],
None, None])
return True
def mkdir(self, path, uid, gid, size, mode, ctime = None):
if ctime is None:
ctime = time.time()
if not len(path.strip('/')):
return False
try:
dir = self.get_path(os.path.dirname(path.strip('/')))
except IndexError:
return False
dir.append([os.path.basename(path), T_DIR, uid, gid, size, mode,
ctime, [], None, None])
return True
def is_dir(self, path):
if path == '/':
return True
dir = self.get_path(os.path.dirname(path))
l = [x for x in dir
if x[A_NAME] == os.path.basename(path) and
x[A_TYPE] == T_DIR]
if l:
return True
return False
# vim: set sw=4 et:

View File

@ -1,22 +0,0 @@
# Copyright (c) 2009 Upi Tamminen <desaster@gmail.com>
# See the COPYRIGHT file for more information
A_NAME, \
A_TYPE, \
A_UID, \
A_GID, \
A_SIZE, \
A_MODE, \
A_CTIME, \
A_CONTENTS, \
A_TARGET, \
A_REALFILE = range(0, 10)
T_LINK, \
T_DIR, \
T_FILE, \
T_BLK, \
T_CHR, \
T_SOCK, \
T_FIFO = range(0, 7)
# vim: set sw=4 et:

View File

@ -13,8 +13,7 @@ from zope.interface import implements
from copy import deepcopy, copy from copy import deepcopy, copy
import sys, os, random, pickle, time, stat, shlex import sys, os, random, pickle, time, stat, shlex
from core import ttylog from core import ttylog, fs
from core.fstypes import *
import commands, config import commands, config
class HoneyPotCommand(object): class HoneyPotCommand(object):
@ -101,7 +100,7 @@ class HoneyPotProtocol(recvline.HistoricRecvLine):
self.env = env self.env = env
self.cwd = '/root' self.cwd = '/root'
self.hostname = config.fake_hostname self.hostname = config.fake_hostname
self.fs = HoneyPotFilesystem(deepcopy(self.env.fs)) self.fs = fs.HoneyPotFilesystem(deepcopy(self.env.fs))
# commands is also a copy so we can add stuff on the fly # commands is also a copy so we can add stuff on the fly
self.commands = copy(self.env.commands) self.commands = copy(self.env.commands)
self.password_input = False self.password_input = False
@ -226,108 +225,6 @@ class HoneyPotEnvironment(object):
self.commands.update(module.commands) self.commands.update(module.commands)
self.fs = pickle.load(file('fs.pickle')) self.fs = pickle.load(file('fs.pickle'))
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):
f = self.getfile(path)
if f is not False:
return True
def update_realfile(self, f, realfile):
if not f[A_REALFILE] and os.path.exists(realfile) and \
not os.path.islink(realfile) and os.path.isfile(realfile) and \
f[A_SIZE] < 25000000:
print 'Updating realfile to %s' % realfile
f[A_REALFILE] = realfile
def realfile(self, f, path):
self.update_realfile(f, path)
if f[A_REALFILE]:
return f[A_REALFILE]
return None
def getfile(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 p
def mkfile(self, path, uid, gid, size, mode, ctime = None):
if ctime is None:
ctime = time.time()
dir = self.get_path(os.path.dirname(path))
outfile = os.path.basename(path)
if outfile in [x[A_NAME] for x in dir]:
dir.remove([x for x in dir if x[A_NAME] == outfile][0])
dir.append([outfile, T_FILE, uid, gid, size, mode, ctime, [],
None, None])
return True
def mkdir(self, path, uid, gid, size, mode, ctime = None):
if ctime is None:
ctime = time.time()
if not len(path.strip('/')):
return False
try:
dir = self.get_path(os.path.dirname(path.strip('/')))
except IndexError:
return False
dir.append([os.path.basename(path), T_DIR, uid, gid, size, mode,
ctime, [], None, None])
return True
def is_dir(self, path):
if path == '/':
return True
dir = self.get_path(os.path.dirname(path))
l = [x for x in dir
if x[A_NAME] == os.path.basename(path) and
x[A_TYPE] == T_DIR]
if l:
return True
return False
class HoneyPotRealm: class HoneyPotRealm:
implements(portal.IRealm) implements(portal.IRealm)