Laravel Scalpel 是一款来自 Laravel 的入侵证据扫描器。 哈里·奥古斯蒂亚纳 它在 Laravel 应用程序内部运行,并检查文件系统是否存在恶意 PHP 文件、混淆代码、更改的服务器指令以及自已知良好快照以来的更改等迹象。
工具,例如 沃德 和 检查点 检查源代码、配置和依赖项是否存在安全问题。Scalpel 的任务则不同:它负责查找已部署应用程序中的文件是否已被添加、更改或删除。
文件系统扫描器
这
scalpel:scan
该命令默认运行六个扫描器。其中五个用于检查当前文件。基线差异扫描器则将它们与已保存的快照进行比较。
结构扫描器会在不应该出现 PHP 文件的目录中查找可执行 PHP 文件。默认情况下,这些目录是:
public/
和
storage/
它能检测到
.php
文件和不太常见的扩展名,例如
.phtml
,
.pht
, 和
.phar
以及双重扩展,例如
shell.php.jpg
扫描仪允许
public/index.php
,
public/vendor/
默认情况下,Laravel 会扫描已编译的视图和缓存。您可以更改扫描的目录,并将您自己的文件和目录添加到允许列表中。
混淆代码扫描器会检查 PHP 文件中常见的后门模式。这些模式包括
eval(base64_decode(...))
压缩有效载荷执行、动态函数调用、直接评估请求输入以及长编码字符串。如果合法代码检测到异常,您可以关闭该模式。
config/scalpel.php
。
这
.htaccess
扫描器报告处理程序和 MIME 类型映射,允许 Web 服务器执行 Python、Perl、CGI 或其他脚本。它还会标记
Options +ExecCGI
重写规则,将页面重定向到外部 URL,以及 PHP 指令,例如:
auto_prepend_file
。这
.user.ini
扫描器报告每个目录的 PHP 指令,包括
auto_prepend_file
,
auto_append_file
,
include_path
, 和
disable_functions
攻击者可以利用
auto_prepend_file
目的是在每次请求时运行一个隐藏文件。
环境扫描器报告称
.env
文件缺失、为空或无法读取,以及任何
.env
文件放置于
public/
在类 Unix 系统中,它还会检查文件是否全局可读。如果文件为空,则报告为空。
APP_KEY
然后比较键
.env
和
.env.example
这与以下工具重叠:
检查多个文件中的环境密钥
但 Scalpel 会将意外丢失或缺失的密钥视为可能的入侵证据。
APP_ENV
是
production
扫描仪标志
APP_DEBUG=true
。这
--production
适用该选项,检查任何内容
APP_ENV
表示,并且还标记
APP_ENV=local
。
您可以运行所有扫描程序,也可以选择运行部分扫描程序:
php
工匠
手术刀:扫描php
工匠
手术刀:扫描
--仅限结构化、混淆php
工匠
手术刀:扫描
--only=userini
基线比较
这
scalpel:baseline
该命令会记录每个包含文件的 SHA-256 哈希值、大小和修改时间。
scalpel:diff
该命令随后将当前文件与该记录进行比较,并报告已添加、已修改和已删除的文件:
php
工匠
手术刀:基线php
工匠
手术刀:差异
只有在应用程序处于您信任的状态后才能创建基线。在基线存在之前,
scalpel:scan
和
scalpel:diff
报告
MEDIUM
找到它后,它会提示你创建一个。每次部署后,项目都会建议运行。
php artisan optimize
进而
scalpel:baseline --force
取代旧的基线。
默认排除项会排除经常更改的路径,例如日志、会话、已编译视图等。
storage/app
。这
vendor/
目录会被内容扫描跳过,但仍然是基线比较的一部分,因此添加到已安装软件包中的文件仍然会出现在差异中。
默认情况下,Scalpel 以严格模式运行,并在每次比较期间对每个文件进行哈希处理。
--fast
该方法首先比较文件大小和修改时间,如果两者匹配则重用旧哈希值。这减少了哈希运算量,但如果攻击者保留了文件的大小和修改时间,则基线比较可能会遗漏已更改的文件。其他扫描器仍然可以根据文件内容或位置报告该文件。
Scalpel 可以对基线和 JSON 报告进行 HMAC 签名
SCALPEL_SIGNING_ENABLED
是
true
和
SCALPEL_SIGNING_KEY
持有专用密钥,该密钥不属于您
APP_KEY
diff 命令在使用签名基线之前会对其进行验证,并将无效或缺失的签名报告为:
CRITICAL
此功能可以检测到未使用签名密钥重新生成的基线,但如果攻击者能够读取该密钥或更改扫描器本身,则无法保护基线。请在创建第一个基线之前启用签名功能。
scalpel:verify
该命令检查已保存的 JSON 报告的签名。
测试扫描
我在一个全新的 Laravel 13.31 应用中测试了 Scalpel 1.9.0。
.env
权限设置为
0600
在建立基线后,默认扫描未发现任何问题。

然后我又添加了四个无害的装置:一个
eval(base64_decode(...))
内部通话
if (false)
块,一个名为
avatar.php.jpg
, 一个
.htaccess
处理程序映射,以及一个
.user.ini
文件
auto_prepend_file
。
运行这四个内容扫描器使得输出结果保持简短:
php
工匠
手术刀:扫描
\
--only=structural,obfuscated,htaccess,userini
\
--no-banner

完整扫描共发现九项结果,因为基线扫描仪也报告了四个新文件和一个变更。
routes/web.php
文件。
同样的测试还发现了一个需要在持续集成(CI)中考虑的默认设置问题。运行中
php artisan optimize
编译框架视图
storage/framework/views
下一次扫描结果显示为 100
MEDIUM
变量-变量结果和两个
HIGH
在这些生成的文件中查找反引号。之后
php artisan optimize:clear
重新建立基线后,扫描完成,未发现任何异常。
结构扫描器允许访问 Laravel 的编译视图目录,但混淆代码扫描器仍然会读取其内容。在生产环境中缓存视图的应用程序应在将 Scalpel 添加到部署门控之前测试此路径。
storage/framework/views
到
content_scan_excluded_paths
避免了这些发现,但代价是跳过了对每个编译视图的内容检查。
CI 输出和 Laravel 事件
两个都
scalpel:scan
和
scalpel:diff
支持表格、JSON、GitHub Actions 注解和 SARIF 输出。
--fail-on
此选项设置 CI 作业失败的最低严重级别。默认值为
HIGH
。
php
工匠
手术刀:扫描
--format=sarif
--fail-on=MEDIUM
退出代码
0
表示扫描已完成,未发现任何异常。代码
1
意味着至少有一项发现达到或超过
--fail-on
严重性。代码
2
涵盖低于该严重程度的发现或不完整的扫描,因此无法读取的目录不会产生干净状态。
后
scalpel:scan
或者
scalpel:diff
包裹发出
ScanFinished
事件。该事件包含调查结果、运行的命令(
scan
或者
diff
),以及持续时间(以毫秒为单位)。应用程序可以监听该事件,并在无需解析命令输出的情况下发送自己的邮件、Slack 或 Webhook 警报。
安装
Laravel Scalpel 需要 PHP 8.2 或更高版本,并支持 Laravel 10 至 13。使用 Composer 安装,然后发布其配置:
作曲家
要求
hryagstn/laravel-scalpelphp
工匠
供应商:发布
--tag=scalpel-config
扫描器与 Laravel 应用运行在同一进程中,并拥有相同的文件系统权限。能够修改应用代码的攻击者也可以修改扫描器或其配置。该项目建议使用外部扫描触发器、只读代码目录,并将结果发送到受感染服务器之外的存储位置。Scalpel 可以检测入侵迹象,但它不提供防火墙或隔离保护。
您可以浏览源代码和完整的命令参考。 GitHub 或者尝试使用命令模拟器 Laravel Scalpel 网站 。







