cowrie/kippo/commands/fs.py

272 lines
9.7 KiB
Python

# Copyright (c) 2010 Upi Tamminen <desaster@gmail.com>
# See the COPYRIGHT file for more information
import os, getopt
from copy import deepcopy, copy
from kippo.core.honeypot import HoneyPotCommand
from kippo.core.fs import *
from twisted.internet import reactor
commands = {}
class command_cat(HoneyPotCommand):
def call(self):
for arg in self.args:
path = self.fs.resolve_path(arg, self.honeypot.cwd)
if not path or not self.fs.exists(path):
self.writeln('bash: cat: %s: No such file or directory' % arg)
return
f = self.fs.getfile(path)
realfile = self.fs.realfile(f, '%s/%s' % \
(self.honeypot.env.cfg.get('honeypot', 'contents_path'), path))
if realfile:
f = file(realfile, 'rb')
self.write(f.read())
f.close()
commands['/bin/cat'] = command_cat
class command_cd(HoneyPotCommand):
def call(self):
if not self.args:
path = '/root'
else:
path = self.args[0]
try:
newpath = self.fs.resolve_path(path, self.honeypot.cwd)
newdir = self.fs.get_path(newpath)
except IndexError:
newdir = None
if newdir is None:
self.writeln('bash: cd: %s: No such file or directory' % path)
return
if not self.fs.is_dir(newpath):
self.writeln('-bash: cd: %s: Not a directory' % path)
return
self.honeypot.cwd = newpath
commands['cd'] = command_cd
class command_rm(HoneyPotCommand):
def call(self):
recursive = False
for f in self.args:
if f.startswith('-') and 'r' in f:
recursive = True
for f in self.args:
path = self.fs.resolve_path(f, self.honeypot.cwd)
try:
dir = self.fs.get_path('/'.join(path.split('/')[:-1]))
except IndexError:
self.writeln(
'rm: cannot remove `%s\': No such file or directory' % f)
continue
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 and not recursive:
self.writeln(
'rm: cannot remove `%s\': Is a directory' % \
i[A_NAME])
else:
dir.remove(i)
commands['/bin/rm'] = command_rm
class command_cp(HoneyPotCommand):
def call(self):
if not len(self.args):
self.writeln("cp: missing file operand")
self.writeln("Try `cp --help' for more information.")
return
try:
optlist, args = getopt.gnu_getopt(self.args,
'-abdfiHlLPpRrsStTuvx')
except getopt.GetoptError, err:
self.writeln('Unrecognized option')
return
recursive = False
for opt in optlist:
if opt[0] in ('-r', '-a', '-R'):
recursive = True
def resolv(path):
return self.fs.resolve_path(path, self.honeypot.cwd)
if len(args) < 2:
self.writeln("cp: missing destination file operand after `%s'" % \
(self.args[0],))
self.writeln("Try `cp --help' for more information.")
return
sources, dest = args[:-1], args[-1]
if len(sources) > 1 and not self.fs.is_dir(resolv(dest)):
self.writeln("cp: target `%s' is not a directory" % (dest,))
return
if dest[-1] == '/' and not self.fs.exists(resolv(dest)) and \
not recursive:
self.writeln(
"cp: cannot create regular file `%s': Is a directory" % \
(dest,))
return
if self.fs.is_dir(resolv(dest)):
is_dir = True
else:
is_dir = False
parent = os.path.dirname(resolv(dest))
if not self.fs.exists(parent):
self.writeln("cp: cannot create regular file " + \
"`%s': No such file or directory" % (dest,))
return
for src in sources:
if not self.fs.exists(resolv(src)):
self.writeln(
"cp: cannot stat `%s': No such file or directory" % (src,))
continue
if not recursive and self.fs.is_dir(resolv(src)):
self.writeln("cp: omitting directory `%s'" % (src,))
continue
s = deepcopy(self.fs.getfile(resolv(src)))
if is_dir:
dir = self.fs.get_path(resolv(dest))
outfile = os.path.basename(src)
else:
dir = self.fs.get_path(os.path.dirname(resolv(dest)))
outfile = os.path.basename(dest.rstrip('/'))
if outfile in [x[A_NAME] for x in dir]:
dir.remove([x for x in dir if x[A_NAME] == outfile][0])
s[A_NAME] = outfile
dir.append(s)
commands['/bin/cp'] = command_cp
class command_mv(HoneyPotCommand):
def call(self):
if not len(self.args):
self.writeln("mv: missing file operand")
self.writeln("Try `mv --help' for more information.")
return
try:
optlist, args = getopt.gnu_getopt(self.args, '-bfiStTuv')
except getopt.GetoptError, err:
self.writeln('Unrecognized option')
self.exit()
def resolv(path):
return self.fs.resolve_path(path, self.honeypot.cwd)
if len(args) < 2:
self.writeln("mv: missing destination file operand after `%s'" % \
(self.args[0],))
self.writeln("Try `mv --help' for more information.")
return
sources, dest = args[:-1], args[-1]
if len(sources) > 1 and not self.fs.is_dir(resolv(dest)):
self.writeln("mv: target `%s' is not a directory" % (dest,))
return
if dest[-1] == '/' and not self.fs.exists(resolv(dest)) and \
len(sources) != 1:
self.writeln(
"mv: cannot create regular file `%s': Is a directory" % \
(dest,))
return
if self.fs.is_dir(resolv(dest)):
is_dir = True
else:
is_dir = False
parent = os.path.dirname(resolv(dest))
if not self.fs.exists(parent):
self.writeln("mv: cannot create regular file " + \
"`%s': No such file or directory" % \
(dest,))
return
for src in sources:
if not self.fs.exists(resolv(src)):
self.writeln(
"mv: cannot stat `%s': No such file or directory" % \
(src,))
continue
s = self.fs.getfile(resolv(src))
if is_dir:
dir = self.fs.get_path(resolv(dest))
outfile = os.path.basename(src)
else:
dir = self.fs.get_path(os.path.dirname(resolv(dest)))
outfile = os.path.basename(dest)
if dir != os.path.dirname(resolv(src)):
s[A_NAME] = outfile
dir.append(s)
sdir = self.fs.get_path(os.path.dirname(resolv(src)))
sdir.remove(s)
else:
s[A_NAME] = outfile
commands['/bin/mv'] = command_mv
class command_mkdir(HoneyPotCommand):
def call(self):
for f in self.args:
path = self.fs.resolve_path(f, self.honeypot.cwd)
if self.fs.exists(path):
self.writeln(
'mkdir: cannot create directory `%s\': File exists' % f)
return
ok = self.fs.mkdir(path, 0, 0, 4096, 16877)
if not ok:
self.writeln(
'mkdir: cannot create directory `%s\': ' % f + \
'No such file or directory')
return
commands['/bin/mkdir'] = command_mkdir
class command_rmdir(HoneyPotCommand):
def call(self):
for f in self.args:
path = self.fs.resolve_path(f, self.honeypot.cwd)
if len(self.fs.get_path(path)):
self.writeln(
'rmdir: failed to remove `%s\': Directory not empty' % f)
continue
try:
dir = self.fs.get_path('/'.join(path.split('/')[:-1]))
except IndexError:
dir = None
if not dir or f not in [x[A_NAME] for x in dir]:
self.writeln(
'rmdir: failed to remove `%s\': ' % f + \
'No such file or directory')
continue
for i in dir[:]:
if i[A_NAME] == f:
dir.remove(i)
commands['/bin/rmdir'] = command_rmdir
class command_pwd(HoneyPotCommand):
def call(self):
self.writeln(self.honeypot.cwd)
commands['/bin/pwd'] = command_pwd
class command_touch(HoneyPotCommand):
def call(self):
if not len(self.args):
self.writeln('touch: missing file operand')
self.writeln('Try `touch --help\' for more information.')
return
for f in self.args:
path = self.fs.resolve_path(f, self.honeypot.cwd)
if not self.fs.exists(os.path.dirname(path)):
self.writeln(
'touch: cannot touch `%s`: no such file or directory' % \
(path))
return
if self.fs.exists(path):
# FIXME: modify the timestamp here
continue
self.fs.mkfile(path, 0, 0, 0, 33188)
commands['/bin/touch'] = command_touch
# vim: set sw=4 et: