mirror of https://github.com/cowrie/cowrie.git
272 lines
9.7 KiB
Python
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:
|