diff --git a/src/vipyr_deobf/deobfuscators/hyperion.py b/src/vipyr_deobf/deobfuscators/hyperion.py index a7dc3e3..a8bff61 100644 --- a/src/vipyr_deobf/deobfuscators/hyperion.py +++ b/src/vipyr_deobf/deobfuscators/hyperion.py @@ -20,7 +20,6 @@ class _theory: import re import zlib from ast import * -from typing import TextIO from ..utils import WEBHOOK_REGEX diff --git a/src/vipyr_deobf/deobfuscators/lzmaspam.py b/src/vipyr_deobf/deobfuscators/lzmaspam.py index 0002957..76ddee5 100644 --- a/src/vipyr_deobf/deobfuscators/lzmaspam.py +++ b/src/vipyr_deobf/deobfuscators/lzmaspam.py @@ -13,7 +13,6 @@ import codecs import lzma import re -from typing import TextIO from ..utils import WEBHOOK_REGEX diff --git a/src/vipyr_deobf/deobfuscators/vare.py b/src/vipyr_deobf/deobfuscators/vare.py index 6f13949..0240e07 100644 --- a/src/vipyr_deobf/deobfuscators/vare.py +++ b/src/vipyr_deobf/deobfuscators/vare.py @@ -9,7 +9,6 @@ import marshal import re import zlib -from typing import TextIO from cryptography.fernet import Fernet diff --git a/src/vipyr_deobf/scanners/fct_scan.py b/src/vipyr_deobf/scanners/fct_scan.py index 398bf09..4c81232 100644 --- a/src/vipyr_deobf/scanners/fct_scan.py +++ b/src/vipyr_deobf/scanners/fct_scan.py @@ -1,6 +1,39 @@ import ast -from ast import (Assign, Attribute, Call, Constant, Expr, Lambda, Load, Name, - Slice, Store, Subscript, UnaryOp, USub, arg, arguments) +from ast import (Assign, Attribute, Call, Constant, Expr, Lambda, Name, + Slice, Subscript, UnaryOp, USub, arg, arguments) + + +def match_inner_underscore_function(node: ast.Call): + match node: + case Call( + func=Attribute( + value=Call( + func=Name(id='__import__'), + args=[Constant(value='zlib')] + ), + attr='decompress', + ), + args=[ + Call( + func=Attribute( + value=Call( + func=Name(id='__import__'), + args=[Constant(value='base64')] + ), + attr='b64decode', + ), + args=[ + Subscript( + value=Name(id='__'), + slice=Slice( + step=UnaryOp(op=USub(), operand=Constant(value=1))), + ) + ] + ) + ] + ): + return True + return False class FCTScanner(ast.NodeVisitor): @@ -11,44 +44,21 @@ def __init__(self): def visit_Assign(self, node): match node: case Assign( - targets=[ - Name(id='_', ctx=Store())], + targets=[Name(id='_')], value=Lambda( - args=arguments( - args=[ - arg(arg='__')], - kwonlyargs=[], - kw_defaults=[], - defaults=[]), + args=arguments(args=[arg(arg='__')]), body=Call( func=Attribute( value=Call( - func=Name(id='__import__', ctx=Load()), - args=[ - Constant(value='zlib')], - keywords=[]), - attr='decompress', - ctx=Load()), - args=[ - Call( - func=Attribute( - value=Call( - func=Name(id='__import__', ctx=Load()), - args=[ - Constant(value='base64')], - keywords=[]), - attr='b64decode', - ctx=Load()), - args=[ - Subscript( - value=Name(id='__', ctx=Load()), - slice=Slice( - step=UnaryOp( - op=USub(), - operand=Constant(value=1))), - ctx=Load())], - keywords=[])], - keywords=[]))): + func=Name(id='__import__'), + args=[Constant(value='marshal')] + ), + attr='loads', + ), + args=[body] + ) | body + ) + ) if match_inner_underscore_function(body): self.underscore_function_found = True return @@ -56,14 +66,15 @@ def visit_Expr(self, node): match node: case Expr( value=Call( - func=Name(id='exec', ctx=Load()), + func=Name(id='exec'), args=[ Call( - func=Name(id='_', ctx=Load()), - args=[ - Constant(value=payload)], - keywords=[])], - keywords=[])) if isinstance(payload, bytes): + func=Name(id='_'), + args=[Constant(value=payload)] + ) + ] + ) + ) if isinstance(payload, bytes): self.payload_found = True return diff --git a/src/vipyr_deobf/scanners/hyperion_scan.py b/src/vipyr_deobf/scanners/hyperion_scan.py index f3f373a..bd61595 100644 --- a/src/vipyr_deobf/scanners/hyperion_scan.py +++ b/src/vipyr_deobf/scanners/hyperion_scan.py @@ -1,32 +1,30 @@ import ast import re -from ast import Assign, Constant, Load, Name, Store, Tuple +from ast import Assign, Constant, Name, Tuple class HyperionScanner(ast.NodeVisitor): def __init__(self): - self.characteristic_found = False + self.signature_found = False def visit_Assign(self, node): match node: case Assign( - targets=[ - Name(id='__obfuscator__', ctx=Store())], + targets=[Name(id='__obfuscator__')], value=Constant(value='Hyperion'), ) | Assign( - targets=[ - Name(id='__authors__', ctx=Store())], + targets=[Name(id='__authors__')], value=Tuple( elts=[ - Constant(value='billythegoat356'), - Constant(value='BlueRed')], - ctx=Load()) + Constant(value='billythegoat356'), + Constant(value='BlueRed') + ], + ) ) | Assign( - targets=[ - Name(id='__github__', ctx=Store())], + targets=[Name(id='__github__')], value=Constant(value='https://github.com/billythegoat356/Hyperion') ): - self.characteristic_found = True + self.signature_found = True return @@ -34,9 +32,10 @@ def visit_Assign(self, node): r'# sourcery skip: collection-to-bool, remove-redundant-boolean, remove-redundant-except-handler' ) + def scan_hyperion(code: str): if COMMENT_REGEX.search(code): return True hyp_scanner = HyperionScanner() hyp_scanner.visit(ast.parse(code)) - return hyp_scanner.characteristic_found + return hyp_scanner.signature_found diff --git a/src/vipyr_deobf/scanners/lzmaspam_scan.py b/src/vipyr_deobf/scanners/lzmaspam_scan.py index 73ef1d4..0b6e6f5 100644 --- a/src/vipyr_deobf/scanners/lzmaspam_scan.py +++ b/src/vipyr_deobf/scanners/lzmaspam_scan.py @@ -1,5 +1,5 @@ import ast -from ast import Attribute, Call, Constant, Expr, Import, Load, Name, alias +from ast import Attribute, Call, Constant, Expr, Import, Name, alias class LZMAScanner(ast.NodeVisitor): @@ -10,14 +10,10 @@ def __init__(self): def visit_Import(self, node): match node: - case Import( - names=[alias(name='base64')] - ): + case Import(names=[alias(name='base64')]): self.base64_import_found = True return - case Import( - names=[alias(name='lzma')] - ): + case Import(names=[alias(name='lzma')]): self.lzma_import_found = True return @@ -25,30 +21,32 @@ def visit_Expr(self, node): match node: case Expr( value=Call( - func=Name(id='print', ctx=Load()), + func=Name(id='print'), args=[ Call( - func=Name(id='compile', ctx=Load()), + func=Name(id='compile'), args=[ Call( func=Attribute( - value=Name(id='lzma', ctx=Load()), + value=Name(id='lzma'), attr='decompress', - ctx=Load()), + ), args=[ Call( func=Attribute( - value=Name(id='base64', ctx=Load()), + value=Name(id='base64'), attr='b64decode', - ctx=Load()), - args=[ - Constant(value=payload)], - keywords=[])], - keywords=[]), + ), + args=[Constant(value=payload)], + ) + ], + ), Constant(value=''), Constant(value='exec')], - keywords=[])], - keywords=[])) if isinstance(payload, bytes): + ) + ], + ) + ) if isinstance(payload, bytes): self.payload_found = True return