mirror of https://github.com/CIRCL/AIL-framework
140 lines
3.9 KiB
Python
Executable File
140 lines
3.9 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# -*-coding:UTF-8 -*
|
|
"""
|
|
Base64 module
|
|
|
|
Dectect Base64 and decode it
|
|
"""
|
|
import time
|
|
import os
|
|
import datetime
|
|
|
|
from pubsublogger import publisher
|
|
|
|
from Helper import Process
|
|
from packages import Paste
|
|
|
|
import re
|
|
import base64
|
|
from hashlib import sha1
|
|
import magic
|
|
import json
|
|
|
|
import signal
|
|
|
|
class TimeoutException(Exception):
|
|
pass
|
|
|
|
def timeout_handler(signum, frame):
|
|
raise TimeoutException
|
|
|
|
signal.signal(signal.SIGALRM, timeout_handler)
|
|
|
|
|
|
def search_base64(content, message):
|
|
find = False
|
|
base64_list = re.findall(regex_base64, content)
|
|
if(len(base64_list) > 0):
|
|
|
|
for b64 in base64_list:
|
|
if len(b64) >= 40 :
|
|
decode = base64.b64decode(b64)
|
|
|
|
type = magic.from_buffer(decode, mime=True)
|
|
#print(type)
|
|
#print(decode)
|
|
|
|
find = True
|
|
hash = sha1(decode).hexdigest()
|
|
|
|
data = {}
|
|
data['name'] = hash
|
|
data['date'] = datetime.datetime.now().strftime("%d/%m/%y")
|
|
data['origin'] = message
|
|
data['estimated type'] = type
|
|
json_data = json.dumps(data)
|
|
|
|
save_base64_as_file(decode, type, hash, json_data)
|
|
print('found {} '.format(type))
|
|
|
|
if(find):
|
|
publisher.warning('base64 decoded')
|
|
#Send to duplicate
|
|
p.populate_set_out(message, 'Duplicate')
|
|
#send to Browse_warning_paste
|
|
msg = ('base64;{}'.format(message))
|
|
p.populate_set_out( msg, 'alertHandler')
|
|
|
|
msg = 'infoleak:automatic-detection="base64";{}'.format(message)
|
|
p.populate_set_out(msg, 'Tags')
|
|
|
|
def save_base64_as_file(decode, type, hash, json_data):
|
|
|
|
filename_b64 = os.path.join(os.environ['AIL_HOME'],
|
|
p.config.get("Directories", "base64"), type, hash[:2], hash)
|
|
|
|
filename_json = os.path.join(os.environ['AIL_HOME'],
|
|
p.config.get("Directories", "base64"), type, hash[:2], hash + '.json')
|
|
|
|
dirname = os.path.dirname(filename_b64)
|
|
if not os.path.exists(dirname):
|
|
os.makedirs(dirname)
|
|
|
|
with open(filename_b64, 'wb') as f:
|
|
f.write(decode)
|
|
|
|
with open(filename_json, 'w') as f:
|
|
f.write(json_data)
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
# If you wish to use an other port of channel, do not forget to run a subscriber accordingly (see launch_logs.sh)
|
|
# Port of the redis instance used by pubsublogger
|
|
publisher.port = 6380
|
|
# Script is the default channel used for the modules.
|
|
publisher.channel = 'Script'
|
|
|
|
# Section name in bin/packages/modules.cfg
|
|
config_section = 'Base64'
|
|
|
|
# Setup the I/O queues
|
|
p = Process(config_section)
|
|
max_execution_time = p.config.getint("Base64", "max_execution_time")
|
|
|
|
# Sent to the logging a description of the module
|
|
publisher.info("Base64 started")
|
|
|
|
regex_base64 = '(?:[A-Za-z0-9+/]{4}){2,}(?:[A-Za-z0-9+/]{2}[AEIMQUYcgkosw048]=|[A-Za-z0-9+/][AQgw]==)'
|
|
re.compile(regex_base64)
|
|
|
|
# Endless loop getting messages from the input queue
|
|
while True:
|
|
# Get one message from the input queue
|
|
message = p.get_from_set()
|
|
if message is None:
|
|
|
|
publisher.debug("{} queue is empty, waiting".format(config_section))
|
|
time.sleep(1)
|
|
continue
|
|
|
|
filename = message
|
|
paste = Paste.Paste(filename)
|
|
|
|
signal.alarm(max_execution_time)
|
|
try:
|
|
# Do something with the message from the queue
|
|
#print(filename)
|
|
content = paste.get_p_content()
|
|
search_base64(content,message)
|
|
|
|
# (Optional) Send that thing to the next queue
|
|
#p.populate_set_out(something_has_been_done)
|
|
|
|
except TimeoutException:
|
|
print ("{0} processing timeout".format(paste.p_path))
|
|
continue
|
|
else:
|
|
signal.alarm(0)
|