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
|
#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
|
# 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
|
forward_redirect_587 = 127.0.0.1:12525
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# SSH Specific Options
|
||||||
|
# ============================================================================
|
||||||
[ssh]
|
[ssh]
|
||||||
|
|
||||||
# Enable SSH support, enabled by default
|
# Enable SSH support
|
||||||
|
# (default: true)
|
||||||
enabled = true
|
enabled = true
|
||||||
|
|
||||||
# Enable SSH direct-tcpip forwarding, enabled by default
|
|
||||||
|
# Enable SSH direct-tcpip forwarding
|
||||||
|
# (default: true)
|
||||||
forwarding = true
|
forwarding = true
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
# Telnet Specific Options
|
# Telnet Specific Options
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
@ -266,6 +283,7 @@ enabled = false
|
|||||||
#reported_port = 23
|
#reported_port = 23
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
# Database logging Specific Options
|
# 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)
|
log.msg("there's no file " + self.safeoutfile)
|
||||||
self.exit()
|
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)
|
hashPath = os.path.join(self.download_path, shasum)
|
||||||
|
|
||||||
# If we have content already, delete temp file
|
# 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
|
# self.safeoutfile = hashPath
|
||||||
|
|
||||||
# Update the honeyfs to point to downloaded file
|
# Update the honeyfs to point to downloaded file
|
||||||
if outfile is not None:
|
self.fs.update_realfile(self.fs.getfile(outfile), hashPath)
|
||||||
f = self.fs.getfile(outfile)
|
|
||||||
f[A_REALFILE] = hashPath
|
|
||||||
self.exit()
|
self.exit()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -104,6 +104,7 @@ Download a file via FTP
|
|||||||
result = self.ftp_download(self.safeoutfile)
|
result = self.ftp_download(self.safeoutfile)
|
||||||
|
|
||||||
if not result:
|
if not result:
|
||||||
|
self.safeoutfile = None
|
||||||
self.exit()
|
self.exit()
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -112,7 +113,8 @@ Download a file via FTP
|
|||||||
self.exit()
|
self.exit()
|
||||||
return
|
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)
|
hash_path = os.path.join(self.download_path, shasum)
|
||||||
|
|
||||||
# If we have content already, delete temp file
|
# If we have content already, delete temp file
|
||||||
@ -120,7 +122,7 @@ Download a file via FTP
|
|||||||
os.rename(self.safeoutfile, hash_path)
|
os.rename(self.safeoutfile, hash_path)
|
||||||
else:
|
else:
|
||||||
os.remove(self.safeoutfile)
|
os.remove(self.safeoutfile)
|
||||||
os.symlink( shasum, self.safeoutfile )
|
log.msg("Not storing duplicate content " + shasum)
|
||||||
|
|
||||||
log.msg(eventid='cowrie.session.file_download',
|
log.msg(eventid='cowrie.session.file_download',
|
||||||
format='Downloaded URL (%(url)s) with SHA-256 %(shasum)s to %(outfile)s',
|
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,
|
outfile=hash_path,
|
||||||
shasum=shasum)
|
shasum=shasum)
|
||||||
|
|
||||||
# Update the honeyfs to point to downloaded file
|
# Link friendly name to hash
|
||||||
self.fs.mkfile(fakeoutfile, 0, 0, os.path.getsize(hash_path), 33188)
|
os.symlink(shasum, self.safeoutfile)
|
||||||
self.fs.update_realfile(self.fs.getfile(fakeoutfile), hash_path)
|
|
||||||
|
|
||||||
|
self.safeoutfile = None
|
||||||
|
|
||||||
|
# Update the honeyfs to point to downloaded file
|
||||||
|
self.fs.update_realfile(self.fs.getfile(fakeoutfile), hash_path)
|
||||||
self.exit()
|
self.exit()
|
||||||
|
|
||||||
def ftp_download(self, safeoutfile):
|
def ftp_download(self, safeoutfile):
|
||||||
|
|||||||
@ -28,6 +28,8 @@
|
|||||||
|
|
||||||
import getopt
|
import getopt
|
||||||
|
|
||||||
|
from twisted.python import log
|
||||||
|
|
||||||
from cowrie.core.honeypot import HoneyPotCommand
|
from cowrie.core.honeypot import HoneyPotCommand
|
||||||
|
|
||||||
commands = {}
|
commands = {}
|
||||||
|
|||||||
@ -62,8 +62,10 @@ class command_tftp(HoneyPotCommand):
|
|||||||
re.sub('[^A-Za-z0-9]', '_', self.file_to_get))
|
re.sub('[^A-Za-z0-9]', '_', self.file_to_get))
|
||||||
self.safeoutfile = os.path.join(self.download_path, tmp_fname)
|
self.safeoutfile = os.path.join(self.download_path, tmp_fname)
|
||||||
|
|
||||||
with tftpy.TftpClient(self.hostname, int(self.port)) as tclient:
|
tclient = None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
tclient = tftpy.TftpClient(self.hostname, int(self.port))
|
||||||
tclient.download(self.file_to_get, self.safeoutfile, progresshook)
|
tclient.download(self.file_to_get, self.safeoutfile, progresshook)
|
||||||
self.file_to_get = self.fs.resolve_path(self.file_to_get, self.protocol.cwd)
|
self.file_to_get = self.fs.resolve_path(self.file_to_get, self.protocol.cwd)
|
||||||
if hasattr(tclient.context, 'metrics'):
|
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.mkfile(self.file_to_get, 0, 0, 0, 33188)
|
||||||
self.fs.update_realfile(self.fs.getfile(self.file_to_get), self.safeoutfile)
|
self.fs.update_realfile(self.fs.getfile(self.file_to_get), self.safeoutfile)
|
||||||
except tftpy.TftpException, err:
|
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):
|
if os.path.exists(self.safeoutfile):
|
||||||
|
|
||||||
@ -103,11 +106,11 @@ class command_tftp(HoneyPotCommand):
|
|||||||
# Link friendly name to hash
|
# Link friendly name to hash
|
||||||
os.symlink(shasum, self.safeoutfile)
|
os.symlink(shasum, self.safeoutfile)
|
||||||
|
|
||||||
|
self.safeoutfile = None
|
||||||
|
|
||||||
# Update the honeyfs to point to downloaded file
|
# Update the honeyfs to point to downloaded file
|
||||||
f = self.fs.getfile(self.file_to_get)
|
self.fs.update_realfile(self.fs.getfile(self.file_to_get), hash_path)
|
||||||
f[A_REALFILE] = hash_path
|
self.exit()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
|
|||||||
@ -207,7 +207,7 @@ class command_wget(HoneyPotCommand):
|
|||||||
format='Downloaded URL (%(url)s) with SHA-256 %(shasum)s to %(outfile)s',
|
format='Downloaded URL (%(url)s) with SHA-256 %(shasum)s to %(outfile)s',
|
||||||
url=self.url,
|
url=self.url,
|
||||||
outfile=hash_path,
|
outfile=hash_path,
|
||||||
shasum=shasum )
|
shasum=shasum)
|
||||||
|
|
||||||
log.msg(eventid='cowrie.session.file_download',
|
log.msg(eventid='cowrie.session.file_download',
|
||||||
format='Downloaded URL (%(url)s) with SHA-256 %(shasum)s to %(outfile)s',
|
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
|
# Link friendly name to hash
|
||||||
os.symlink(shasum, self.safeoutfile)
|
os.symlink(shasum, self.safeoutfile)
|
||||||
|
|
||||||
# FIXME: is this necessary?
|
self.safeoutfile = None
|
||||||
# self.safeoutfile = hash_path
|
|
||||||
|
|
||||||
# Update the honeyfs to point to downloaded file
|
# Update the honeyfs to point to downloaded file
|
||||||
f = self.fs.getfile(outfile)
|
self.fs.update_realfile(self.fs.getfile(outfile), hash_path)
|
||||||
f[A_REALFILE] = hash_path
|
|
||||||
self.exit()
|
self.exit()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -31,6 +31,11 @@ class LoggingServerProtocol(insults.ServerProtocol):
|
|||||||
self.ttylogPath = cfg.get('honeypot', 'log_path')
|
self.ttylogPath = cfg.get('honeypot', 'log_path')
|
||||||
self.downloadPath = cfg.get('honeypot', 'download_path')
|
self.downloadPath = cfg.get('honeypot', 'download_path')
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.ttylogEnabled = cfg.getboolean('honeypot', 'ttylog')
|
||||||
|
except:
|
||||||
|
self.ttylogEnabled = True
|
||||||
|
|
||||||
self.redirFiles = set()
|
self.redirFiles = set()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -44,24 +49,28 @@ class LoggingServerProtocol(insults.ServerProtocol):
|
|||||||
else:
|
else:
|
||||||
self.type = 'i' # Interactive
|
self.type = 'i' # Interactive
|
||||||
|
|
||||||
|
|
||||||
def getSessionId(self):
|
def getSessionId(self):
|
||||||
|
"""
|
||||||
|
"""
|
||||||
transportId = self.transport.session.conn.transport.transportId
|
transportId = self.transport.session.conn.transport.transportId
|
||||||
channelId = self.transport.session.id
|
channelId = self.transport.session.id
|
||||||
return (transportId, channelId)
|
return (transportId, channelId)
|
||||||
|
|
||||||
|
|
||||||
def connectionMade(self):
|
def connectionMade(self):
|
||||||
"""
|
"""
|
||||||
"""
|
"""
|
||||||
transportId, channelId = self.getSessionId()
|
transportId, channelId = self.getSessionId()
|
||||||
|
|
||||||
self.startTime = time.time()
|
self.startTime = time.time()
|
||||||
|
|
||||||
|
if self.ttylogEnabled:
|
||||||
self.ttylogFile = '%s/tty/%s-%s-%s%s.log' % \
|
self.ttylogFile = '%s/tty/%s-%s-%s%s.log' % \
|
||||||
(self.ttylogPath, time.strftime('%Y%m%d-%H%M%S'),
|
(self.ttylogPath, time.strftime('%Y%m%d-%H%M%S'),
|
||||||
transportId, channelId, self.type)
|
transportId, channelId, self.type)
|
||||||
ttylog.ttylog_open(self.ttylogFile, self.startTime)
|
ttylog.ttylog_open(self.ttylogFile, self.startTime)
|
||||||
self.ttylogOpen = True
|
self.ttylogOpen = True
|
||||||
self.ttylogSize = 0
|
self.ttylogSize = 0
|
||||||
|
|
||||||
log.msg(eventid='cowrie.log.open',
|
log.msg(eventid='cowrie.log.open',
|
||||||
ttylog=self.ttylogFile,
|
ttylog=self.ttylogFile,
|
||||||
format='Opening TTY Log: %(ttylog)s')
|
format='Opening TTY Log: %(ttylog)s')
|
||||||
@ -82,7 +91,7 @@ class LoggingServerProtocol(insults.ServerProtocol):
|
|||||||
"""
|
"""
|
||||||
Output sent back to user
|
Output sent back to user
|
||||||
"""
|
"""
|
||||||
if self.ttylogOpen:
|
if self.ttylogEnabled and self.ttylogOpen:
|
||||||
ttylog.ttylog_write(self.ttylogFile, len(bytes),
|
ttylog.ttylog_write(self.ttylogFile, len(bytes),
|
||||||
ttylog.TYPE_OUTPUT, time.time(), bytes)
|
ttylog.TYPE_OUTPUT, time.time(), bytes)
|
||||||
self.ttylogSize += len(bytes)
|
self.ttylogSize += len(bytes)
|
||||||
@ -105,7 +114,7 @@ class LoggingServerProtocol(insults.ServerProtocol):
|
|||||||
if self.stdinlogOpen:
|
if self.stdinlogOpen:
|
||||||
with open(self.stdinlogFile, 'ab') as f:
|
with open(self.stdinlogFile, 'ab') as f:
|
||||||
f.write(data)
|
f.write(data)
|
||||||
elif self.ttylogOpen:
|
elif self.ttylogEnabled and self.ttylogOpen:
|
||||||
ttylog.ttylog_write(self.ttylogFile, len(data),
|
ttylog.ttylog_write(self.ttylogFile, len(data),
|
||||||
ttylog.TYPE_INPUT, time.time(), data)
|
ttylog.TYPE_INPUT, time.time(), data)
|
||||||
|
|
||||||
@ -181,8 +190,7 @@ class LoggingServerProtocol(insults.ServerProtocol):
|
|||||||
pass
|
pass
|
||||||
self.redirFiles.clear()
|
self.redirFiles.clear()
|
||||||
|
|
||||||
if self.ttylogOpen:
|
if self.ttylogEnabled and self.ttylogOpen:
|
||||||
# TODO: Add session duration to this entry
|
|
||||||
log.msg(eventid='cowrie.log.closed',
|
log.msg(eventid='cowrie.log.closed',
|
||||||
format='Closing TTY Log: %(ttylog)s after %(duration)d seconds',
|
format='Closing TTY Log: %(ttylog)s after %(duration)d seconds',
|
||||||
ttylog=self.ttylogFile,
|
ttylog=self.ttylogFile,
|
||||||
@ -193,6 +201,8 @@ class LoggingServerProtocol(insults.ServerProtocol):
|
|||||||
|
|
||||||
insults.ServerProtocol.connectionLost(self, reason)
|
insults.ServerProtocol.connectionLost(self, reason)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class LoggingTelnetServerProtocol(LoggingServerProtocol):
|
class LoggingTelnetServerProtocol(LoggingServerProtocol):
|
||||||
"""
|
"""
|
||||||
Wrap LoggingServerProtocol with single method to fetch session id for Telnet
|
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
|
configparser
|
||||||
pyopenssl
|
pyopenssl
|
||||||
gmpy2
|
gmpy2
|
||||||
|
pyparsing
|
||||||
|
packaging
|
||||||
|
appdirs
|
||||||
|
pyasn1_modules
|
||||||
|
attrs
|
||||||
service_identity
|
service_identity
|
||||||
pycrypto
|
pycrypto
|
||||||
python-dateutil
|
python-dateutil
|
||||||
|
|||||||
Reference in New Issue
Block a user