Last active
June 1, 2024 08:03
-
-
Save ivanpu/c5347bf107fa900ac79f1fcf2f056e7c to your computer and use it in GitHub Desktop.
Jar Infection Checker (python)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Adapted by @ivanpu to Python from Overwolf's scanner, because I couldn't launch it | |
# Original code: https://github.com/overwolf/jar-infection-scanner/ | |
# Check for updates to this script: https://gist.github.com/ivanpu/c5347bf107fa900ac79f1fcf2f056e7c | |
from __future__ import annotations | |
import zipfile | |
from argparse import ArgumentParser | |
from pathlib import Path | |
SIGNATURES: list[bytes] = [ | |
b"\x38\x54\x59\x04\x10\x35\x54\x59\x05\x10\x2E\x54\x59\x06\x10\x32\x54\x59\x07\x10\x31\x54\x59\x08\x10\x37\x54\x59\x10\x06\x10\x2E\x54\x59\x10\x07\x10\x31\x54\x59\x10\x08\x10\x34\x54\x59\x10\x09\x10\x34\x54\x59\x10\x0A\x10\x2E\x54\x59\x10\x0B\x10\x31\x54\x59\x10\x0C\x10\x33\x54\x59\x10\x0D\x10\x30\x54\xB7", | |
b"\x68\x54\x59\x04\x10\x74\x54\x59\x05\x10\x74\x54\x59\x06\x10\x70\x54\x59\x07\x10\x3a\x54\x59\x08\x10\x2f\x54\x59\x10\x06\x10\x2f\x54\x59\x10\x07\x10\x66\x54\x59\x10\x08\x10\x69\x54\x59\x10\x09\x10\x6c\x54\x59\x10\x0a\x10\x65\x54\x59\x10\x0b\x10\x73\x54\x59\x10\x0c\x10\x2e\x54\x59\x10\x0a\x10\x73\x54\x59\x10\x0e\x10\x6b\x54\x59\x10\x0f\x10\x79\x54\x59\x10\x10\x10\x72\x54\x59\x10\x11\x10\x61\x54\x59\x10\x12\x10\x67\x54\x59\x10\x13\x10\x65\x54\x59\x10\x14\x10\x2e\x54\x59\x10\x15\x10\x64", | |
b"\x2d\x54\x59\x04\x10\x6a\x54\x59\x05\x10\x61\x54\x59\x06\x10\x72", | |
] | |
def check_jar_file(jar_file_path: Path) -> bool: | |
def check_zip_dir(path: zipfile.Path) -> bool: | |
for entry in path.iterdir(): | |
if entry.is_file() and entry.name.endswith(".class"): | |
buffer = entry.read_bytes() | |
if any(sig in buffer for sig in SIGNATURES): | |
return True | |
elif entry.is_dir(): | |
if check_zip_dir(entry): | |
return True | |
return False | |
try: | |
return check_zip_dir(zipfile.Path(jar_file_path)) | |
except Exception as e: | |
print(f"Error while extracting {jar_file_path}: {e}") | |
return False | |
def main(): | |
parser = ArgumentParser() | |
parser.add_argument("directories", nargs="+", type=Path, help="directories to scan", metavar="directory") | |
args = parser.parse_args() | |
for path in args.directories: # type: Path | |
jars = path.rglob("*.[jJ][aA][rR]") | |
for jar in jars: | |
if check_jar_file(jar): | |
print("!!! INFECTED:", jar) | |
if __name__ == "__main__": | |
main() |
While I did try to make the code backwards compatible as much as possible (I was assuming python 3.7+), I missed to check the zipfile
documentation thoroughly:
zipfile.Path
was added in Python 3.8
zipfile.Path.suffix
was added in Python 3.11
@silmaril42
If you want something a bit more elegant than you currently have, you can use this:
if entry.is_file() and entry.name.endswith(".class"):
Which I think I'll actually update into the script, to lower the Python dependency to 3.8.
Yes, this looks much nicer! ๐ ๐
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thank you very much, @ivanpu for turning this into a Python script!
Unfortunately, I was getting a lot of errors
'Path' object has no attribute 'suffix'
(using Python 3.10.6).I made it work by replacing
with
This is slightly less elegant and probably a bit slower, but it works.
I guess this has something to do with the python version, but didn't dig any deeper.