Created
May 16, 2013 00:23
-
-
Save zwned/5588521 to your computer and use it in GitHub Desktop.
kippo base.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Copyright (c) 2009 Upi Tamminen <desaster@gmail.com> | |
# See the COPYRIGHT file for more information | |
import os, time, anydbm, datetime | |
from kippo.core.honeypot import HoneyPotCommand | |
from twisted.internet import reactor | |
from kippo.core.config import config | |
from kippo.core.userdb import UserDB | |
from kippo.core import utils | |
commands = {} | |
class command_whoami(HoneyPotCommand): | |
def call(self): | |
self.writeln(self.honeypot.user.username) | |
commands['/usr/bin/whoami'] = command_whoami | |
def uptime(): | |
try: | |
f = open( "/proc/uptime" ) | |
contents = f.read().split() | |
f.close() | |
except: | |
return "Cannot open uptime file: /proc/uptime" | |
total_seconds = float(contents[0]) | |
MINUTE = 60 | |
HOUR = MINUTE * 60 | |
DAY = HOUR * 24 | |
days = int( total_seconds / DAY )+15 | |
hours = int( ( total_seconds % DAY ) / HOUR ) | |
minutes = int( ( total_seconds % HOUR ) / MINUTE ) | |
seconds = int( total_seconds % MINUTE ) | |
string = " up " + str(days) + " days, " + str(hours) + ":" + str(minutes) + ", 1 users, load averages: 0.09 0.05 0.05" | |
return string | |
class command_uptime(HoneyPotCommand): | |
def call(self): | |
self.writeln(' %s' % time.strftime('%H:%M:%S') + uptime()) | |
commands['/usr/bin/uptime'] = command_uptime | |
class command_w(HoneyPotCommand): | |
def call(self): | |
self.writeln(' %s' % time.strftime('%H:%M:%S') + uptime()) | |
self.writeln('USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT') | |
self.writeln('%-8s pts/0 %s %s 0.00s 0.00s 0.00s w' % \ | |
(self.honeypot.user.username, | |
self.honeypot.clientIP[:17].ljust(17), | |
time.strftime('%H:%M', time.localtime(self.honeypot.logintime)))) | |
commands['/usr/bin/w'] = command_w | |
commands['/usr/bin/who'] = command_w | |
class command_echo(HoneyPotCommand): | |
def call(self): | |
self.writeln(' '.join(self.args)) | |
commands['/bin/echo'] = command_echo | |
# for testing purposes | |
class command_exxxit(HoneyPotCommand): | |
def call(self): | |
if self.honeypot.clientIP.startswith('127.0.0.'): | |
self.honeypot.terminal.loseConnection() | |
else: | |
self.writeln('bash: exxxit: command not found') | |
commands['exxxit'] = command_exxxit | |
class command_exit(HoneyPotCommand): | |
def call(self): | |
if 'PuTTY' in self.honeypot.clientVersion or \ | |
'libssh' in self.honeypot.clientVersion or \ | |
'sshlib' in self.honeypot.clientVersion: | |
self.honeypot.terminal.loseConnection() | |
return | |
self.honeypot.terminal.reset() | |
self.writeln('Connection to server closed.') | |
self.honeypot.hostname = 'localhost' | |
self.honeypot.cwd = '/root' | |
if not self.fs.exists(self.honeypot.cwd): | |
self.honeypot.cwd = '/' | |
commands['exit'] = command_exit | |
commands['logout'] = command_exit | |
class command_clear(HoneyPotCommand): | |
def call(self): | |
self.honeypot.terminal.reset() | |
commands['/usr/bin/clear'] = command_clear | |
class command_hostname(HoneyPotCommand): | |
def call(self): | |
self.writeln(self.honeypot.hostname) | |
commands['/bin/hostname'] = command_hostname | |
class command_uname(HoneyPotCommand): | |
def call(self): | |
if len(self.args) and self.args[0].strip() == '-a': | |
self.writeln( | |
'Linux %s 2.6.26-2-686 #1 SMP Wed Nov 4 20:45:37 UTC 2009 i686 GNU/Linux' % \ | |
self.honeypot.hostname) | |
else: | |
self.writeln('Linux') | |
commands['/bin/uname'] = command_uname | |
class command_ps(HoneyPotCommand): | |
def call(self): | |
user = self.honeypot.user.username | |
args = '' | |
if len(self.args): | |
args = self.args[0].strip() | |
_user, _pid, _cpu, _mem, _vsz, _rss, _tty, _stat, \ | |
_start, _time, _command = range(11) | |
output = ( | |
('USER ', ' PID', ' %CPU', ' %MEM', ' VSZ', ' RSS', ' TTY ', 'STAT ', 'START', ' TIME ', 'COMMAND',), | |
('root ', ' 1', ' 0.0', ' 0.1', ' 2100', ' 688', ' ? ', 'Ss ', ''+(datetime.datetime.now()-datetime.timedelta(days=15)).strftime("%b%d")+'', ' 0:07 ', 'init [2] ',), | |
('root ', ' 2', ' 0.0', ' 0.0', ' 0', ' 0', ' ? ', 'S< ', ''+(datetime.datetime.now()-datetime.timedelta(days=15)).strftime("%b%d")+'', ' 0:00 ', '[kthreadd]',), | |
('root ', ' 3', ' 0.0', ' 0.0', ' 0', ' 0', ' ? ', 'S< ', ''+(datetime.datetime.now()-datetime.timedelta(days=15)).strftime("%b%d")+'', ' 0:00 ', '[migration/0]',), | |
('root ', ' 4', ' 0.0', ' 0.0', ' 0', ' 0', ' ? ', 'S< ', ''+(datetime.datetime.now()-datetime.timedelta(days=15)).strftime("%b%d")+'', ' 0:00 ', '[ksoftirqd/0]',), | |
('root ', ' 5', ' 0.0', ' 0.0', ' 0', ' 0', ' ? ', 'S< ', ''+(datetime.datetime.now()-datetime.timedelta(days=15)).strftime("%b%d")+'', ' 0:00 ', '[watchdog/0]',), | |
('root ', ' 6', ' 0.0', ' 0.0', ' 0', ' 0', ' ? ', 'S< ', ''+(datetime.datetime.now()-datetime.timedelta(days=15)).strftime("%b%d")+'', ' 0:17 ', '[events/0]',), | |
('root ', ' 7', ' 0.0', ' 0.0', ' 0', ' 0', ' ? ', 'S< ', ''+(datetime.datetime.now()-datetime.timedelta(days=15)).strftime("%b%d")+'', ' 0:00 ', '[khelper]',), | |
('root ', ' 39', ' 0.0', ' 0.0', ' 0', ' 0', ' ? ', 'S< ', ''+(datetime.datetime.now()-datetime.timedelta(days=15)).strftime("%b%d")+'', ' 0:00 ', '[kblockd/0]',), | |
('root ', ' 41', ' 0.0', ' 0.0', ' 0', ' 0', ' ? ', 'S< ', ''+(datetime.datetime.now()-datetime.timedelta(days=15)).strftime("%b%d")+'', ' 0:00 ', '[kacpid]',), | |
('root ', ' 42', ' 0.0', ' 0.0', ' 0', ' 0', ' ? ', 'S< ', ''+(datetime.datetime.now()-datetime.timedelta(days=15)).strftime("%b%d")+'', ' 0:00 ', '[kacpi_notify]',), | |
('root ', ' 170', ' 0.0', ' 0.0', ' 0', ' 0', ' ? ', 'S< ', ''+(datetime.datetime.now()-datetime.timedelta(days=15)).strftime("%b%d")+'', ' 0:00 ', '[kseriod]',), | |
('root ', ' 207', ' 0.0', ' 0.0', ' 0', ' 0', ' ? ', 'S ', ''+(datetime.datetime.now()-datetime.timedelta(days=15)).strftime("%b%d")+'', ' 0:01 ', '[pdflush]',), | |
('root ', ' 208', ' 0.0', ' 0.0', ' 0', ' 0', ' ? ', 'S ', ''+(datetime.datetime.now()-datetime.timedelta(days=15)).strftime("%b%d")+'', ' 0:00 ', '[pdflush]',), | |
('root ', ' 209', ' 0.0', ' 0.0', ' 0', ' 0', ' ? ', 'S< ', ''+(datetime.datetime.now()-datetime.timedelta(days=15)).strftime("%b%d")+'', ' 0:00 ', '[kswapd0]',), | |
('root ', ' 210', ' 0.0', ' 0.0', ' 0', ' 0', ' ? ', 'S< ', ''+(datetime.datetime.now()-datetime.timedelta(days=15)).strftime("%b%d")+'', ' 0:00 ', '[aio/0]',), | |
('root ', ' 748', ' 0.0', ' 0.0', ' 0', ' 0', ' ? ', 'S< ', ''+(datetime.datetime.now()-datetime.timedelta(days=15)).strftime("%b%d")+'', ' 0:00 ', '[ata/0]',), | |
('root ', ' 749', ' 0.0', ' 0.0', ' 0', ' 0', ' ? ', 'S< ', ''+(datetime.datetime.now()-datetime.timedelta(days=15)).strftime("%b%d")+'', ' 0:00 ', '[ata_aux]',), | |
('root ', ' 929', ' 0.0', ' 0.0', ' 0', ' 0', ' ? ', 'S< ', ''+(datetime.datetime.now()-datetime.timedelta(days=15)).strftime("%b%d")+'', ' 0:00 ', '[scsi_eh_0]',), | |
('root ', '1014', ' 0.0', ' 0.0', ' 0', ' 0', ' ? ', 'D< ', ''+(datetime.datetime.now()-datetime.timedelta(days=15)).strftime("%b%d")+'', ' 0:03 ', '[kjournald]',), | |
('root ', '1087', ' 0.0', ' 0.1', ' 2288', ' 772', ' ? ', 'S<s ', ''+(datetime.datetime.now()-datetime.timedelta(days=15)).strftime("%b%d")+'', ' 0:00 ', 'udevd --daemon',), | |
('root ', '1553', ' 0.0', ' 0.0', ' 0', ' 0', ' ? ', 'S< ', ''+(datetime.datetime.now()-datetime.timedelta(days=15)).strftime("%b%d")+'', ' 0:00 ', '[kpsmoused]',), | |
('root ', '2054', ' 0.0', ' 0.2', ' 28428', ' 1508', ' ? ', 'Sl ', ''+(datetime.datetime.now()-datetime.timedelta(days=15)).strftime("%b%d")+'', ' 0:01 ', '/usr/sbin/rsyslogd -c3',), | |
('root ', '2103', ' 0.0', ' 0.2', ' 2628', ' 1196', ' tty1 ', 'Ss ', ''+(datetime.datetime.now()-datetime.timedelta(days=15)).strftime("%b%d")+'', ' 0:00 ', '/bin/login -- ',), | |
('root ', '2105', ' 0.0', ' 0.0', ' 1764', ' 504', ' tty2 ', 'Ss+ ', ''+(datetime.datetime.now()-datetime.timedelta(days=15)).strftime("%b%d")+'', ' 0:00 ', '/sbin/getty 38400 tty2',), | |
('root ', '2107', ' 0.0', ' 0.0', ' 1764', ' 504', ' tty3 ', 'Ss+ ', ''+(datetime.datetime.now()-datetime.timedelta(days=15)).strftime("%b%d")+'', ' 0:00 ', '/sbin/getty 38400 tty3',), | |
('root ', '2109', ' 0.0', ' 0.0', ' 1764', ' 504', ' tty4 ', 'Ss+ ', ''+(datetime.datetime.now()-datetime.timedelta(days=15)).strftime("%b%d")+'', ' 0:00 ', '/sbin/getty 38400 tty4',), | |
('root ', '2110', ' 0.0', ' 0.0', ' 1764', ' 504', ' tty5 ', 'Ss+ ', ''+(datetime.datetime.now()-datetime.timedelta(days=15)).strftime("%b%d")+'', ' 0:00 ', '/sbin/getty 38400 tty5',), | |
('root ', '2112', ' 0.0', ' 0.0', ' 1764', ' 508', ' tty6 ', 'Ss+ ', ''+(datetime.datetime.now()-datetime.timedelta(days=15)).strftime("%b%d")+'', ' 0:00 ', '/sbin/getty 38400 tty6',), | |
('root ', '2133', ' 0.0', ' 0.1', ' 2180', ' 620', ' ? ', 'S<s ', ''+(datetime.datetime.now()-datetime.timedelta(days=15)).strftime("%b%d")+'', ' 0:00 ', 'dhclient3 -pf /var/run/dhclient.eth0.pid -lf /var/lib/dhcp3/dhclien',), | |
('root ', '4969', ' 0.0', ' 0.1', ' 5416', ' 1024', ' ? ', 'Ss ', ''+(datetime.datetime.now()-datetime.timedelta(days=13)).strftime("%b%d")+'', ' 0:00 ', '/usr/sbin/sshd: %s@pts/0' % user,), | |
('%s'.ljust(8) % user, '5673', ' 0.0', ' 0.2', ' 2924', ' 1540', ' pts/0 ', 'Ss ', '04:30', ' 0:00 ', '-bash',), | |
('%s'.ljust(8) % user, '5679', ' 0.0', ' 0.1', ' 2432', ' 928', ' pts/0 ', 'R+ ', '04:32', ' 0:00 ', 'ps %s' % ' '.join(self.args),) | |
) | |
for i in range(len(output)): | |
if i != 0: | |
if 'a' not in args and output[i][_user].strip() != user: | |
continue | |
elif 'a' not in args and 'x' not in args \ | |
and output[i][_tty].strip() != 'pts/0': | |
continue | |
l = [_pid, _tty, _time, _command] | |
if 'a' in args or 'x' in args: | |
l = [_pid, _tty, _stat, _time, _command] | |
if 'u' in args: | |
l = [_user, _pid, _cpu, _mem, _vsz, _rss, _tty, _stat, | |
_start, _time, _command] | |
s = ''.join([output[i][x] for x in l]) | |
if 'w' not in args: | |
s = s[:80] | |
self.writeln(s) | |
commands['/bin/ps'] = command_ps | |
class command_id(HoneyPotCommand): | |
def call(self): | |
u = self.honeypot.user | |
self.writeln('uid=%d(%s) gid=%d(%s) groups=%d(%s)' % \ | |
(u.uid, u.username, u.gid, u.username, u.gid, u.username)) | |
commands['/usr/bin/id'] = command_id | |
class command_passwd(HoneyPotCommand): | |
def start(self): | |
self.write('Enter new UNIX password: ') | |
self.honeypot.password_input = True | |
self.callbacks = [self.ask_again, self.finish] | |
self.passwd = None | |
def ask_again(self, line): | |
self.passwd = line | |
self.write('Retype new UNIX password: ') | |
def finish(self, line): | |
self.honeypot.password_input = False | |
if line != self.passwd: | |
self.writeln('Sorry, passwords do not match') | |
self.exit() | |
return | |
userdb = UserDB() | |
userdb.adduser(self.honeypot.user.username, | |
self.honeypot.user.uid, self.passwd) | |
self.writeln('passwd: password updated successfully') | |
self.exit() | |
def lineReceived(self, line): | |
print 'INPUT (passwd):', line | |
self.password = line.strip() | |
self.callbacks.pop(0)(line) | |
commands['/usr/bin/passwd'] = command_passwd | |
class command_shutdown(HoneyPotCommand): | |
def start(self): | |
if len(self.args) and self.args[0].strip().count('--help'): | |
output = ( | |
"Usage: shutdown [-akrhHPfnc] [-t secs] time [warning message]", | |
"-a: use /etc/shutdown.allow ", | |
"-k: don't really shutdown, only warn. " , | |
"-r: reboot after shutdown. " , | |
"-h: halt after shutdown. " , | |
"-P: halt action is to turn off power. " , | |
"-H: halt action is to just halt. " , | |
"-f: do a 'fast' reboot (skip fsck). " , | |
"-F: Force fsck on reboot. " , | |
"-n: do not go through \"init\" but go down real fast. " , | |
"-c: cancel a running shutdown. " , | |
"-t secs: delay between warning and kill signal. " , | |
"** the \"time\" argument is mandatory! (try \"now\") **", | |
) | |
for l in output: | |
self.writeln(l) | |
self.exit() | |
elif len(self.args) > 1 and self.args[0].strip().count('-h') \ | |
and self.args[1].strip().count('now'): | |
self.nextLine() | |
self.writeln( | |
'Broadcast message from root@%s (pts/0) (%s):' % \ | |
(self.honeypot.hostname, time.ctime())) | |
self.nextLine() | |
self.writeln('The system is going down for maintenance NOW!') | |
reactor.callLater(3, self.finish) | |
elif len(self.args) > 1 and self.args[0].strip().count('-r') \ | |
and self.args[1].strip().count('now'): | |
self.nextLine() | |
self.writeln( | |
'Broadcast message from root@%s (pts/0) (%s):' % \ | |
(self.honeypot.hostname, time.ctime())) | |
self.nextLine() | |
self.writeln('The system is going down for reboot NOW!') | |
reactor.callLater(3, self.finish) | |
else: | |
self.writeln("Try `shutdown --help' for more information.") | |
self.exit() | |
return | |
def finish(self): | |
self.writeln('Connection to server closed.') | |
self.honeypot.hostname = 'localhost' | |
self.honeypot.cwd = '/root' | |
if not self.fs.exists(self.honeypot.cwd): | |
self.honeypot.cwd = '/' | |
self.exit() | |
commands['/sbin/shutdown'] = command_shutdown | |
class command_reboot(HoneyPotCommand): | |
def start(self): | |
self.nextLine() | |
self.writeln( | |
'Broadcast message from root@%s (pts/0) (%s):' % \ | |
(self.honeypot.hostname, time.ctime())) | |
self.nextLine() | |
self.writeln('The system is going down for reboot NOW!') | |
reactor.callLater(3, self.finish) | |
def finish(self): | |
self.writeln('Connection to server closed.') | |
self.honeypot.hostname = 'localhost' | |
self.honeypot.cwd = '/root' | |
if not self.fs.exists(self.honeypot.cwd): | |
self.honeypot.cwd = '/' | |
self.honeypot.uptime(time.time()) | |
self.exit() | |
commands['/sbin/reboot'] = command_reboot | |
class command_history(HoneyPotCommand): | |
def call(self): | |
if len(self.args) and self.args[0] == '-c': | |
self.honeypot.historyLines = [] | |
self.honeypot.historyPosition = 0 | |
return | |
count = 1 | |
for l in self.honeypot.historyLines: | |
self.writeln(' %s %s' % (str(count).rjust(4), l)) | |
count += 1 | |
commands['history'] = command_history | |
class command_date(HoneyPotCommand): | |
def call(self): | |
time = datetime.datetime.utcnow(); | |
self.writeln(time.strftime("%a %b %d %H:%M:%S UTC %Y")) | |
commands['/bin/date'] = command_date | |
class command_yes(HoneyPotCommand): | |
def start(self): | |
self.y() | |
def y(self): | |
self.writeln('y') | |
self.scheduled = reactor.callLater(0.01, self.y) | |
def ctrl_c(self): | |
self.scheduled.cancel() | |
self.exit() | |
commands['/usr/bin/yes'] = command_yes | |
class command_nop(HoneyPotCommand): | |
def call(self): | |
pass | |
commands['/bin/chmod'] = command_nop | |
commands['set'] = command_nop | |
commands['unset'] = command_nop | |
commands['export'] = command_nop | |
commands['/bin/bash'] = command_nop | |
commands['/bin/sh'] = command_nop | |
commands['/bin/kill'] = command_nop | |
commands['/bin/su'] = command_nop | |
# vim: set sw=4 et: |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment