Skip to content

Commit bdee3b2

Browse files
committed
Release v1.0
1 parent 09531c0 commit bdee3b2

File tree

7 files changed

+1047
-0
lines changed

7 files changed

+1047
-0
lines changed

.dockerignore

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
__pycache__/
2+
*.pyc
3+
*.pyo
4+
*.pyd
5+
6+
.env
7+
8+
*.md
9+
*.png
10+
*.log
11+
*.tmp
12+
13+
README.md
14+
LICENSE
15+
16+
.git/
17+
.cache/
18+
.gitignore
19+
.dockerignore

Dockerfile

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
FROM python:3.13-alpine as builder
2+
3+
RUN apk add --no-cache gcc musl-dev libffi-dev cmake make build-base unzip
4+
5+
WORKDIR /app
6+
COPY . .
7+
8+
RUN pip install --no-cache-dir -r requirements.txt
9+
10+
ADD https://github.com/DFIR-ORC/orc-decrypt/archive/refs/heads/master.zip /tmp/orc-decrypt.zip
11+
RUN unzip /tmp/orc-decrypt.zip -d /tmp \
12+
&& pip install --no-cache-dir /tmp/orc-decrypt-master \
13+
&& rm -rf /tmp/orc-decrypt.zip /tmp/orc-decrypt-master
14+
15+
FROM python:3.13-alpine
16+
17+
RUN apk add --no-cache p7zip bash openssl
18+
19+
COPY --from=builder /app /app
20+
COPY --from=builder /usr/local/lib/python3.13/site-packages /usr/local/lib/python3.13/site-packages
21+
COPY --from=builder /usr/local/bin/orc-decrypt /usr/local/bin/orc-decrypt
22+
COPY --from=builder /usr/local/bin/unstream /usr/local/bin/unstream
23+
24+
RUN mkdir /data
25+
WORKDIR /data
26+
27+
ENTRYPOINT ["python", "/app/orc2tree.py"]

README.md

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
# DFIR-ORC to Tree
2+
3+
The main goal to **orc2tree** is to extract the files harvested by the DFIR-ORC tool (https://dfir-orc.github.io/) and reorganizes them according to their original location on the disk. The tool also parse outputs from ORC's commands to provide usable data for investigative purposes. The script uses the metadata from "GetThis.csv" populated by the DFIR-ORC tool to reconstruct the tree structure of the original disk(s) in a directory named "Volumes" and the results of the ORC's commands in various directories alongside it. The output provided the "Volumes" directory might be used in different forensics tools (i-e: Plaso, yara, autopsy, etc.).
4+
5+
<div align="center">
6+
<img alt="Logo orc2tree" height="256px" src="./orc2tree-logo.png">
7+
</div>
8+
9+
The tool [DFIR-ORC](https://dfir-orc.github.io/) will gather files (evtx, winreg, suspicious files) from different commands. To avoid overwriting, the files are renamed in the form `<VolumeID>_<ParentFRN>_<FRN>_<AttrID>_<FileName>_{<UUID>}.data` and all placed in a single 7-Zip archive (or ZIP). Directory tree is lost during the process. For example :
10+
11+
```
12+
Event.7z
13+
├── evtx
14+
│ ├── 36DA2C4BDA2C0A27_10000000009E5_100000000E576_0_Application.evtx_{00000000-0000-0000-0000-000000000000}.data
15+
│ ├── 36DA2C4BDA2C0A27_10000000009E5_500000005AF3A_0_Security.evtx_{00000000-0000-0000-0000-000000000000}.data
16+
│ ├── 36DA2C4BDA2C0A27_10000000009E5_2000000000025_4_Setup.evtx_{00000000-0000-0000-0000-000000000000}.data
17+
│ │
18+
│ │ [...]
19+
│ │
20+
│ └── 36DA2C4BDA2C0A27_10000000009E5_400000005AF5B_3_System.evtx_{00000000-0000-0000-0000-000000000000}.data
21+
└── GetThis.csv
22+
```
23+
24+
In addition, the CSV file `GetThis.csv`, present in each of the harvested archives, gathers information specific to each file, including absolute paths and metadata. For example :
25+
26+
```csv
27+
ComputerName,VolumeID,ParentFRN,FRN,FullName,SampleName,SizeInBytes,MD5,SHA1,FindMatch,ContentType,SampleCollectionDate,CreationDate,LastModificationDate,LastAccessDate,LastAttrChangeDate,FileNameCreationDate,FileNameLastModificationDate,FileNameLastAccessDate,FileNameLastAttrModificationDate,AttrType,AttrName,AttrID,SnapshotID,SHA256,SSDeep,TLSH,YaraRules
28+
"WIN-C23B9AE4",0x36DA2C4BDA2C0A27,0x00010000000009E5,0x000100000000E576,"\Windows\System32\winevt\Logs\Application.evtx","evtx\36DA2C4BDA2C0A27_10000000009E5_100000000E576_0_Application.evtx_{00000000-0000-0000-0000-000000000000}.data",512036864,E4C12597F822C7974020F760C33556D2,5492495B0E2A6D518949C6A95508167686B1FDD9,"Name matches *.evtx, Header=456c6646696c65","data",2022-06-29 08:15:24.734,2014-10-13 11:05:06.667,2022-06-29 07:55:50.096,2014-10-13 11:05:06.667,2022-06-29 07:55:50.096,2014-10-13 11:05:06.667,2014-10-13 11:05:06.667,2014-10-13 11:05:06.667,2014-10-13 11:05:06.667,"$DATA",,0,{00000000-0000-0000-0000-000000000000},,,,
29+
"WIN-C23B9AE4",0x36DA2C4BDA2C0A27,0x00010000000009E5,0x0002000000000025,"\Windows\System32\winevt\Logs\Setup.evtx","evtx\36DA2C4BDA2C0A27_10000000009E5_2000000000025_4_Setup.evtx_{00000000-0000-0000-0000-000000000000}.data",1052672,6A346D6FAC62F3FAC1990B9CFAE96DF2,2ACE3789A68F63311C0143691D8FF742F8BCCE37,"Name matches *.evtx, Header=456c6646696c65","data",2022-06-29 08:15:24.734,2014-10-13 11:07:26.833,2022-04-22 19:32:59.661,2014-10-13 11:07:26.833,2022-04-22 19:32:59.661,2014-10-13 11:07:26.833,2014-10-13 11:07:26.833,2014-10-13 11:07:26.833,2014-10-13 11:07:26.833,"$DATA",,4,{00000000-0000-0000-0000-000000000000},,,,
30+
"WIN-C23B9AE4",0x36DA2C4BDA2C0A27,0x00010000000009E5,0x0002000000006115,"\Windows\System32\winevt\Logs\Microsoft-Windows-Windows Firewall With Advanced Security%4ConnectionSecurity.evtx","evtx\36DA2C4BDA2C0A27_10000000009E5_2000000006115_4_Microsoft-Windows-Windows_Firewall_With_Advanced_Security%4ConnectionSecurity.evtx_{00000000-0000-0000-0000-000000000000}.data",69632,BBE7FE15D335DF6B0C993017B1EB5FE7,FBA95C044ED3BA22FA4EF501CEF7C0865F3B5CAB,"Name matches *.evtx, Header=456c6646696c65","data",2022-06-29 08:15:24.734,2014-10-13 11:05:13.843,2014-10-13 11:07:28.627,2014-10-13 11:05:13.843,2014-10-13 11:07:28.627,2014-10-13 11:05:13.843,2014-10-13 11:05:13.843,2014-10-13 11:05:13.843,2014-10-13 11:05:13.843,"$DATA",,4,{00000000-0000-0000-0000-000000000000},,,,
31+
"WIN-C23B9AE4",0x36DA2C4BDA2C0A27,0x00010000000009E5,0x000500000005AF3A,"\Windows\System32\winevt\Logs\Security.evtx","evtx\36DA2C4BDA2C0A27_10000000009E5_500000005AF3A_0_Security.evtx_{00000000-0000-0000-0000-000000000000}.data",512036864,A06C060C1FAE63271AF23E6EC2C56CCD,4D45CC4E44A0EA0FEC58FD253DB388770F08DF4B,"Name matches *.evtx, Header=456c6646696c65","data",2022-06-29 08:15:24.734,2014-10-13 11:05:06.667,2022-06-29 07:55:50.018,2019-07-15 13:43:39.891,2022-06-29 07:55:50.018,2019-07-15 13:43:39.891,2019-07-15 13:43:41.623,2019-07-15 13:43:39.891,2019-07-15 13:43:41.623,"$DATA",,0,{00000000-0000-0000-0000-000000000000},,,,
32+
"WIN-C23B9AE4",0x36DA2C4BDA2C0A27,0x00010000000009E5,0x000400000005AF5B,"\Windows\System32\winevt\Logs\System.evtx","evtx\36DA2C4BDA2C0A27_10000000009E5_400000005AF5B_3_System.evtx_{00000000-0000-0000-0000-000000000000}.data",49352704,3661070B93F5BDDC73BB843628699CF9,EB46032FE6BD207246C468CE9A566E0A258721B0,"Name matches *.evtx, Header=456c6646696c65","data",2022-06-29 08:15:24.734,2014-10-13 11:05:06.651,2022-06-29 07:55:50.003,2019-07-15 18:15:57.418,2022-06-29 07:55:50.003,2019-07-15 18:15:57.418,2019-07-15 18:15:57.683,2019-07-15 18:15:57.418,2019-07-15 18:15:57.683,"$DATA",,3,{00000000-0000-0000-0000-000000000000},,,,
33+
```
34+
35+
Once the data gathered by DFIR_ORC, **orc2tree** will extract all of these files (evtx, hives, user registers, suspicious files harvested, etc.) and will use the CSV `GetThis.csv` to rebuild the directory tree.
36+
37+
## Installation
38+
39+
The project requires the use of _Python 3_, the development and testing having been done with _Python 3.10_. Two external libraries are required : `py7zr` for reading and extracting 7-Zip archives, `pandas` for CSV reading and `coloredlogs` for pretty output. Once you have cloned the repository, the best way to install _orc2tree_ is to build the Docker image.
40+
41+
```bash
42+
docker build -t orc2tree:latest .
43+
```
44+
45+
If you prefer not to use Docker, you can run _orc2tree_ directly on your local machine. Ensure that `7z` is installed (package `p7zip-full` for Debian/Ubuntu or `p7zip` for MacOS). It is recommended to use a virtual environment to manage dependencies.
46+
47+
```bash
48+
python3 -m venv ./venv-orc2tree
49+
source venv-orc2tree/bin/activate
50+
pip3 install -r requirements.txt
51+
```
52+
53+
## Usage
54+
55+
```
56+
usage: orc2tree.py [-h] [--zip ZIPFILE [ZIPFILE ...]] [--json JSONFILE [JSONFILE ...]] [--outdir DIRNAME] [--check] [--key KEYFILE] [--fix-crc] [--debug]
57+
58+
extracts DFIR archives harvested by the DFIR-ORC tool (https://dfir-orc.github.io) and reorganizes them according to their original location on the disk. The script uses the metadata from "GetThis.csv" populated by the DFIR-ORC tool to reconstruct the tree of the original disk(s).
59+
60+
options:
61+
-h, --help show this help message and exit
62+
--zip ZIPFILE [ZIPFILE ...] one or more archives from DFIR-ORC (7-Zip or ZIP)
63+
--json JSONFILE [JSONFILE ...] the DFIR-ORC Execution Outline
64+
--outdir DIRNAME the directory in which to extract files (default: ".")
65+
--check check for SHA1 of extracted files
66+
--key KEYFILE the private key for encrypted archives
67+
--fix-crc use an external script to resolve CRC errors
68+
--debug enable debug output
69+
```
70+
71+
The following examples run with Docker, but local use (via _venv_) is identical.
72+
73+
**Basic Help Command**
74+
75+
```bash
76+
docker run -it --rm -v orc2tree:latest --help
77+
```
78+
79+
**Process a JSON file from DFIR-ORC outputs**
80+
81+
```bash
82+
docker run -it --rm -v $PWD:/data orc2tree:latest --json <JSONFILE>
83+
```
84+
85+
**Extract data from a corrupted archive (CRC error)**
86+
87+
```bash
88+
docker run -it --rm -v $PWD:/data orc2tree:latest --zip <ZIPFILE> --fix-crc
89+
```
90+
91+
## Future Improvements
92+
93+
### Handle CRC errors
94+
95+
When the CRC check fails, `py7zr` raises an `CRCError` exception and stops file extraction. As a result, the extracted data is incomplete. However, the data is present in the archive created by DFIR-ORC and can be extracted from 7z CLI and GUI tools. This problem is well known (https://github.com/miurahr/py7zr/issues/359) and seems to be caused by the empty files that are sometimes included in archives.
96+
97+
The `orc2tree` script will ignore these errors and display a error message before continuing its execution. A temporary workaround for these errors is to use 7z CLI to extract the data and recreate an uncorrupted archive. The `fixCRCerror.sh` script takes care of this operation and can be automatically called by `orc2tree.py` with `--fix-crc`.
98+
99+
### Unconsolidated information
100+
101+
- Directories and files MACB (dates)
102+
- Permissions
103+
- Symlink between directories or files
104+
- MFT reference (cluster/sector will not match)
105+
- Outputs from ORC internal commands
106+
107+
## Contributing
108+
109+
Contributions are welcome. If you'd like to add new analysis modules, enhance existing scripts, or report issues, please follow these steps:
110+
111+
- Fork the repository
112+
- Create a new branch for your feature or bug fix
113+
- Make your changes and test them
114+
- Submit a pull request, describing your changes and their purpose
115+
116+
## License
117+
118+
This project is licensed under the GNU Lesser General Public License v2.1 (LGPL-2.1). It grants you certain permissions and responsibilities when using and distributing this software. You are free to modify and distribute this software, either under the terms of the license or under the terms of any later version published by the Free Software Foundation. However, this project is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Please see the [LICENSE](./LICENSE) file for more details.

fixCRCerror.sh

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#!/bin/bash
2+
3+
BIN7Z="7z"
4+
5+
# Check if 7-Zip is installed
6+
if ! type "$BIN7Z" > /dev/null; then
7+
printf "error: you have to install 7z!\n" 1>&2
8+
exit 1
9+
fi
10+
11+
# Check if the corrupted archive is provided
12+
if [ -z "$1" ]; then
13+
printf "usage: %s CORRUPTED_DFIR_ORC\n" "$0" 1>&2
14+
exit 1
15+
fi
16+
17+
# Check if the given argument is a file
18+
if [ ! -f "$1" ]; then
19+
printf "%s: %s: No such file or directory\n" "$0" "$1" 1>&2
20+
exit 1
21+
fi
22+
23+
# Get paths of the given file and its parent directory
24+
file_path=$(realpath "$1")
25+
file_name=$(basename "$file_path")
26+
root_path=$(dirname "$file_path")
27+
28+
# Build paths for output
29+
tmp_dir=${root_path}/${file_name/.7z/.tmp}
30+
fixed_file_path=${root_path}/${file_name/.7z/.fixed.7z}
31+
fixed_file_name=$(basename "$fixed_file_path")
32+
corrupted_file_path=${root_path}/${file_name/.7z/.corrupted.7z}
33+
corrupted_file_name=$(basename "$corrupted_file_path")
34+
35+
# Extracting the corrupted archive into the temporary folder
36+
mv "${file_path}" "${corrupted_file_path}"
37+
printf "[*] Corrupted file: %s (%s)\n" "${corrupted_file_name}" \
38+
"$(du -sh "${corrupted_file_path}" | cut -f1)"
39+
40+
printf "[*] Extracting '%s' using '%s'\n" "${corrupted_file_name}" "${BIN7Z}"
41+
${BIN7Z} x "${corrupted_file_path}" -O"${tmp_dir}" > /dev/null
42+
43+
# Recreating a fresh archive
44+
printf "[*] Recreating '%s' using '%s'\n" "${fixed_file_name}" "${BIN7Z}"
45+
cd "${tmp_dir}" && ${BIN7Z} a "${fixed_file_path}" * >/dev/null
46+
47+
printf "[*] Fixed file: %s (%s)\n" "${fixed_file_name}" \
48+
"$(du -sh "${fixed_file_path}" | cut -f1)"
49+
mv "${fixed_file_path}" "${file_path}"
50+
51+
printf "[*] Cleaning extracted files (%s)\n" "$(basename "${tmp_dir}")"
52+
rm -r "${tmp_dir}"

orc2tree-logo.png

160 KB
Loading

0 commit comments

Comments
 (0)