Apache/Linux服务器,来自自己IP的DoS攻击

信息安全 linux http 阿帕奇 拒绝服务 ip欺骗
2021-08-28 12:58:49

我有一个不寻常的问题,我一直在尝试诊断:

  • 它是关于 Debian 服务器运行自定义编译的 apache 2.2 与 PHP、Red5、MySQL 5.5(标准二进制)、sendmail(发行版)和崩溃计划。

  • 每隔一天,我就会看到大量对随机文件(主要是图像)的 HTTP 请求——我们正在谈论超过一千个并发连接。

  • 这些请求来自服务器自己的 IP 地址(!)。

  • 它通常是反复请求的一组有限的文件。我没有看到真正的模式,但它看起来不像是有人在抓取信息,它看起来像是一次 DoS 尝试。

  • Cron 运行一个脚本,暂时禁止超过 200 个连接的 IP,因此通常会在它真正出现问题之前加以控制。1-3 10 分钟禁令后,攻击通常停止。

  • 这种情况已经持续了几个月。由于攻击被捕获和遏制,我完全看不出重点。

  • 它以随机的时间和间隔发生,但通常在 UTC 早上时间左右。

  • 没有向这些请求发送推荐人或代理。

我几乎同时检查了网络服务器和 red5 日志中的相关请求,以防服务器上的脚本被滥用以向自身发送查询,但找不到任何东西。那时 apache 错误日志或 syslog 中没有任何内容。Rkhunter 也没有发现任何异常。服务器不提供路由数据包,因此欺骗也不应该是一种选择。

我对方法和原因完全不知所措。任何要检查的想法将不胜感激。:)

更新: 根据 Isernis 的建议,我准备了一种机制来捕获下一次发生的一些信息。这是该方法的(稍微概括的版本):http : //pastebin.com/6uSUKVbh

回答: 这是一个社交媒体网站,允许使用 FCK 编辑器的 mySpace 类型配置文件。由于这有点像安全噩梦,因此用户发布的配置文件会经过广泛的检查,其中一项会探测发布的链接/图像。一方面,我没有在这些检查中排除网站自己的域,另一方面,由于与重定向相关的错误,每个链接或图像都被点击了 10 次而不是一次。因此,当用户的个人资料包含与网站本身的广泛链接时,点击保存按钮,该网站将自行拒绝服务。:P 特别是这涉及一位用户,她的个人资料中有大量项目并且倾向于经常保存。

感谢 Iserni 提供了如何诊断此问题的正确想法!

答案编辑: 我错了这个错误。实际上,她的个人资料中确实有 10 次或更多的图像。更具体地说,每次保存都要检查近 1000 个链接和图像。我没有看到那会发生。:P

4个回答

第一件事:找出这些请求来自哪里。它必须是一个本地进程,在现代 Linux 平台上,没有任何其他东西能够欺骗 TCP 握手(也就是说,没有任何东西会继续浪费这样的壮举来请求随机图像)。

如果有重复的 URL,您可以将它们隐藏在 a 后面,RewriteRule这样任何此类请求都会实际触发script在脚本中,您可以运行其他检查以查看请求是否合法(然后您将输出正确的标头,就像它是合法客户端期望的图像一样),或者它是否是虚假请求之一。针对虚假请求,您可以记录例如传入端口。有了它,您可以查询netstat并找出过程。您还可以ps在虚假请求的瞬间运行和检查所有活动进程。

我很确定罪魁祸首将被证明是 Apache 本身(由于 vhost 修改,我曾经有一个“缓存启动”脚本在我身上流氓 - 我忘记将脚本放在 crontab 中 - 并且得到了非常奇怪的症状,有点像你的,直到一切都回到我身边;但你的情况感觉不同)。

要在控制成本的同时进一步细化场景,您可以将 PID/TID 添加到 Apache 的CustomLog. 然后,您将能够交叉检查从 Apache 子流氓收到的请求。

另一种可能性是确定这些请求是如何发出的。如果通过 Apache,这意味着 fopen_wrappers、cURL、socket 函数,或者可能是 shell 实用程序(这些都应该出现在ps输出中并导致更大规模的服务器过载)。您可以准备一系列脚本,这些脚本将:

  • 优雅地重新启动 Apache而不做任何更改
  • " " ,暂时禁用其中一项功能
  • " " ,重新启用相同

在验证(只是为了确定)重启并不能解决问题之后(如果确实如此,那将是完全不同的蠕虫罐),您可以继续暂时禁用 - 每次几十秒,不再 - 一个功能一个接一个。假设禁用 curl 会导致系统立即恢复正常:那么您可以使用 cURL 限制对脚本的调查,甚至可以使用日志包装器包装 cURL 函数

如果有罪的一方不是 Apache,您仍然可以确定是什么在做这件事;然后要么重新安装受影响的程序(即使我发现任何随机异常都不太可能将程序变成重复 HTTP-GET 请求程序)或检查其配置、辅助数据文件、脚本等等,寻找与已知的干净安装有任何区别。因为我通常不相信小精灵,所以我预计最终会出现一些差异。

Unix(和 Linux)有很多工具可以用来分析这样的东西。我的第一站是获取 netstat -nap 的输出,例如在我的本地机器上......

Proto Recv-Q Send-Q Local Address               Foreign Address             State       PID/Program name
...
tcp        0      0 192.168.0.2:80              192.168.0.2:59875           ESTABLISHED 5281/httpd
...
tcp        0      0 192.168.0.2:59875           192.168.0.2:80              ESTABLISHED 32588/chrome
...

在这里我可以看到 chrome (pid 32588) 连接到端口 80 / httpd (pid 5281)。由于这是 apache 的 pre-fork 安装,我可以通过记录 %P 或查看 /proc/5281/fd 来获取有关 httpd 进程的更多信息(后者可能需要编写脚本以在请求时获取数据)。

这将允许您识别客户端进程。

最有可能的候选者是配置错误的代理或错误代码。

如果这是我的服务器,我会strace在 Apache 上运行。在 prefork 模式下在每个子进程上运行它可能会占用大量磁盘,尤其是当您的服务器已经超载时。你也必须留意你的磁盘空间,因为如果它用完了,Apache 就会停止服务请求。

确保使用足够长的 snaplength 来捕获整个请求:-s 400应该这样做。

如果 Apache 向自己发出请求,任何 GET 字符串都将出现在 strace 转储中,用于两个不同的 PID:一个发出请求,一个接收请求。在发出请求的那个中,您希望找到它收到并在向自己发出请求时正在处理的请求。

我通常会这样做:

for x in `ps -ef | grep apache | awk '{print $2}'`; do strace -s 2000 -p $x -o trace.$x & done

如果出于性能原因您想将自己限制为 Apache 子集的子集,请head在其中添加:

for x in `ps -ef | grep apache | head | awk '{print $2}'`; do strace -s 2000 -p $x -o trace.$x & done

但请注意,这会降低您捕捉正在发生的事情的可能性。

确保您打开了两个 SSH 会话,因为所有这些后台任务仍然可以写入您的会话。当您想停止跟踪时,请重新启动 Apache 或在另一个中运行它:

 for x in `ps -ef | grep strace | awk '{print $2}'`; do kill $x; done

我对这个的直觉是一个用 PHP 编写的“静态”模块,它在将图像发送到客户端之前对图像进行预处理(例如调整大小),它使用include($image). 如果$image碰巧包含来自您自己站点的图像 URL,而不是来自本地文件系统的文件路径,则结果是递归请求。

它可能正在使用curl()函数而不是include().

这听起来像是典型的 DOS 攻击。他们可能希望让服务器响应来自自身的请求,并希望得到像“死亡之平”这样的循环。这也是一种方便的方法来欺骗绕过一些防火墙规则并引起普遍的头痛。在防火墙处阻止外部 IP 可能是最好的选择,这样他们就无法获得门内的请求。