Skip to content

Instantly share code, notes, and snippets.

@OptoCloud
Last active July 3, 2022 11:39
Show Gist options
  • Save OptoCloud/f58788144996af2b6e2df1a34411684f to your computer and use it in GitHub Desktop.
Save OptoCloud/f58788144996af2b6e2df1a34411684f to your computer and use it in GitHub Desktop.
import os
import gzip
import shutil
import tarfile
def ensure_dir(dir):
if not os.path.exists(dir):
os.makedirs(dir)
def move_if_exists(src, dst):
if os.path.exists(src):
ensure_dir(os.path.dirname(dst))
shutil.move(src, dst)
def read_all_text(path):
with open(path, 'r') as f:
return f.read()
def unpack_unitypackage(path):
package_name = os.path.basename(path)
package_dir = os.path.dirname(path)
unpack_folder = os.path.join(package_dir, os.path.splitext(package_name)[0])
tar_path = os.path.join(unpack_folder, "archtemp.tar")
# Create target folder for package files
ensure_dir(unpack_folder)
# Extract unitypackage (gzip)
with gzip.open(path, 'rb') as f_in:
with open(tar_path, 'wb+') as f_out:
shutil.copyfileobj(f_in, f_out)
# Create folder to extract artifacts to
artifact_folder = os.path.join(unpack_folder, "artifacts")
ensure_dir(artifact_folder)
# Extract artifacts (tar)
tar = tarfile.open(tar_path, "r:*")
tar.extractall(artifact_folder)
tar.close()
# delete the archive
os.remove(tar_path)
# Get all subdirectories of the archive folder
artifact_dirs = get_subdirs(artifact_folder)
# Malicious folder in case someone has messed with the package and wants to extract to a different directory
malicious_folder = os.path.join(unpack_folder, "Malicious")
# Move all files and subdirectories to the target directory
for artifact_name in artifact_dirs:
artifact_dir = os.path.join(artifact_folder, artifact_name)
final_path = read_all_text(os.path.join(artifact_dir, "pathname"))
final_name = os.path.basename(final_path)
# If pathname contains a ".." in the path, it is not a valid path, extract it to a "Malicious" folder
if ".." in final_path or final_path.startswith("/"):
final_path = os.path.join(malicious_folder, artifact_name, final_name)
else:
final_path = os.path.join(unpack_folder, final_path)
move_if_exists(os.path.join(artifact_dir, "asset"), final_path)
move_if_exists(os.path.join(artifact_dir, "asset.meta"), final_path + ".meta")
# Delete the artifact folder
shutil.rmtree(artifact_folder)
# Get all subdirecotries of a directory
def get_subdirs(dir):
return [name for name in os.listdir(dir)
if os.path.isdir(os.path.join(dir, name))]
# Unpack all .unitypackage files
def unpack_all(sourceDir):
# Get all .unitypackage files in the source directory
packages = [name for name in os.listdir(sourceDir) if name.endswith(".unitypackage")]
# Unpack with 7zip
for package in packages:
unpack_unitypackage(os.path.join(sourceDir, package))
# Main function
if __name__ == "__main__":
unpack_all(".")
print("Unpacking complete!")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment