-
Notifications
You must be signed in to change notification settings - Fork 57
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
π version 1.2.0 π added hachoir to deps π added pyexiftool to deps βΉοΈ loop_list and loop_dict now only uses string callbacks βΉοΈ minor changes π updated docs β from_hex method added β get_mime method added β get_metadata method added β embedded_files method added β get_exif method added
- Loading branch information
1 parent
afb43fb
commit 92005ce
Showing
10 changed files
with
223 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
__version__ = "1.1.0" # pragma: no cover | ||
__version__ = "1.2.0" # pragma: no cover | ||
__author__ = "Hapsida @securisec" # pragma: no cover |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,121 @@ | ||
import io | ||
import os | ||
import logging | ||
import pathlib | ||
import tempfile | ||
import pprint | ||
|
||
import exiftool | ||
from hachoir.core.log import Logger | ||
from hachoir.parser import createParser | ||
from hachoir.metadata import extractMetadata | ||
from hachoir.subfile.search import SearchSubfile | ||
from hachoir.stream import FileInputStream | ||
from hachoir.metadata.metadata_item import QUALITY_BEST | ||
import hachoir.core.config as hachoir_config | ||
|
||
from ..core import ChepyCore, ChepyDecorators | ||
|
||
|
||
class Forensics(ChepyCore): | ||
pass | ||
hachoir_config.quiet = True | ||
|
||
def _temp_file(self) -> str: | ||
"""Get a random temporary file. os.urandom is used here | ||
because of permission issues using tempfile on Windows. | ||
The state is then saved in this temp file. | ||
Returns: | ||
str: cross platform temporary file | ||
""" | ||
temp_file = str(pathlib.Path(tempfile.gettempdir()) / os.urandom(24).hex()) | ||
with open(temp_file, "wb") as f: | ||
f.write(self._convert_to_bytes()) | ||
return temp_file | ||
|
||
@ChepyDecorators.call_stack | ||
def get_mime(self, set_state: bool = False): | ||
"""Detect the file type based on magic. | ||
Args: | ||
set_state (bool, optional): Save the output to state. Defaults to False. | ||
Returns: | ||
Chepy: The Chepy object. | ||
""" | ||
filename = self._temp_file() | ||
parser = createParser(filename) | ||
if not parser: | ||
mimetype = "text/plain" | ||
logging.info(mimetype) | ||
else: | ||
mimetype = str(parser.mime_type) | ||
logging.info(mimetype) | ||
if set_state: | ||
self.state = mimetype | ||
pathlib.Path(filename).unlink() | ||
return self | ||
|
||
@ChepyDecorators.call_stack | ||
def get_metadata(self, set_state: bool = False): | ||
"""Get metadata from a file | ||
Args: | ||
set_state (bool, optional): Save the output to state. Defaults to False. | ||
Returns: | ||
Chepy: The Chepy object. | ||
""" | ||
filename = self._temp_file() | ||
filename, realname = filename, filename | ||
parser = createParser(filename, realname) | ||
if not parser: # pragma: no cover | ||
logging.warning("Unable to parse file") | ||
|
||
metadata = extractMetadata(parser, quality=QUALITY_BEST) | ||
|
||
if metadata is not None: | ||
meta = metadata.exportDictionary()["Metadata"] | ||
if set_state: | ||
self.state = meta | ||
else: # pragma: no cover | ||
logging.info(pprint.pformat(meta)) | ||
pathlib.Path(filename).unlink() | ||
return self | ||
|
||
@ChepyDecorators.call_stack | ||
def embedded_files(self, extract_path: str = None): | ||
"""Search for embedded files and extract them | ||
This method does not change the state. | ||
Args: | ||
extract_path (str, optional): Path to extract files to. Defaults to None. | ||
Returns: | ||
Chepy: The Chepy object. | ||
""" | ||
filename = self._temp_file() | ||
inp = FileInputStream(filename) | ||
subfile = SearchSubfile(inp) | ||
if extract_path is not None: # pragma: no cover | ||
subfile.setOutput(extract_path) | ||
subfile.loadParsers() | ||
subfile.main() | ||
pathlib.Path(filename).unlink() | ||
return self | ||
|
||
@ChepyDecorators.call_stack | ||
def get_exif(self): # pragma: no cover | ||
"""Extract EXIF data from a file | ||
Returns: | ||
Chepy: The Chepy object. | ||
""" | ||
filename = self._temp_file() | ||
with exiftool.ExifTool() as et: | ||
exif = et.get_metadata(filename) | ||
if exif: | ||
self.state = exif | ||
pathlib.Path(filename).unlink() | ||
return self |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
from chepy import Chepy | ||
|
||
|
||
def test_detect_file_type(): | ||
Chepy("tests/files/hello").load_file().get_mime( | ||
set_state=True | ||
).o == "application/x-executable" | ||
assert True | ||
Chepy("tests/files/encoding").load_file().get_mime( | ||
set_state=True | ||
).o == "text/plain" | ||
assert True | ||
|
||
|
||
def test_get_metadata(): | ||
assert Chepy("logo.png").load_file().get_metadata(set_state=True).o == { | ||
"Bits/pixel": "32", | ||
"Compression": "deflate", | ||
"Compression rate": "117.2x", | ||
"Creation date": "2019-11-19 02:46:07", | ||
"Endianness": "Big endian", | ||
"Image DPI height": "3780 DPI", | ||
"Image DPI width": "3780 DPI", | ||
"Image height": "1080 pixels", | ||
"Image width": "1080 pixels", | ||
"MIME type": "image/png", | ||
"Pixel format": "RGBA", | ||
} | ||
|
||
|
||
def test_embedded(): | ||
Chepy("logo.png").load_file().embedded_files() | ||
assert True |