A recently discovered Python-based remote access trojan (RAT) exhibits unprecedented polymorphic behavior, altering its code signature each time it runs.
First observed on VirusTotal, the sample, dubbed nirorat.py, initially scored only 26/100 on detection engines, despite containing a full suite of RAT capabilities.
Analysts believe the malware leverages Python’s introspection and code-modification features to evade signature-based detection by continuously transforming critical code sections.
Internet Storm Center analysts identified the threat after correlating function names such as selfmodifyingwrapper
, decryptandexecute
, and polymorphcode
in the sample’s source.
These functions drive the malware’s evasion tactics by extracting its own code from memory, applying randomized XOR-based packing, and injecting junk snippets before execution. Such dynamic mutation ensures no two executions share an identical fingerprint, compounding challenges for static scanners.
Delivered primarily through phishing emails containing a benign-looking Python script, the RAT also spreads via compromised network shares. Upon execution, it unpacks itself entirely in memory, avoiding disk artifacts.
Persistence is achieved by appending a copy of the mutated script to startup folders under randomized filenames. Its low VirusTotal detection score reflects how traditional file-hash signatures are nearly useless against this threat.
Detection Evasion Techniques
The RAT’s detection evasion hinges on two core mechanisms: self-modification and junk-code insertion.
At runtime, the selfmodifyingwrapper
function retrieves a target routine’s source with Python’s inspect
module, encodes it by XORing each byte with a random key, and then reconstructs it in memory before execution.
This technique closely simulates a packer’s behavior without leaving a packed file footprint on disk.
import inspect, random, marshal, zlib
def selfmodifyingwrapper(func):
code = inspect.getsource(func).encode()
key = random.randint(1,255)
packed = bytes(b ^ key for b in code)
unpacked = bytes(b ^ key for b in packed)
codeobj = marshal.loads(zlib.decompress(unpacked))
exec(codeobj)
Additionally, the polymorphcode
function injects randomized junk—unused functions, shuffled variable names, and no-op loops—into core routines.
By combining variable renaming and random snippet insertion, the malware produces a virtually unique source each run, undermining both static signature and heuristic approaches.
Given these advanced evasion strategies, defenders must rely on behavioral analysis and real-time monitoring rather than traditional signature-based tools.
Follow us on Google News, LinkedIn, and X to Get More Instant Updates, Set CSN as a Preferred Source in Google.