Skip to content
Snippets Groups Projects
Commit ca456e1e authored by Daniel Studený's avatar Daniel Studený
Browse files

Replacement of old and malfunction Cowrie and Dionaea connectors with new ones.

parent c0eefc39
No related branches found
No related tags found
No related merge requests found
# ============================================================================
# General Cowrie Options
# ============================================================================
[honeypot]
sensor_name= hugo.example.org
hostname = dbsrv-07.accounting
log_path = var/log
state_path = var/lib
download_path = ${honeypot:state_path}/downloads
share_path = share/cowrie
etc_path = etc
contents_path = honeyfs
txtcmds_path = ${honeypot:share_path}/txtcmds
download_limit_size = 10485760
ttylog = false
ttylog_path = ${honeypot:state_path}/tty
interactive_timeout = 180
authentication_timeout = 120
backend = shell
timezone = UTC
auth_class = UserDB
# ============================================================================
# Shell Options
# Options around Cowrie's Shell Emulation
# ============================================================================
[shell]
filesystem = ${honeypot:share_path}/fs.pickle
processes = ${honeypot:share_path}/cmdoutput.json
arch = linux-x64-lsb
kernel_version = 3.2.0-4-amd64
kernel_build_string = #1 SMP Debian 3.2.68-1+deb7u1
hardware_platform = x86_64
operating_system = GNU/Linux
ssh_version = OpenSSH_7.9p1, OpenSSL 1.1.1a 20 Nov 2018
# ============================================================================
# SSH Specific Options
# ============================================================================
[ssh]
enabled = true
rsa_public_key = ${honeypot:state_path}/ssh_host_rsa_key.pub
rsa_private_key = ${honeypot:state_path}/ssh_host_rsa_key
dsa_public_key = ${honeypot:state_path}/ssh_host_dsa_key.pub
dsa_private_key = ${honeypot:state_path}/ssh_host_dsa_key
version = SSH-2.0-OpenSSH_6.0p1 Debian-4+deb7u2
ciphers = aes128-ctr,aes192-ctr,aes256-ctr,aes256-cbc,aes192-cbc,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc
macs = hmac-sha2-512,hmac-sha2-384,hmac-sha2-56,hmac-sha1,hmac-md5
compression = zlib@openssh.com,zlib,none
listen_endpoints = systemd:domain=INET6:index=0 systemd:domain=INET6:index=1
sftp_enabled = true
forwarding = false
forward_redirect = false
forward_tunnel = false
auth_none_enabled = false
auth_keyboard_interactive_enabled = false
# ============================================================================
# Telnet Specific Options
# ============================================================================
[telnet]
enabled = false
# ============================================================================
# Output Plugins
# These provide an extensible mechanism to send audit log entries to third
# parties. The audit entries contain information on clients connecting to
# the honeypot.
#
# Output entries need to start with 'output_' and have the 'enabled' entry.
# ============================================================================
# JSON based logging module
#
[output_jsonlog]
enabled = false
# Wardefiler logging module
#
[output_wardenfiler]
enabled = true
detector_name = org.example.hugo.cowrie
resolve_nat = no
#reported_public_ipv4 =
#reported_public_ipv6 =
reported_ssh_port = 22
#nat_host = gateway
#nat_port = 1456
#anon_mask_4 = 24
#anon_mask_6 = 64
aggr_win = 300
test_mode = true
output_dir = var/spool/warden
port_xlat = 2223:22 2222:2222
drop_malware = true
[Unit]
Description=A SSH and Telnet honeypot service
After=network.target
After=rsyslog.service
Requires=cowrie.socket
[Service]
User=cowrie
Group=cowrie
PIDFile=/opt/cowrie/var/run/cowrie.pid
Restart=always
RestartSec=5
Environment=PYTHONPATH=/opt/cowrie/src
Environment=COWRIE_VIRTUAL_ENV=/opt/cowrie/usr
Environment=TZ="/usr/share/zoneinfo/UTC"
WorkingDirectory=/opt/cowrie
ExecStart=/opt/cowrie/bin/cowrie start
ExecStop=/opt/cowrie/bin/cowrie stop
ExecRestart=/opt/cowrie/bin/cowrie restart
StandardOutput=journal
StandardError=journal
SyslogIdentifier=cowrie
[Install]
WantedBy=multi-user.target
[Unit]
Description=Cowrie socket
[Socket]
ListenStream=2223
ListenStream=2222
NoDelay=true
{
"warden": "warden_client.cfg",
"name": "cz.cesnet.server.kippo",
"secret": "",
"anonymised": "no",
"target_net": "195.113.0.0/16",
"dbhost": "localhost",
"dbuser": "kippo",
"dbpass": "kippopass",
"dbname": "kippo",
"dbport": 3306,
"awin": 5
}
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
from warden_client import Client, Error, read_cfg, format_timestamp
from time import time, gmtime, strftime
from math import trunc
from uuid import uuid4
import MySQLdb as my
import MySQLdb.cursors as mycursors
import tempfile, subprocess, base64
import json
import string
import os
import sys
#warden client startup
aconfig = read_cfg('warden_client_cowrie.cfg')
wconfig = read_cfg('warden_client.cfg')
aclient_name = aconfig['name']
wconfig['name'] = aclient_name
aanonymised = aconfig['anonymised']
aanonymised_net = aconfig['target_net']
aanonymised = aanonymised if (aanonymised_net != '0.0.0.0/0') or (aanonymised_net == 'omit') else '0.0.0.0/0'
awin = aconfig['awin'] * 60
atest = aconfig['test_mode']
wclient = Client(**wconfig)
def idea_fill_addresses(event, source_ip, destination_ip, anonymised, anonymised_net):
af = "IP4" if not ':' in source_ip else "IP6"
event['Source'][0][af] = [source_ip]
if anonymised != 'omit':
if anonymised == 'yes':
event['Target'][0]['Anonymised'] = True
event['Target'][0][af] = [anonymised_net]
else:
event['Target'][0][af] = [destination_ip]
return event
def gen_event_idea_cowrie_info(detect_time, src_ip, dst_ip, win_start_time, win_end_time, aggr_win, conn_count):
event = {
"Format": "IDEA0",
"ID": str(uuid4()),
"DetectTime": detect_time,
"WinStartTime": win_start_time,
"WinEndTime": win_end_time,
"Category": ["Attempt.Login"],
"Note": "SSH login attempt",
"ConnCount": conn_count,
"Source": [{}],
"Target": [{ "Proto": ["tcp", "ssh"], "Port": [22]}],
"Node": [
{
"Name": aclient_name,
"Type": ["Connection","Honeypot","Recon"],
"SW": ["Cowrie"],
"AggrWin": strftime("%H:%M:%S", gmtime(aggr_win))
}
]
}
# Test if we're testing
if atest == "true":
event["Category"].append('Test')
event = idea_fill_addresses(event, src_ip, dst_ip, aanonymised, aanonymised_net)
return event
def gen_event_idea_cowrie_auth(detect_time, src_ip, dst_ip, username, password, sessionid):
event = {
"Format": "IDEA0",
"ID": str(uuid4()),
"DetectTime": detect_time,
"Category": ["Information.UnauthorizedAccess"],
"Note": "SSH successfull attempt",
"ConnCount": 1,
"Source": [{}],
"Target": [{ "Proto": ["tcp", "ssh"], "Port" : [22] }],
"Node": [
{
"Name": aclient_name,
"Type": ["Honeypot", "Connection", "Auth"],
"SW": ["Cowrie"],
}
],
"Attach": [{ "sessionid": sessionid, "username": username, "password": password }]
}
# Test if we're testing
if atest == "true":
event["Category"].append('Test')
event = idea_fill_addresses(event, src_ip, dst_ip, aanonymised, aanonymised_net)
return event
def gen_event_idea_cowrie_ttylog(detect_time, src_ip, dst_ip, sessionid, ttylog, iinput):
event = {
"Format": "IDEA0",
"ID": str(uuid4()),
"DetectTime": detect_time,
"Category": ["Information.UnauthorizedAccess"],
"Note": "Cowrie ttylog",
"ConnCount": 1,
"Source": [{}],
"Target": [{ "Proto": ["tcp", "ssh"], "Port" : [22] }],
"Node": [
{
"Name": aclient_name,
"Type": ["Honeypot", "Data"],
"SW": ["Cowrie"],
}
],
"Attach": [ { "sessionid": sessionid, "ttylog": ttylog, "iinput": iinput, "smart": iinput } ]
}
# Test if we're testing
if atest == "true":
event["Category"].append('Test')
event = idea_fill_addresses(event, src_ip, dst_ip, aanonymised, aanonymised_net)
return event
def gen_event_idea_cowrie_download(detect_time, src_ip, dst_ip, sessionid, url, outfile):
event = {
"Format": "IDEA0",
"ID": str(uuid4()),
"DetectTime": detect_time,
"Category": ["Malware"],
"Note": "Cowrie download",
"ConnCount": 1,
"Source": [{}],
"Target": [{ "Proto": ["tcp", "ssh"], "Port" : [22]}],
"Node": [
{
"Name": aclient_name,
"Type": ["Honeypot", "Data"],
"SW": ["Cowrie"],
}
],
"Attach": [{ "sessionid": sessionid, "url": url, "outfile": outfile, "smart": url }]
}
# Test if we're testing
if atest == "true":
event["Category"].append('Test')
event = idea_fill_addresses(event, src_ip, dst_ip, aanonymised, aanonymised_net)
return event
def get_iinput(sessionid):
ret = []
query = "SELECT GROUP_CONCAT(input SEPARATOR '--SEP--') as i FROM input WHERE session=%s GROUP BY session;"
crs.execute(query, (sessionid,))
rows = crs.fetchall()
for row in rows:
ret.append(row["i"])
return ''.join(ret)
def get_ttylog(sessionid):
ret = ""
query = "SELECT id, session, ttylog FROM ttylog WHERE session=%s;"
crs.execute(query, (sessionid,))
rows = crs.fetchall()
for row in rows:
try:
tf = tempfile.NamedTemporaryFile(delete=False)
with open(tf.name, 'w') as f:
f.write(row['ttylog'])
ret = subprocess.check_output(["/opt/cowrie/bin/playlog", "-m0", tf.name])
finally:
os.remove(tf.name)
#try to dumpit to json to see if there are some binary input and perhaps wrap it to base64
try:
a = json.dumps(ret)
except UnicodeDecodeError as e:
wclient.logger.warning("wraping binary content")
ret = base64.b64encode(ret)
return ret
con = my.connect( host=aconfig['dbhost'], user=aconfig['dbuser'], passwd=aconfig['dbpass'],
db=aconfig['dbname'], port=aconfig['dbport'], cursorclass=mycursors.DictCursor)
crs = con.cursor()
events = []
#kippo vs cowrie
#cowrie/core/dblog.py: def nowUnix(self):
#cowrie/core/dblog.py- """return the current UTC time as an UNIX timestamp"""
#cowrie/core/dblog.py- return int(time.time())
#kippo/core/dblog.py: def nowUnix(self):
#kippo/core/dblog.py- """return the current UTC time as an UNIX timestamp"""
#kippo/core/dblog.py- return int(time.mktime(time.gmtime()[:-1] + (-1,)))
# k sozalenju
# >>> int(time.mktime(time.gmtime()[:-1] + (-1,)))-int(time.time()) != 0
#old senders data
query = "SELECT UNIX_TIMESTAMP(s.starttime) as starttime, s.ip, COUNT(s.id) as attack_scale, sn.ip as sensor \
FROM sessions s \
LEFT JOIN sensors sn ON s.sensor=sn.id \
WHERE s.starttime > DATE_SUB(UTC_TIMESTAMP(), INTERVAL + %s SECOND) \
GROUP BY s.ip ORDER BY s.starttime ASC;"
crs.execute(query, (awin,))
etime = format_timestamp(time())
stime = format_timestamp(time() - awin)
rows = crs.fetchall()
for row in rows:
a = gen_event_idea_cowrie_info(
detect_time = format_timestamp(row['starttime']),
src_ip = row['ip'],
dst_ip = row['sensor'],
win_start_time = stime,
win_end_time = etime,
aggr_win = awin,
conn_count = row['attack_scale']
)
events.append(a)
#success login
query = "SELECT UNIX_TIMESTAMP(a.timestamp) as timestamp, s.ip as sourceip, sn.ip as sensor, a.session as sessionid, a.username as username, a.password as password \
FROM auth a JOIN sessions s ON s.id=a.session JOIN sensors sn ON s.sensor=sn.id \
WHERE a.success=1 AND a.timestamp > DATE_SUB(UTC_TIMESTAMP(), INTERVAL + %s SECOND) \
ORDER BY a.timestamp ASC;"
crs.execute(query, (awin,))
rows = crs.fetchall()
for row in rows:
a = gen_event_idea_cowrie_auth(
detect_time = format_timestamp(row['timestamp']),
src_ip = row['sourceip'],
dst_ip = row['sensor'],
username = row['username'],
password = row['password'],
sessionid = row['sessionid']
)
events.append(a)
#ttylog+iinput reporter
query = "SELECT UNIX_TIMESTAMP(s.starttime) as starttime, s.ip as sourceip, sn.ip as sensor, t.session as sessionid \
FROM ttylog t JOIN sessions s ON s.id=t.session JOIN sensors sn ON s.sensor=sn.id \
WHERE s.starttime > DATE_SUB(UTC_TIMESTAMP(), INTERVAL + %s SECOND) \
ORDER BY s.starttime ASC;"
crs.execute(query, (awin,))
rows = crs.fetchall()
for row in rows:
a = gen_event_idea_cowrie_ttylog(
detect_time = format_timestamp(row['starttime']),
src_ip = row['sourceip'],
dst_ip = row['sensor'],
sessionid = row['sessionid'],
ttylog = get_ttylog(row['sessionid']),
iinput = get_iinput(row['sessionid'])
)
events.append(a)
#download
query = "SELECT UNIX_TIMESTAMP(s.starttime) as starttime, s.ip as sourceip, sn.ip as sensor, d.session as sessionid, d.url as url, d.outfile as ofile \
FROM downloads d JOIN sessions s ON s.id=d.session JOIN sensors sn ON s.sensor=sn.id \
WHERE s.starttime > DATE_SUB(UTC_TIMESTAMP(), INTERVAL + %s SECOND) \
ORDER BY s.starttime ASC;"
crs.execute(query, (awin,))
rows = crs.fetchall()
for row in rows:
a = gen_event_idea_cowrie_download(
detect_time = format_timestamp(row['starttime']),
src_ip = row['sourceip'],
dst_ip = row['sensor'],
sessionid = row['sessionid'],
url = row['url'],
outfile = row['ofile']
)
events.append(a)
print "=== Sending ==="
start = time()
ret = wclient.sendEvents(events)
if 'saved' in ret:
wclient.logger.info("%d event(s) successfully delivered." % ret['saved'])
print "Time: %f" % (time() - start)
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (C) 2019 Cesnet z.s.p.o
# Use of this source is governed by a 3-clause BSD-style license, see LICENSE file.
"""
Wardenfiler output connector. Writes audit logs to Wardenfiler spool directory in IDEA format
"""
import os
import errno
import socket
import json
import string
from urllib.parse import urlparse
from time import time, gmtime, strftime
from datetime import datetime
from uuid import uuid4
from hashlib import sha1
from base64 import b64encode
from ipaddress import IPv4Network
from ipaddress import IPv6Network
from cowrie.core.config import CowrieConfig
import cowrie.core.output
class Filer(object):
"""
IDEA files creator
"""
def __init__(self, directory):
self.basedir = self._ensure_path(directory)
self.tmp = self._ensure_path(os.path.join(self.basedir, "tmp"))
self.incoming = self._ensure_path(os.path.join(self.basedir, "incoming"))
self.hostname = socket.gethostname()
self.pid = os.getpid()
def _ensure_path(self, p):
try:
os.mkdir(p)
except OSError:
if not os.path.isdir(p):
raise
return p
def _get_new_name(self, fd=None):
(inode, device) = os.fstat(fd)[1:3] if fd else (0, 0)
return "%s.%d.%f.%d.%d" % (
self.hostname, self.pid, time(), device, inode)
def create_unique_file(self):
tmpname = None
while not tmpname:
tmpname = self._get_new_name()
try:
fd = os.open(os.path.join(self.tmp, tmpname), os.O_CREAT | os.O_RDWR | os.O_EXCL)
except OSError as e:
if e.errno != errno.EEXIST:
raise
tmpname = None
newname = self._get_new_name(fd)
os.rename(os.path.join(self.tmp, tmpname), os.path.join(self.tmp, newname))
nf = os.fdopen(fd, "w")
return nf, newname
def publish_file(self, short_name):
os.rename(os.path.join(self.tmp, short_name), os.path.join(self.incoming, short_name))
class Output(cowrie.core.output.Output):
"""
Wardenfiler Output
"""
detector_name = None
resolve_nat = False
reported_public_ipv4 = None
reported_public_ipv6 = None
reported_ssh_port = None
nat_host = "gateway"
nat_port = 1456
anon_mask_4 = 32
anon_mask_6 = 128
aggr_win = 5 * 60
test_mode = True
output_dir = "var/spool/warden"
drop_malware = True
win_start = None
attackers = {}
sessions = {}
port_xlat = {}
def save_event(self, event):
f, name = self.filer.create_unique_file()
with f:
f.write(json.dumps(event, ensure_ascii=True))
self.filer.publish_file(name)
def start(self):
if CowrieConfig.has_option('output_wardenfiler', 'detector_name'):
self.detector_name = CowrieConfig.get('output_wardenfiler', 'detector_name')
if CowrieConfig.has_option('output_wardenfiler', 'resolve_nat'):
self.resolve_nat = CowrieConfig.getboolean('output_wardenfiler', 'resolve_nat')
if CowrieConfig.has_option('output_wardenfiler', 'reported_public_ipv4'):
self.reported_public_ipv4 = CowrieConfig.get('output_wardenfiler', 'reported_public_ipv4')
if CowrieConfig.has_option('output_wardenfiler', 'reported_public_ipv6'):
self.reported_public_ipv6 = CowrieConfig.get('output_wardenfiler', 'reported_public_ipv6')
if CowrieConfig.has_option('output_wardenfiler', 'reported_ssh_port'):
self.reported_ssh_port = CowrieConfig.getint('output_wardenfiler', 'reported_ssh_port')
if CowrieConfig.has_option('output_wardenfiler', 'nat_host'):
self.nat_host = CowrieConfig.get('output_wardenfiler', 'nat_host')
if CowrieConfig.has_option('output_wardenfiler', 'nat_port'):
self.nat_port = CowrieConfig.getint('output_wardenfiler', 'nat_port')
if CowrieConfig.has_option('output_wardenfiler', 'anon_mask_4'):
self.anon_mask_4 = CowrieConfig.getint('output_wardenfiler', 'anon_mask_4')
if CowrieConfig.has_option('output_wardenfiler', 'anon_mask_6'):
self.anon_mask_6 = CowrieConfig.getint('output_wardenfiler', 'anon_mask_6')
if CowrieConfig.has_option('output_wardenfiler', 'aggr_win'):
self.aggr_win = CowrieConfig.getint('output_wardenfiler', 'aggr_win')
if CowrieConfig.has_option('output_wardenfiler', 'test_mode'):
self.test_mode = CowrieConfig.getboolean('output_wardenfiler', 'test_mode')
if CowrieConfig.has_option('output_wardenfiler', 'output_dir'):
self.output_dir = CowrieConfig.get('output_wardenfiler', 'output_dir')
if CowrieConfig.has_option('output_wardenfiler', 'port_xlat'):
self.port_xlat = dict((int(x), int(y)) for x, y in (e.split(':') for e in CowrieConfig.get('output_wardenfiler', 'port_xlat').split()))
if CowrieConfig.has_option('output_wardenfiler', 'drop_malware'):
self.drop_malware = CowrieConfig.getboolean('output_wardenfiler', 'drop_malware')
self.filer = Filer(self.output_dir)
def stop(self):
"""
No actions needed on honeypot shutdown
"""
def write(self, entry):
event = {
"Format": "IDEA0",
"ID": str(uuid4()),
"DetectTime": entry['timestamp'],
"Category": [],
"Source": [{"Proto": ["tcp", "ssh"]}],
"Target": [{ "Proto": ["tcp", "ssh"]}],
"Node": [
{
"Name": self.detector_name,
"Type": ["Connection", "Auth", "Honeypot"],
"SW": ["Cowrie with Warden Filer output module"],
}
]
}
if self.test_mode:
event["Category"].append("Test")
entry["src_ip"] = entry["src_ip"].lstrip("::ffff:")
if entry.get("dst_ip"):
entry["dst_ip"] = entry["dst_ip"].lstrip("::ffff:")
# detect IPv4 or IPv6
af = "IP4" if not ':' in entry["src_ip"] else "IP6"
# If configured, override destination IP and port
if entry.get("dst_ip"):
if af == "IP4" and self.reported_public_ipv4:
entry["dst_ip"] = self.reported_public_ipv4
elif af == "IP6" and self.reported_public_ipv6:
entry["dst_ip"] = self.reported_public_ipv6
if entry.get("dst_port") and self.reported_ssh_port:
entry["dst_port"] = self.reported_ssh_port
if entry["eventid"] == 'cowrie.session.connect':
if self.resolve_nat:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((self.nat_host, self.nat_port))
s.sendall((','.join((entry["src_ip"], str(entry["src_port"]))).encode("utf-8")))
dst = s.recv(50).decode("utf-8")
s.close()
if dst != "NE":
entry["dst_ip"] = dst
else:
return()
entry["dst_ip"] = (
str(IPv4Network("/".join((entry["dst_ip"], str(self.anon_mask_4))), False).network_address) if not ':' in entry["dst_ip"] else
str(IPv6Network("/".join((entry["dst_ip"], str(self.anon_mask_6))), False).network_address)
)
entry["loggedin"] = False
self.sessions[entry["session"]] = entry
ws = self.win_start or time()
aid = ','.join((entry["src_ip"], entry["dst_ip"]))
cnt = self.attackers.get(aid, 0)
if (time() - ws < self.aggr_win):
self.attackers[aid] = cnt + 1
else:
event["Node"][0]["AggrWin"] = strftime("%H:%M:%S", gmtime(float(self.aggr_win)))
event["WinStartTime"] = datetime.utcfromtimestamp(ws).isoformat() + 'Z'
event["WinEndTime"] = datetime.utcfromtimestamp(ws + self.aggr_win).isoformat() + 'Z'
event["Category"].append("Attempt.Login")
event["Note"] = "SSH login attempt"
for i, c in self.attackers.items():
src_ip, dst_ip = i.split(',')
af = "IP4" if not ':' in src_ip else "IP6"
event["ID"] = str(uuid4())
event["DetectTime"] = event["WinEndTime"]
event["ConnCount"] = c
event["Source"] = [{"Proto": ["tcp", "ssh"], af: [src_ip]}]
event["Target"] = [{"Proto": ["tcp", "ssh"], af: [dst_ip]}]
if (self.anon_mask_4 < 32) and (not ':' in entry["dst_ip"]) or (self.anon_mask_6 < 128):
event["Target"][0]["Anonymised"] = True
self.save_event(event)
self.attackers = {}
ws = time()
self.attackers[aid] = 1
self.win_start = ws
elif entry["eventid"] == 'cowrie.login.success':
s = entry["session"]
if s in self.sessions:
self.sessions[s]["input"] = []
self.sessions[s]["loggedin"] = True
elif entry["eventid"] == 'cowrie.command.input':
s = entry["session"]
if s in self.sessions:
self.sessions[s]["input"].append(entry["input"])
elif entry["eventid"] == 'cowrie.session.file_download':
s = entry["session"]
if s in self.sessions:
sch = { "http": 80, "https": 443, "ftp": 21 }
# deal with the file first (drop even if not reported)
mware = None
fname = None
if "outfile" in entry and os.path.exists(entry["outfile"]):
fp = open(entry["outfile"], "r")
mware = fp.read()
fp.close()
if self.drop_malware:
os.remove(entry["outfile"])
if mware:
# TODO: Classify everything as Malware?
event["Category"].append("Malware")
event["Note"] = "Malware download during honeypot session"
if "url" in entry and entry["url"].startswith(tuple(sch.keys())):
url = urlparse(entry["url"])
host = url.hostname
ai = socket.getaddrinfo(host, None)[0]
af = "IP6" if ai[0] == socket.AddressFamily.AF_INET6 else "IP4"
ip = ai[4][0]
proto = [ "tcp", url.scheme ]
port = url.port or sch[url.scheme]
fname = os.path.basename(entry["url"])
if not fname and 'destfile' in entry:
fname = os.path.basename(entry['destfile'])
elif not "url" in entry:
# TODO implement the path for other files after discussion
return()
# The remainder of this branch will not execute now
if entry["format"].startswith("Saved redir"):
event["Note"] = "Saved file during honeypot session"
fname = os.path.basename(entry['destfile'])
else:
event["Note"] = "Stdin contents during honeypot session"
# End of the not executed part
else:
# TODO: Some exotic protocol? Let's not worry with that now
return()
event["DetectTime"] = entry["timestamp"]
if "url" in entry:
event["Source"][0] = { "Type": ["Malware"] }
event["Source"][0]["URL"] = [entry["url"]]
event["Source"][0][af] = [ip]
event["Source"][0]["Proto"] = proto
event["Source"][0]["Port"] = [port]
if ip != host:
event["Source"][0]["Hostname"] = [host]
else:
# TODO implement later
pass
del event["Target"]
event["Attach"] = [{
"Type": ["ShellCode"],
"Hash": ["sha1:" + entry["shasum"]],
"Size": len(mware),
"Note": "Some probably malicious code downloaded during honeypot SSH session",
"ContentEncoding": "base64",
"Content": b64encode(mware.encode()).decode(),
}]
if fname:
event["Attach"][0]["FileName"] = [fname]
if "url" in entry:
event["Attach"][0]["ExternalURI"] = [entry["url"]]
self.save_event(event)
elif entry["eventid"] == 'cowrie.session.closed':
s = entry["session"]
if s in self.sessions and self.sessions[s]["loggedin"]:
idata = '\n'.join(self.sessions[s]["input"])
plain = all(c in string.printable for c in idata)
event["Category"].append("Intrusion.UserCompromise")
event["Note"] = "SSH successful login" + (" with unauthorized command input" if len(idata) else "")
af = "IP4" if not ':' in entry["src_ip"] else "IP6"
event["Source"][0][af] = [entry["src_ip"]]
event["Target"][0][af] = [self.sessions[s]["dst_ip"]]
event["Source"][0]["Port"] = [self.sessions[s]["src_port"]]
dst_port = self.sessions[s]["dst_port"]
if dst_port in self.port_xlat:
dst_port = self.port_xlat[dst_port]
event["Target"][0]["Port"] = [dst_port]
if len(idata):
eidata = idata if plain else b64encode(idata.encode()).decode()
attach = {
"Type": ["Exploit"],
"Hash": ["sha1:" + sha1(idata.encode("utf-8")).hexdigest()],
"Size": len(idata),
"Note": "Commands entered by attacker during honeypot SSH session",
"Content": eidata
}
if not plain:
attach["ContentEncoding"] = "base64"
event["Attach"] = [attach]
self.save_event(event)
self.sessions.pop(s, None)
[Unit]
Description=A malware capturing honeypot service
After=network.target
After=rsyslog.service
#Requires=dionaea.socket
[Service]
User=root
Group=root
PIDFile=/opt/dionaea/var/run/dionaea.pid
Restart=always
RestartSec=5
WorkingDirectory=/opt/dionaea
ExecStart=/opt/dionaea/bin/dionaea -c /opt/dionaea/etc/dionaea/dionaea.cfg -w /opt/dionaea -D -p /opt/dionaea/var/run/dionaea.pid -u dionaea -g dionaea
KillMode=process
Type=forking
[Install]
WantedBy=multi-user.target
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (C) 2020 Cesnet z.s.p.o
# Use of this source is governed by a 3-clause BSD-style license, see LICENSE file.
"""
Wardenfiler output connector. Writes audit logs to Wardenfiler spool directory in IDEA format
"""
import os
import errno
import socket
import json
import hashlib
import logging
import string
from urllib.parse import urlparse
from time import time, gmtime, strftime
from datetime import datetime
from uuid import uuid4
from hashlib import sha1
from base64 import b64encode
from ipaddress import IPv4Network
from ipaddress import IPv6Network
from dionaea import IHandlerLoader
from dionaea.core import ihandler, connection
from dionaea.exception import LoaderError
logger = logging.getLogger("log_wardenfiler")
logger.setLevel(logging.DEBUG)
class Filer(object):
"""
IDEA files creator
"""
def __init__(self, directory):
self.basedir = self._ensure_path(directory)
self.tmp = self._ensure_path(os.path.join(self.basedir, "tmp"))
self.incoming = self._ensure_path(os.path.join(self.basedir, "incoming"))
self.hostname = socket.gethostname()
self.pid = os.getpid()
def _ensure_path(self, p):
try:
os.mkdir(p)
except OSError:
if not os.path.isdir(p):
raise
return p
def _get_new_name(self, fd=None):
(inode, device) = os.fstat(fd)[1:3] if fd else (0, 0)
return "%s.%d.%f.%d.%d" % (
self.hostname, self.pid, time(), device, inode)
def create_unique_file(self):
tmpname = None
while not tmpname:
tmpname = self._get_new_name()
try:
fd = os.open(os.path.join(self.tmp, tmpname), os.O_CREAT | os.O_RDWR | os.O_EXCL)
except OSError as e:
if e.errno != errno.EEXIST:
raise
tmpname = None
newname = self._get_new_name(fd)
os.rename(os.path.join(self.tmp, tmpname), os.path.join(self.tmp, newname))
nf = os.fdopen(fd, "w")
return nf, newname
def publish_file(self, short_name):
os.rename(os.path.join(self.tmp, short_name), os.path.join(self.incoming, short_name))
class LogWardenfilerHandlerLoader(IHandlerLoader):
name = "log_wardenfiler"
@classmethod
def start(cls, config=None):
try:
return LogWardenfilerHandler("*", config=config)
except LoaderError as e:
logger.error(e.msg, *e.args)
return None
class LogWardenfilerHandler(ihandler):
detector_name = None
resolve_nat = False
nat_host = "gateway"
nat_port = 1456
anon_mask_4 = 32
anon_mask_6 = 128
aggr_win = 5 * 60
test_mode = True
output_dir = "var/spool/warden"
drop_malware = True
win_start = None
attackers = {}
sessions = {}
def __init__(self, path, config = None):
logger.debug("%s ready!", self.__class__.__name__)
ihandler.__init__(self, path)
self.path = path
self._config = config
def _save_event(self, event):
f, name = self.filer.create_unique_file()
with f:
f.write(json.dumps(event, ensure_ascii = True))
self.filer.publish_file(name)
def start(self):
if 'detector_name' in self._config:
self.detector_name = self._config.get('detector_name')
if 'resolve_nat' in self._config:
self.resolve_nat = self._config.get('resolve_nat')
if 'nat_host' in self._config:
self.nat_host = self._config.get('nat_host')
if 'nat_port' in self._config:
self.nat_port = self._config.get('nat_port')
if 'anon_mask_4' in self._config:
self.nat_port = self._config.get('anon_mask_4')
if 'anon_mask_6' in self._config:
self.nat_port = self._config.get('anon_mask_6')
if 'aggr_win' in self._config:
self.aggr_win = self._config.get('aggr_win')
if 'test_mode' in self._config:
self.test_mode = self._config.get('test_mode')
if 'output_dir' in self._config:
self.output_dir = self._config.get('output_dir')
if 'drop_malware' in self._config:
self.drop_malware = self._config.get('drop_malware')
self.filer = Filer(self.output_dir)
def _aggregate(self):
ws = self.win_start or time()
if (time() - ws >= self.aggr_win):
logger.info("Counting attacks: %s" % json.dumps(self.attackers, ensure_ascii = True))
we = datetime.utcfromtimestamp(ws + self.aggr_win).isoformat() + 'Z'
sevent = {
"Format": "IDEA0",
"WinStartTime": datetime.utcfromtimestamp(ws).isoformat() + 'Z',
"WinEndTime": we,
"DetectTime": we,
"Category": [],
"Node": [
{
"Name": self.detector_name,
"Type": ["Connection", "Auth", "Honeypot"],
"SW": ["Dionaea with Warden Filer output module"],
"AggrWin": strftime("%H:%M:%S", gmtime(float(self.aggr_win)))
}
]
}
if self.test_mode:
sevent["Category"].append("Test")
for i, a in self.attackers.items():
c = a["count"]
if c > 1:
src_ip, dst_ip, dst_port, proto = i.split(',')
if (self.anon_mask_4 < 32) and (not ':' in dst_ip) or (self.anon_mask_6 < 128):
Target[0]["Anonymised"] = "true"
sevent["ID"] = str(uuid4())
if len(a["creds"]):
sevent["Category"] = ["Recon.Scanning"]
sevent["Note"] = "Successful logins to honeypoted service."
else:
sevent["Category"] = ["Attempt.Login"]
sevent["Note"] = "Connection attempts to IPs assigned to honeypot."
sevent["ConnCount"] = c
af = "IP4" if not ':' in src_ip else "IP6"
proto = [proto]
if a["proto"]
proto.append(a["proto"])
sevent["Source"] = [{"Proto": proto, af: [src_ip], "Port": a["sports"]}]
sevent["Target"] = [{"Proto": proto, af: [dst_ip], "Port": [int(dst_port)]}]
if len(a["creds"]):
attach = {
"Type": ["Credentials"],
"Note": "Credentials used by attacker used for simulated honeypot login",
"Credentials": a["creds"]
}
sevent["Attach"] = attach
self._save_event(sevent)
logger.info("sending scanning event for %s probing %s (%i times)" % (src_ip, dst_ip, c))
self.attackers = {}
self.win_start = time()
def _make_idea(self, con):
s = self.sessions[con]
proto = [s["trans"]]
if s["proto"]:
proto.append(s["proto"])
event = {
"Format": "IDEA0",
"ID": s["id"],
"DetectTime": s["dt"],
"Category": s["cat"],
"Source": [{"Proto": proto, s["af"]: [s["src_ip"]], "Port": [s["src_port"]]}],
"Target": [{ "Proto": proto, s["af"]: [s["dst_ip"]], "Port": [s["dst_port"]]}],
"Node": [
{
"Name": self.detector_name,
"Type": ["Connection", "Auth", "Honeypot"],
"SW": ["Dionaea with Warden Filer output module"],
}
]
}
if s["anon"]:
event["Target"][0]["Anonymised"] = "true"
if len(s["creds"]):
p = {
"ftp": "FTP",
"mysql": "MySQL",
"ms-sql-s": "MSSQL",
}
event["Category"].append("Intrusion.UserCompromise")
if s["proto"]:
event["Note"] = p[s["proto"]] + "successful login"
else
event["Note"] = "Successful login attempt"
attach = {
"Type": ["Credentials"],
"Note": "Credentials used by attacker used for simulated honeypot login",
"Credentials": s["creds"]
}
event["Attach"] = [attach]
if len(s["cmds"]):
event["Category"].append("Attempt.Exploit")
event["Note"] += " with unauthorized command input"
idata = "\n".join(str(c) for c in s[cmds])
plain = all(c in string.printable for c in idata)
eidata = idata if plain else b64encode(idata.encode()).decode()
attach = {
"Type": ["Exploit"],
"Hash": ["sha1:" + sha1(idata.encode("utf-8")).hexdigest()],
"Size": len(idata),
"Note": "Commands entered by attacker during honeypot session",
"Content": eidata
}
if not plain:
attach["ContentEncoding"] = "base64"
event["Attach"].append(attach)
return(event)
def _register_connection(self, con, proto = None, cred = None, cmd = None)
if not con in self.sessions:
src_ip = con.remote.host.lstrip("::ffff:")
dst_ip = con.local.host.lstrip("::ffff:")
if self.resolve_nat:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((self.nat_host, self.nat_port))
s.sendall((','.join((src_ip, str(con.local.port))).encode("utf-8")))
dst = s.recv(50).decode("utf-8")
s.close()
if dst != "NE":
dst_ip = dst
else:
logger.warn("no translation for %s:%s" % (src_ip, con.local.port))
return()
af = "IP4" if not ':' in src_ip else "IP6"
anon = (self.anon_mask_4 < 32) and (not ':' in dst_ip) or (self.anon_mask_6 < 128)
if anon:
dst_ip = [(
str(IPv4Network("/".join((dst_ip, str(self.anon_mask_4))), False).network_address) if not ':' in dst_ip else
str(IPv6Network("/".join((dst_ip, str(self.anon_mask_6))), False).network_address)
)]
self.sessions[con]["id"] = str(uuid4())
self.sessions[con]["dt"] = datetime.utcnow().isoformat() + "Z"
self.sessions[con]["cat"] = ["Test"] if self.test_mode else []
self.sessions[con]["af"] = af
self.sessions[con]["anon"] = anon
self.sessions[con]["src_ip"] = src_ip
self.sessions[con]["dst_ip"] = dst_ip
self.sessions[con]["src_port"] = con.remote.port
self.sessions[con]["dst_port"] = con.local.port
self.sessions[con]["trans"] = con.transport
self.sessions[con]["proto"] = None
self.sessions[con]["creds"] = []
self.sessions[con]["cmds"] = []
aid = ','.join((src_ip, dst_ip, str(con.local.port), con.transport))
if not aid in in self.attackers:
self.attackers[aid] = {
"count": 0,
"sports": [],
"creds": [],
"proto": None
}
self.attackers[aid]["count"] += 1
if not con.remote.port in self.attackers[aid]["sports"]:
self.attackers[aid]["sports"].append(con.remote.port)
if proto:
self.sessions[con]["proto"] = proto
self.attackers[aid]["proto"] = proto
if cred:
self.sessions[con]["creds"].append(cred)
self.attackers[aid]["creds"].append(cred)
if cmd:
self.sessions[con]["cmds"].append(cmd)
def handle_incident(self, icd):
pass
def handle_incident_dionaea_connection_tcp_listen(self, icd):
pass;
def handle_incident_dionaea_connection_tls_listen(self, icd):
pass
def handle_incident_dionaea_connection_tcp_connect(self, icd):
con = icd.con
self._register_connection(con)
logger.info("connect connection to %s/%s:%i from %s:%i" % (con.remote.host, con.remote.hostname, con.remote.port, con.local.host, con.local.port))
def handle_incident_dionaea_connection_tls_connect(self, icd):
con = icd.con
self._register_connection(con, "ssl-tls")
logger.info("connect connection to %s/%s:%i from %s:%i" % (con.remote.host, con.remote.hostname, con.remote.port, con.local.host, con.local.port))
def handle_incident_dionaea_connection_udp_connect(self, icd):
con = icd.con
self._register_connection(con)
logger.info("connect connection to %s/%s:%i from %s:%i" % (con.remote.host, con.remote.hostname, con.remote.port, con.local.host, con.local.port))
def handle_incident_dionaea_connection_tcp_accept(self, icd):
con = icd.con
self._register_connection(con)
logger.info("accepted connection from %s:%i to %s:%i" % (con.remote.host, con.remote.port, con.local.host, con.local.port))
def handle_incident_dionaea_connection_tls_accept(self, icd):
con = icd.con
self._register_connection(con, "ssl-tls")
logger.info("accepted connection from %s:%i to %s:%i" % (con.remote.host, con.remote.port, con.local.host, con.local.port))
def handle_incident_dionaea_connection_tcp_reject(self, icd):
con = icd.con
self._register_connection(con)
logger.info("reject connection from %s:%i to %s:%i" % (con.remote.host, con.remote.port, con.local.host, con.local.port))
def handle_incident_dionaea_modules_python_ftp_command(self, icd):
con = icd.con
cmd = icd.command.decode()
if hasattr(icd, 'arguments'):
cmd = " ".join([cmd], icd.arguments)
self._register_connection(con, "ftp", cmd = cmd)
logger.info("new FTP command within connection from %s:%i to %s:%i" % (con.remote.host, con.remote.port, con.local.host, con.local.port))
def handle_incident_dionaea_modules_python_mssql_cmd(self, icd):
con = icd.con
self._register_connection(con, "ms-sql-s", cmd = icd.cmd)
logger.info("new MSSQL command within connection from %s:%i to %s:%i" % (con.remote.host, con.remote.port, con.local.host, con.local.port))
def handle_incident_dionaea_modules_python_mysql_command(self, icd):
con = icd.con
cmd = icd.command
if hasattr(icd, 'args'):
cmd = " ".join([cmd], icd.args)
self._register_connection(con, "mysql", cmd = cmd)
logger.info("new MYSQL command within connection from %s:%i to %s:%i" % (con.remote.host, con.remote.port, con.local.host, con.local.port))
def handle_incident_dionaea_modules_python_ftp_login(self, icd):
con = icd.con
self._register_connection(con, "ftp", cred = {"User": icd.username, "Password": icd.password})
logger.info("new FTP login within connection from %s:%i to %s:%i" % (con.remote.host, con.remote.port, con.local.host, con.local.port))
def handle_incident_dionaea_modules_python_mssql_login(self, icd):
con = icd.con
self._register_connection(con, "ms-sql-s", cred = {"User": icd.username, "Password": icd.password})
logger.info("new MSSQL login within connection from %s:%i to %s:%i" % (con.remote.host, con.remote.port, con.local.host, con.local.port))
def handle_incident_dionaea_modules_python_mysql_login(self, icd):
con = icd.con
self._register_connection(con, "mysql", cred = {"User": icd.username, "Password": icd.password})
logger.info("new MySQL login within connection from %s:%i to %s:%i" % (con.remote.host, con.remote.port, con.local.host, con.local.port))
def handle_incident_dionaea_modules_python_p0f(self, icd):
pass;
def handle_incident_dionaea_connection_free(self, icd):
con = icd.con
self._aggregate()
if con in self.sessions:
s = self.sessions[con]
if len(s["cmds"]):
event = self._make_idea(con)
self._save_event(event)
logger.info("sending connection event from %s:%i to %s:%i" % (con.remote.host, con.remote.port, con.local.host, con.local.port))
self.sessions.pop(con, None)
logger.info("closing connection from %s:%i to %s:%i" % (con.remote.host, con.remote.port, con.local.host, con.local.port))
else:
logger.warn("no attack data for %s:%s" % (con.remote.host, con.remote.port))
- name: log_wardenfiler
config:
detector_name: "org.example.hugo.dionaea"
resolve_nat: no
# nat_host: "gateway"
# nat_port: 1456
# anon_mask_4: 24
# anon_mask_6: 64
aggr_win: 300
test_mode: True
output_dir: "var/spool/warden"
drop_malware: True
drop_stream: True
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (C) 2011-2018 Cesnet z.s.p.o
# Use of this source is governed by a 3-clause BSD-style license, see LICENSE file.
from warden_client import Client, Error, read_cfg, format_timestamp
import json
import string
import urllib
from time import time, gmtime, strftime, sleep
from math import trunc
from uuid import uuid4
from os import path, remove
import base64
import sqlite3
import sys
import re
aconfig = read_cfg('warden_client_dio.cfg')
wconfig = read_cfg('warden_client.cfg')
aclient_name = aconfig['name']
wconfig['name'] = aclient_name
aanonymised = aconfig['anonymised']
aanonymised_net = aconfig['target_net']
aanonymised = aanonymised if (aanonymised_net != '0.0.0.0/0') or (aanonymised_net == 'omit') else '0.0.0.0/0'
atest = aconfig['test_mode']
awin = aconfig['awin'] * 60
abinpath = aconfig['binaries_path']
adbfile = aconfig['dbfile']
aconattempts = aconfig['con_attempts']
aretryinterval = aconfig['con_retry_interval']
areportbinaries = aconfig['report_binaries']
apurgebinaries = aconfig['purge_binaries']
wconfig['secret'] = aconfig.get('secret', '')
wclient = Client(**wconfig)
def idea_fill_addresses(event, source_ip, destination_ip, anonymised, anonymised_net):
af = "IP4" if not ':' in source_ip else "IP6"
event['Source'][0][af] = [source_ip]
if anonymised != 'omit':
if anonymised == 'yes':
event['Target'][0]['Anonymised'] = True
event['Target'][0][af] = [anonymised_net]
else:
event['Target'][0][af] = [destination_ip]
return event
def gen_attach_idea_smb(logger, report_binaries, purge_binaries, binaries_path, filename, hashtype, hashdigest, vtpermalink, avref):
refs = []
attach = {
"Handle": 'att1',
"FileName": [filename],
"Type": ["Malware"],
"Hash": ["%s:%s" % (hashtype, hashdigest)],
}
if vtpermalink is not None:
refs.append('url:' + vtpermalink)
if avref is not None:
refs.extend(avref.split(';'))
if refs:
refs = [urllib.quote(ref, safe=':') for ref in refs]
refs = list(set(refs))
attach['Ref'] = refs
if report_binaries == 'true':
try:
fpath = path.join(binaries_path, hashdigest)
with open(fpath, "r") as f:
fdata = f.read()
attach['ContentType'] = 'application/octet-stream'
attach['ContentEncoding'] = 'base64'
attach['Size'] = len(fdata)
attach['Content'] = base64.b64encode(fdata)
except (IOError) as e:
logger.info("Reading id file \"%s\" with malware failed, information will not be attached." % (fpath))
if purge_binaries == 'true':
try:
remove(filename)
except OSError:
pass
return attach
def gen_attach_idea_db(logger, data):
attach = {}
attach["Handle"] = 'att1'
attach["Type"] = ["Malware"]
attach['ContentType'] = 'application/octet-stream'
attach['ContentEncoding'] = 'base64'
attach['Size'] = len(data)
attach['Content'] = base64.b64encode(data)
return attach
def gen_event_idea_dio(logger, binaries_path, report_binaries, purge_binaries, client_name, anonymised, target_net, detect_time, win_start_time, win_end_time, aggr_win, data):
category = []
event = {
"Format": "IDEA0",
"ID": str(uuid4()),
"DetectTime": detect_time,
"WinStartTime": win_start_time,
"WinEndTime": win_end_time,
"ConnCount": data['attack_scale'],
"Source": [{}],
"Target": [{}],
"Node": [
{
"Name": client_name,
"Type": ["Connection", "Protocol", "Honeypot"],
"SW": ["Dionaea"],
"AggrWin": strftime("%H:%M:%S", gmtime(aggr_win))
}
]
}
# Save TCP/UDP proto
proto = [data['proto']]
# smbd allows save malware
if data['service'] == 'smbd' and data['download_md5_hash'] is not None:
category.append('Attempt.Exploit')
category.append('Malware')
proto.append('smb')
if data['download_url'] != '':
event['Source'][0]['URL'] = [data['download_url']]
filename = data['download_url'].split('/')[-1]
if filename != '' and data['download_md5_hash'] != '':
# Generate "SMB Attach" part of IDEA
a = gen_attach_idea_smb(logger, report_binaries, binaries_path, filename, "md5", data['download_md5_hash'], data['virustotal_permalink'], data['scan_result'])
event['Source'][0]['AttachHand'] = ['att1']
event['Attach'] = [a]
if data['service'] == 'mysqld':
#Clean exported data
if data['mysql_query'] is not None:
mysql_data = re.sub("select @@version_comment limit 1,?", "", data['mysql_query'])
if mysql_data != "":
# Generate "MySQL Attach" part of IDEA
a = gen_attach_idea_db(logger, mysql_data)
category.append('Attempt.Exploit')
proto.append('mysql')
event['Source'][0]['AttachHand'] = ['att1']
event['Attach'] = [a]
if data['service'] == 'mssqld':
#Clean exported data
if data['mssql_query'] is not None:
mssql_data = data['mssql_query']
if mssql_data != "":
# Generate "MSSQL Attach" part of IDEA
a = gen_attach_idea_db(logger, mssql_data)
category.append('Attempt.Exploit')
proto.append('mssql')
event['Source'][0]['AttachHand'] = ['att1']
event['Attach'] = [a]
event['Source'][0]['Port'] = [data['src_port']]
event['Target'][0]['Port'] = [data['dst_port']]
event['Source'][0]['Proto'] = proto
event['Target'][0]['Proto'] = proto
idea_fill_addresses(event, data['src_ip'], data['dst_ip'], aanonymised, aanonymised_net)
# Add default category
if not category:
category.append('Recon.Scanning')
# Test if we're testing
if atest == "true":
category.append('Test')
event['Category'] = category
return event
def main():
con = sqlite3.connect(adbfile)
con.row_factory = sqlite3.Row
con.text_factory = str
crs = con.cursor()
events = []
query = "SELECT c.connection_timestamp AS timestamp, c.remote_host AS src_ip, c.remote_port AS src_port, c.connection_transport AS proto, \
c.local_host AS dst_ip, c.local_port AS dst_port, COUNT(c.connection) as attack_scale, c.connection_protocol AS service, d.download_url, d.download_md5_hash, \
v.virustotal_permalink, GROUP_CONCAT('urn:' || vt.virustotalscan_scanner || ':' || vt.virustotalscan_result,';') AS scan_result, \
group_concat(mca.mysql_command_arg_data) as mysql_query, \
group_concat(msc.mssql_command_cmd) as mssql_query \
FROM connections AS c LEFT JOIN downloads AS d ON c.connection = d.connection \
LEFT JOIN virustotals AS v ON d.download_md5_hash = v.virustotal_md5_hash \
LEFT JOIN virustotalscans vt ON v.virustotal = vt.virustotal \
LEFT JOIN mysql_commands mc ON c.connection = mc.connection \
LEFT JOIN mysql_command_args mca ON mc.mysql_command = mca.mysql_command \
LEFT JOIN mssql_commands msc ON c.connection = msc.connection \
WHERE datetime(connection_timestamp,'unixepoch') > datetime('now','-%d seconds') AND c.remote_host != '' \
GROUP BY c.remote_host, c.local_port ORDER BY c.connection_timestamp ASC;" % (awin)
attempts = 0
while attempts < aconattempts:
try:
crs.execute(query)
break
except sqlite3.Error, e:
attempts += 1
wclient.logger.info("Info: %s - attempt %d/%d." % (e.args[0], attempts, aconattempts))
if attempts == aconattempts:
wclient.logger.error("Error: %s (dbfile: %s)" % (e.args[0], adbfile))
sleep(aretryinterval)
rows = crs.fetchall()
if con:
con.close
etime = format_timestamp(time())
stime = format_timestamp(time() - awin)
for row in rows:
dtime = format_timestamp(row['timestamp'])
events.append(gen_event_idea_dio(logger = wclient.logger, binaries_path = abinpath, report_binaries = areportbinaries, purge_binaries = apurgebinaries, client_name = aclient_name, anonymised = aanonymised, target_net = aanonymised_net, detect_time = dtime, win_start_time = stime, win_end_time = etime, aggr_win = awin, data = row))
start = time()
ret = wclient.sendEvents(events)
if 'saved' in ret:
wclient.logger.info("%d event(s) successfully delivered in %d seconds" % (ret['saved'], (time() - start)))
if __name__ == "__main__":
main()
{
"warden": "warden_client.cfg",
"name": "cz.cesnet.server.dionaea",
"secret": "",
"anonymised": "no",
"target_net": "195.113.0.0/16",
"dbfile": "/opt/dionaea/var/dionaea/logsql.sqlite",
"binaries_path" : "/opt/dionaea/var/dionaea/binaries",
"report_binaries" : "true",
"con_attempts" : 3,
"con_retry_interval" : 5,
"awin": 5
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment