From a Regular Infostealer to its Obfuscated Version

    Published: 2024-11-30. Last Updated: 2024-11-30 06:48:43 UTC
    by Xavier Mertens (Version: 1)
    0 comment(s)

    There are many malicious scripts available on the Internet. Github has plenty of info stealers and RATs made available “for testing or research purposes”. Here is one that I found recently: Trap-Stealer[1]. Often those scripts are pretty well obfuscated to pass through security controls and make Security Analysts’ life harder. Let’s review a practical example.

    Today, I won't review the info stealer capabilities because they are common but let's check the obfuscation techniques. The file was dropped as a fake JPEG image: C:\Users\user\AppData\Local\apxpvddh.jpeg. It has a low score on VT: 3/63[2].

    First, the code is “flooded” with classes that do nothing:

    class TtV4adTuzK:
        def __init__(self):
            self.data = True
        def get_data(self):
            return self.data
    class nxTJRP4oBo:
        def __init__(self):
            self.data = True
        def get_data(self):
            return self.data
    class cLaiqjSQel:
        def __init__(self):
            self.data = True
        def get_data(self):
            return self.data

    Or useless variables:

    J4BL2VTnoS = 95994844
    Q5eKoFfYgd = 79322716
    ME2ZgJpLA0 = 84016443
    m4tvU1GFfJ = 31572061
    EacvCg0xlz = 58092955
    TRwCJhKsQb = 88130587

    Dependencies with some Python modules are resolved:

    requirements = [
        ["requests", "requests"],
        ["Cryptodome.Cipher", "pycryptodomex" if not 'PythonSoftwareFoundation' in executable else 'pycryptodome']
    ]
    for modl in requirements:
        try:
            import_module(module[0])
        except:
            subprocess.Popen(executable + " -m pip install " +modl[1], shell=True)
            time.sleep(3)

    The interesting code starts here:

    f2KQN4bukRZMWSZicAmmYUWycFs6d0m5AqoEhG(base64.b64decode(S3ZpuwXgombrIYkwUNwRUJmSFtqLNOGKAHETR1))

    A huge chunk of Base64 data is decoded and passed to f2KQN4bukRZMWSZicAmmYUWycFs6d0m5AqoEhG, an alias for exe()!

    Once decoded, a second script obfuscated with the same techniques is disclosed. It contains another Base64 chunk of data. This time, the decoded data is encrypted.

    Here a funny technique is used to decrypt the next payload. An array of encryption keys is provided and all of them are tested until the decryption succeeds:

    s = [b'Co-7hDMhMh7UtUQ29kT0J7krqsTXPUAFXA7RtpcU6xY=',
         b'cbkSAtHBbB-1QGa6bhIz_faB_iLXMnoQ2DnoXOGCxLo=', 
         b'0d5ykqArsb7Gkb3ZJtjr5-nzIF-2bOYgKtwAyny8B8k=', 
         b'ztG6jHYX0PPlTa_yMzrrxLelrKf79hovRQADx5sioXo=', 
         b'JT0JyIIHm3LfeAuit0xf-vej3m37Qhxvnwc3flWQ3ew=', 
         b'0lSaIjRa6nePT6QiGIoPpVrw8EMHDCT_I7T6JwCk0Cc=', 
         b'KhJzINwra-Dv78aZpTZeqClzc484KhtXEO8fvmV38nY=', 
         b'cRReHk0vv3NlLplRTBxly-B5LamTR4s-7UwaGl-iuak=', 
         b'NWXrr-8oMnHPP9q46JheOjH46abeH9_kHUcUjhxRbsE=', 
         b'4Vu6YVdZGOSclihs4ukSRppyV1M62QFqwp7ZU6y3RBs=', 
         b'M1qQk8eFmk_tigtJgYhOFQVb6pxA4YAfzXAbzx-0BhA=', 
         b'0KjwnWf-Bqri4ae4UVy3pBUCCcAWiFbgWjkWmd7zsdI=', 
         b'WBkyoZfIwgzunYz9je8_-lBeotQ2ntjx59kVuscHboQ=', 
         b'usQcLUBWrVM7dENg0A6ge15mHK9RtB4RV6MB4hbD70o=']
    for key in s:
        try:
            decrypted_code = wqSJRHIzn7T3FiBgqfmquhhSEyCwLpRRMcdtF3(key.decode("utf-8")).decrypt(encrypted_code)
            break
        except Exception as e:
            pass

    Finally, the decrypted code is decompressed and executed:

    decompressed_code = zlib.decompress(decrypted_code).decode('utf-8')
    f2KQN4bukRZMWSZicAmmYUWycFs6d0m5AqoEhG(decompressed_code)

    You may wonder how these obfuscation techniques are implemented by the attacker. They have tools for this! In the context of Trap-Stealer, the obfuscation tool is even part of the repository[3]. Here is how it works:

    remnux@remnux:/MalwareZoo/20241125/Trap-Stealer$ mkdir build
    remnux@remnux:/MalwareZoo/20241125/Trap-Stealer$ cat <<__END__ >build/temp.py
    print("This is a super malicious Python script! }:->")
    __END__
    remnux@remnux:/MalwareZoo/20241125/Trap-Stealer$ python3 ./obfucator.py my_super_cool_infostealer
    INFO:root:The code has been encrypted, Filename: ./build/my_super_cool_infostealer.py
    remnux@remnux:/MalwareZoo/20241125/Trap-Stealer$ head build/my_super_cool_infostealer.py 
    
    
    from sys import executable, stderr
    ueupD5ALo7 = 33628666
    VKkflw4g74 = 98340683
    XRPK2HJT5b = 80807402
    fhaj93exmX = 5089192
    class fMVSRbmSTG:
        def __init__(self):
            self.data = True
    remnux@remnux:/MalwareZoo/20241125/Trap-Stealer$ python3 build/my_super_cool_infostealer.py
    [...pip stuff removed ...]
    This is a super malicious Python script! }:->
    

    Note that the obfuscated file is pretty big compared to the "clear text" version: 37 bytes for "temp.py" and 20087 bytes for "my_super_cool_infostealer.py". Obfuscation has a cost! :-)

    [1] https://github.com/TheCuteOwl/Trap-Stealer/tree/main
    [2] https://www.virustotal.com/gui/file/85a0342027420025c477f3f6ab68376aa1608a447d1fb24920ac36b7cf7fd59d/detection
    [3] https://github.com/TheCuteOwl/Trap-Stealer/blob/main/obfuscator.py

    Xavier Mertens (@xme)
    Xameco
    Senior ISC Handler - Freelance Cyber Security Consultant
    PGP Key

    0 comment(s)

      Comments


      Diary Archives