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
from core.honeypot import HoneyPotCommand
from core.fstypes import *
from core.fs import *
from twisted.internet import reactor
import config

View File

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

View File

@ -2,7 +2,7 @@
# See the COPYRIGHT file for more information
from core.honeypot import HoneyPotCommand
from core.fstypes import *
from core.fs import *
from commands import dice
import time, random, tarfile, os
@ -26,7 +26,8 @@ class command_tar(HoneyPotCommand):
path = self.fs.resolve_path(filename, self.honeypot.cwd)
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: Child returned status 2')
self.writeln('tar: Error exit delayed from previous errors')
@ -34,9 +35,19 @@ class command_tar(HoneyPotCommand):
f = self.fs.getfile(path)
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
try:
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
t = tarfile.open(f[A_REALFILE])
for f in t:
dest = self.fs.resolve_path(f.name.strip('/'), self.honeypot.cwd)
if verbose:
@ -47,8 +58,7 @@ class command_tar(HoneyPotCommand):
self.fs.mkdir(dest, 0, 0, 4096, f.mode, f.mtime)
elif f.isfile():
self.fs.mkfile(dest, 0, 0, f.size, f.mode, f.mtime)
self.honeypot.commands[dest] = \
random.choice(dice.clist)
self.honeypot.commands[dest] = random.choice(dice.clist)
else:
print 'tar: skipping [%s]' % f.name
commands['/bin/tar'] = command_tar

View File

@ -2,7 +2,7 @@
# See the COPYRIGHT file for more information
from core.honeypot import HoneyPotCommand
from core.fstypes import *
from core.fs import *
from twisted.web import client
from twisted.internet import reactor
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
import sys, os, random, pickle, time, stat, shlex
from core import ttylog
from core.fstypes import *
from core import ttylog, fs
import commands, config
class HoneyPotCommand(object):
@ -101,7 +100,7 @@ class HoneyPotProtocol(recvline.HistoricRecvLine):
self.env = env
self.cwd = '/root'
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
self.commands = copy(self.env.commands)
self.password_input = False
@ -226,108 +225,6 @@ class HoneyPotEnvironment(object):
self.commands.update(module.commands)
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:
implements(portal.IRealm)