svn breakage

git-svn-id: https://kippo.googlecode.com/svn/trunk@51 951d7100-d841-11de-b865-b3884708a8e2
This commit is contained in:
desaster
2009-11-22 07:09:09 +00:00
parent 88d377cfc6
commit 512491c640
8 changed files with 0 additions and 846 deletions

View File

@@ -1,12 +0,0 @@
# Copyright (c) 2009 Upi Tamminen <desaster@gmail.com>
# See the COPYRIGHT file for more information
__all__ = [
'base',
'ls',
'ping',
'ssh',
'tar',
'wget',
'dice',
]

View File

@@ -1,293 +0,0 @@
# Copyright (c) 2009 Upi Tamminen <desaster@gmail.com>
# See the COPYRIGHT file for more information
import os, time
from core.honeypot import HoneyPotCommand
from core.fs import *
from twisted.internet import reactor
import config
commands = {}
class command_whoami(HoneyPotCommand):
def call(self):
self.writeln(self.honeypot.user.username)
commands['/usr/bin/whoami'] = command_whoami
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' % (config.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):
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:
self.writeln(
'rm: cannot remove `%s\': Is a directory' % \
i[A_NAME])
else:
dir.remove(i)
commands['/bin/rm'] = command_rm
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_uptime(HoneyPotCommand):
def call(self):
self.writeln(
' %s up 14 days, 3:53, 0 users, load average: 0.08, 0.02, 0.01' % \
time.strftime('%H:%M:%S'))
commands['/usr/bin/uptime'] = command_uptime
class command_w(HoneyPotCommand):
def call(self):
self.writeln(
' %s up 14 days, 3:53, 0 users, load average: 0.08, 0.02, 0.01' % \
time.strftime('%H:%M:%S'))
self.writeln('USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT')
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
class command_exit(HoneyPotCommand):
def call(self):
#self.honeypot.terminal.loseConnection()
self.honeypot.terminal.reset()
self.writeln('Connection to server closed.')
self.honeypot.hostname = 'localhost'
commands['exit'] = command_exit
class command_clear(HoneyPotCommand):
def call(self):
self.honeypot.terminal.reset()
commands['/usr/bin/clear'] = command_clear
class command_vi(HoneyPotCommand):
def call(self):
self.writeln('E558: Terminal entry not found in terminfo')
commands['/usr/bin/vi'] = command_vi
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):
if len(self.args) and self.args[0].strip().count('a'):
output = (
'USER PID %%CPU %%MEM VSZ RSS TTY STAT START TIME COMMAND',
'root 1 0.0 0.1 2100 688 ? Ss Nov06 0:07 init [2] ',
'root 2 0.0 0.0 0 0 ? S< Nov06 0:00 [kthreadd]',
'root 3 0.0 0.0 0 0 ? S< Nov06 0:00 [migration/0]',
'root 4 0.0 0.0 0 0 ? S< Nov06 0:00 [ksoftirqd/0]',
'root 5 0.0 0.0 0 0 ? S< Nov06 0:00 [watchdog/0]',
'root 6 0.0 0.0 0 0 ? S< Nov06 0:17 [events/0]',
'root 7 0.0 0.0 0 0 ? S< Nov06 0:00 [khelper]',
'root 39 0.0 0.0 0 0 ? S< Nov06 0:00 [kblockd/0]',
'root 41 0.0 0.0 0 0 ? S< Nov06 0:00 [kacpid]',
'root 42 0.0 0.0 0 0 ? S< Nov06 0:00 [kacpi_notify]',
'root 170 0.0 0.0 0 0 ? S< Nov06 0:00 [kseriod]',
'root 207 0.0 0.0 0 0 ? S Nov06 0:01 [pdflush]',
'root 208 0.0 0.0 0 0 ? S Nov06 0:00 [pdflush]',
'root 209 0.0 0.0 0 0 ? S< Nov06 0:00 [kswapd0]',
'root 210 0.0 0.0 0 0 ? S< Nov06 0:00 [aio/0]',
'root 748 0.0 0.0 0 0 ? S< Nov06 0:00 [ata/0]',
'root 749 0.0 0.0 0 0 ? S< Nov06 0:00 [ata_aux]',
'root 929 0.0 0.0 0 0 ? S< Nov06 0:00 [scsi_eh_0]',
'root 1014 0.0 0.0 0 0 ? D< Nov06 0:03 [kjournald]',
'root 1087 0.0 0.1 2288 772 ? S<s Nov06 0:00 udevd --daemon',
'root 1553 0.0 0.0 0 0 ? S< Nov06 0:00 [kpsmoused]',
'root 2054 0.0 0.2 28428 1508 ? Sl Nov06 0:01 /usr/sbin/rsyslogd -c3',
'root 2103 0.0 0.2 2628 1196 tty1 Ss Nov06 0:00 /bin/login -- ',
'root 2105 0.0 0.0 1764 504 tty2 Ss+ Nov06 0:00 /sbin/getty 38400 tty2',
'root 2107 0.0 0.0 1764 504 tty3 Ss+ Nov06 0:00 /sbin/getty 38400 tty3',
'root 2109 0.0 0.0 1764 504 tty4 Ss+ Nov06 0:00 /sbin/getty 38400 tty4',
'root 2110 0.0 0.0 1764 504 tty5 Ss+ Nov06 0:00 /sbin/getty 38400 tty5',
'root 2112 0.0 0.0 1764 508 tty6 Ss+ Nov06 0:00 /sbin/getty 38400 tty6',
'root 2133 0.0 0.1 2180 620 ? S<s Nov06 0:00 dhclient3 -pf /var/run/dhclient.eth0.pid -lf /var/lib/dhcp3/dhclien',
'root 4969 0.0 0.1 5416 1024 ? Ss Nov08 0:00 /usr/sbin/sshd',
'root 5673 0.0 0.2 2924 1540 pts/0 Ss 04:30 0:00 -bash',
'root 5679 0.0 0.1 2432 928 pts/0 R+ 04:32 0:00 ps %s' % ' '.join(self.args),
)
else:
output = (
' PID TTY TIME CMD',
' 5673 pts/0 00:00:00 bash',
' 5677 pts/0 00:00:00 ps %s' % ' '.join(self.args),
)
for l in output:
self.writeln(l)
commands['/bin/ps'] = command_ps
class command_id(HoneyPotCommand):
def call(self):
self.writeln('uid=0(root) gid=0(root) groups=0(root)')
commands['/usr/bin/id'] = command_id
class command_mount(HoneyPotCommand):
def call(self):
if self.args and len(self.args[0].strip()):
return
for i in [
'/dev/sda1 on / type ext3 (rw,errors=remount-ro)',
'tmpfs on /lib/init/rw type tmpfs (rw,nosuid,mode=0755)',
'proc on /proc type proc (rw,noexec,nosuid,nodev)',
'sysfs on /sys type sysfs (rw,noexec,nosuid,nodev)',
'udev on /dev type tmpfs (rw,mode=0755)',
'tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev)',
'devpts on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=620)',
]:
self.writeln(i)
commands['/usr/mount'] = command_mount
class command_pwd(HoneyPotCommand):
def call(self):
self.writeln(self.honeypot.cwd)
commands['/bin/pwd'] = command_pwd
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]
def ask_again(self):
self.write('Retype new UNIX password: ')
def finish(self):
self.honeypot.password_input = False
self.writeln('Sorry, passwords do not match')
self.writeln(
'passwd: Authentication information cannot be recovered')
self.writeln('passwd: password unchanged')
self.exit()
def lineReceived(self, line):
print 'INPUT (passwd):', line
self.callbacks.pop(0)()
commands['/usr/bin/passwd'] = command_passwd
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.exit()
commands['/sbin/reboot'] = command_reboot
class command_nop(HoneyPotCommand):
def call(self):
pass
commands['/bin/chmod'] = command_nop
commands['set'] = command_nop
commands['unset'] = command_nop
commands['history'] = command_nop
commands['export'] = command_nop
commands['/bin/bash'] = command_nop
commands['/bin/sh'] = command_nop
commands['/bin/kill'] = command_nop
# vim: set sw=4 et:

View File

@@ -1,45 +0,0 @@
# Copyright (c) 2009 Upi Tamminen <desaster@gmail.com>
# See the COPYRIGHT file for more information
# Random commands when running new executables
from core.honeypot import HoneyPotCommand
commands = {}
clist = []
class command_orly(HoneyPotCommand):
def start(self):
self.orly()
def orly(self):
self.writeln(' ___ ')
self.writeln(' {o,o}')
self.writeln(' |)__)')
self.writeln(' -"-"-')
self.write('O RLY? ')
def lineReceived(self, data):
if data.strip().lower() in ('ya', 'yarly', 'ya rly', 'yes', 'y'):
self.writeln(' ___')
self.writeln(' {o,o}')
self.writeln(' (__(|')
self.writeln(' -"-"-')
self.writeln('NO WAI!')
self.exit()
return
self.orly()
clist.append(command_orly)
class command_wargames(HoneyPotCommand):
def start(self):
self.write('Shall we play a game? ')
def lineReceived(self, data):
self.writeln('A strange game. ' + \
'The only winning move is not to play. ' + \
'How about a nice game of chess?')
self.exit()
clist.append(command_wargames)
# vim: set sw=4 et:

View File

@@ -1,121 +0,0 @@
# Copyright (c) 2009 Upi Tamminen <desaster@gmail.com>
# See the COPYRIGHT file for more information
from core.honeypot import HoneyPotCommand
from core.fs import *
import stat, time
commands = {}
class command_ls(HoneyPotCommand):
def uid2name(self, uid):
if uid == 0:
return 'root'
return uid
def gid2name(self, gid):
if gid == 0:
return 'root'
return gid
def call(self):
path = self.honeypot.cwd
paths = []
if len(self.args):
for arg in self.args:
if not arg.startswith('-'):
paths.append(self.honeypot.fs.resolve_path(arg,
self.honeypot.cwd))
self.show_hidden = False
func = self.do_ls_normal
for x in self.args:
if x.startswith('-') and x.count('l'):
func = self.do_ls_l
if x.startswith('-') and x.count('a'):
self.show_hidden = True
if not paths:
func(path)
else:
for path in paths:
func(path)
def do_ls_normal(self, path):
try:
files = self.honeypot.fs.list_files(path)
except:
self.honeypot.writeln(
'ls: cannot access %s: No such file or directory' % path)
return
if not len(files):
return
l = [x[A_NAME] for x in files \
if self.show_hidden or not x[A_NAME].startswith('.')]
if not l:
return
count = 0
maxlen = max([len(x) for x in l])
perline = int(self.honeypot.user.windowSize[1] / (maxlen + 1))
if self.show_hidden:
l.insert(0, '..')
l.insert(0, '.')
for f in l:
if count == perline:
count = 0
self.nextLine()
self.write(f.ljust(maxlen + 1))
count += 1
self.nextLine()
def do_ls_l(self, path):
try:
files = self.honeypot.fs.list_files(path)[:]
except:
self.honeypot.writeln(
'ls: cannot access %s: No such file or directory' % path)
return
largest = 0
if len(files):
largest = max([x[A_SIZE] for x in files])
# FIXME: should grab these off the parents instead
files.insert(0,
['..', T_DIR, 0, 0, 4096, 16877, time.time(), [], None])
files.insert(0,
['.', T_DIR, 0, 0, 4096, 16877, time.time(), [], None])
for file in files:
perms = ['-'] * 10
if file[A_MODE] & stat.S_IRUSR: perms[1] = 'r'
if file[A_MODE] & stat.S_IWUSR: perms[2] = 'w'
if file[A_MODE] & stat.S_IXUSR: perms[3] = 'x'
if file[A_MODE] & stat.S_IRGRP: perms[4] = 'r'
if file[A_MODE] & stat.S_IWGRP: perms[5] = 'w'
if file[A_MODE] & stat.S_IXGRP: perms[6] = 'x'
if file[A_MODE] & stat.S_IROTH: perms[7] = 'r'
if file[A_MODE] & stat.S_IWOTH: perms[8] = 'w'
if file[A_MODE] & stat.S_IXOTH: perms[9] = 'x'
if file[A_TYPE] == T_DIR:
perms[0] = 'd'
perms = ''.join(perms)
ctime = time.localtime(file[A_CTIME])
l = '%s 1 %s %s %s %s %s' % \
(perms,
self.uid2name(file[A_UID]),
self.gid2name(file[A_GID]),
str(file[A_SIZE]).rjust(len(str(largest))),
time.strftime('%Y-%m-%d %H:%M', ctime),
file[A_NAME])
self.honeypot.writeln(l)
commands['/bin/ls'] = command_ls
# vim: set sw=4 et:

View File

@@ -1,52 +0,0 @@
# Copyright (c) 2009 Upi Tamminen <desaster@gmail.com>
# See the COPYRIGHT file for more information
from core.honeypot import HoneyPotCommand
from twisted.internet import reactor
import time, re, random, md5
commands = {}
class command_ping(HoneyPotCommand):
def start(self):
if not len(self.args):
for l in (
'Usage: ping [-LRUbdfnqrvVaA] [-c count] [-i interval] [-w deadline]',
' [-p pattern] [-s packetsize] [-t ttl] [-I interface or address]',
' [-M mtu discovery hint] [-S sndbuf]',
' [ -T timestamp option ] [ -Q tos ] [hop1 ...] destination',
):
self.writeln(l)
self.exit()
return
self.host = self.args[0]
if re.match('^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$',
self.host):
self.ip = self.host
else:
s = md5.md5(self.host).hexdigest()
self.ip = '.'.join([str(int(x, 16)) for x in
(s[0:2], s[2:4], s[4:6], s[6:8])])
self.writeln('PING %s (%s) 56(84) bytes of data.' % \
(self.host, self.ip))
self.scheduled = reactor.callLater(0.2, self.showreply)
self.count = 0
def showreply(self):
ms = 40 + random.random() * 10
self.writeln(
'64 bytes from %s (%s): icmp_seq=%d ttl=50 time=%.1f ms' % \
(self.host, self.ip, self.count + 1, ms))
self.count += 1
self.scheduled = reactor.callLater(1, self.showreply)
def ctrl_c(self):
self.scheduled.cancel()
self.writeln('--- %s ping statistics ---' % self.host)
self.writeln('%d packets transmitted, %d received, 0%% packet loss, time 907ms' % \
(self.count, self.count))
self.writeln('rtt min/avg/max/mdev = 48.264/50.352/52.441/2.100 ms')
self.exit()
commands['/bin/ping'] = command_ping

View File

@@ -1,63 +0,0 @@
# Copyright (c) 2009 Upi Tamminen <desaster@gmail.com>
# See the COPYRIGHT file for more information
from core.honeypot import HoneyPotCommand
from twisted.internet import reactor
import time
commands = {}
class command_ssh(HoneyPotCommand):
def start(self):
if not self.args:
for l in (
'usage: ssh [-1246AaCfgKkMNnqsTtVvXxY] [-b bind_address] [-c cipher_spec]',
' [-D [bind_address:]port] [-e escape_char] [-F configfile]',
' [-i identity_file] [-L [bind_address:]port:host:hostport]',
' [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]',
' [-R [bind_address:]port:host:hostport] [-S ctl_path]',
' [-w local_tun[:remote_tun]] [user@]hostname [command]',
):
self.writeln(l)
self.exit()
return
self.host = self.args[0].strip()
self.writeln('The authenticity of host \'187.42.2.9 (187.42.2.9)\' can\'t be established.')
self.writeln('RSA key fingerprint is 9d:30:97:8a:9e:48:0d:de:04:8d:76:3a:7b:4b:30:f8.')
self.write('Are you sure you want to continue connecting (yes/no)? ')
self.callbacks = [self.yesno, self.wait]
def yesno(self, line):
host = line.strip()
self.writeln(
'Warning: Permanently added \'%s\' (RSA) to the list of known hosts.' % \
host)
self.write('%s\'s password: ' % self.host)
self.honeypot.password_input = True
def wait(self, line):
reactor.callLater(2, self.finish, line)
def finish(self, line):
self.pause = False
user, rest, host = 'root', self.host, 'localhost'
if self.host.count('@'):
user, rest = self.host.split('@', 1)
rest = rest.strip().split('.')
if len(rest) and rest[0].isalpha():
host = rest[0]
self.honeypot.hostname = host
self.honeypot.password_input = False
self.writeln(
'Linux %s 2.6.26-2-686 #1 SMP Wed Nov 4 20:45:37 UTC 2009 i686' % \
self.honeypot.hostname)
self.writeln('Last login: %s from 192.168.9.4' % \
time.ctime(time.time() - 123123))
self.exit()
def lineReceived(self, line):
if len(self.callbacks):
self.callbacks.pop(0)(line)
commands['/usr/bin/ssh'] = command_ssh
# vim: set sw=4 et:

View File

@@ -1,66 +0,0 @@
# Copyright (c) 2009 Upi Tamminen <desaster@gmail.com>
# See the COPYRIGHT file for more information
from core.honeypot import HoneyPotCommand
from core.fs import *
from commands import dice
import time, random, tarfile, os
commands = {}
class command_tar(HoneyPotCommand):
def call(self):
if len(self.args) < 2:
self.writeln('tar: You must specify one of the `-Acdtrux\' options')
self.writeln('Try `tar --help\' or `tar --usage\' for more information.')
return
filename = self.args[1]
extract = False
if 'x' in self.args[0]:
extract = True
verbose = False
if 'v' in self.args[0]:
verbose = True
path = self.fs.resolve_path(filename, self.honeypot.cwd)
if not path or not self.honeypot.fs.exists(path):
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')
return
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
for f in t:
dest = self.fs.resolve_path(f.name.strip('/'), self.honeypot.cwd)
if verbose:
self.writeln(f.name)
if not extract or not len(dest):
continue
if f.isdir():
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)
else:
print 'tar: skipping [%s]' % f.name
commands['/bin/tar'] = command_tar
# vim: set sw=4 et:

View File

@@ -1,194 +0,0 @@
# Copyright (c) 2009 Upi Tamminen <desaster@gmail.com>
# See the COPYRIGHT file for more information
from core.honeypot import HoneyPotCommand
from core.fs import *
from twisted.web import client
from twisted.internet import reactor
import stat, time, urlparse, random, re
commands = {}
def tdiff(seconds):
t = seconds
days = int(t / (24 * 60 * 60))
t -= (days * 24 * 60 * 60)
hours = int(t / (60 * 60))
t -= (hours * 60 * 60)
minutes = int(t / 60)
t -= (minutes * 60)
s = '%ds' % int(t)
if minutes >= 1: s = '%dm %s' % (minutes, s)
if hours >= 1: s = '%dh %s' % (hours, s)
if days >= 1: s = '%dd %s' % (days, s)
return s
def sizeof_fmt(num):
for x in ['bytes','K','M','G','T']:
if num < 1024.0:
return "%d%s" % (num, x)
num /= 1024.0
# Luciano Ramalho @ http://code.activestate.com/recipes/498181/
def splitthousands( s, sep=','):
if len(s) <= 3: return s
return splitthousands(s[:-3], sep) + sep + s[-3:]
class command_wget(HoneyPotCommand):
def start(self):
url = None
for arg in self.args:
if arg.startswith('-'):
continue
url = arg.strip()
break
if not url:
self.writeln('wget: missing URL')
self.writeln('Usage: wget [OPTION]... [URL]...')
self.nextLine()
self.writeln('Try `wget --help\' for more options.')
self.exit()
return
if url and not url.startswith('http://'):
url = 'http://%s' % url
urldata = urlparse.urlparse(url)
outfile = urldata.path.split('/')[-1]
if not len(outfile.strip()) or not urldata.path.count('/'):
outfile = 'index.html'
self.safeoutfile = '%s/%s_%s' % \
(self.honeypot.env.cfg.get('honeypot', 'download_path'),
time.strftime('%Y%m%d%H%M%S'),
re.sub('[^A-Za-z0-9]', '_', url))
self.deferred = self.download(url, outfile,
file(self.safeoutfile, 'wb'))
if self.deferred:
self.deferred.addCallback(self.success)
self.deferred.addErrback(self.error, url)
def download(self, url, fakeoutfile, outputfile, *args, **kwargs):
scheme, host, port, path = client._parse(url)
if scheme == 'https':
self.writeln('Sorry, SSL not supported in this release')
return None
self.writeln('--%s-- %s' % (time.strftime('%Y-%m-%d %H:%M:%S'), url))
self.writeln('Connecting to %s:%d... connected.' % (host, port))
self.write('HTTP request sent, awaiting response... ')
factory = HTTPProgressDownloader(
self, fakeoutfile, url, outputfile, *args, **kwargs)
self.connection = reactor.connectTCP(host, port, factory)
return factory.deferred
def ctrl_c(self):
self.writeln('^C')
self.connection.transport.loseConnection()
def success(self, data):
self.exit()
def error(self, error, url):
if hasattr(error, 'getErrorMessage'): # exceptions
error = error.getErrorMessage()
self.writeln(error)
# Real wget also adds this:
#self.writeln('%s ERROR 404: Not Found.' % \
# time.strftime('%Y-%m-%d %T'))
self.exit()
commands['/usr/bin/wget'] = command_wget
# from http://code.activestate.com/recipes/525493/
class HTTPProgressDownloader(client.HTTPDownloader):
def __init__(self, wget, fakeoutfile, url, outfile, headers=None):
client.HTTPDownloader.__init__(self, url, outfile, headers=headers)
self.status = None
self.wget = wget
self.fakeoutfile = fakeoutfile
self.lastupdate = 0
self.started = time.time()
self.proglen = 0
def noPage(self, reason): # called for non-200 responses
if self.status == '304':
client.HTTPDownloader.page(self, '')
else:
client.HTTPDownloader.noPage(self, reason)
def gotHeaders(self, headers):
if self.status == '200':
self.wget.writeln('200 OK')
if headers.has_key('content-length'):
self.totallength = int(headers['content-length'][0])
else:
self.totallength = 0
if headers.has_key('content-type'):
self.contenttype = headers['content-type'][0]
else:
self.contenttype = 'text/whatever'
self.currentlength = 0.0
if self.totallength > 0:
self.wget.writeln('Length: %d (%s) [%s]' % \
(self.totallength,
sizeof_fmt(self.totallength),
self.contenttype))
else:
self.wget.writeln('Length: unspecified [%s]' % \
(self.contenttype))
self.wget.writeln('Saving to: `%s' % self.fakeoutfile)
self.wget.honeypot.terminal.nextLine()
return client.HTTPDownloader.gotHeaders(self, headers)
def pagePart(self, data):
if self.status == '200':
self.currentlength += len(data)
if (time.time() - self.lastupdate) < 0.5:
return client.HTTPDownloader.pagePart(self, data)
if self.totallength:
percent = (self.currentlength/self.totallength)*100
spercent = "%i%%" % percent
else:
spercent = '%dK' % (self.currentlength/1000)
percent = 0
self.speed = self.currentlength / (time.time() - self.started)
eta = (self.totallength - self.currentlength) / self.speed
s = '\r%s [%s] %s %dK/s eta %s' % \
(spercent.rjust(3),
('%s>' % (int(39.0 / 100.0 * percent) * '=')).ljust(39),
splitthousands(str(int(self.currentlength))).ljust(12),
self.speed / 1000,
tdiff(eta))
self.wget.write(s.ljust(self.proglen))
self.proglen = len(s)
self.lastupdate = time.time()
return client.HTTPDownloader.pagePart(self, data)
def pageEnd(self):
if self.totallength != 0 and self.currentlength != self.totallength:
return client.HTTPDownloader.pageEnd(self)
self.wget.write('\r100%%[%s] %s %dK/s' % \
('%s>' % (38 * '='),
splitthousands(str(int(self.totallength))).ljust(12),
self.speed / 1000))
self.wget.honeypot.terminal.nextLine()
self.wget.honeypot.terminal.nextLine()
self.wget.writeln(
'%s (%d KB/s) - `%s\' saved [%d/%d]' % \
(time.strftime('%Y-%m-%d %H:%M:%S'),
self.speed / 1000,
self.fakeoutfile, self.currentlength, self.totallength))
outfile = '%s/%s' % (self.wget.honeypot.cwd, self.fakeoutfile)
self.wget.fs.mkfile(outfile, 0, 0, self.totallength, 33188)
self.wget.fs.update_realfile(
self.wget.fs.getfile(outfile),
self.wget.safeoutfile)
return client.HTTPDownloader.pageEnd(self)
# vim: set sw=4 et: