-
-
Save ivanpu/c5347bf107fa900ac79f1fcf2f056e7c to your computer and use it in GitHub Desktop.
| # 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() |
This script does not work, because it doesn't recursively check inside the jar files. When it finds a folder it skips the entry instead of checking all the entries within that folder.
@MentalHolyGlobe
Thanks, fixed.
Looks like it's working now, thanks.
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
if entry.is_file() and entry.suffix == ".class":with
if entry.is_file() and str(entry).endswith(".class"):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.
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! ๐ ๐
DISCLAIMER:
It didn't find any infected jars on my computer, so I can't guarantee that it actually finds stage-0 infection.
I assume that this code is correct if the original Overwolf's scanner is correct.