mirror of
https://github.com/cowrie/cowrie.git
synced 2025-07-01 18:07:27 -04:00
@ -19,6 +19,7 @@ from twisted.python import log, compat
|
||||
from cowrie.shell.honeypot import HoneyPotCommand
|
||||
from cowrie.shell.fs import *
|
||||
|
||||
from cowrie.core.artifact import Artifact
|
||||
from cowrie.core.config import CONFIG
|
||||
|
||||
"""
|
||||
@ -120,6 +121,7 @@ class command_wget(HoneyPotCommand):
|
||||
if not path or not self.fs.exists(path) or not self.fs.isdir(path):
|
||||
self.errorWrite('wget: %s: Cannot open: No such file or directory\n' % outfile)
|
||||
self.exit()
|
||||
return
|
||||
|
||||
self.url = url
|
||||
|
||||
@ -128,9 +130,8 @@ class command_wget(HoneyPotCommand):
|
||||
self.limit_size = CONFIG.getint('honeypot', 'download_limit_size')
|
||||
self.downloadPath = CONFIG.get('honeypot', 'download_path')
|
||||
|
||||
self.artifactFile = tempfile.NamedTemporaryFile(dir=self.downloadPath, delete=False)
|
||||
self.artifactFile = Artifact(outfile)
|
||||
# HTTPDownloader will close() the file object so need to preserve the name
|
||||
self.artifactName = self.artifactFile.name
|
||||
|
||||
d = self.download(url, outfile, self.artifactFile)
|
||||
if d:
|
||||
@ -139,7 +140,6 @@ class command_wget(HoneyPotCommand):
|
||||
else:
|
||||
self.exit()
|
||||
|
||||
|
||||
def download(self, url, fakeoutfile, outputfile, *args, **kwargs):
|
||||
"""
|
||||
url - URL to download
|
||||
@ -182,49 +182,42 @@ class command_wget(HoneyPotCommand):
|
||||
|
||||
return factory.deferred
|
||||
|
||||
|
||||
def handle_CTRL_C(self):
|
||||
"""
|
||||
"""
|
||||
self.errorWrite('^C\n')
|
||||
self.connection.transport.loseConnection()
|
||||
|
||||
|
||||
def success(self, data, outfile):
|
||||
"""
|
||||
"""
|
||||
if not os.path.isfile(self.artifactName):
|
||||
log.msg("there's no file " + self.artifactName)
|
||||
if not os.path.isfile(self.artifactFile.shasumFilename):
|
||||
log.msg("there's no file " + self.artifactFile.shasumFilename)
|
||||
self.exit()
|
||||
|
||||
with open(self.artifactName, 'rb') as f:
|
||||
filedata = f.read()
|
||||
shasum = hashlib.sha256(filedata).hexdigest()
|
||||
hash_path = os.path.join(self.downloadPath, shasum)
|
||||
|
||||
# Rename temp file to the hash
|
||||
if not os.path.exists(hash_path):
|
||||
os.rename(self.artifactName, hash_path)
|
||||
unique = True
|
||||
else:
|
||||
os.remove(self.artifactName)
|
||||
log.msg("Not storing duplicate content " + shasum)
|
||||
unique = False
|
||||
# log to cowrie.log
|
||||
log.msg(format='Downloaded URL (%(url)s) with SHA-256 %(shasum)s to %(outfile)s',
|
||||
url=self.url,
|
||||
outfile=self.artifactFile.shasumFilename,
|
||||
shasum=self.artifactFile.shasum)
|
||||
|
||||
# log to output modules
|
||||
self.protocol.logDispatch(eventid='cowrie.session.file_download',
|
||||
format='Downloaded URL (%(url)s) with SHA-256 %(shasum)s to %(outfile)s',
|
||||
url=self.url, outfile=hash_path, shasum=shasum, unique=unique)
|
||||
format='Downloaded URL (%(url)s) with SHA-256 %(shasum)s to %(outfile)s',
|
||||
url=self.url,
|
||||
outfile=self.artifactFile.shasumFilename,
|
||||
shasum=self.artifactFile.shasum)
|
||||
|
||||
# Update honeyfs to point to downloaded file or write to screen
|
||||
if outfile != '-':
|
||||
self.fs.update_realfile(self.fs.getfile(outfile), hash_path)
|
||||
self.fs.update_realfile(self.fs.getfile(outfile), self.artifactFile.shasumFilename)
|
||||
self.fs.chown(outfile, self.protocol.user.uid, self.protocol.user.gid)
|
||||
else:
|
||||
self.write(filedata)
|
||||
with open(self.artifactFile.shasumFilename, 'rb') as f:
|
||||
self.write(f.read())
|
||||
|
||||
self.exit()
|
||||
|
||||
|
||||
def error(self, error, url):
|
||||
"""
|
||||
"""
|
||||
@ -233,14 +226,22 @@ class command_wget(HoneyPotCommand):
|
||||
self.errorWrite(errorMessage + '\n')
|
||||
# Real wget also adds this:
|
||||
if hasattr(error, 'webStatus') and hasattr(error, 'webMessage'): # exceptions
|
||||
self.errorWrite('{} ERROR {}: {}\n'.format(time.strftime('%Y-%m-%d %T'), error.webStatus.decode(), error.webMessage.decode()))
|
||||
self.errorWrite('{} ERROR {}: {}\n'.format(time.strftime('%Y-%m-%d %T'), error.webStatus.decode(),
|
||||
error.webMessage.decode()))
|
||||
else:
|
||||
self.errorWrite('{} ERROR 404: Not Found.\n'.format(time.strftime('%Y-%m-%d %T')))
|
||||
self.protocol.logDispatch(eventid='cowrie.session.file_download.failed',
|
||||
format='Attempt to download file(s) from URL (%(url)s) failed',
|
||||
url=self.url)
|
||||
|
||||
# prevent cowrie from crashing if the terminal have been already destroyed
|
||||
try:
|
||||
self.protocol.logDispatch(eventid='cowrie.session.file_download.failed',
|
||||
format='Attempt to download file(s) from URL (%(url)s) failed',
|
||||
url=self.url)
|
||||
except:
|
||||
pass
|
||||
|
||||
self.exit()
|
||||
|
||||
|
||||
commands['/usr/bin/wget'] = command_wget
|
||||
commands['/usr/bin/dget'] = command_wget
|
||||
|
||||
@ -258,7 +259,6 @@ class HTTPProgressDownloader(client.HTTPDownloader):
|
||||
self.nomore = False
|
||||
self.quiet = self.wget.quiet
|
||||
|
||||
|
||||
def noPage(self, reason): # Called for non-200 responses
|
||||
"""
|
||||
"""
|
||||
@ -272,7 +272,6 @@ class HTTPProgressDownloader(client.HTTPDownloader):
|
||||
|
||||
client.HTTPDownloader.noPage(self, reason)
|
||||
|
||||
|
||||
def gotHeaders(self, headers):
|
||||
"""
|
||||
"""
|
||||
@ -292,9 +291,9 @@ class HTTPProgressDownloader(client.HTTPDownloader):
|
||||
if self.totallength > 0:
|
||||
if not self.quiet:
|
||||
self.wget.errorWrite('Length: %d (%s) [%s]\n' % \
|
||||
(self.totallength,
|
||||
sizeof_fmt(self.totallength),
|
||||
self.contenttype))
|
||||
(self.totallength,
|
||||
sizeof_fmt(self.totallength),
|
||||
self.contenttype))
|
||||
else:
|
||||
if not self.quiet:
|
||||
self.wget.errorWrite('Length: unspecified [{}]\n'.format(self.contenttype))
|
||||
@ -309,7 +308,6 @@ class HTTPProgressDownloader(client.HTTPDownloader):
|
||||
|
||||
return client.HTTPDownloader.gotHeaders(self, headers)
|
||||
|
||||
|
||||
def pagePart(self, data):
|
||||
"""
|
||||
"""
|
||||
@ -348,17 +346,17 @@ class HTTPProgressDownloader(client.HTTPDownloader):
|
||||
if self.totallength != 0 and self.currentlength != self.totallength:
|
||||
return client.HTTPDownloader.pageEnd(self)
|
||||
if not self.quiet:
|
||||
self.wget.errorWrite('\r100%%[%s] %s %dK/s' % \
|
||||
('%s>' % (38 * '='),
|
||||
splitthousands(str(int(self.totallength))).ljust(12),
|
||||
self.speed / 1000))
|
||||
self.wget.errorWrite('\r100%%[%s] %s %dK/s' %
|
||||
('%s>' % (38 * '='),
|
||||
splitthousands(str(int(self.totallength))).ljust(12),
|
||||
self.speed / 1000))
|
||||
self.wget.errorWrite('\n\n')
|
||||
self.wget.errorWrite(
|
||||
'%s (%d KB/s) - `%s\' saved [%d/%d]\n\n' % \
|
||||
'%s (%d KB/s) - `%s\' saved [%d/%d]\n\n' %
|
||||
(time.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
self.speed / 1000,
|
||||
self.fakeoutfile, self.currentlength, self.totallength))
|
||||
|
||||
self.wget.fs.mkfile(self.fakeoutfile, 0, 0, self.totallength, 33188)
|
||||
if self.fakeoutfile != '-':
|
||||
self.wget.fs.mkfile(self.fakeoutfile, 0, 0, self.totallength, 33188)
|
||||
|
||||
return client.HTTPDownloader.pageEnd(self)
|
||||
|
@ -24,14 +24,13 @@ from __future__ import division, absolute_import
|
||||
|
||||
import hashlib
|
||||
import os
|
||||
import re
|
||||
import time
|
||||
import tempfile
|
||||
|
||||
from twisted.python import log
|
||||
|
||||
from cowrie.core.config import CONFIG
|
||||
|
||||
|
||||
class Artifact:
|
||||
"""
|
||||
"""
|
||||
@ -45,6 +44,8 @@ class Artifact:
|
||||
self.fp = tempfile.NamedTemporaryFile(dir=self.artifactDir, delete=False)
|
||||
self.tempFilename = self.fp.name
|
||||
|
||||
self.shasum = ''
|
||||
self.shasumFilename = ''
|
||||
|
||||
def __enter__(self):
|
||||
"""
|
||||
@ -75,26 +76,23 @@ class Artifact:
|
||||
"""
|
||||
size = self.fp.tell()
|
||||
self.fp.seek(0)
|
||||
shasum = hashlib.sha256(self.fp.read()).hexdigest()
|
||||
data = self.fp.read()
|
||||
self.fp.close()
|
||||
shasumFilename = self.artifactDir + "/" + shasum
|
||||
self.shasum = hashlib.sha256(data).hexdigest()
|
||||
self.shasumFilename = os.path.join(self.artifactDir, self.shasum)
|
||||
|
||||
if size == 0 and keepEmpty == False:
|
||||
if size == 0 and not keepEmpty:
|
||||
log.msg("Not storing empty file")
|
||||
os.remove(self.fp.name)
|
||||
elif os.path.exists(shasumFilename):
|
||||
elif os.path.exists(self.shasumFilename):
|
||||
log.msg("Not storing duplicate content " + self.shasum)
|
||||
os.remove(self.fp.name)
|
||||
else:
|
||||
os.rename(self.fp.name, shasumFilename)
|
||||
os.rename(self.fp.name, self.shasumFilename)
|
||||
umask = os.umask(0)
|
||||
os.umask(umask)
|
||||
os.chmod(shasumFilename, 0o666 & ~umask)
|
||||
os.chmod(self.shasumFilename, 0o666 & ~umask)
|
||||
|
||||
# if size>0:
|
||||
# linkName = self.artifactDir + "/" \
|
||||
# + time.strftime('%Y%m%dT%H%M%S') \
|
||||
# + "_" + re.sub('[^-A-Za-z0-9]', '_', self.label)
|
||||
# os.symlink(shasum, linkName)
|
||||
|
||||
return shasum, shasumFilename
|
||||
return self.shasum, self.shasumFilename
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user