Skip to content

Commit

Permalink
Merge pull request #165 from ninoseki/update-oleid-based-analysis
Browse files Browse the repository at this point in the history
feat: update OleID based analysis
  • Loading branch information
ninoseki committed May 31, 2022
2 parents f528077 + acc1f32 commit 3134b96
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 5 deletions.
17 changes: 16 additions & 1 deletion app/factories/oldid.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,15 @@ def _parse_as_ole_file(self, attachment: Attachment) -> List[Detail]:
oleid = OleID(data)
file_info = f"{attachment.filename}({attachment.hash_.sha256})"
if oleid.has_vba_macros():
key = "vba_macros"
key = "vba"
description = f"{file_info} contains VBA macros."
details.append(Detail(key=key, description=description))

if oleid.has_xlm_macros():
key = "xlm"
description = f"{file_info} contains XLM macros."
details.append(Detail(key=key, description=description))

if oleid.has_flash_objects():
key = "flash"
description = f"{file_info} contains Flash objects."
Expand All @@ -34,6 +39,16 @@ def _parse_as_ole_file(self, attachment: Attachment) -> List[Detail]:
description = f"{file_info} is encrypted."
details.append(Detail(key=key, description=description))

if oleid.has_external_relationships():
key = "ext_rels"
description = f"{file_info} contains external relationships."
details.append(Detail(key=key, description=description))

if oleid.has_object_pool():
key = "ObjectPool"
description = f"{file_info} contains an ObjectPool stream."
details.append(Detail(key=key, description=description))

return details

def to_model(self) -> Verdict:
Expand Down
45 changes: 41 additions & 4 deletions app/services/oleid.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,25 @@
from typing import Optional
from typing import Any, Optional

import oletools.oleid
from olefile import isOleFile


def is_truthy(v: Any) -> bool:
if v is None:
return False

if isinstance(v, bool):
return v is True

if isinstance(v, int):
return v > 0

try:
return str(v).upper() == "YES"
except Exception:
return False


class OleID:
def __init__(self, data: bytes):
self.oid: Optional[oletools.oleid.OleID] = None
Expand All @@ -17,18 +33,39 @@ def is_encrypted(self) -> bool:
return False

encrypted = self.oid.get_indicator("encrypted")
return encrypted is not None and encrypted.value is True
return is_truthy(encrypted.value)

def has_vba_macros(self) -> bool:
if self.oid is None:
return False

macros = self.oid.get_indicator("vba")
return macros is not None and macros.value == "Yes"
return is_truthy(macros.value)

def has_xlm_macros(self) -> bool:
if self.oid is None:
return False

macros = self.oid.get_indicator("xlm")
return is_truthy(macros.value)

def has_flash_objects(self) -> bool:
if self.oid is None:
return False

flash = self.oid.get_indicator("flash")
return flash is not None and flash.value > 0
return is_truthy(flash.value)

def has_external_relationships(self) -> bool:
if self.oid is None:
return False

flash = self.oid.get_indicator("ext_rels")
return is_truthy(flash.value)

def has_object_pool(self) -> bool:
if self.oid is None:
return False

flash = self.oid.get_indicator("ObjectPool")
return is_truthy(flash.value)

0 comments on commit 3134b96

Please sign in to comment.