So I was tasked with developing a way to show customers how Syslog messages are sent to their SIEM. The problem I don't have a SIEM at home :)
I decided to fake it some good buddies over at DC719 recommend some great software(all free of course - Logstash, Filebeat, Logwatch, fluentd). But for me, it was more overkill and I wanted some I can reuse easily on my MacBook for demoing purpose
So I started my Google Search, came across this "gem" called "Tiny Python Syslog Server" - Link
## Tiny Syslog Server in Python. |
## |
## This is a tiny syslog server that is able to receive UDP based syslog |
## entries on a specified port and save them to a file. |
## That's it... it does nothing else... |
## There are a few configuration parameters. |
LOG_FILE = 'youlogfile.log' |
HOST, PORT = "0.0.0.0", 514 |
# |
# NO USER SERVICEABLE PARTS BELOW HERE... |
# |
import logging |
import SocketServer |
logging.basicConfig(level=logging.INFO, format='%(message)s', datefmt='', filename=LOG_FILE, filemode='a') |
class SyslogUDPHandler(SocketServer.BaseRequestHandler): |
def handle(self): |
data = bytes.decode(self.request[0].strip()) |
socket = self.request[1] |
print( "%s : " % self.client_address[0], str(data)) |
logging.info(str(data)) |
if __name__ == "__main__": |
try: |
server = SocketServer.UDPServer((HOST,PORT), SyslogUDPHandler) |
server.serve_forever(poll_interval=0.5) |
except (IOError, SystemExit): |
raise |
except KeyboardInterrupt: |
print ("Crtl+C Pressed. Shutting down.") |
This got me started on then looking how to parse the Syslog file and then send an email (just me some more googling) :)
Found another "gem" from StackOverFlow - Link
import os
import time
def follow(name):
current = open(name, "r")
curino = os.fstat(current.fileno()).st_ino
while True:
while True:
line = current.readline()
if not line:
break
yield line
try:
if os.stat(name).st_ino != curino:
new = open(name, "r")
current.close()
current = new
curino = os.fstat(current.fileno()).st_ino
continue
except IOError:
pass
time.sleep(1)
if __name__ == '__main__':
fname = "test.log"
for l in follow(fname):
print "LINE: {}".format(l)
Here is where I ran into an issue, I was running python3 for the "Tiny Python Syslog Server" and Python 2.x for the Syslog live reader, I was getting confused between versions.
So decided to run everything using Python3 and make one file for everything and also tossed in an email alert using GMail (found this at http://rosettacode.org/wiki/Send_email#Python)
#!/usr/bin/env python3 HOST, PORT = "0.0.0.0", 514 import logging import socketserver import re import smtplib #Send mail Funcation def sendemail(from_addr, to_addr_list, cc_addr_list, subject, message, login, password, smtpserver='smtp.gmail.com:587'): header = 'From: %s\r\n' % from_addr header += 'To: %s\r\n' % ','.join(to_addr_list) header += 'Cc: %s\r\n' % ','.join(cc_addr_list) header += 'Subject: %s\r\n\n' % subject message = header + message server = smtplib.SMTP(smtpserver) server.starttls() server.login(login,password) problems = server.sendmail(from_addr, to_addr_list, message) server.quit() return problems logging.basicConfig(level=logging.INFO, format='%(message)s', datefmt='') # Start listening on port 514 define above and then send email base off # the regex of "p" which is looking for any syslog message with the word "Threat" class SyslogUDPHandler(socketserver.BaseRequestHandler): def handle(self): data = bytes.decode(self.request[0].strip()) socket = self.request[1] p = re.compile(r"Threat") m = p.search( str(data) ) if m: print( "%s : " % self.client_address[0], str(data)) sendemail(from_addr = 'Your SIEM <This email address is being protected from spambots. You need JavaScript enabled to view it.>', to_addr_list = [This email address is being protected from spambots. You need JavaScript enabled to view it.'], cc_addr_list = [''], subject = 'Attack', message = 'Please check your SIEM Server ASAP', login = This email address is being protected from spambots. You need JavaScript enabled to view it.', password = "yourpassword") #logging.info(str(data)) if __name__ == "__main__": try: server = socketserver.UDPServer((HOST,PORT), SyslogUDPHandler) server.serve_forever(poll_interval=0.5) except (IOError, SystemExit): raise except KeyboardInterrupt: print ("Crtl+C Pressed. Shutting down.")
Comments: