mirror of
https://github.com/cowrie/cowrie.git
synced 2025-07-01 18:07:27 -04:00
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:
@ -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
|
||||||
|
|
||||||
|
|||||||
@ -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 = {}
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
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
|
return
|
||||||
|
|
||||||
t = tarfile.open(f[A_REALFILE])
|
|
||||||
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
|
||||||
|
|||||||
@ -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
126
core/fs.py
Normal 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:
|
||||||
@ -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:
|
|
||||||
107
core/honeypot.py
107
core/honeypot.py
@ -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)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user