mirror of
https://github.com/cowrie/cowrie.git
synced 2025-07-01 18:07:27 -04:00
Merge branch 'master' of https://github.com/micheloosterhof/cowrie
This commit is contained in:
@ -83,6 +83,13 @@ txtcmds_path = txtcmds
|
||||
#download_limit_size = 10485760
|
||||
|
||||
|
||||
# TTY logging will log a transcript of the complete terminal interaction in UML
|
||||
# compatible format.
|
||||
# (default: true)
|
||||
ttylog = true
|
||||
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# Network Specific Options
|
||||
# ============================================================================
|
||||
@ -154,7 +161,8 @@ auth_class = UserDB
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# SSH Specific Options
|
||||
# Historical SSH Specific Options
|
||||
# historical options in [honeypot] that have not yet been moved to [ssh]
|
||||
# ============================================================================
|
||||
|
||||
|
||||
@ -233,14 +241,23 @@ forward_redirect_25 = 127.0.0.1:12525
|
||||
forward_redirect_587 = 127.0.0.1:12525
|
||||
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# SSH Specific Options
|
||||
# ============================================================================
|
||||
[ssh]
|
||||
|
||||
# Enable SSH support, enabled by default
|
||||
# Enable SSH support
|
||||
# (default: true)
|
||||
enabled = true
|
||||
|
||||
# Enable SSH direct-tcpip forwarding, enabled by default
|
||||
|
||||
# Enable SSH direct-tcpip forwarding
|
||||
# (default: true)
|
||||
forwarding = true
|
||||
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# Telnet Specific Options
|
||||
# ============================================================================
|
||||
@ -266,6 +283,7 @@ enabled = false
|
||||
#reported_port = 23
|
||||
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# Database logging Specific Options
|
||||
# ============================================================================
|
||||
|
||||
@ -314,7 +314,8 @@ Options: (H) means HTTP/HTTPS only, (F) means FTP only
|
||||
log.msg("there's no file " + self.safeoutfile)
|
||||
self.exit()
|
||||
|
||||
shasum = hashlib.sha256(open(self.safeoutfile, 'rb').read()).hexdigest()
|
||||
with open(self.safeoutfile, 'rb') as f:
|
||||
shasum = hashlib.sha256(f.read()).hexdigest()
|
||||
hashPath = os.path.join(self.download_path, shasum)
|
||||
|
||||
# If we have content already, delete temp file
|
||||
@ -343,9 +344,7 @@ Options: (H) means HTTP/HTTPS only, (F) means FTP only
|
||||
# self.safeoutfile = hashPath
|
||||
|
||||
# Update the honeyfs to point to downloaded file
|
||||
if outfile is not None:
|
||||
f = self.fs.getfile(outfile)
|
||||
f[A_REALFILE] = hashPath
|
||||
self.fs.update_realfile(self.fs.getfile(outfile), hashPath)
|
||||
self.exit()
|
||||
|
||||
|
||||
|
||||
@ -104,6 +104,7 @@ Download a file via FTP
|
||||
result = self.ftp_download(self.safeoutfile)
|
||||
|
||||
if not result:
|
||||
self.safeoutfile = None
|
||||
self.exit()
|
||||
return
|
||||
|
||||
@ -112,7 +113,8 @@ Download a file via FTP
|
||||
self.exit()
|
||||
return
|
||||
|
||||
shasum = hashlib.sha256(open(self.safeoutfile, 'rb').read()).hexdigest()
|
||||
with open(self.safeoutfile, 'rb') as f:
|
||||
shasum = hashlib.sha256(f.read()).hexdigest()
|
||||
hash_path = os.path.join(self.download_path, shasum)
|
||||
|
||||
# If we have content already, delete temp file
|
||||
@ -120,7 +122,7 @@ Download a file via FTP
|
||||
os.rename(self.safeoutfile, hash_path)
|
||||
else:
|
||||
os.remove(self.safeoutfile)
|
||||
os.symlink( shasum, self.safeoutfile )
|
||||
log.msg("Not storing duplicate content " + shasum)
|
||||
|
||||
log.msg(eventid='cowrie.session.file_download',
|
||||
format='Downloaded URL (%(url)s) with SHA-256 %(shasum)s to %(outfile)s',
|
||||
@ -128,10 +130,13 @@ Download a file via FTP
|
||||
outfile=hash_path,
|
||||
shasum=shasum)
|
||||
|
||||
# Update the honeyfs to point to downloaded file
|
||||
self.fs.mkfile(fakeoutfile, 0, 0, os.path.getsize(hash_path), 33188)
|
||||
self.fs.update_realfile(self.fs.getfile(fakeoutfile), hash_path)
|
||||
# Link friendly name to hash
|
||||
os.symlink(shasum, self.safeoutfile)
|
||||
|
||||
self.safeoutfile = None
|
||||
|
||||
# Update the honeyfs to point to downloaded file
|
||||
self.fs.update_realfile(self.fs.getfile(fakeoutfile), hash_path)
|
||||
self.exit()
|
||||
|
||||
def ftp_download(self, safeoutfile):
|
||||
|
||||
@ -28,6 +28,8 @@
|
||||
|
||||
import getopt
|
||||
|
||||
from twisted.python import log
|
||||
|
||||
from cowrie.core.honeypot import HoneyPotCommand
|
||||
|
||||
commands = {}
|
||||
|
||||
@ -62,8 +62,10 @@ class command_tftp(HoneyPotCommand):
|
||||
re.sub('[^A-Za-z0-9]', '_', self.file_to_get))
|
||||
self.safeoutfile = os.path.join(self.download_path, tmp_fname)
|
||||
|
||||
with tftpy.TftpClient(self.hostname, int(self.port)) as tclient:
|
||||
tclient = None
|
||||
|
||||
try:
|
||||
tclient = tftpy.TftpClient(self.hostname, int(self.port))
|
||||
tclient.download(self.file_to_get, self.safeoutfile, progresshook)
|
||||
self.file_to_get = self.fs.resolve_path(self.file_to_get, self.protocol.cwd)
|
||||
if hasattr(tclient.context, 'metrics'):
|
||||
@ -72,7 +74,8 @@ class command_tftp(HoneyPotCommand):
|
||||
self.fs.mkfile(self.file_to_get, 0, 0, 0, 33188)
|
||||
self.fs.update_realfile(self.fs.getfile(self.file_to_get), self.safeoutfile)
|
||||
except tftpy.TftpException, err:
|
||||
pass
|
||||
if tclient and tclient.context and not tclient.context.fileobj.closed:
|
||||
tclient.context.fileobj.close()
|
||||
|
||||
if os.path.exists(self.safeoutfile):
|
||||
|
||||
@ -103,11 +106,11 @@ class command_tftp(HoneyPotCommand):
|
||||
# Link friendly name to hash
|
||||
os.symlink(shasum, self.safeoutfile)
|
||||
|
||||
self.safeoutfile = None
|
||||
|
||||
# Update the honeyfs to point to downloaded file
|
||||
f = self.fs.getfile(self.file_to_get)
|
||||
f[A_REALFILE] = hash_path
|
||||
|
||||
|
||||
self.fs.update_realfile(self.fs.getfile(self.file_to_get), hash_path)
|
||||
self.exit()
|
||||
|
||||
|
||||
def start(self):
|
||||
|
||||
@ -207,7 +207,7 @@ class command_wget(HoneyPotCommand):
|
||||
format='Downloaded URL (%(url)s) with SHA-256 %(shasum)s to %(outfile)s',
|
||||
url=self.url,
|
||||
outfile=hash_path,
|
||||
shasum=shasum )
|
||||
shasum=shasum)
|
||||
|
||||
log.msg(eventid='cowrie.session.file_download',
|
||||
format='Downloaded URL (%(url)s) with SHA-256 %(shasum)s to %(outfile)s',
|
||||
@ -218,12 +218,10 @@ class command_wget(HoneyPotCommand):
|
||||
# Link friendly name to hash
|
||||
os.symlink(shasum, self.safeoutfile)
|
||||
|
||||
# FIXME: is this necessary?
|
||||
# self.safeoutfile = hash_path
|
||||
self.safeoutfile = None
|
||||
|
||||
# Update the honeyfs to point to downloaded file
|
||||
f = self.fs.getfile(outfile)
|
||||
f[A_REALFILE] = hash_path
|
||||
self.fs.update_realfile(self.fs.getfile(outfile), hash_path)
|
||||
self.exit()
|
||||
|
||||
|
||||
|
||||
@ -31,6 +31,11 @@ class LoggingServerProtocol(insults.ServerProtocol):
|
||||
self.ttylogPath = cfg.get('honeypot', 'log_path')
|
||||
self.downloadPath = cfg.get('honeypot', 'download_path')
|
||||
|
||||
try:
|
||||
self.ttylogEnabled = cfg.getboolean('honeypot', 'ttylog')
|
||||
except:
|
||||
self.ttylogEnabled = True
|
||||
|
||||
self.redirFiles = set()
|
||||
|
||||
try:
|
||||
@ -44,24 +49,28 @@ class LoggingServerProtocol(insults.ServerProtocol):
|
||||
else:
|
||||
self.type = 'i' # Interactive
|
||||
|
||||
|
||||
def getSessionId(self):
|
||||
"""
|
||||
"""
|
||||
transportId = self.transport.session.conn.transport.transportId
|
||||
channelId = self.transport.session.id
|
||||
return (transportId, channelId)
|
||||
|
||||
|
||||
def connectionMade(self):
|
||||
"""
|
||||
"""
|
||||
transportId, channelId = self.getSessionId()
|
||||
|
||||
self.startTime = time.time()
|
||||
|
||||
if self.ttylogEnabled:
|
||||
self.ttylogFile = '%s/tty/%s-%s-%s%s.log' % \
|
||||
(self.ttylogPath, time.strftime('%Y%m%d-%H%M%S'),
|
||||
transportId, channelId, self.type)
|
||||
ttylog.ttylog_open(self.ttylogFile, self.startTime)
|
||||
self.ttylogOpen = True
|
||||
self.ttylogSize = 0
|
||||
|
||||
log.msg(eventid='cowrie.log.open',
|
||||
ttylog=self.ttylogFile,
|
||||
format='Opening TTY Log: %(ttylog)s')
|
||||
@ -82,7 +91,7 @@ class LoggingServerProtocol(insults.ServerProtocol):
|
||||
"""
|
||||
Output sent back to user
|
||||
"""
|
||||
if self.ttylogOpen:
|
||||
if self.ttylogEnabled and self.ttylogOpen:
|
||||
ttylog.ttylog_write(self.ttylogFile, len(bytes),
|
||||
ttylog.TYPE_OUTPUT, time.time(), bytes)
|
||||
self.ttylogSize += len(bytes)
|
||||
@ -105,7 +114,7 @@ class LoggingServerProtocol(insults.ServerProtocol):
|
||||
if self.stdinlogOpen:
|
||||
with open(self.stdinlogFile, 'ab') as f:
|
||||
f.write(data)
|
||||
elif self.ttylogOpen:
|
||||
elif self.ttylogEnabled and self.ttylogOpen:
|
||||
ttylog.ttylog_write(self.ttylogFile, len(data),
|
||||
ttylog.TYPE_INPUT, time.time(), data)
|
||||
|
||||
@ -181,8 +190,7 @@ class LoggingServerProtocol(insults.ServerProtocol):
|
||||
pass
|
||||
self.redirFiles.clear()
|
||||
|
||||
if self.ttylogOpen:
|
||||
# TODO: Add session duration to this entry
|
||||
if self.ttylogEnabled and self.ttylogOpen:
|
||||
log.msg(eventid='cowrie.log.closed',
|
||||
format='Closing TTY Log: %(ttylog)s after %(duration)d seconds',
|
||||
ttylog=self.ttylogFile,
|
||||
@ -193,6 +201,8 @@ class LoggingServerProtocol(insults.ServerProtocol):
|
||||
|
||||
insults.ServerProtocol.connectionLost(self, reason)
|
||||
|
||||
|
||||
|
||||
class LoggingTelnetServerProtocol(LoggingServerProtocol):
|
||||
"""
|
||||
Wrap LoggingServerProtocol with single method to fetch session id for Telnet
|
||||
|
||||
55
doc/graylog/README.md
Normal file
55
doc/graylog/README.md
Normal file
@ -0,0 +1,55 @@
|
||||
# How to process Cowrie output into Graylog
|
||||
|
||||
|
||||
## Prerequisites
|
||||
|
||||
* Working Cowrie installation
|
||||
* Working Graylog installation
|
||||
|
||||
## Cowrie Configuration
|
||||
|
||||
|
||||
* Open the Cowrie configuration file and uncomment these 3 lines.
|
||||
|
||||
```
|
||||
[output_localsyslog]
|
||||
facility = USER
|
||||
format = text
|
||||
```
|
||||
|
||||
* Restart Cowrie
|
||||
|
||||
## Graylog Configuration
|
||||
|
||||
* Open the Graylog web interface and click on the **System** drop-down in the top menu. From the drop-down menu select **Inputs**. Select **Syslog UDP** from the drop-down menu and click the **Launch new input** button. In the modal dialog enter the following information.
|
||||
|
||||
**Title:** Cowrie
|
||||
**Port:** 8514
|
||||
**Bind address:** 127.0.0.1
|
||||
|
||||
* Then click **Launch.**
|
||||
|
||||
## Syslog Configuration
|
||||
|
||||
* Create a rsyslog configuration file in /etc/rsyslog.d
|
||||
|
||||
```
|
||||
$ sudo nano /etc/rsyslog.d/85-graylog.conf
|
||||
```
|
||||
|
||||
* Add the following lines to the file
|
||||
|
||||
```
|
||||
$template GRAYLOGRFC5424,"<%pri%>%protocol-version% %timestamp:::date-rfc3339% %HOSTNAME% %app-name% %procid% %msg%\n"
|
||||
*.* @127.0.0.1:8514;GRAYLOGRFC5424
|
||||
```
|
||||
|
||||
* Save and quit.
|
||||
|
||||
* Restart rsyslog
|
||||
|
||||
```
|
||||
$ sudo service rsyslog restart
|
||||
```
|
||||
|
||||
|
||||
@ -3,6 +3,11 @@ cryptography
|
||||
configparser
|
||||
pyopenssl
|
||||
gmpy2
|
||||
pyparsing
|
||||
packaging
|
||||
appdirs
|
||||
pyasn1_modules
|
||||
attrs
|
||||
service_identity
|
||||
pycrypto
|
||||
python-dateutil
|
||||
|
||||
Reference in New Issue
Block a user