|||

网络攻防:wordpress被黑客爆破密码时的对策

症状1——/xmlrpc.php爆破

在wordpress的日志插件里发现大量登陆尝试,来自各种IP,查看docker logs发现大量类似”POST /xmlrpc.php HTTP/1.0″这样的请求。

一、xmlrpc.php 是什么?

xmlrpc.php 是 WordPress 自带的一个远程接口文件。

协议:XML-RPC

作用:允许 “不通过网页” 来远程操作 WordPress

诞生背景:移动端 / 桌面客户端时代

文件位置:/wordpress/xmlrpc.php

二、它本来是干嘛用的?(正常用途)

远程发文章 / 管理网站

例如:WordPress 官方手机 App,老式博客客户端(Windows / macOS)

它可以做:登录,发文章,改文章,获取评论

三、那为什么黑客「特别爱」它?(核心)

因为它是完美的攻击入口,它能绕过传统登录限制

/wp-login.php:有验证码,有失败次数限制,有插件防护

xmlrpc.php: 默认无验证码,默认无登录次数限制,不走 wp-login 流程,天生就是爆破接口

四、我自己会不会「正常用到」它?
对 90% 的个人 / 博客 / 企业站,不会用到

你可以自测一下项目,如果全部都是 NO,就可以放心禁用:

场景是否使用
用 WordPress 手机 App 发文章
用 Jetpack
用 WordPress.com 远程管理
依赖 Pingback
第三方博客客户端

五、最佳实践:怎么处理 xmlrpc.php?

方案 1(强烈推荐):直接禁用

Nginx

location = /xmlrpc.php {
    deny all;
}

方案 2:只允许自己 IP(如果你要用的话)

location = /xmlrpc.php {
    allow YOUR.IP.ADDR;
    deny all;
}

症状2——/wp-login.php爆破(进阶)

如果应用了上面的对策之后,日志里依然出现很多登录尝试,且都是通过wp-login.php访问的,那么说明黑客开始直接怼你的登录页面了。比较推荐的方法是限制每个IP在单位时间内的登录次数,比如一分钟达到5次就暂时禁止这个IP登录。

具体实现需要修改/etc/nginx/nginx.conf和/etc/nginx/sites-enable/你的页面配置文件:

# /etc/nginx/nginx.conf

http {
    
    # =============  添加部分Start  =============
    
    # 定义login_limit_key来设置让访问限制只对POST请求有效,这样用户正常用GET打开页面就不会被count,只有点击登录按钮会count
    map $request_method $login_limit_key {  
        GET     "";
        POST    $binary_remote_addr;  
    }
    
    # 设置上限每分钟5次
    limit_req_zone $login_limit_key zone=wp_login:10m rate=5r/m;

    # =============  添加部分End  =============

    ......
}
# /etc/nginx/sites-enable/你的页面配置文件

server{
    
    ......

    # =============  添加部分Start  =============
    location = /wp-login.php {
        limit_req zone=wp_login burst=3 nodelay;  # 允许极快速度瞬时连点3次,算上上面的就是8次
        limit_req_status 429;

        # 以下四行用于在docker反向代理时让请求带有足够的信息,以避免加载不出css和js
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        proxy_pass http://127.0.0.1:8080;  # 样例,请填写你自己的网站入口。另外要注意不要在最后加斜杠,那样会导致登陆页面永远被重定向到主页
    }

    # =============  添加部分End  =============

    ......

}

通过以上设置就可以让每个IP只能在一分钟内登录5次。如果需要进一步限制,可以使用fail2ban / CrowdSec来设置在一定条件下直接封禁IP。

此外,还有一个有效手段是更改登录入口url,具体原理如下:

首先WordPress 内部的登录入口永远是wp-login.php,不能真的改名。

所谓“换路径”,实际做的是:

🔁 外部访问 /my-secret-login-123 → nginx 内部转发到 /wp-login.php

同时:

🚫 直接访问 /wp-login.php→ 拒绝

这对扫描器是致命的,因为它们只会扫固定路径。

具体方法只需要基于上面的/etc/nginx/sites-enable/配置文件进行进一步修改:

server {

    ......

    # =============  添加部分Start  =============
    
    location = /wp-login.php {

            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;

        # 由于注销按钮和一些其它页面功能仍然会从浏览器访问带URI的wp-login.php,并且在访问后做一些工作,因此我们只屏蔽纯/wp-login.php,对于后面带URI的情况则全部放行。
        if ($args != "") {
            proxy_pass http://127.0.0.1:8080;
            break;
        }
        
        # 使用307跳转而不是302,因为307代表原样重放请求,会带POST body,而302跳转不会
        return 307 /my-secret-login-123;
    }

    location = /my-secret-login-123 {

        limit_req zone=wp_login burst=3 nodelay;

        limit_req_status 429;

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # 需要显式指定URI,否则登录按钮会直接跳转主页。
        proxy_pass http://127.0.0.1:8080/wp-login.php;
    }

    # =============  添加部分End  =============

    ......
}

完成这一步之后的效果是:当黑客使用工具爆破POST /wp-login.php时,他的工具会得到一个307跳转而不是正常的POST返回值。而如果黑客已经对你针对性地使用POST /my-secret-login-123来爆破,那我们还有一分钟五次的限制可以延缓他的进攻。

类似文章

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注