Skip to content

Instantly share code, notes, and snippets.

@yosignals
Created May 7, 2024 11:25
Show Gist options
  • Save yosignals/860da7a7bbdc1efbdc00d62db7b1cd8b to your computer and use it in GitHub Desktop.
Save yosignals/860da7a7bbdc1efbdc00d62db7b1cd8b to your computer and use it in GitHub Desktop.
File Folding with folders and files and extension preferences
import os
import argparse
import hashlib
import json
from itertools import islice
def file_to_hex(filename):
"""Convert file content to a hex string."""
with open(filename, 'rb') as file:
content = file.read()
return content.hex(), content
def calculate_sha256(file_content):
"""Calculate SHA-256 hash of the given file content."""
sha256 = hashlib.sha256()
sha256.update(file_content)
return sha256.hexdigest()
def chunked(iterable, size):
"""Yield successive chunks of a given size from an iterable."""
iterable = iter(iterable)
return iter(lambda: tuple(islice(iterable, size)), ())
def create_subfolders(base_path, subfolder_prefix):
"""Create a subfolder and return its path."""
subfolder_name = f"{subfolder_prefix}"
subfolder_path = os.path.join(base_path, subfolder_name)
os.makedirs(subfolder_path, exist_ok=True)
return subfolder_path
def create_hierarchical_folders_with_metadata(hex_data, base_path, max_length=230, split_percent=25, extension='json'):
"""Create a hierarchical structure of folders and files with metadata."""
num_segments = (len(hex_data) + max_length - 1) // max_length
segments = [hex_data[i * max_length:(i + 1) * max_length] for i in range(num_segments)]
num_subfolders = (num_segments * split_percent) // 100 or 1
chunk_size = (num_segments + num_subfolders - 1) // num_subfolders
folder_metadata = {}
file_metadata = {}
for i, segment_chunk in enumerate(chunked(segments, chunk_size)):
subfolder_prefix = segment_chunk[0][:8] if segment_chunk else 'empty'
subfolder_name = f"{i:04d}_{subfolder_prefix}"
subfolder_path = create_subfolders(base_path, subfolder_name)
folder_metadata[subfolder_name] = []
for j, segment in enumerate(segment_chunk):
filename = f"{j:04d}_{segment[:max_length]}.{extension}"
file_path = os.path.join(subfolder_path, filename)
with open(file_path, 'w') as file:
file.write(segment[:max_length])
segment_hash = hashlib.sha256(segment[:max_length].encode()).hexdigest()
file_metadata[file_path] = segment_hash
folder_metadata[subfolder_name].append({'file': filename, 'checksum': segment_hash})
metadata = {'folders': folder_metadata, 'files': file_metadata}
with open(os.path.join(base_path, 'metadata.json'), 'w') as meta_file:
json.dump(metadata, meta_file, indent=4)
return len(folder_metadata), len(file_metadata)
def hex_to_binary(hex_str):
"""Convert hexadecimal string to binary data."""
return bytes.fromhex(hex_str)
def rebuild_file_from_metadata(base_path, output_filename):
"""Rebuild a file from a hierarchical folder structure using a metadata file."""
base_path = os.path.abspath(base_path)
metadata_file = os.path.join(base_path, 'metadata.json')
if not os.path.exists(metadata_file):
print("Error: Metadata file is missing.")
return
with open(metadata_file, 'r') as meta_file:
metadata = json.load(meta_file)
all_segments = []
for folder, files in metadata['folders'].items():
folder_path = os.path.join(base_path, folder)
for entry in files:
file_name = entry['file']
file_path = os.path.join(folder_path, file_name)
expected_checksum = entry['checksum']
with open(file_path, 'r') as file:
segment = file.read().strip()
actual_checksum = hashlib.sha256(segment.encode()).hexdigest()
if actual_checksum != expected_checksum:
print(f"Warning: Segment checksum mismatch for file {file_name}. Skipping.")
else:
all_segments.append(segment)
if not all_segments:
print("Error: No valid segments found for reconstruction.")
else:
hex_data = ''.join(all_segments)
binary_data = hex_to_binary(hex_data)
with open(output_filename, 'wb') as file:
file.write(binary_data)
def main():
parser = argparse.ArgumentParser(
description="File Folding: Create or rebuild files from hierarchical folders.",
epilog=("Examples:\n"
" python3 Folding.py create input.txt --output out --split_percent 25 --extension json\n"
" python3 Folding.py rebuild out --output rebuilt_input.txt"),
formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument('mode', choices=['create', 'rebuild'], help='Operation mode: "create" or "rebuild"')
parser.add_argument('path', help='Path to the input file or directory')
parser.add_argument('--output', help='Output file or directory', required=True)
parser.add_argument('--split_percent', type=int, default=25, help='Percentage of files per subfolder (default is 25%)')
parser.add_argument('--extension', default='json', help='File extension for the segments (default is "json")')
args = parser.parse_args()
if args.mode == 'create':
hex_data, original_content = file_to_hex(args.path)
folder_count, file_count = create_hierarchical_folders_with_metadata(hex_data, args.output, max_length=230, split_percent=args.split_percent, extension=args.extension)
file_size = os.path.getsize(args.path)
file_sha256 = calculate_sha256(original_content)
print(f"Created hierarchical folder structure in {args.output} based on the file {args.path}")
print(f"Original file size: {file_size} bytes")
print(f"SHA-256 hash of the original file: {file_sha256}")
print(f"Summary: {folder_count} folders and {file_count} files created.")
# Write the checksum to a file
with open(os.path.join(args.output, 'checksum.txt'), 'w') as checksum_file:
checksum_file.write(file_sha256)
elif args.mode == 'rebuild':
rebuild_file_from_metadata(args.path, args.output)
if __name__ == "__main__":
main()
@yosignals
Copy link
Author

python3 Folding.py file.exe --output out --split_percent 25 --extension json

python3 Folding.py rebuild out --output mimikatz.exe

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment