Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
F
fact_pdf_report
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
fact-depend
fact_pdf_report
Commits
c34caf96
Commit
c34caf96
authored
Apr 04, 2019
by
dorp
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
larger refactoring
parent
6077c308
Hide whitespace changes
Inline
Side-by-side
Showing
28 changed files
with
132 additions
and
187 deletions
+132
-187
.gitignore
.gitignore
+1
-0
pytest.ini
pytest.ini
+2
-3
filter.py
src/jinja_filters/filter.py
+10
-11
code_generation.py
src/latex_code_generation/code_generation.py
+67
-85
pdf_generator.py
src/pdf_generator.py
+2
-2
rest.py
src/rest_import/rest.py
+7
-19
base64_decoder.tex
src/templates/default/base64_decoder.tex
+0
-0
binwalk.tex
src/templates/default/binwalk.tex
+0
-0
cpu_architecture.tex
src/templates/default/cpu_architecture.tex
+0
-0
crypto_material.tex
src/templates/default/crypto_material.tex
+0
-0
exploit_mitigations.tex
src/templates/default/exploit_mitigations.tex
+0
-0
file_hashes_template.tex
src/templates/default/file_hashes_template.tex
+0
-32
file_type.tex
src/templates/default/file_type.tex
+0
-0
init_systems.tex
src/templates/default/init_systems.tex
+0
-0
ip_and_uri_finder.tex
src/templates/default/ip_and_uri_finder.tex
+0
-0
known_vulnerabilities.tex
src/templates/default/known_vulnerabilities.tex
+0
-0
main.tex
src/templates/default/main.tex
+0
-0
malware_scanner.tex
src/templates/default/malware_scanner.tex
+0
-0
meta_data_template.tex
src/templates/default/meta_data_template.tex
+0
-24
printable_strings.tex
src/templates/default/printable_strings.tex
+0
-0
software_components.tex
src/templates/default/software_components.tex
+17
-0
source_code_analysis.tex
src/templates/default/source_code_analysis.tex
+17
-0
string_evaluator.tex
src/templates/default/string_evaluator.tex
+0
-0
unpacker.tex
src/templates/default/unpacker.tex
+0
-0
users_and_passwords.tex
src/templates/default/users_and_passwords.tex
+0
-0
fact_logo.png
src/templates/fact_logo.png
+0
-0
test_latex_code_generation.py
src/test/integration/test_latex_code_generation.py
+2
-2
test_code_generation.py
src/test/unit/test_code_generation.py
+7
-9
No files found.
.gitignore
View file @
c34caf96
.project
.pydevproject
.idea
# Byte-compiled / optimized / DLL files
__pycache__/
...
...
pytest.ini
View file @
c34caf96
[pytest]
addopts
=
--pep8 -v
--cov=./
addopts
=
--pep8 -v
pep8ignore
=
*.py E501
\ No newline at end of file
*.py E501
src/jinja_filters/filter.py
View file @
c34caf96
#from common_helper_files import human_readable_file_size
from
time
import
localtime
,
strftime
from
base64
import
decodebytes
from
time
import
localtime
,
strftime
from
common_helper_files
import
human_readable_file_size
'''
def byte_number_filter(i, verbose=True):
if isinstance(i, int) or isinstance(i, float):
def
byte_number_filter
(
number
,
verbose
=
True
):
if
isinstance
(
number
,
int
)
or
isinstance
(
number
,
float
):
if
verbose
:
return '{} ({})'.format(human_readable_file_size(i), format(i, ',d') + ' bytes')
else:
return human_readable_file_size(i)
else:
return 'not available'
'''
return
'{} ({})'
.
format
(
human_readable_file_size
(
int
(
number
)),
format
(
number
,
',d'
)
+
' bytes'
)
return
human_readable_file_size
(
int
(
number
))
return
'not available'
def
nice_unix_time
(
unix_time_stamp
):
'''
...
...
src/latex_code_generation/code_generation.py
View file @
c34caf96
import
jinja2
import
logging
import
argparse
import
os
from
pathlib
import
Path
from
src.rest_import.rest
import
*
# from web_interface.filter import byte_number_filter, nice_unix_time, nice_number_filter
from
src.jinja_filters.filter
import
*
from
tempfile
import
TemporaryDirectory
import
shutil
import
jinja2
from
common_helper_process
import
execute_shell_command_get_return_code
from
jinja_filters.filter
import
(
nice_unix_time
,
nice_number_filter
,
filter_latex_special_chars
,
count_elements_in_list
,
convert_base64_to_png_filter
,
check_if_list_empty
,
split_hash
,
split_output_lines
,
byte_number_filter
)
from
rest_import.rest
import
create_request_url
,
request_firmware_data
def
_set_jinja_env
(
templates_to_use
=
'default'
):
...
...
@@ -25,27 +31,30 @@ def _set_jinja_env(templates_to_use='default'):
)
def
_setup_jinja_filters
():
jinja_env
=
_set_jinja_env
()
# jinja_env.filters['number_format'] = byte_number_filter
jinja_env
.
filters
[
'nice_unix_time'
]
=
nice_unix_time
jinja_env
.
filters
[
'nice_number'
]
=
nice_number_filter
jinja_env
.
filters
[
'filter_chars'
]
=
filter_latex_special_chars
jinja_env
.
filters
[
'elements_count'
]
=
count_elements_in_list
jinja_env
.
filters
[
'base64_to_png'
]
=
convert_base64_to_png_filter
jinja_env
.
filters
[
'check_list'
]
=
check_if_list_empty
jinja_env
.
filters
[
'split_hash'
]
=
split_hash
jinja_env
.
filters
[
'split_output_lines'
]
=
split_output_lines
def
_setup_jinja_filters
(
environment
):
environment
.
filters
[
'number_format'
]
=
byte_number_filter
environment
.
filters
[
'nice_unix_time'
]
=
nice_unix_time
environment
.
filters
[
'nice_number'
]
=
nice_number_filter
environment
.
filters
[
'filter_chars'
]
=
filter_latex_special_chars
environment
.
filters
[
'elements_count'
]
=
count_elements_in_list
environment
.
filters
[
'base64_to_png'
]
=
convert_base64_to_png_filter
environment
.
filters
[
'check_list'
]
=
check_if_list_empty
environment
.
filters
[
'split_hash'
]
=
split_hash
environment
.
filters
[
'split_output_lines'
]
=
split_output_lines
def
generate_meta_data_code
(
environment
,
meta_data
):
template
=
environment
.
get_template
(
'{}.tex'
.
format
(
'meta_data'
))
return
template
.
render
(
meta_data
=
meta_data
)
def
generate_code
(
analysis_dict
,
output_path
):
jinja_env
=
_set_jinja_env
()
_render_template
(
analysis_dict
,
jinja_env
,
'meta_data'
)
def
generate_analysis_codes
(
environment
,
analysis
):
return
[(
'{}.tex'
.
format
(
analysis_plugin
),
_render_analysis_result
(
analysis
[
analysis_plugin
],
environment
,
analysis_plugin
))
for
analysis_plugin
in
analysis
]
def
_render_template
(
data
,
jinja_env
,
template
):
output
=
jinja_env
.
get_template
(
'{}.tex'
.
format
(
template
))
return
output
.
render
(
analysis
=
data
[
'analysis'
],
meta_data
=
data
[
'meta_data'
])
def
_render_analysis_result
(
analysis
,
environment
,
analysis_plugin
):
template
=
environment
.
get_template
(
'{}.tex'
.
format
(
analysis_plugin
))
return
template
.
render
(
selected_analysis
=
analysis
)
def
_create_tex_files
(
analysis_dict
,
jinja_env
):
...
...
@@ -53,71 +62,45 @@ def _create_tex_files(analysis_dict, jinja_env):
module_list
.
append
(
'meta_data'
)
for
module
in
module_list
:
try
:
_render_
template
(
analysis_dict
,
jinja_env
,
module
)
_render_
analysis_result
(
analysis_dict
,
jinja_env
,
module
)
except
Exception
as
e
:
logging
.
error
(
'Could not generate tex file: {} -> {}'
.
format
(
type
(
Exception
),
e
))
def
_write_file
(
raw_data
,
file_path
):
with
open
(
file_path
,
'w'
)
as
fp
:
fp
.
write
(
raw_data
)
def
create_report_filename
(
meta_data
):
main_tex_filename
=
meta_data
[
'device_name'
]
+
"_analysis_report.pdf"
main_tex_filename
=
main_tex_filename
.
replace
(
" "
,
"_"
)
return
main_tex_filename
.
replace
(
"/"
,
"__"
)
def
_copy_fact_image
(
target
):
shutil
.
copy
(
Path
(
__file__
)
.
parent
.
parent
/
'templates'
/
'fact_logo.png'
,
Path
(
target
)
/
'fact_logo.png'
)
def
create_pdf_report
(
meta_data
):
main_tex_filename
=
meta_data
[
'device_name'
]
+
"_Analysis_Report.tex"
main_tex_filename
=
main_tex_filename
.
replace
(
" "
,
"_"
)
main_tex_filename
=
main_tex_filename
.
replace
(
"/"
,
"__"
)
os
.
system
(
"env buf_size=1000000 pdflatex "
+
main_tex_filename
)
def
delete_unnecessary_files
():
dir
=
"./"
dir_content
=
os
.
listdir
(
dir
)
for
file
in
dir_content
:
if
file
.
endswith
(
".tex"
):
os
.
remove
(
os
.
path
.
join
(
dir
,
file
))
elif
file
.
endswith
(
".log"
):
os
.
remove
(
os
.
path
.
join
(
dir
,
file
))
elif
file
.
endswith
(
".aux"
):
os
.
remove
(
os
.
path
.
join
(
dir
,
file
))
elif
os
.
path
.
splitext
(
os
.
path
.
basename
(
file
))[
0
]
==
"entropy_analysis_graph"
:
os
.
remove
(
os
.
path
.
join
(
dir
,
"entropy_analysis_graph.png"
))
if
__name__
==
"__main__"
:
argparser
=
argparse
.
ArgumentParser
(
description
=
'PDF Genearator for the Firmware Analysis and Comparison Tool (FACT)'
)
argparser
.
add_argument
(
'-s'
,
'--summaries'
,
default
=
False
,
help
=
'Create a PDF report including summaries'
,
dest
=
"summary"
,
action
=
"store_false"
)
argparser
.
add_argument
(
'-uid'
,
'--uid'
,
help
=
'firmware analysis UID'
,
dest
=
"uid"
)
args
=
argparser
.
parse_args
()
'''
if args.verbose:
logging.basicConfig(level=logging.INFO, stream=sys.stdout)
else:
logging.basicConfig(level=logging.WARNING, stream=sys.stdout)
'''
# request_url = create_request_url(args.uid)
request_url
=
create_request_url
()
firmware_dict
=
get_firmware
(
request_url
)
firmware_meta_data
=
get_firmware_meta_data
(
firmware_dict
)
firmware_analyses
=
get_firmware_analyses
(
firmware_dict
)
_set_jinja_env
()
_setup_jinja_filters
()
# create_pdf_report(firmware_meta_data)
delete_unnecessary_files
()
'''
if args.summary:
pass
else:
setup_jinja_filters()
create_main_tex(meta_data, analysis)
create_meta_tex(meta_data)
create_analysis_texs_with_summary(analysis)
create_pdf_report(meta_data)
delete_generated_files()
print("Analysis report generated successfully.")
'''
\ No newline at end of file
def
main
(
firmware_uid
=
"bab8d95fc42176abc9126393b6035e4012ebccc82c91e521b91d3bcba4832756_3801088"
):
request_url
=
create_request_url
(
firmware_uid
)
firmware_analyses
,
firmware_meta_data
=
request_firmware_data
(
request_url
)
jinja_environment
=
_set_jinja_env
()
_setup_jinja_filters
(
environment
=
jinja_environment
)
with
TemporaryDirectory
()
as
tmp_dir
:
Path
(
tmp_dir
,
'meta.tex'
)
.
write_text
(
generate_meta_data_code
(
environment
=
jinja_environment
,
meta_data
=
firmware_meta_data
))
for
filename
,
result_code
in
generate_analysis_codes
(
environment
=
jinja_environment
,
analysis
=
firmware_analyses
):
Path
(
tmp_dir
,
filename
)
.
write_text
(
result_code
)
# main_template_code = Path(Path(__file__).parent.parent, 'templates', 'default', 'main.tex').read_text()
template
=
jinja_environment
.
get_template
(
'main.tex'
)
main_code
=
template
.
render
(
analysis
=
firmware_analyses
,
meta_data
=
firmware_meta_data
)
Path
(
tmp_dir
,
'main.tex'
)
.
write_text
(
main_code
)
pdf_filename
=
create_report_filename
(
firmware_meta_data
)
_copy_fact_image
(
tmp_dir
)
current_dir
=
os
.
getcwd
()
os
.
chdir
(
tmp_dir
)
output
,
return_code
=
execute_shell_command_get_return_code
(
'env buf_size=1000000 pdflatex main.tex'
)
os
.
chdir
(
current_dir
)
shutil
.
move
(
Path
(
tmp_dir
,
'main.pdf'
),
Path
(
'.'
,
pdf_filename
))
src/pdf_generator.py
View file @
c34caf96
...
...
@@ -71,10 +71,10 @@ def _load_config(args):
if
__name__
==
'__main__'
:
args
=
_setup_argparser
()
print
(
args
.
config_file
)
config
=
_load_config
(
args
)
_setup_logging
(
config
,
args
.
debug
)
logging
.
info
(
args
.
config_file
)
# insert your program here
# insert your program here
sys
.
exit
()
src/rest_import/rest.py
View file @
c34caf96
import
json
import
requests
def
create_request_url
():
host
=
"http://127.0.0.1:5000"
path
=
"/rest/firmware/"
# firmware_uid = cmd_arg
firmware_uid
=
"bab8d95fc42176abc9126393b6035e4012ebccc82c91e521b91d3bcba4832756_3801088"
rest_url
=
host
+
path
+
firmware_uid
return
rest_url
def
create_request_url
(
firmware_uid
):
base_url
=
'http://127.0.0.1:5000/rest/firmware/'
return
'{}{}'
.
format
(
base_url
,
firmware_uid
)
def
get_firmware
(
request_url
):
def
request_firmware_data
(
request_url
):
response
=
requests
.
get
(
request_url
)
firmware_data
=
response
.
text
firmware_dict
=
json
.
loads
(
firmware_data
)
return
firmware_dict
[
'firmware'
]
def
get_firmware_analyses
(
firmware_dict
):
return
firmware_dict
[
'analysis'
]
firmware_data
=
response
.
json
()
def
get_firmware_meta_data
(
firmware_dict
):
return
firmware_dict
[
'meta_data'
]
\ No newline at end of file
return
firmware_data
[
'firmware'
][
'analysis'
],
firmware_data
[
'firmware'
][
'meta_data'
]
src/templates/default/base64_decoder
_template
.tex
→
src/templates/default/base64_decoder.tex
View file @
c34caf96
File moved
src/templates/default/binwalk
_template
.tex
→
src/templates/default/binwalk.tex
View file @
c34caf96
File moved
src/templates/default/cpu_architecture
_template
.tex
→
src/templates/default/cpu_architecture.tex
View file @
c34caf96
File moved
src/templates/default/crypto_material
_template
.tex
→
src/templates/default/crypto_material.tex
View file @
c34caf96
File moved
src/templates/default/exploit_mitigations
_template
.tex
→
src/templates/default/exploit_mitigations.tex
View file @
c34caf96
File moved
src/templates/default/file_hashes_template.tex
deleted
100644 → 0
View file @
6077c308
\begin{tabular}
{
|p
{
3cm
}
|p
{
11.5cm
}
|
}
\hline
Time of Analysis
&
\VAR
{
selected
_
analysis['analysis
_
date'] | nice
_
unix
_
time
}
\\
\hline
Plugin Version
&
\VAR
{
selected
_
analysis['plugin
_
version']
}
\\
\hline
imphash
&
\VAR
{
selected
_
analysis['imphash']
}
\\
\hline
md5
&
\VAR
{
selected
_
analysis['md5']
}
\\
\hline
ripemd160
&
\VAR
{
selected
_
analysis['ripemd160']
}
\\
\hline
sha1
&
\VAR
{
selected
_
analysis['sha1']
}
\\
\hline
sha256
&
\VAR
{
selected
_
analysis['sha256']
}
\\
\hline
sha512
&
\VAR
{
selected
_
analysis['sha512'] | split
_
hash
}
\\
\hline
ssdeep
&
\VAR
{
selected
_
analysis['ssdeep'] | split
_
hash
}
\\
\hline
whirpool
&
\VAR
{
selected
_
analysis['whirlpool'] | split
_
hash
}
\\
\hline
\end{tabular}
src/templates/default/file_type
_template
.tex
→
src/templates/default/file_type.tex
View file @
c34caf96
File moved
src/templates/default/init_systems
_template
.tex
→
src/templates/default/init_systems.tex
View file @
c34caf96
File moved
src/templates/default/ip_and_uri_finder
_template
.tex
→
src/templates/default/ip_and_uri_finder.tex
View file @
c34caf96
File moved
src/templates/default/
software_components_template
.tex
→
src/templates/default/
known_vulnerabilities
.tex
View file @
c34caf96
File moved
src/templates/default/main
_template
.tex
→
src/templates/default/main.tex
View file @
c34caf96
File moved
src/templates/default/malware_scanner
_template
.tex
→
src/templates/default/malware_scanner.tex
View file @
c34caf96
File moved
src/templates/default/meta_data_template.tex
deleted
100644 → 0
View file @
6077c308
\begin{tabular}
{
|p
{
3cm
}
|p
{
11.5cm
}
|
}
\hline
HID
&
\VAR
{
meta
_
data['hid']
}
\\
\hline
Device Name
&
\VAR
{
meta
_
data['device
_
name']
}
\\
\hline
Vendor
&
\VAR
{
meta
_
data['vendor']
}
\\
\hline
Device Class
&
\VAR
{
meta
_
data['device
_
class']
}
\\
\hline
Version
&
\VAR
{
meta
_
data['version']
}
\\
\hline
Release Date
&
\VAR
{
meta
_
data['release
_
date']
}
\\
\hline
Size
&
\VAR
{
meta
_
data['size'] | number
_
format
}
\\
\hline
\end{tabular}
\ No newline at end of file
src/templates/default/printable_strings
_template
.tex
→
src/templates/default/printable_strings.tex
View file @
c34caf96
File moved
src/templates/default/software_components.tex
0 → 100644
View file @
c34caf96
\begin{longtable}
{
|p
{
3cm
}
|p
{
11.5cm
}
|
}
\hline
Time of Analysis
&
\VAR
{
selected
_
analysis['analysis
_
date'] | nice
_
unix
_
time
}
\\
\hline
Plugin Version
&
\VAR
{
selected
_
analysis['plugin
_
version']
}
\\
\hline
\BLOCK
{
if selected
_
analysis['summary']
}
Summary
\BLOCK
{
for selected
_
summary in selected
_
analysis['summary']
}
&
\VAR
{
selected
_
summary | filter
_
chars
}
\\
\BLOCK
{
endfor
}
\hline
\BLOCK
{
endif
}
\end{longtable}
\ No newline at end of file
src/templates/default/source_code_analysis.tex
0 → 100644
View file @
c34caf96
\begin{longtable}
{
|p
{
3cm
}
|p
{
11.5cm
}
|
}
\hline
Time of Analysis
&
\VAR
{
selected
_
analysis['analysis
_
date'] | nice
_
unix
_
time
}
\\
\hline
Plugin Version
&
\VAR
{
selected
_
analysis['plugin
_
version']
}
\\
\hline
\BLOCK
{
if selected
_
analysis['summary']
}
Summary
\BLOCK
{
for selected
_
summary in selected
_
analysis['summary']
}
&
\VAR
{
selected
_
summary | filter
_
chars
}
\\
\BLOCK
{
endfor
}
\hline
\BLOCK
{
endif
}
\end{longtable}
\ No newline at end of file
src/templates/default/string_evaluator
_template
.tex
→
src/templates/default/string_evaluator.tex
View file @
c34caf96
File moved
src/templates/default/unpacker
_template
.tex
→
src/templates/default/unpacker.tex
View file @
c34caf96
File moved
src/templates/default/users_and_passwords
_template
.tex
→
src/templates/default/users_and_passwords.tex
View file @
c34caf96
File moved
src/templates/fact_logo.png
0 → 100644
View file @
c34caf96
69.2 KB
src/test/integration/test_latex_code_generation.py
View file @
c34caf96
from
tempfile
import
TemporaryDirectory
from
pathlib
import
Path
from
..data.test_dict
import
test_dict
from
latex_code_generation.code_generation
import
generate_code
from
latex_code_generation.code_generation
import
generate_
meta_data_
code
def
test_latex_code_generation
():
output_dir
=
TemporaryDirectory
()
main_tex_path
=
Path
(
output_dir
.
name
,
'main.tex'
)
generate_code
(
test_dict
,
Path
(
output_dir
.
name
))
generate_
meta_data_
code
(
test_dict
,
Path
(
output_dir
.
name
))
assert
main_tex_path
.
exists
()
src/test/unit/test_
generate_code
.py
→
src/test/unit/test_
code_generation
.py
View file @
c34caf96
from
tempfile
import
TemporaryDirectory
from
pathlib
import
Path
from
latex_code_generation.code_generation
import
_set_jinja_env
,
_render_
template
,
_write_file
,
_create_tex_files
from
latex_code_generation.code_generation
import
_set_jinja_env
,
_render_
analysis_result
,
_create_tex_files
,
main
def
test_render_template
():
test_data
=
{
'meta_data'
:
'123'
,
'analysis'
:
'456'
}
jinja_env
=
_set_jinja_env
(
templates_to_use
=
'test'
)
output
=
_render_
template
(
test_data
,
jinja_env
,
'render_test'
)
output
=
_render_
analysis_result
(
test_data
,
jinja_env
,
'render_test'
)
assert
output
==
'Test 123 - 456'
def
test_write_file
():
tmp_dir
=
TemporaryDirectory
()
file_path
=
Path
(
tmp_dir
.
name
,
'test.tex'
)
_write_file
(
'test'
,
file_path
)
assert
file_path
.
exists
()
def
test_create_tex_files
():
test_data
=
{
'analysis'
:
{
'file_hashes'
:
{
'ssdeep'
:
'bla'
,
'sha1'
:
'blah'
},
'meta_data'
:
dict
()}}
tmp_dir
=
TemporaryDirectory
()
...
...
@@ -25,3 +18,8 @@ def test_create_tex_files():
_create_tex_files
(
test_data
,
jinja_env
)
file_path
=
Path
(
tmp_dir
.
name
,
template_name
+
'.tex'
)
assert
file_path
.
exists
()
def
test_main
():
main
(
firmware_uid
=
'b79ea608e2f0390744642bad472f8d9fd7e4713791857da5d5fcabf70a009e50_29626948'
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment