我被 Wordpress Pingback BOTNET 攻击了,现在我想屏蔽所有包含Wordpress
Useragents 的客户端。例如:
WordPress/4.0; http://vk.lokos.net; verifying pingback from 107.158.239.82
我需要阻止 HTTP 端口 80 和 HTTPS 端口 443。我该怎么做?
答案1
第一的:你不想这样做,正如我在下面描述的。
第二:这里回答了一个非常相似的问题http://spamcleaner.org/en/misc/w00tw00t.html。我正在转述他们针对您的具体问题的解决方案。有一个 iptablesstring
模块,您可以使用它来匹配浏览器代理。但是,iptables 随后会检查每一个数据包...我们可以用模块来优化它connmark
。我还没有尝试过,所以我的答案只是朝着正确的方向推动了一下:
<other rules>
iptables -t mangle -A PREROUTING -m connmark --mark 0xBAD1 -j DROP
iptables -t mangle -A PREROUTING -m connmark --mark 0xBAD0 -j ACCEPT
iptables -t mangle -A PREROUTING -p tcp --dport 80 -m string --string "User-Agent: " -j CHECK_UAGENT
iptables -t mangle -A CHECK_UAGENT -m string --string "User-Agent: WordPress/4.0" -j CATCH
iptables -t mangle -A CHECK_UAGENT -j CONNMARK --set-xmark 0xBAD0
<otherrules>
iptables -t mangle -N CATCH
iptables -t mangle -A CATCH -j LOG --log-level alert --log-prefix "WordPress attack "
iptables -t mangle -A CATCH -j CONNMARK --set-xmark 0xBAD1
iptables -t mangle -A CATCH -j DROP
思路如下。connmark
模块和相关目标将按照您的意愿标记数据包,并且该连接流中的任何后续数据包都将被类似地标记。因此,我们寻找前往端口 80 并具有“用户代理”字符串的数据包。如果它们具有不良用户代理,我们将其标记为 0xBAD1——将其列入黑名单。然后我们记录它并丢弃它。否则,一旦我们看到“用户代理”但没有不良用户代理,它就会被列入白名单,标记为 0xBAD0。通过将其列入白名单,我们减少了数据包检查器的负载(这是一个优化步骤)。否则,我们将搜索每张上传图片的每个数据包——这是毫无意义的浪费。
** 为什么上述做法是个坏主意** 一:HTTPS 无法在数据包过滤器级别解码。二:因为上述做法可能会引发 DDOS 攻击。连接启动后,在您的 Web 服务器上打开一个连接,然后消失(从您的网络服务器的角度来看)。它会等待很长时间,然后放弃不再允许任何数据包通过的客户端。与此同时,还会有更多的尝试通过。最终,HTTP 将耗尽资源,不请求无法通过。(解决这个问题的一种方法是使用recent
模块。更彻底的方法是让一个进程监控日志文件中的“WordPress 攻击”,让它记录远程 IP 和端口,然后强制关闭连接刀具,或者交叉引用该连接和与其关联的服务器 PID,然后终止该进程。)
A类似问题提出并回答:使用反向代理。这是最好的选择,但需要大量重新配置,并且可能需要中间服务器。
这样做使用 mod_rewrite(在 Apache/*ngnx 中)匹配 User-Agent 字符串,设置环境变量用于日志记录,并返回 403 错误状态。这样就可以关闭远程端。现在,为了使其更加持久,让一个单独的进程监控该日志文件中是否存在此类断开的连接,并将远程 IP 添加到表中recent
,iptables 将在接下来的 5 分钟内断开来自该表的新连接。所以...
# Apache config
RewriteCond %{HTTP_USER_AGENT} ^WordPress/4\.0
RewriteRule - [L,R=403,E=WordPress]
LogFormat "%t\t%a\t%{remote}p\t%{User-Agent}i"
CustomLog wordpress wordpress.log env=WordPress
自定义日志格式让我们的外部进程更容易解码。IPtables 只有一条规则:
iptables -A INPUT --syn -m recent --name WordPress --rcheck --seconds 300 -j DROP
外部进程(以 root 身份运行)如下所示:
#!perl
open(STDIN,"tail -f /var/log/http/wordpress.log|")
while (<>) {
my ($time,$ip,$port,$useragent)=split('\t');
open(RECENT,"> /proc/net/xt_recent/WordPress")
print RECENT "+$ip\n"
close RECENT
}
时间戳和用户代理字符串只是为了让您能够验证事情是否按预期工作。我要补充的是,使用 mod-rewrite 的方式,您可以更灵活地选择拒绝/禁止哪些内容。
答案2
运行以下命令将阻止此特定攻击:
iptables -N Wordpress-PingVerify
iptables -I INPUT -p tcp --dport 80 -m string --to 70 --algo bm --string 'GET /' -j Wordpress-PingVerify
iptables -A Wordpress-PingVerify -p tcp --dport 80 -m string --to 80 --algo bm ! --string 'User-Agent: WordPress/' -j RETURN
iptables -A Wordpress-PingVerify -p tcp --dport 80 -m string --to 300 --algo bm --string 'verifying pingback from' -j DROP
iptables -A Wordpress-PingVerify -j RETURN
上述规则假设攻击目的地是 HTTP(端口 80)。
另外,您可以使用这些规则来阻止所有 WordPress pingback 请求 - 这不仅会阻止 pingback 验证,还会阻止 pingback:
iptables -N Wordpress-PingBacks
iptables -I INPUT -p tcp --dport 80 -m string --to 70 --algo bm --string 'GET /' -j Wordpress-PingBacks
iptables -A Wordpress-PingBacks -p tcp --dport 80 -m string --to 80 --algo bm ! --string 'User-Agent: WordPress/' -j RETURN
iptables -A Wordpress-PingBacks -p tcp --dport 80 -j DROP
iptables -A Wordpress-PingBacks -j RETURN
来源 :https://sysadminblog.net/2016/05/blocking-wordpress-pingback-verification-ddos/
答案3
正如其他人提到的,一般来说,-m string
在服务器中使用规则并不是很有效,因为它会检查每个数据包中的字符串,这很慢。但这还不是全部。黑客可以故意将数据拆分成单独的数据包,在第一个数据包中说“Word”,在第二个数据包中说“press”。所以这没有帮助。不仅如此,我们现在有了 HTTP/3,它使用 UDP 数据包……可以加密。
最重要的是,真正的 DDoS 攻击往往会发生得非常快,所以我认为如果您认为它真的发生了,您需要尽快阻止 IP 地址。
这意味着您希望尽快发送 IP iptables
。防火墙有一个_新接口_¹,允许您在排序表中添加最多 65535 个 IP 地址(搜索速度非常快)。由于攻击者不太可能拥有那么多台计算机,因此它将按预期工作。
首先,在 Apache2 设置中,捕获标头Wordpress
中的单词User-Agent
:
RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} Wordpress
RewriteRule !^/?scripts/ scripts/script-to-run.cgi [L]
然后你可以像这样script-to-run.cgi
使用:ipset
#!/bin/bash
ipset add unwanted $REMOTE_ADDR -exist
来源:如何根据条件在 Apache2 中运行某些代码或命令?
然后你需要在防火墙中制定一条规则来检查unwanted
IP 列表,它看起来像这样:
iptables -A unwanted -m set --match-set unwanted src -j DROP
注意:请确保您的 SSH 用户不会因在该
unwanted
规则之前接受端口 22 上的流量而被阻止——如果您的所有用户都有静态 IP 地址,则这是安全的。
但是,您在尝试运行该命令时可能会遇到问题ipset
。它将以 Apache2 用户身份运行,而不是 root 用户。一个简单的解决方案是编写一个可以授予 root 权限的 C++ 进程。如下所示:
int main(int argc, char *argv[])
{
if(setuid(0) != 0) return 1; // could not become root?!
if(argc != 2) return 1; // exactly one parameter: IP address
std::string ip(argv[1]);
if(ip.find(' ') != std::string::npos) return 1; // IP can't include spaces
if(ip.find('\'') != std::string::npos) return 1; // IP can't include quotes
std::string cmd("ipset add unwanted '");
cmd += ip;
cmd += "' -exist";
return system(cmd.c_str());
}
注意:它是安全的,因为它只允许向特定表“unwanted”添加一个“add”。提供它本身支持的所有选项
ipset
并不安全。
编译使用:
g++ safeipset.cpp -o safeipset
将结果复制到/usr/bin
并确保它可以成为root:
sudo cp safeipset /usr/bin/.
sudo chmod u+s /usr/bin/safeipset
在你的 CGI 脚本中使用如下:
#!/bin/bash
safeipset $REMOTE_ADDR
可以为该表ipset
指定一个默认超时时间,这样被阻止的 IP 地址将在给定时间后被删除。您可以先在没有该超时时间的情况下进行测试,看看添加了多少个 IP。
这里将时间设置为 5 分钟:
ipset create unwanted hash:ip timeout 300
请检查man ipset
手册页以获取更多信息。
¹ipset
早在 2001 年发布的 Linux 2.4.x 中就已经存在。所以它并不是那么新,但是很长时间内都没有人使用它。