Skip to content

Commit

Permalink
chg: [barcode] add and extract barcode object
Browse files Browse the repository at this point in the history
  • Loading branch information
Terrtia committed Nov 5, 2024
1 parent ee576ca commit 79a187b
Show file tree
Hide file tree
Showing 18 changed files with 1,161 additions and 48 deletions.
2 changes: 1 addition & 1 deletion bin/LAUNCH.sh
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ function launching_scripts {
sleep 0.1
screen -S "Script_AIL" -X screen -t "OcrExtractor" bash -c "cd ${AIL_BIN}/modules; ${ENV_PY} ./OcrExtractor.py; read x"
sleep 0.1
screen -S "Script_AIL" -X screen -t "QrCodeReader" bash -c "cd ${AIL_BIN}/modules; ${ENV_PY} ./QrCodeReader.py; read x"
screen -S "Script_AIL" -X screen -t "CodeReader" bash -c "cd ${AIL_BIN}/modules; ${ENV_PY} ./CodeReader.py; read x"
sleep 0.1

# TITLES
Expand Down
17 changes: 9 additions & 8 deletions bin/lib/ail_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,17 @@
r_object = config_loader.get_db_conn("Kvrocks_Objects")
config_loader = None

AIL_OBJECTS = sorted({'chat', 'chat-subchannel', 'chat-thread', 'cookie-name', 'cve', 'cryptocurrency', 'decoded',
'domain', 'dom-hash', 'etag', 'favicon', 'file-name', 'hhhash','item', 'image', 'message', 'ocr',
'pgp', 'qrcode', 'screenshot', 'title', 'user-account', 'username'})
AIL_OBJECTS = sorted({'barcode', 'chat', 'chat-subchannel', 'chat-thread', 'cookie-name', 'cve', 'cryptocurrency',
'decoded', 'domain', 'dom-hash', 'etag', 'favicon', 'file-name', 'hhhash','item', 'image',
'message', 'ocr', 'pgp', 'qrcode', 'screenshot', 'title', 'user-account', 'username'})

AIL_OBJECTS_WITH_SUBTYPES = {'chat', 'chat-subchannel', 'cryptocurrency', 'pgp', 'username', 'user-account'}

# TODO by object TYPE ????
AIL_OBJECTS_CORRELATIONS_DEFAULT = sorted({'chat', 'chat-subchannel', 'chat-thread', 'cve', 'cryptocurrency', 'decoded',
'domain', 'dom-hash', 'favicon', 'file-name', 'item', 'image', 'message',
'ocr', 'pgp', 'qrcode', 'screenshot', 'title', 'user-account', 'username'})
AIL_OBJECTS_CORRELATIONS_DEFAULT = sorted({'barcode', 'chat', 'chat-subchannel', 'chat-thread', 'cve', 'cryptocurrency',
'decoded', 'domain', 'dom-hash', 'favicon', 'file-name', 'item', 'image',
'message', 'ocr', 'pgp', 'qrcode', 'screenshot', 'title', 'user-account',
'username'})

def get_ail_uuid():
ail_uuid = r_serv_db.get('ail:uuid')
Expand Down Expand Up @@ -86,10 +87,10 @@ def get_default_correlation_objects():
return AIL_OBJECTS_CORRELATIONS_DEFAULT

def get_obj_queued():
return ['item', 'image', 'message', 'ocr', 'qrcode'] # screenshot ???
return ['barcode', 'item', 'image', 'message', 'ocr', 'qrcode'] # screenshot ???

def get_objects_tracked():
return ['decoded', 'item', 'pgp', 'message', 'ocr', 'qrcode', 'title']
return ['barcode', 'decoded', 'item', 'pgp', 'message', 'ocr', 'qrcode', 'title']

def get_objects_retro_hunted():
return ['decoded', 'item', 'message']
Expand Down
22 changes: 21 additions & 1 deletion bin/lib/chats_viewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from lib.objects import ChatSubChannels
from lib.objects import ChatThreads
from lib.objects import Messages
from lib.objects.BarCodes import Barcode
from lib.objects.QrCodes import Qrcode
from lib.objects import UsersAccount
from lib.objects import Usernames
Expand Down Expand Up @@ -429,6 +430,12 @@ def get_chat_object_messages_meta(c_messages):
temp_chats[meta['forwarded_from']] = chat.get_meta({'icon'})
else:
meta['forwarded_from'] = temp_chats[meta['forwarded_from']]
if meta['barcodes']:
barcodes = []
for q in meta['barcodes']:
obj = Barcode(q)
barcodes.append({'id': obj.id, 'content': obj.get_content(), 'tags': obj.get_tags()})
meta['qrcodes'] = barcodes
if meta['qrcodes']:
qrcodes = []
for q in meta['qrcodes']:
Expand Down Expand Up @@ -746,6 +753,14 @@ def api_get_chat_service_instance(chat_instance_uuid):
# return chat_instance.get_meta({'chats'}), 200
return chat_instance.get_meta({'chats_with_messages'}), 200

def api_get_chats_selector():
selector = []
for instance_uuid in get_chat_service_instances():
for chat_id in ChatServiceInstance(instance_uuid).get_chats():
chat = Chats.Chat(chat_id, instance_uuid)
selector.append({'id': chat.get_global_id(), 'name': f'{chat.get_chat_instance()}: {chat.get_label()}'})
return selector

def api_get_chat(chat_id, chat_instance_uuid, translation_target=None, nb=-1, page=-1, messages=True):
chat = Chats.Chat(chat_id, chat_instance_uuid)
if not chat.exists():
Expand Down Expand Up @@ -826,10 +841,15 @@ def api_get_message(message_id, translation_target=None):
message = Messages.Message(message_id)
if not message.exists():
return {"status": "error", "reason": "Unknown uuid"}, 404
meta = message.get_meta({'chat', 'content', 'files-names', 'forwarded_from', 'icon', 'images', 'language', 'link', 'parent', 'parent_meta', 'qrcodes', 'reactions', 'thread', 'translation', 'user-account'}, translation_target=translation_target)
meta = message.get_meta({'barcodes', 'chat', 'content', 'files-names', 'forwarded_from', 'icon', 'images', 'language', 'link', 'parent', 'parent_meta', 'qrcodes', 'reactions', 'thread', 'translation', 'user-account'}, translation_target=translation_target)
if 'forwarded_from' in meta:
chat = get_obj_chat_from_global_id(meta['forwarded_from'])
meta['forwarded_from'] = chat.get_meta({'icon'})
barcodes = []
for q in meta['barcodes']:
obj = Barcode(q)
barcodes.append({'id': obj.id, 'content': obj.get_content(), 'tags': obj.get_tags()})
meta['barcodes'] = barcodes
qrcodes = []
for q in meta['qrcodes']:
qr = Qrcode(q)
Expand Down
17 changes: 9 additions & 8 deletions bin/lib/correlations_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,26 +41,27 @@
##################################

CORRELATION_TYPES_BY_OBJ = {
"chat": ["chat-subchannel", "chat-thread", "image", "message", "ocr", "user-account"], # message or direct correlation like cve, bitcoin, ... ???
"barcode": ["chat", "cve", "cryptocurrency", "decoded", "domain", "image", "message", "screenshot"],
"chat": ["barcode", "chat-subchannel", "chat-thread", "image", "message", "ocr", "user-account"], # message or direct correlation like cve, bitcoin, ... ???
"chat-subchannel": ["chat", "chat-thread", "image", "message", "ocr", "user-account"],
"chat-thread": ["chat", "chat-subchannel", "image", "message", "ocr", "user-account"],
"cookie-name": ["domain"],
"cryptocurrency": ["domain", "item", "message", "ocr", "qrcode"],
"cve": ["domain", "item", "message", "ocr", "qrcode"],
"decoded": ["domain", "item", "message", "ocr", "qrcode"],
"domain": ["cve", "cookie-name", "cryptocurrency", "dom-hash", "decoded", "etag", "favicon", "hhhash", "item", "pgp", "title", "screenshot", "username"],
"cryptocurrency": ["barcode", "domain", "item", "message", "ocr", "qrcode"],
"cve": ["barcode", "domain", "item", "message", "ocr", "qrcode"],
"decoded": ["barcode", "domain", "item", "message", "ocr", "qrcode"],
"domain": ["barcode", "cve", "cookie-name", "cryptocurrency", "dom-hash", "decoded", "etag", "favicon", "hhhash", "item", "pgp", "title", "screenshot", "username"],
"dom-hash": ["domain", "item"],
"etag": ["domain"],
"favicon": ["domain", "item"], # TODO Decoded
"file-name": ["chat", "message"],
"hhhash": ["domain"],
"image": ["chat", "chat-subchannel", "chat-thread", "message", "ocr", "qrcode", "user-account"], # TODO subchannel + threads ????
"image": ["barcode", "chat", "chat-subchannel", "chat-thread", "message", "ocr", "qrcode", "user-account"], # TODO subchannel + threads ????
"item": ["cve", "cryptocurrency", "decoded", "domain", "dom-hash", "favicon", "pgp", "screenshot", "title", "username"], # chat ???
"message": ["chat", "chat-subchannel", "chat-thread", "cve", "cryptocurrency", "decoded", "file-name", "image", "ocr", "pgp", "user-account"],
"message": ["barcode", "chat", "chat-subchannel", "chat-thread", "cve", "cryptocurrency", "decoded", "file-name", "image", "ocr", "pgp", "user-account"],
"ocr": ["chat", "chat-subchannel", "chat-thread", "cve", "cryptocurrency", "decoded", "image", "message", "pgp", "user-account"],
"pgp": ["domain", "item", "message", "ocr"],
"qrcode": ["chat", "cve", "cryptocurrency", "decoded", "domain", "image", "message", "screenshot"], # "chat-subchannel", "chat-thread" ?????
"screenshot": ["domain", "item", "qrcode"],
"screenshot": ["barcode", "domain", "item", "qrcode"],
"title": ["domain", "item"],
"user-account": ["chat", "chat-subchannel", "chat-thread", "image", "message", "ocr", "username"],
"username": ["domain", "item", "message", "user-account"],
Expand Down
163 changes: 163 additions & 0 deletions bin/lib/objects/BarCodes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
#!/usr/bin/env python3
# -*-coding:UTF-8 -*

import os
import sys

from hashlib import sha256
from pymisp import MISPObject

sys.path.append(os.environ['AIL_BIN'])
##################################
# Import Project packages
##################################
from lib.objects.abstract_daterange_object import AbstractDaterangeObject, AbstractDaterangeObjects
from lib.ConfigLoader import ConfigLoader
from packages import Date
# from lib.data_retention_engine import update_obj_date, get_obj_date_first

from flask import url_for

config_loader = ConfigLoader()
r_object = config_loader.get_db_conn("Kvrocks_Objects")
r_cache = config_loader.get_redis_conn("Redis_Cache")
baseurl = config_loader.get_config_str("Notifications", "ail_domain")
IMAGE_FOLDER = config_loader.get_files_directory('images')
config_loader = None

# SET x1,y1:x2,y2:x3,y3:x4,y4:extracted_text

class Barcode(AbstractDaterangeObject):
"""
AIL Message Object. (strings)
"""

def __init__(self, id):
super(Barcode, self).__init__('barcode', id)

def get_content(self, r_type='str'):
"""
Returns content
"""
global_id = self.get_global_id()
content = r_cache.get(f'content:{global_id}')
if not content:
content = self._get_field('content')
# Set Cache
if content:
global_id = self.get_global_id()
r_cache.set(f'content:{global_id}', content)
r_cache.expire(f'content:{global_id}', 300)
if r_type == 'str':
return content
elif r_type == 'bytes':
if content:
return content.encode()

def get_date(self): # TODO
return Date.get_today_date_str()

def get_nb_seen(self):
return self.get_nb_correlation('image') + self.get_nb_correlation('screenshot')

def get_source(self): # TODO
"""
Returns source/feeder name
"""
return 'barcode'

def get_basename(self): # TODO
return 'barcode'

def get_link(self, flask_context=False):
if flask_context:
url = url_for('correlation.show_correlation', type=self.type, id=self.id)
else:
url = f'{baseurl}/correlation/show?type={self.type}&id={self.id}'
return url

def get_svg_icon(self): # TODO
return {'style': 'fas', 'icon': '\uf02a', 'color': 'yellow', 'radius': 5}

def get_misp_object(self): # TODO
pass
# obj = MISPObject('instant-message', standalone=True)
# obj_date = self.get_date()
# if obj_date:
# obj.first_seen = obj_date
# else:
# self.logger.warning(
# f'Export error, None seen {self.type}:{self.subtype}:{self.id}, first={obj_date}')
#
# # obj_attrs = [obj.add_attribute('first-seen', value=obj_date),
# # obj.add_attribute('raw-data', value=self.id, data=self.get_raw_content()),
# # obj.add_attribute('sensor', value=get_ail_uuid())]
# obj_attrs = []
# for obj_attr in obj_attrs:
# for tag in self.get_tags():
# obj_attr.add_tag(tag)
# return obj

# options: set of optional meta fields
def get_meta(self, options=None):
"""
:type options: set
"""
if options is None:
options = set()
meta = self._get_meta(options=options)
meta['tags'] = self.get_tags()
meta['content'] = self.get_content()

# optional meta fields
if 'investigations' in options:
meta['investigations'] = self.get_investigations()
if 'link' in options:
meta['link'] = self.get_link(flask_context=True)
if 'icon' in options:
meta['svg_icon'] = self.get_svg_icon()
return meta

def create(self, content, im_obj, tags=[]):
self._set_field('content', content)
if im_obj.type == 'screenshot':
for date in im_obj.get_dates():
self._add(date, None)
else:
self._copy_from(im_obj.type, im_obj.get_id())

for tag in tags:
self.add_tag(tag)
return self.id

# # WARNING: UNCLEAN DELETE /!\ TEST ONLY /!\
def delete(self):
r_object.delete(f'barcode:{self.id}')


def create(content, im_obj, tags=[]):
if content:
obj_id = sha256(content.encode()).hexdigest()
obj = Barcode(obj_id)
if not obj.exists():
obj.create(content, im_obj, tags=tags)
return obj

class Barcodes(AbstractDaterangeObjects):
"""
Barcodes Objects
"""
def __init__(self):
super().__init__('barcode', Barcode)

def sanitize_id_to_search(self, name_to_search):
return name_to_search # TODO


#### API ####
def api_get_barcode(obj_id):
obj = Barcode(obj_id)
if not obj.exists():
return {"status": "error", "reason": "Unknown barcode"}, 404
meta = obj.get_meta({'content', 'icon', 'link'})
return meta, 200
26 changes: 19 additions & 7 deletions bin/lib/objects/Messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,12 @@ def get_images(self):
images.append({'id': obj_id, 'ocr': self._get_image_ocr(obj_id)})
return images

def get_barcodes(self):
barcodes = []
for c in self.get_correlation('barcode').get('barcode', []):
barcodes.append(c[1:])
return barcodes

def get_qrcodes(self):
qrcodes = []
for c in self.get_correlation('qrcode').get('qrcode', []):
Expand Down Expand Up @@ -306,6 +312,8 @@ def get_meta(self, options=None, timestamp=None, translation_target=''):
meta['thread'] = thread
if 'images' in options:
meta['images'] = self.get_images()
if 'barcodes' in options:
meta['barcodes'] = self.get_barcodes()
if 'qrcodes' in options:
meta['qrcodes'] = self.get_qrcodes()
if 'files-names' in options:
Expand Down Expand Up @@ -336,16 +344,20 @@ def get_meta(self, options=None, timestamp=None, translation_target=''):

## Language ##

def get_objs_container(self):
def get_root_obj(self):
return self.get_objs_container(root=True)

def get_objs_container(self, root=False):
objs_containers = set()
# chat
objs_containers.add(self.get_chat())
subchannel = self.get_subchannel()
if subchannel:
objs_containers.add(subchannel)
thread = self.get_current_thread()
if thread:
objs_containers.add(thread)
if not root:
subchannel = self.get_subchannel()
if subchannel:
objs_containers.add(subchannel)
thread = self.get_current_thread()
if thread:
objs_containers.add(thread)
return objs_containers

#- Language -#
Expand Down
3 changes: 3 additions & 0 deletions bin/lib/objects/ail_objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

from lib import chats_viewer

from lib.objects import BarCodes
from lib.objects import Chats
from lib.objects import ChatSubChannels
from lib.objects import ChatThreads
Expand Down Expand Up @@ -102,6 +103,8 @@ def get_object(obj_type, subtype, obj_id):
return Messages.Message(obj_id)
elif obj_type == 'ocr':
return Ocrs.Ocr(obj_id)
elif obj_type == 'barcode':
return BarCodes.Barcode(obj_id)
elif obj_type == 'qrcode':
return QrCodes.Qrcode(obj_id)
elif obj_type == 'screenshot':
Expand Down
Loading

0 comments on commit 79a187b

Please sign in to comment.