Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
setup-wordpress-with-security-best-practice — WordPress 安装加固全面指南:涵盖管理员用户更改、HTTPS 强制、插件安全、文件权限以及针对静态企业网站的服务器配置。 | Kitploit
工具/GitHubGitHub/password123456/setup-wordpress-with-security-best-practice
配置审计Web安全学习与教育
GitHubpassword123456/setup-wordpress-with-security-best-practice

setup-wordpress-with-security-best-practice

WordPress 安装加固全面指南:涵盖管理员用户更改、HTTPS 强制、插件安全、文件权限以及针对静态企业网站的服务器配置。

查看仓库

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享
29432年前Kitploit 审核通过

Setup WordPress With Security Best Practice

Hits

本文档旨在适用于使用WordPress开发且不与用户交互的Web应用程序。主要适用于企业品牌页面、各类静态视图、招聘页面及类似网站。

对于用户注册并自由使用网站的开放社区等场景,本文档中的某些项目可能不适用。请在阅读时牢记这一点。

本文档不包含确保WordPress安全所需的全部内容。

但是,它包含了一般性和详细的信息,达到了可以根据指南进行安全风险评估和漏洞响应的程度。

如果您觉得有帮助,请点击 "star"🌟 以支持进一步改进。


目录

  • 1. 确保默认 WordPress 管理员用户名已更改
  • 2. 确保 WordPress 用户角色和权限得到妥善管理
  • 3. 确保用户注册已禁用
  • 4. 确保插件文件编辑器已禁用
  • 5. 确保未使用、不必要的插件已停用
  • 6. 确保 WordPress 配置为仅使用 HTTPS,包括 WordPress 管理后台
  • 7. 确保 IP 访问限制 (ACL) 已应用
    • 7.1. 确保对 WordPress 管理后台应用 IP 访问限制。
    • 7.2. 限制 IP 访问或禁用 JSON REST API 功能
    • 7.3. 禁用 XML-RPC API 功能
    • 7.4. 禁用 WP-Cron 或限制功能
  • 8. 保护 WordPress 的系统配置
    • 8.1. 确保使用未生命周期结束 (EOL) 的 WordPress 和 PHP 版本
    • 8.2. 确保仅启用 WordPress 必需的 PHP 扩展
    • 8.3. 确保具有文件上传功能的插件安全
    • 8.4. 确保 PHP 函数和设置配置正确
    • 8.5. 确保 Web 服务器以非 root 用户运行 - 为服务器应用程序使用唯一、非特权用户和组
    • 8.6. 确保 PHP-FPM 以非 root 用户运行 - 为服务器应用程序使用唯一、非特权用户和组
    • 8.7. 确保 WordPress 主目录的安全配置
    • 8.8. 确保在可写目录中禁用 PHP 执行
    • 8.9. 确保 Web 服务器仅响应基于域名的主机头
    • 8.10. 完成的 Web 服务器配置
  • 9. 确保 WordPress 安全更新
  • 10. 确保定期对 WordPress 进行安全漏洞检查

1. 确保默认 WordPress 管理员用户名已更改

安装 WordPress 时,除非在设置过程中更改,否则默认管理员用户名为 "admin"。 "admin" 账户名称广为人知,因此应更改为其他名称。 如果继续使用 "admin" 作为管理员用户名,攻击者可能会尝试使用 "admin" 进行暴力破解攻击,从而访问您的 WordPress 网站。

如果攻击者获得 WordPress 管理员账户的访问权限,他们将拥有对网站的完全控制权。 默认的 WordPress 管理员用户名应更改为其他名称。

审计:

  • 检查默认的 WordPress 管理员用户名是否仍为 "admin"。

修复:

  • 如果用户名为 "admin",请立即将其更改为更不可预测的用户名。
  1. 使用管理员账户登录 WordPress 管理面板。
  2. 从仪表板进入 "用户" 区域,点击 "添加新用户"。
  3. 填写表单,在 "角色" 下拉菜单中选择 "管理员"(记得使用强密码,并利用提供的密码强度指示器确认新密码足够强)。
  4. 完成后,点击 "添加新用户" 按钮。
  5. 使用新的 WordPress 管理员用户名重新登录。
  6. 再次进入 "用户" 区域。
  7. 在用户列表中选择之前的 "admin" 用户名,从下拉菜单中选择 "删除"。
  8. 删除旧管理员时,系统会询问如何处理之前由 "admin" 发布的文章。
    • 选择 "将所有文章和链接归到:" 选项,并选择新的管理员。
    • 设置完成后,点击 "确认删除"。

注意:

  • 始终使用与用户名不同的 "显示名称"。 如果实际用户名被用作内容作者的显示名称,黑客将很容易识别用户名并针对该账户。

2. 确保 WordPress 用户角色和权限得到妥善管理

默认情况下,WordPress 有五个用户角色——"管理员"、"编辑"、"作者"、"贡献者"、"订阅者"

这些角色允许您通过分配适当的权限来控制用户可以在网站上执行哪些任务。 如果用户角色和权限未妥善管理,用户可能会获得对关键功能的不必要访问权限,从而带来重大安全风险。

审计:

  • 检查 WordPress 用户角色和权限是否根据网站需求进行了调整。
  • 审阅所有用户角色,确保其与网站当前运营策略保持一致。

修复:

  • 根据网站需求分配和管理用户角色。
  • 通常,WordPress 应保持一个管理员、一个编辑、一个作者的操作模式。
  • 移除不必要的管理员账户或在需要时降低权限。
  • 定期审查用户及其角色,确保其与任何变更保持同步。

注意:

  • 大多数情况下,对于公司博客、招聘页面、品牌网站和推广网站等以展示内容为主、用户交互较少的服务型网站,"管理员"、"编辑"和"作者"角色就足够了。

3. 确保用户注册已禁用

WordPress 包含一个内置的用户注册功能。此功能默认禁用,但管理员可以激活。

如果启用此功能,任何人都可以注册并可能访问 WordPress 管理面板,这可能导致安全问题。 对于大多数并非作为开放社区运营的网站,用户注册功能是不必要的,应保持禁用。

审计:

  • 检查用户注册是否已禁用。您可以通过尝试访问用户注册页面来检查。
  1. 使用 Web 浏览器

    • 访问 https://yourwordpress.com/wp-login.php?action=register
    • 如果用户注册已禁用,您将看到 "用户注册当前不允许。" 3.1!
  2. 使用 curl

    • 如果用户注册已禁用,它将重定向到禁用页面。```

curl -i -k "https://yourwordpress.com/wp-login.php?action=register"

(response) HTTP/1.1 302 Moved Temporarily cache-control: no-cache, no-store, must-revalidate, max-age=0 content-type: text/html; charset=UTF-8 server: Apache content-length: 0 ... location: https://yourwordpress.com/wp-login.php?registration=disabled

root@kitploit:~
**修复措施:**
- 如果启用了用户注册,请将其禁用。
- 取消勾选“任何人都可以注册”
![3.2!](https://assets.kitploit.com/production/public/readmes/6586/46991061b1bec392d06e00e986f048c6369b8db2c9e5a6b30f4f66dbc9b862d1.png)


## 4. 确保插件文件编辑器已禁用
如果攻击者入侵了WordPress管理员账户,他们就可以完全控制你的网站。
他们可以通过内置的“编辑器”功能编辑主题和插件的代码,上传恶意脚本、篡改网站、向用户发送垃圾邮件等。

通过这些编辑器进行的常见攻击包括SQL注入、SEO垃圾邮件攻击和日本SEO垃圾邮件。

**审计:**
- 确认文件编辑器已禁用。
- 检查是否可以通过外观 > 编辑器或插件 > 插件编辑器访问编辑器。

**修复措施:**
- 如果文件编辑器已启用,请按以下步骤禁用它:

1. 使用文件管理器或FTP访问你的wp-config.php文件。
2. 打开wp-config.php文件进行编辑。
3. 滚动到文件底部(如果使用的是默认wp-config.php)。
4. 找到以下行:
`
/* That’s all, stop editing! Happy publishing. */
`
5. 在此行上方添加以下代码:
`
define('DISALLOW_FILE_EDIT', true);
`
6. 保存更改并关闭编辑器。
7. 返回你的WordPress仪表盘,确认编辑器选项已不可用。


## 5. 确保未使用、不必要的插件已停用
WordPress的许多漏洞源于插件安全问题。
插件是开源的,这使得攻击者更容易发现和利用漏洞。
保持你使用的插件处于最新状态,并停用任何未使用的插件以防止潜在利用至关重要。

**审计:**
- 检查未使用、不必要的插件是否已停用。
- 确认未使用和不必要的插件已停用。

**修复措施:**
- 通过以下步骤停用所有未使用、不必要的插件:

**使用插件检查 - PCP:**
- PCP:https://wordpress.org/plugins/plugin-check
1. 安装并激活插件检查 (PCP):
   - 进入你的WordPress管理员仪表盘
   - 导航到插件 > 安装插件。
   - 搜索“Plugin Check”并安装、激活。

2. 运行插件检查:
   - 在WordPress仪表盘中,进入插件检查菜单。
   - 选择要检查的插件并运行扫描。

3. 分析扫描结果:
   - PCP将分析插件的代码并提供报告,包括:
     - 代码标准合规性:插件符合WordPress编码标准的程度。
     - 安全问题:潜在漏洞或恶意代码。
     - 性能问题:对网站性能的影响。
     - 兼容性问题:插件是否与其他插件和主题兼容。

4. 识别有问题的插件:
   - 如果报告突出显示严重的安全漏洞、恶意代码或大量编码标准违规,则该插件很可能“可疑”。
   - 对发出不必要外部请求或运行过多数据库查询的插件保持警惕。

5. 解决问题:
   - 通过更新或在插件页面上查找问题来解决已识别的问题。
   - 避免使用具有严重安全问题的插件。必要时寻找替代插件。

**插件管理:**
1. 插件选择:
   - 使用官方仓库、查看评分和评论、确认开发者可信度
   - 不要使用未知、未经验证的插件

2. 定期更新
   - 保持插件最新,以确保拥有最新的安全补丁。

3. 停用并删除未使用的插件
   - 即使是不活动的插件也可能带来安全风险,因此如果未使用,请将其删除。
   - 最小化插件:仅使用必要的插件


## 6. 确保WordPress仅配置为使用HTTPS,包括WordPress管理后台
如今,大多数网站都配置为通过SSL(HTTPS)运行。
然而,一些Web服务器可能仍然错误地设置为同时处理HTTP和HTTPS连接。
这可能导致通过两种协议访问WordPress,存在安全风险。应强制WordPress(包括WordPress管理后台)仅使用HTTPS。

**审计:**
- 确认WordPress(包括WordPress管理后台)已配置为仅通过HTTPS访问。
- 检查Web服务器的VirtualHost配置,确保没有设置HTTP VirtualHost。

**修复措施:**
- 如果HTTP访问可用,首先检查并修改Web服务器设置。
- 如果服务器有HTTP VirtualHost,将其重定向到HTTPS或删除HTTP VirtualHost。
- 必要时,启用“FORCE_SSL_ADMIN”功能,强制WordPress管理后台使用HTTPS访问。

**启用FORCE_SSL_ADMIN的步骤:**
1. 使用文件管理器或FTP访问你的wp-config.php文件。
2. 打开wp-config.php文件进行编辑。
3. 滚动到文件底部(如果使用的是默认wp-config.php)。
4. 找到以下行:
`
/* That’s all, stop editing! Happy publishing. */
`
5. 在此行上方添加以下代码:
`
define('FORCE_SSL_ADMIN', true);`
`
6. 保存更改并关闭编辑器。
返回你的WordPress仪表盘并重新登录,确保WordPress管理后台仅可通过HTTPS访问。

**在Web服务器上将HTTP重定向到HTTPS:**
1. 对于Apache:
    ```
    <VirtualHost *:80>
        ServerName yourwordpress.com
    
        RewriteEngine On
        RewriteCond %{HTTPS} off
        RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
    </VirtualHost>
    ```
2. 对于Nginx:
    ```
    server {
        listen 80;
        server_name yourwordpress.com;
    
        location / {
            return 301 https://$host$request_uri;
        }
    }
    ```
通过确保WordPress和WordPress管理后台仅可通过HTTPS访问,你可以显著增强网站的安全性,保护数据并防止未经授权的访问。   

## 7. 确保应用IP访问限制(ACL)
确认已应用IP访问限制

为了安全地运行WordPress,对特定URL(包括WordPress管理后台)应用IP访问限制至关重要,以防止未授权的用户、计算机和机器人访问。这涉及仅允许来自许可IP地址(如管理员IP)的访问。此外,需要禁用未使用的功能以最小化攻击面。

需要保护的URL包括WordPress管理后台、用户注册(wp-signup.php)、JSON REST API和XML-RPC功能。

本安全指南针对服务导向型网站,如公司博客、招聘页面、品牌站点和推广站点,这些网站用户交互较少,内容主要以展示为主。

通过实施IP访问限制,你可以显著降低未经授权访问的风险,并增强网站的整体安全性。


### 7.1. 确保对WordPress管理后台应用IP访问限制
WordPress管理后台访问路径固定为wp-login.php或/wp-admin的形式,使得未经授权的用户可以轻松访问。
确保应用IP访问限制以防止对管理页面的未授权访问。

**审计:**
- 确认已对WordPress管理后台应用IP访问限制。
- 大多数情况下,这是通过Web服务器(Apache、Nginx)配置的。

**修复措施:**
- 如果未应用IP访问限制,请实施它们。
- 以下是使用Apache和Nginx Web服务器应用IP访问限制的方法。

**对WordPress管理后台应用IP访问限制:**
- /wp-admin, wp-login.php 

1. 对于Apache:
    ```
   # Files Directive 
    <Files "wp-login.php">
        Require ip 10.10.77.49  # Replace with your IP address
    </Files>
    
    # FilesMatch Directive
    <FilesMatch "^wp-login\.php$">
        Require all granted
    </FilesMatch>

   # Directory, Files Mixing Directive
    <Directory /www/vhosts/yourwordpress>
        Require all granted
        AllowOverride None
        <Files "wp-login.php">
            Require ip 10.10.77.49  # Replace with your IP address
        </Files>
    </Directory>
   
   # Location Directive
    <Location "/wp-admin">
        Require ip 10.10.77.49  # Replace with your IP address
    </Location>
    
    <Location "/wp-login.php">
        Require ip 10.10.77.49  # Replace with your IP address
    </Location>
    ```
2. 对于Nginx:
    ```
    location /wp-admin {
        allow 10.10.77.49;  # Replace with your IP address
        deny all;
    }
    
    location ~* \wp-login.php {
        allow 10.10.77.49;  # Replace with your IP address
        deny all;
    }
    ```


### 7.2. 限制IP访问或禁用JSON REST API功能
WordPress提供两种REST功能(xmlrpc, json rest api),并且在安装WordPress时默认启用。
REST API为WordPress数据类型提供端点,允许远程与网站交互,执行诸如查询文章或数据、修改资源、编辑和删除等任务。

对于大多数WordPress网站,REST API功能并非必需。
启用它可能使WordPress暴露于DDoS攻击,并可能导致资源消耗和网站变慢。

**审计:**
- 确认JSON REST API功能已启用。(默认:已启用)```
# curl -i -k https://yourwordpress.com/wp-json

(response)
HTTP/1.1 200 OK
cache-control: no-cache, no-store, must-revalidate, max-age=0
content-type: text/html; charset=UTF-8
...
Server: Apache

{"name":"mywordress","description":"".......................

修复措施:

  • 如果不需要REST API,请将其停用。通过简单的插件安装即可禁用。
  • 如果使用REST API,请应用IP访问限制,仅允许来自允许IP的访问。

安装“Disable REST API”插件并激活:

  1. 进入WordPress管理后台
  2. 导航至插件 > 安装插件。
  3. 搜索并安装、激活“Disable REST API"插件。
  4. 激活后,该插件会自动禁用网站上的REST API功能。

JSON REST API的IP访问限制:

  1. 对于Apache:
    root@kitploit:~
    <Location "/wp-json">
        Require ip 10.10.77.49  # Replace with your IP address
    </Location>
    
  2. 对于Nginx:
    root@kitploit:~
    location ~ ^/wp-json/ {
        allow 10.10.77.49;   # Replace with your allowed IP address
        deny all;
    }
    

7.3. 禁用XML-RPC API功能

与JSON REST API类似,建议禁用XML-RPC API,因为大多数WordPress安装并不需要它。

如果确实需要REST API,建议改用JSON REST API。

XML-RPC有两个主要弱点:

暴力破解攻击:

  • 攻击者通过xmlrpc.php尝试使用尽可能多的用户名/密码组合登录WordPress。
  • xmlrpc.php中的一个方法允许攻击者使用单个命令(system.multicall)猜测数百个密码。

通过Pingback的拒绝服务攻击:

  • 早在2013年,攻击者通过大约2500个WordPress网站的xmlrpc.php发送Pingback请求。
  • 这为任何攻击者提供了一个几乎无限的IP地址集,使其能够在一百多万个WordPress网站网络中发起分布式拒绝服务攻击,而无需攻破这些网站。

如果XML-RPC处于启用状态,它仍然可能被利用进行此类攻击。

审计:

  • 验证XML-RPC API功能是否启用。(默认:启用)```

curl -i -k https://yourwordpress.com/xmlrpc.php

(response) HTTP/1.1 405 Method Not Allowed Date: Mon, 25 Jun 2018 08:30:24 GMT Server: Apache Allow: POST Content-Length: 42 Content-Type: text/plain; charset=UTF-8

XML-RPC server accepts POST requests only.

root@kitploit:~
**修复方法:**
- 使用插件禁用 XML-RPC 功能

**安装"Disable XML-RPC-API"插件并激活:**
1. 进入你的 WordPress 管理后台
2. 导航到插件 > 安装插件。
3. 搜索 "[Disable XML-RPC-API](https://wordpress.org/plugins/disable-xml-rpc-api/)" 并安装、激活。
4. XML-RPC-API 现已禁用。

**关于 XML-RPC 回引攻击:**

1. 验证 XML-RPC 是否已启用
    ```
    # curl -i -k https://yourwordpress.com/xmlrpc.php
    
    (response)
    HTTP/1.1 405 Method Not Allowed
    Date: Mon, 25 Jun 2018 08:30:24 GMT
    Server: Apache
    Allow: POST
    Content-Length: 42
    Content-Type: text/plain; charset=UTF-8
     
     
    XML-RPC server accepts POST requests only.
    ```
2. 搜索可用的 XML-RPC 方法
    ```
    (request)
    POST /xmlrpc.php HTTP/1.1
    Host: yourwordpress.com
    Content-Length: 135
    
    <?xml version="1.0" encoding="utf-8"?>
    <methodCall>
        <methodName>system.listMethods</methodName>
        <params></params>
    </methodCall>
    
    
    (response)
    HTTP/1.1 200 OK
    cache-control: no-cache, no-store, must-revalidate, max-age=0
    ...
    Server: Apache
    Content-Length: 4272
    Content-Type: text/xml; charset=UTF-8
    
    <?xml version="1.0" encoding="UTF-8"?>
    <methodResponse>
        <params>
            <param>
                <value>
                    <array><data>
                        <value><string>system.multicall</string></value>
                        <value><string>system.listMethods</string></value>
                        <value><string>system.getCapabilities</string></value>
                        <value><string>demo.addTwoNumbers</string></value>
                        <value><string>demo.sayHello</string></value>
                        <value><string>pingback.extensions.getPingbacks</string></value>
                        <value><string>pingback.ping</string></value>
                        <value><string>mt.publishPost</string></value>
                        ...
                        <value><string>wp.getUsersBlogs</string></value>
                    </data></array>
                </value>
            </param>
        </params>
    </methodResponse>
    
    ```
3. 执行回引攻击
    - 回引攻击的成功与否及具体验证方法未作描述。
    ```
    (request)
    POST /xmlrpc.php HTTP/1.1
    Host: yourwordpress.com
    Content-Length: 303
    
    <?xml version="1.0" encoding="UTF-8"?>
        <methodCall>
        <methodName>pingback.ping</methodName>
            <params>
                <param>
                    <value><string>call-back url for pingback result</string></value>
                </param>
                <param>
                    <value><string>https://yourwordpress.com/</string></value>
            </param>
        </params>
    </methodCall>
    
    
    (response)
    HTTP/1.1 200 OK
    ...
    Server: Apache
    Content-Length: 370
    Content-Type: text/xml; charset=UTF-8
    
    <?xml version="1.0" encoding="UTF-8"?>
    <methodResponse>
      <fault>
        <value>
          <struct>
            <member>
              <name>faultCode</name>
              <value><int>0</int></value>
            </member>
            <member>
              <name>faultString</name>
              <value><string></string></value>
            </member>
          </struct>
        </value>
      </fault>
    </methodResponse>
    ```


### 7.4. 禁用 WP-Cron 或限制功能
在 WordPress 中,WP-Cron (wp-cron.php) 用于自动化执行任务,如定时发布文章、检查插件/主题更新以及发送通知邮件。

WP-Cron 的基本工作原理是在每次页面加载时检查预定任务列表。
问题出现在页面加载量很大时。

由于每次页面加载都会执行 WP-Cron 任务,多次重复访问会导致相应的 WP-Cron 调用。因此,系统资源可能变得紧缺,导致网站变慢甚至停止响应。
这是真实存在的情况,并且经常被用于针对 WordPress 的漏洞攻击。

如果不需要 WP-Cron,建议禁用它。
如果需要,则限制仅本地主机访问。

**审计:**
- 验证 WP-Cron 是否已启用。(默认:启用)```
# curl -i -k https://yourwordpress.com/wp-cron.php

(response)
HTTP/1.1 200 ok
Date: Mon, 25 Jun 2018 08:30:24 GMT
Server: Apache
Allow: POST
Content-Length: 42
Content-Type: text/plain; charset=UTF-8

修复措施:

  • 如果未使用 WP-Cron,请禁用该功能。
  • 如果已使用,请酌情选用以下方案之一:
    1. 启用“ALTERNATE_WP_CRON”并限制对 wp-cron.php 的 IP 访问。
    2. 使用系统 cron (crontab) 或其他替代方式执行定时任务。

禁用 WP-Cron 的步骤:

  1. 使用文件管理器或 FTP 访问你的 wp-config.php 文件。
  2. 打开 wp-config.php 文件进行编辑。
  3. 向下滚动到文件底部(如果使用默认的 wp-config.php)。
  4. 找到以下这一行: /* That’s all, stop editing! Happy publishing. */
  5. 在这一行上方添加以下代码: define('DISABLE_WP_CRON', true);
  6. 保存更改并关闭编辑器。
  7. 使用 Apache 和 Nginx 应用 IP 访问限制。
    1. 对于 Apache:
      root@kitploit:~
      # Files 指令
      <Files "wp-cron.php">
          Require ip 127.0.0.1  # 仅限本地主机
      </Files>
      
      # FilesMatch 指令
      <FilesMatch "^wp-cron\.php$">
          Require ip 127.0.0.1  # 仅限本地主机
      </FilesMatch>
      
      # Location 指令
      <Location "/wp-cron.php">
          Require ip 127.0.0.1  # 仅限本地主机
      </Location>
      
    2. 对于 Nginx:
      root@kitploit:~
       location = /wp-cron.php {
           allow 127.0.0.1;
           deny all;
           access_log off;
           log_not_found off;
       }
      

启用“ALTERNATE_WP_CRON”的步骤:

  1. 使用文件管理器或 FTP 访问你的 wp-config.php 文件。
  2. 打开 wp-config.php 文件进行编辑。
  3. 向下滚动到文件底部(如果使用默认的 wp-config.php)。
  4. 找到以下这一行: /* That’s all, stop editing! Happy publishing. */
  5. 在这一行上方添加以下代码: define( 'ALTERNATE_WP_CRON', true );
  6. 保存更改并关闭编辑器。
  7. 使用 Apache 和 Nginx 应用 IP 访问限制。
    1. 对于 Apache:
      root@kitploit:~
      # Files 指令
      <Files "wp-cron.php">
          Require ip 127.0.0.1  # 仅限本地主机
      </Files>
      
      # FilesMatch 指令
      <FilesMatch "^wp-cron\.php$">
          Require ip 127.0.0.1  # 仅限本地主机
      </FilesMatch>
      
      # Location 指令
      <Location "/wp-cron.php">
          Require ip 127.0.0.1  # 仅限本地主机
      </Location>
      
    2. 对于 Nginx:
      root@kitploit:~
       location = /wp-cron.php {
           allow 127.0.0.1;
           deny all;
           access_log off;
           log_not_found off;
       }
      

示例:使用系统 Cron (crontab):

  • 在应用前,请先禁用 WP-Cron。```

vim /etc/crontab

.. ... */10 * * * * curl http://yourwordpress.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1

*/10 * * * * cd /var/www/yourwordpress.com/htdocs; php /var/www/yourwordpress.com/htdocs/wp-cron.php?doing_wp_cron > /dev/null 2>&1

Also can use WP-Cli

*/10 * * * * cd /var/www/example.com/htdocs; wp cron event run --due-now > /dev/null 2>&1

root@kitploit:~
**关于使用 wp-cron.php 进行拒绝服务攻击:**
- 向 wp-cron.php 发送大量请求
- 这会导致脚本消耗过量资源,最终使服务器过载
![7.4.1!](https://assets.kitploit.com/production/public/readmes/6586/b1647fd6883b8d7b3178e7f042290fada6614e9de11a4e6e256f435902b12633.png)
![7.4.2!](https://assets.kitploit.com/production/public/readmes/6586/07d6a5d1794a3ba03177b78f63631eb5fb8f8f6092d6156965535847636d2769.png)


## 8. 安全 WordPress 的系统配置
确保 WordPress 的安全运行需要对 Web 服务器进行正确配置并加固后端组件。
以下是几个必须检查和实施的关键项目。

### 8.1. 确保使用非生命周期终结 (EOL) 的 WordPress 和 PHP 版本
为了维护安全的 WordPress 安装,使用非生命周期终结(EOL)的 WordPress 和 PHP 版本至关重要。
EOL 版本不再受支持,也不会收到安全更新,这会使您的网站容易受到未修补的安全问题影响。

使用受支持的版本可确保任何发现的漏洞都能及时得到修复,从而保护您的站点免受潜在攻击。
以下是验证和更新 WordPress 及 PHP 版本所需执行的操作:

**审计:**
- 确认您当前的 WordPress 和 PHP 版本并非 EOL。

**修复:**
- 安装并运行非 EOL 版本的 WordPress 和 PHP。
- 截至 2024 年 5 月,受支持的 WordPress 版本为 6.5 及以上。受支持的 PHP 版本为 8.1、8.2 和 8.3。
- 如果您使用 Web 托管服务,请利用其版本切换功能,确保您运行的 WordPress 和 PHP 版本均受支持。

**截至 2024 年 5 月的 EOL 状态**
 1. PHP: [supported-versions](https://www.php.net/supported-versions.php)
    - 当前受支持版本:8.1、8.2、8.3
 2. WordPress: [current-releases](https://wordpress.org/download/releases/)
    - 当前受支持版本:6.5 系列

**示例:RockyLinux 8.5 中的 PHP**
- 在 RockyLinux 8.5 中,默认可用的 PHP 版本为 7.2、7.3 和 7.4。
    ```
    # dnf module list php
    Rocky Linux 8 - AppStream
    Name         Stream          Profiles                           Summary                       
    php          7.2 [d]         common [d], devel, minimal         PHP scripting language        
    php          7.3             common [d], devel, minimal         PHP scripting language        
    php          7.4             common [d], devel, minimal         PHP scripting language        
    
    Hint: [d]efault, [e]nabled, [x]disabled, [i]nstalled
    
    # dnf module enable php:7.4
    ==============================================================================================
     Package               Architecture         Version               Repository             Size
    ==============================================================================================
    Enabling module streams:
     httpd                                      2.4                                              
     php                                        7.4                                              
    
    Transaction Summary
    ==============================================================================================
    
    Is this ok [y/N]: y
    Complete!
    ```
- PHP 7 已到达生命周期终结(EOL);建议升级到 PHP 8。
- PHP 8 可以从 REMI 仓库安装。
- 以下是如何使用 REMI 启用并安装 PHP 8.2 的示例:
    ```
    # Install PHP 8.2 in Rocky Linux 8
    
    # dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
    # dnf -y install https://rpms.remirepo.net/enterprise/remi-release-8.rpm
    # dnf -y install yum-utils
    # dnf module reset php
    # dnf module install php:remi-8.2
    Last metadata expiration check: 0:00:39 ago on Tue 13 Dec 2022 07:19:26 AM UTC.
    Dependencies resolved.
    =======================================================================================================================================
     Package                       Architecture        Version                                             Repository                 Size
    =======================================================================================================================================
    Installing group/module packages:
     php-cli                       x86_64              8.2.0-1.el8.remi                                    remi-modular              5.4 M
     php-common                    x86_64              8.2.0-1.el8.remi                                    remi-modular              1.3 M
     php-fpm                       x86_64              8.2.0-1.el8.remi                                    remi-modular              1.9 M
     php-mbstring                  x86_64              8.2.0-1.el8.remi                                    remi-modular              574 k
     php-xml                       x86_64              8.2.0-1.el8.remi                                    remi-modular              254 k
    Installing dependencies:
     httpd-filesystem              noarch              2.4.37-51.module+el8.7.0+1059+126e9251              appstream                  41 k
     libxslt                       x86_64              1.1.32-6.el8                                        baseos                    249 k
     oniguruma5php                 x86_64              6.9.8-1.el8.remi                                    remi-safe                 212 k
    Installing weak dependencies:
     nginx-filesystem              noarch              1:1.14.1-9.module+el8.4.0+542+81547229              appstream                  23 k
    Installing module profiles:
     php/common
    Enabling module streams:
     httpd                                             2.4
     nginx                                             1.14
     php                                               remi-8.2
    
    Transaction Summary
    =======================================================================================================================================
    Install  9 Packages
    
    # dnf update
    # dnf install php
    Last metadata expiration check: 0:00:23 ago on Tue 13 Dec 2022 07:29:55 AM UTC.
    Dependencies resolved.
    =======================================================================================================================================
     Package                       Architecture       Version                                               Repository                Size
    =======================================================================================================================================
    Installing:
     php                           x86_64             8.2.0-1.el8.remi                                      remi-modular             1.8 M
    Installing dependencies:
     apr                           x86_64             1.6.3-12.el8                                          appstream                128 k
     apr-util                      x86_64             1.6.1-6.el8.1                                         appstream                104 k
     httpd                         x86_64             2.4.37-51.module+el8.7.0+1059+126e9251                appstream                1.4 M
     httpd-tools                   x86_64             2.4.37-51.module+el8.7.0+1059+126e9251                appstream                108 k
     libsodium                     x86_64             1.0.18-2.el8                                          epel                     162 k
     mailcap                       noarch             2.1.48-3.el8                                          baseos                    38 k
     mod_http2                     x86_64             1.15.7-5.module+el8.6.0+823+f143cee1                  appstream                153 k
     rocky-logos-httpd             noarch             86.3-1.el8                                            baseos                    24 k
    Installing weak dependencies:
     apr-util-bdb                  x86_64             1.6.1-6.el8.1                                         appstream                 23 k
     apr-util-openssl              x86_64             1.6.1-6.el8.1                                         appstream                 26 k
     php-opcache                   x86_64             8.2.0-1.el8.remi                                      remi-modular             633 k
     php-pdo                       x86_64             8.2.0-1.el8.remi                                      remi-modular             166 k
     php-sodium                    x86_64             8.2.0-1.el8.remi                                      remi-modular             105 k
    
    Transaction Summary
    =======================================================================================================================================
    Install  14 Packages
    
    Total download size: 4.8 M
    Installed size: 14 M
    Is this ok [y/N]: y
    
    # php -v
    PHP 8.2.0 (cli) (built: Dec  6 2022 14:26:47) (NTS gcc x86_64)
    Copyright (c) The PHP Group
    Zend Engine v4.2.0, Copyright (c) Zend Technologies
        with Zend OPcache v8.2.0, Copyright (c), by Zend Technologies
    ```
**注意:**
- 有关从 REMI 仓库安装 PHP 的详细说明,请参阅:[rpms.remirepo.net](https://rpms.remirepo.net/)
- WordPress 和 PHP 兼容性文档:[php-compatibility-and-wordpress-versions](https://make.wordpress.org/core/handbook/references/php-compatibility-and-wordpress-versions/)


### 8.2. 确保仅启用 WordPress 所需的 PHP 扩展
确保仅启用了 WordPress 站点所需的 PHP 扩展。
不必要的扩展会增加网站的受攻击面,并可能使 WordPress 暴露于安全漏洞之下。

通过只启用必需的扩展,可以最大程度地降低潜在风险并提高整体安全性。

以下是 WordPress 站点正常运行所必需的扩展。**(并非针对安全加固目的的列表)**

| 扩展 | 描述 |
|-----------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| json      | 用于与其他服务器通信以及处理 JSON 格式的数据。 |
| mysqli    | 连接 MySQL 以进行数据库交互。 |
| curl      | 执行远程请求操作。 |
| dom       | 用于验证文本小部件内容以及自动配置 IIS7+。 |
| exif      | 处理图像中存储的元数据。 |
| fileinfo  | 用于检测文件上传的 MIME 类型。 |
| hash      | 用于哈希处理,包括密码和更新包。 |
| igbinary  | 作为标准 PHP 序列化器的替代品,提升性能。 |
| imagick   | 为媒体上传提供更好的图像质量。详见 WP_Image_Editor。在同时安装 Ghost Script 时,支持更智能的图像缩放(适用于较小图像)和 PDF 缩略图生成。 |
| intl      | 启用区域感知操作,包括但不限于格式化、音译、编码转换、日历操作、一致性排序、定位文本边界,以及处理区域标识符、时区和字形簇。 |
| mbstring  | 用于正确处理 UTF8 文本。 |
| openssl   | 与其他主机建立基于 SSL 的连接。 |
| pcre      | 提高代码搜索中模式匹配的性能。 |
| xml       | 用于 XML 解析,例如来自第三方站点。 |
| zip       | 用于解压缩插件、主题和 WordPress 更新包。 |
| bc        | 用于任意精度数学运算,支持任意大小和精度(最高 2147483647 个十进制数字)的数字。 |
| filter    | 用于安全过滤用户输入。 |
| image     | 如果未安装 Imagick,则使用 GD 图形库作为图像处理的功能有限的回退方案。 |
| iconv     | 用于在不同字符集之间进行转换。 |
| shmop     | Shmop 是一组易于使用的函数,允许 PHP 读取、写入、创建和删除 Unix 共享内存段。 |
| simplexml | 用于 XML 解析。 |
| sodium    | 验证签名并提供安全的随机字节。 |
| xmlreader | 用于 XML 解析。 |
| zlib      | Gzip 压缩和解压缩。 |

必要的扩展可在此处找到:[WordPress 托管手册:PHP 扩展](https://make.wordpress.org/hosting/handbook/server-environment/#php-extensions)

**审计:**
- 确认仅启用了 WordPress 站点所需的 PHP 扩展。

**修复:**
- 移除任何不必要的扩展。有时,扩展会随插件一起安装,而您的站点可能并不需要它们。
- 要检查当前启用的 PHP 扩展,可以查看 **php.ini** 文件,或使用 **phpinfo()** 函数列出所有活动扩展。

![8.2!](https://assets.kitploit.com/production/public/readmes/6586/1e270a242227b8dc8fa965765c69b7927b170de108acdbe1fad91455e484e615.png)

- 某些扩展如果不需要,应禁用,以防止潜在的安全问题。
- 例如,像 exif、fileinfo、imap、soap、pdo_sqlite 和 opcache 这样的扩展如果启用却不使用,可能会被利用。
- 如果您使用 Web 托管服务,许多提供商提供易于使用的界面来切换 PHP 设置,包括启用或禁用 PHP 扩展。利用这些功能,您可以有效地管理扩展。


### 8.3. 确保具有文件上传功能的插件安全
具有文件上传功能的插件如果未正确保护,可能会构成重大安全风险。文件上传功能中的漏洞可能允许攻击者上传 Web shell,从而导致系统完全受损。因此,确保任何文件上传功能包含验证和清理机制至关重要。

为什么这很重要?
1. 扩展名验证:
   - 服务器应根据允许类型的白名单验证文件扩展名,以防止上传恶意文件。

2. MIME 类型检查:
   - 应检查文件的 MIME 类型,确保其符合预期类型,从而增加一层额外的安全保护。

3. 上传路径限制:
   - 确保不存在未经验证即可直接访问上传文件的暴露路径。

文件上传漏洞尤其危险,因为它们为攻击者上传可执行代码并运行任意命令提供了直接途径。与 SQL 注入等其他安全缺陷相比,文件上传漏洞通常更容易识别和利用。

**审计:**
- 识别您的 WordPress 站点上具有文件上传功能的插件。
- 验证这些插件是否对上载文件实施了适当的验证检查,包括扩展名和 MIME 类型验证。

**修复:**
- 如果具有文件上传功能的插件缺乏适当的验证,要么增强其安全性,要么移除该插件。
- 以下是具有文件上传功能的流行 WordPress 插件示例及其文件验证处理方式。

**示例:具有文件上传处理功能的流行 WordPress 插件**

1. Contact Form 7
   - Contact Form 7 是 WordPress 中使用最广泛的表单插件之一。它包含基本的文件上传功能,并带有扩展名和 MIME 类型验证。**允许的扩展名和MIME类型检查的代码:**
     ```
      function wpcf7_allowed_file_extensions() {
          // Default allowed file extensions
          $allowed_file_extensions = array(
              'jpg', 'jpeg', 'png', 'gif', 'pdf', 'doc', 'docx',
              'xls', 'xlsx', 'txt', 'csv', 'rtf', 'html', 'zip'
          );
          return $allowed_file_extensions;
      }
    
      function wpcf7_handle_upload( $file ) {
          $allowed_mime_types = wpcf7_allowed_file_extensions();
          $file_type = wp_check_filetype( $file['name'] );
    
          // Check if the file type is allowed
          if ( ! in_array( $file_type['ext'], $allowed_mime_types ) ) {
              return new WP_Error( 'wpcf7_upload_failed', __( 'File type is not allowed.', 'contact-form-7' ) );
          }
    
          // Handle the file upload
          $upload = wp_handle_upload( $file, array( 'test_form' => false ) );
    
          // Check if the upload was successful
          if ( isset( $upload['error'] ) ) {
              return new WP_Error( 'wpcf7_upload_failed', $upload['error'] );
          }
    
          return $upload;
      }
      ```
      在Contact Form 7中,`wpcf7_allowed_file_extensions()`函数返回允许的文件扩展名列表,而`wpcf7_handle_upload()`函数在上传前检查文件扩展名是否在此列表中。

2. WPForms
   - WPForms通过检查允许的文件类型来处理文件上传。

      **WPForms的示例代码:**
       ```
         function wpforms_get_file_types() {
          // Return an array of allowed file types
          return array( 'jpg', 'jpeg', 'png', 'gif', 'pdf', 'doc', 'docx' );
      }
    
      function wpforms_process_file_upload( $file ) {
          $allowed_file_types = wpforms_get_file_types();
          $file_type = wp_check_filetype( $file['name'] );
    
          if ( ! in_array( $file_type['ext'], $allowed_file_types ) ) {
              return new WP_Error( 'wpforms_upload_failed', __( 'File type is not allowed.', 'wpforms' ) );
          }
    
          $upload = wp_handle_upload( $file, array( 'test_form' => false ) );
    
          if ( isset( $upload['error'] ) ) {
              return new WP_Error( 'wpforms_upload_failed', $upload['error'] );
          }
    
          return $upload;
      }
      ```

3. WooCommerce
   - WooCommerce也在其上传处理代码中直接定义和检查允许的文件扩展名。
   
       **WooCommerce的示例代码:**
        ```
        function woocommerce_handle_upload( $file ) {
            $allowed_file_types = array( 'jpg', 'jpeg', 'png', 'gif', 'pdf', 'doc', 'docx' );
            $file_type = wp_check_filetype( $file['name'] );
        
            if ( ! in_array( $file_type['ext'], $allowed_file_types ) ) {
                return new WP_Error( 'woocommerce_upload_failed', __( 'File type is not allowed.', 'woocommerce' ) );
            }
        
            $upload = wp_handle_upload( $file, array( 'test_form' => false ) );
        
            if ( isset( $upload['error'] ) ) {
                return new WP_Error( 'woocommerce_upload_failed', $upload['error'] );
            }
        
            return $upload;
        }
        ```

**示例:恶意文件上传插件**
- 一个恶意插件可能看起来无害,但会利用fileinfo扩展来绕过安全检查:
    ```
    <?php
    /*
    Plugin Name: Simple Malicious Upload
    Description: A plugin with hidden malicious file upload capability.
    Version: 1.0
    */
    
    function simple_file_upload_menu() {
        add_menu_page('File Upload', 'File Upload', 'manage_options', 'file-upload', 'simple_file_upload_page');
    }
    
    add_action('admin_menu', 'simple_file_upload_menu');
    
    function simple_file_upload_page() {
        ?>
        <h1>File Upload</h1>
        <form method="post" enctype="multipart/form-data">
            <input type="file" name="uploaded_file" />
            <input type="submit" name="upload_file" value="Upload" />
        </form>
        <?php
    
        if (isset($_POST['upload_file'])) {
            simple_handle_file_upload();
        }
    }
    
    function simple_handle_file_upload() {
        if (!empty($_FILES['uploaded_file']['tmp_name'])) {
            $file_tmp = $_FILES['uploaded_file']['tmp_name'];
            $file_name = basename($_FILES['uploaded_file']['name']);
    
            // Using fileinfo to check MIME type
            $finfo = finfo_open(FILEINFO_MIME_TYPE);
            $mime_type = finfo_file($finfo, $file_tmp);
            finfo_close($finfo);
    
            // Insecure handling: allows any PHP files to be uploaded
            if ($mime_type === 'text/plain' || $mime_type === 'application/x-php') {
                $upload_dir = wp_upload_dir();
                $upload_file = $upload_dir['path'] . '/' . $file_name;
    
                // Move the uploaded file to the uploads directory
                if (move_uploaded_file($file_tmp, $upload_file)) {
                    echo "File uploaded successfully.";
                } else {
                    echo "File upload failed.";
                }
            } else {
                echo "Invalid file type.";
            }
        }
    }
    ?>
    ```
**漏洞利用说明:**
- 恶意插件允许上传PHP文件,只要其MIME类型是`application/x-php.`
- 攻击者可以利用此功能上传PHP Web shell。
- 上传后,攻击者访问文件的URL并执行任意命令。

**示例:PHP Web Shell代码**```
<?php
if (isset($_GET['cmd'])) {
    echo "<pre>";
    system($_GET['cmd']);
    echo "</pre>";
}
?>

攻击演示

  1. 上传 Web Shell:
    • 攻击者通过插件的上传表单上传 webshell.php。
  2. 访问并使用 Web Shell:
    • 攻击者通过 http://yourwordpress.com/wp-content/uploads/webshell.php 访问 Web Shell。
    • 通过访问 http://yourwordpress.com/wp-content/uploads/webshell.php?cmd=ls,攻击者可执行任意命令。

注意:

  • 该示例旨在说明具有文件上传功能的插件可能被滥用。
  • 确保实施正确的验证和清理可以防止潜在的利用,并维护 WordPress 站点的安全。
  • 上述插件代码仅用于教育目的。

8.4. 确保 PHP 函数和设置已正确配置

确保 PHP 函数和设置已正确配置,可以显著增强 WordPress 站点的安全性。错误的配置可能使站点暴露于多种漏洞,包括远程代码执行、信息泄露和会话劫持。加固 PHP,禁用或正确配置这些函数至关重要。

为什么这很重要?

  1. 远程代码执行:

    • 诸如 allow_url_fopen 的设置以及 exec 等函数可能导致远程代码执行,从而可能危及系统安全。
  2. 信息泄露:

    • display_errors 和 expose_php 等选项可能泄露服务器设置相关的敏感信息,使攻击者更容易发现漏洞。
  3. 会话安全:

    • 正确的会话管理设置(如 session.cookie_secure 和 session.cookie_httponly)可保护会话 Cookie 不被客户端脚本访问,也不通过不安全通道传输。

审计:

  • 验证下列不安全的 PHP 函数和设置是否已正确配置并加固。

修复:

  • 检查以下 PHP 设置和函数,并根据需要进行调整,以确保 WordPress 站点安全且功能正常。
  1. allow_url_fopen:

    • 允许函数通过 URL 打开和读取文件。
    • 启用后,file_get_contents()、fopen()、include() 和 require() 等函数可通过 FTP 或 HTTP 从远程位置获取数据。
    • WordPress 及其许多插件可能依赖 allow_url_fopen 实现某些功能。
    • 但并非始终需要启用此设置。出于安全考虑,最好仅在必要时启用。
      root@kitploit:~
      ; (可选)如果不需要,请禁用 allow_url_fopen
      
       allow_url_fopen = Off
      
  2. display_errors:

    • 决定 PHP 错误是否作为输出的一部分打印到屏幕。
    • 显示错误可能泄露服务器环境和应用程序的敏感信息,攻击者可利用这些信息利用漏洞。
      root@kitploit:~
      ; 禁用 PHP 错误,不在你的 WordPress 网站上显示
      
      display_errors = Off
      
  3. expose_php:

    • 控制 PHP 是否在 HTTP 头中声明其存在和版本。
    • 泄露此信息可能帮助攻击者识别存在漏洞的 PHP 版本。
      root@kitploit:~
      ; 防止在 HTTP 响应头中暴露 PHP 版本
      
      expose_php = Off
      session.cookie_secure
      
  4. session.cookie_secure:

    • 确保会话 Cookie 仅通过安全的 HTTPS 连接传输,防止传输过程中被拦截。
      root@kitploit:~
      ; 确保会话 Cookie 通过 HTTPS 发送
      
      session.cookie_secure = On
      session.cookie_httponly
      
  5. session.cookie_httponly:

    • 使会话 Cookie 无法被 JavaScript 访问,从而降低跨站脚本(XSS)攻击的风险。

示例:以下是实际 WordPress 中已禁用的 PHP 函数列表``` system, exec, shell_exec, passthru, mysql_list_dbs, ini_alter, dl, symlink, link, chgrp, leak, popen, apache_child_terminate, virtual, mb_send_mail

root@kitploit:~
### 8.5. 确保 Web 服务器以非 root 用户运行 - 为服务器应用使用唯一、非特权的用户和组

在大多数情况下,Web 服务器以诸如 "www-data"(Debian/Ubuntu)或 "apache"(RHEL/CentOS)之类的用户运行。

这些用户是专用的服务账户,在服务器上没有任何特殊权限,用于指定 Web 服务器工作进程将采用的用户和组。

如果这些用户拥有系统权限或正以 root 身份运行,则必须进行更改。

**审计:**
- 验证运行 Web 服务器进程的用户。(具体而言,是 Web 服务器工作进程。)

1. 对于 Apache:
    ```
    # ps -ef | grep httpd
    root     2257     1  0 Apr08 ?        00:00:01 /usr/local/apache/bin/httpd -k start
    apache   5678  1234  0 Apr08 ?        00:00:00 /usr/sbin/httpd -k start
    apache   5679  1234  0 Apr08 ?        00:00:00 /usr/sbin/httpd -k start
    apache   5680  1234  0 Apr08 ?        00:00:00 /usr/sbin/httpd -k start
    apache   5681  1234  0 Apr08 ?        00:00:00 /usr/sbin/httpd -k start
    ```

2. 对于 Nginx:
    ```
    # ps -ef | grep nginx
    root      626653       1  0 Apr08 ?        00:00:00 nginx: master process /usr/sbin/nginx
    nginx     626654  626653  0 Apr08 ?        00:00:00 nginx: worker process
    nginx     626655  626653  0 Apr08 ?        00:00:00 nginx: worker process
    nginx     626656  626653  0 Apr08 ?        00:00:00 nginx: worker process
    nginx     626657  626653  0 Apr08 ?        00:00:00 nginx: worker process
    ```

**修复:**
- Web 服务器应以非特权、专用的账户运行。
- 在大多数情况下,会使用这些常用账户之一,例如 "www-data"、"apache"、"nginx"、"nobody" 或 "daemon"。

1. 对于 Apache:
    ```
    # vim /etc/httpd/httpd.conf
    ..
    ...
    User www-data
    Group www-data
    ..
    ...
    ```

2. 对于 Nginx:
    ```
    # vim /etc/nginx/nginx.conf
    ..
    ...
    user daemon;
    ```

**注意:**
- Web 服务器的进程用户不应具有 shell 登录权限。  ```
  # cat /etc/passwd | grep -i www-data
  www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin

8.6. 确保PHP-FPM以非root用户运行 - 为服务器应用程序使用唯一的、非特权用户和组

WordPress由PHP构建,因此正确的系统配置对于正确执行PHP代码是必要的。

WordPress中的PHP代码执行由PHP-FPM管理,这是一个FastCGI进程管理器。 为了确保PHP-FPM的安全运行,它应该在一个非特权、专用的服务账户下运行。

通常,Web服务器进程账户和PHP-FPM账户设置为同一账户。 然而,为了增强安全性,最好将它们分别运行在不同的账户下。

原因如下:

  1. 进程隔离:

    • 将Web服务器和PHP-FPM分别运行在不同的账户下可实现进程隔离。
    • 这降低了某一服务被攻破后影响另一服务的风险。
    • 如果攻击者获得了Web服务器进程的访问权限,他们不一定能访问PHP-FPM,反之亦然。
  2. 最小权限原则:

    • 通过为每个服务使用专用的、非特权的账户,可以遵循最小权限原则。
    • 这限制了每个服务所具有的权限和访问范围,从而最大限度地减少安全漏洞或破坏可能造成的损害。

审计:

  • 验证运行PHP-FPM进程的账户。```

ps -ef | grep php-fpm

root 1234 1 0 12:00 ? 00:00:01 php-fpm: master process (/etc/php-fpm.conf) php-fpm 5678 1234 0 12:00 ? 00:00:00 php-fpm: pool www php-fpm 5679 1234 0 12:00 ? 00:00:00 php-fpm: pool www php-fpm 5680 1234 0 12:00 ? 00:00:00 php-fpm: pool www php-fpm 5681 1234 0 12:00 ? 00:00:00 php-fpm: pool www

root@kitploit:~
**修复措施:**
- PHP-FPM 应以一个非特权专用账户运行。
- 在大多数情况下,使用的账户是 "php-fpm"。

**更改 PHP-FPM 的进程账户:**```
# vim /etc/php-fpm.d/www.conf # Adjust the path based on your PHP version
...
user = php-fpm
group = php-fpm
listen.owner = php-fpm 
listen.group = php-fpm 

PHP-FPM 进程账户不应拥有 shell 登录权限。```

cat /etc/passwd | grep php-fpm

php-fpm❌999:999:PHP-FPM:/run/php:/usr/sbin/nologin

root@kitploit:~
**注意:**
- 从安全角度来看,最好为 PHP-FPM 进程和 Web 服务器进程使用不同的用户账户。
- 当被问及哪种方式更安全时,它们应该是不同的。在此上下文中,避免使用相同的执行账户。

### 8.7. 确保 WordPress 主目录的安全配置

为了安全地运行 Web 服务器,正确配置 WordPress 主目录的所有权和权限至关重要。

在大多数情况下,WordPress 文件和目录的所有权和权限设置为与 Web 服务器的进程账户匹配。
这种配置允许 Web 服务器访问 Web 根目录中的文件并无错误地运行。

然而,这种配置是不安全的。

例如,如果 Web 服务器进程是 'apache',并且 Web 根目录和文件都由 'apache' 所有者拥有,则可能导致严重漏洞。
攻击者可以利用这些漏洞获得对 WordPress 主目录中关键文件和目录的未授权访问。

**常见漏洞示例:**
- 如果 Web 服务器进程账户和主目录(Web 根目录)以及文件都由 'apache' 拥有:
- 如果网站存在漏洞且外部可访问系统(如 webshell),攻击者可以在 Web 根目录内执行多种操作:
  1. 创建、修改或删除 Web 根目录内的文件或目录。
  2. 操作 Web 访问日志,包括修改、删除或创建(某些环境除外)。
  3. 可以访问已登录用户的活跃会话 cookie(在特别易受攻击的环境中)。

为了减轻这些风险,正确调整 WordPress 主目录的所有权和权限至关重要。

**补救措施:**
- 将主目录(Web 根目录)和文件的所有者设置为 'root:root'。(避免与 Web 服务器进程账户相同)
- 目录和文件的默认 UMASK 为 022。(目录:755,文件:644)
- 对于需要写入权限的目录(如 Web 服务上传文件),将这些目录的所有者设置为 Web 服务器进程账户。

**WordPress 中通常需要写入权限的目录:**```
/wp-content/uploads
/wp-content/cache
/wp-content/wflogs (when using security plugins like Wordfence)
/wp-content/upgrade (used during the WordPress upgrade process)

按照上述修复措施配置主目录的所有权和权限后,WordPress 主目录的输出如下:

示例:WordPress 主目录``` drwxr-xr-x 5 root root 4096 May 27 2024 . drwxr-xr-x 3 root root 4096 May 27 2024 .. -rw-r--r-- 1 root root 418 May 27 2024 index.php -rw-r--r-- 1 root root 19935 May 27 2024 license.txt -rw-r--r-- 1 root root 7346 May 27 2024 readme.html -rw-r--r-- 1 root root 7106 May 27 2024 wp-activate.php drwxr-xr-x 9 root root 4096 May 27 2024 wp-admin -rw-r--r-- 1 root root 351 May 27 2024 wp-blog-header.php -rw-r--r-- 1 root root 2328 May 27 2024 wp-comments-post.php -rw-r--r-- 1 root root 4973 May 27 2024 wp-config-sample.php -rw-r--r-- 1 root root 2755 May 27 2024 wp-config.php drwxr-xr-x 8 root root 4096 May 27 2024 wp-content -rw-r--r-- 1 root root 3940 May 27 2024 wp-cron.php drwxr-xr-x 25 root root 12288 May 27 2024 wp-includes -rw-r--r-- 1 root root 2496 May 27 2024 wp-links-opml.php -rw-r--r-- 1 root root 3300 May 27 2024 wp-load.php -rw-r--r-- 1 root root 51556 May 27 2024 wp-login.php -rw-r--r-- 1 root root 8403 May 27 2024 wp-mail.php -rw-r--r-- 1 root root 24568 May 27 2024 wp-settings.php -rw-r--r-- 1 root root 30869 May 27 2024 wp-signup.php -rw-r--r-- 1 root root 4620 May 27 2024 wp-trackback.php -rw-r--r-- 1 root root 3065 May 27 2024 xmlrpc.php

root@kitploit:~
**在 php-fpm 和 Web 服务器进程账户不同时(分离权限)**

如果 Web 服务器进程账户是 "apache",而 php-fpm 进程账户是 "php-fpm"。

更改 WordPress 中需要写入权限的目录(例如 /wp-content/uploads)的权限。
- 所有者:php-fpm
- 组:apache
- 目录权限:775(必要时使用 755)

**文件和目录结构**

设置所需目录的写入权限,以便 "php-fpm" 和 "apache" 账户都能写入。```
ex) /service/wordpress/www
├── index.php             (root:root, 644)
├── license.txt           (root:root, 644)
├── readme.html           (root:root, 644)
├── wp-activate.php       (root:root, 644)
├── wp-admin/             (root:root, 755)
├── wp-blog-header.php    (root:root, 644)
├── wp-comments-post.php  (root:root, 644)
├── wp-config-sample.php  (root:root, 644)
├── wp-config.php         (root:root, 644)
├── wp-content/           (root:root, 755)
│   ├── plugins/          (root:root, 755)
│   ├── themes/           (root:root, 755)
│   ├── uploads/          (php-fpm:apache, 775)
│   │   ├── 2024/         (php-fpm:apache, 775)
│   │   └── ...           (php-fpm:apache, 775)
│   └── ...               (root:root, 755)
├── wp-cron.php           (root:root, 644)
├── wp-includes/          (root:root, 755)
├── wp-links-opml.php     (root:root, 644)
├── wp-load.php           (root:root, 644)
├── wp-login.php          (root:root, 644)
├── wp-mail.php           (root:root, 644)
├── wp-settings.php       (root:root, 644)
├── wp-signup.php         (root:root, 644)
├── wp-trackback.php      (root:root, 644)
└── xmlrpc.php            (root:root, 644)

总结

  1. Web服务器工作进程账户:"www-data" 或 "apache" 或 "nginx"
  2. PHP-FPM进程账户:"php-fpm"
  3. WordPress目录设置:
    • 主目录:
      • 由 root:root 拥有
      • 目录权限 755
      • 文件权限 644
    • 需要写入权限的目录
      • 由 "php-fpm:www-data" 拥有
      • 目录权限 775(必要时为755)

通过这种方式设置,可以分离Web服务器和PHP-FPM的权限,正确应用主目录的所有权和权限设置,并增强安全性。

该方法不仅适用于WordPress,也适用于任何提供Web内容的Web服务器结构。

8.8. 确保在可写目录中禁用PHP执行

确保在可以上传文件的目录中禁用PHP执行对于维护安全环境至关重要。

具有写入权限的上传目录是攻击者上传恶意脚本(如Web shell)的潜在目标,这些脚本可能被执行以危害服务器。

为什么这很重要?

  1. 减轻Web shell攻击:

    • 通过阻止上传目录中PHP脚本的执行,可以减轻可能导致服务器完全被攻陷的Web shell攻击风险。
  2. 减少攻击面:

    • 在可以写入文件的目录中禁用PHP执行可以减少攻击面,使攻击者更难利用漏洞。
  3. 符合安全最佳实践:

    • 确保正确的权限和执行设置符合安全最佳实践,提供额外的防御层。

审计:

  • 验证可写目录(例如上传目录)是否配置为阻止PHP脚本执行。

修复:

  • 配置您的Web服务器(Apache或Nginx)以在具有写入权限的目录(例如 /wp-content/uploads 目录)中禁用PHP执行。

配置步骤

  1. 将上传目录中的文件设置为下载
    • 对于Apache:
      root@kitploit:~
      <Location "/wp-content/uploads">
          SetHandler application/octet-stream
      </Location>
      
    • 对于Nginx:
      root@kitploit:~
      location /wp-content/uploads {
          default_type application/octet-stream;
      }
      
  2. 禁用上传目录中的PHP执行
    • 对于Apache:
      root@kitploit:~
      <Location "/wp-content/uploads">
          php_flag engine off
          # or alternatively
          php_value engine 0
      </Location>
      
       <Location "/wp-content/uploads">
           <FilesMatch "\.php$">
               SetHandler none
               Require all denied
           </FilesMatch>
       </Location>
       
       <Directory "/var/www/html/yourwordpress/wp-content/uploads">
           # Disable PHP execution
           <FilesMatch "\.php$">
               SetHandler none
               Require all denied
           </FilesMatch>
       </Directory>
      
    • 对于Nginx:
      root@kitploit:~
      location /wp-content/uploads {
          location ~ \.php$ {
              fastcgi_pass off;
          }
      }
      
       location /wp-content/uploads {
           location ~ \.php$ {
               deny all;
           }
       }
      

这些配置确保即使PHP文件被上传到 /wp-content/uploads 目录,也无法执行,从而防止潜在的攻击。

配置指令说明

  1. SetHandler application/octet-stream:

    • 强制将文件视为二进制流,提示下载而不是执行。
  2. php_flag engine off / php_value engine 0:

    • 禁用指定目录的PHP引擎,阻止PHP脚本执行。
  3. SetHandler none:

    • 取消匹配文件的处理器,确保它们不作为PHP处理。

注意:

  • 上述设置不影响图像文件的显示。
  • 例如,/wp-content/uploads 目录中的图像文件仍然可以通过 标签访问并正确显示:``` Example Image
root@kitploit:~
通过应用这些配置,您可以显著增强上传目录,防止潜在的脚本执行漏洞。

### 8.9. 确保 Web 服务器仅响应基于域名的 Host 头
为了确保您的 Web 服务器安全,必须确保它仅响应指向您域名的请求,而不是直接针对服务器 IP 地址的请求。

这可以通过正确配置 VirtualHost 指令来实现。

在大多数情况下,Web 服务通过域名访问,例如 `https://yourwordpress.com`。Web 服务器接收此请求并提供相应内容。为了强制执行此行为,我们需要将 Web 服务器配置为仅响应带有正确 Host 头的请求。

**允许基于 IP 访问的潜在安全风险**
1. 服务枚举:
   - 攻击者可以使用 IP 地址枚举服务器上运行的服务,从而增加发现和利用漏洞的风险。
2. 敏感信息暴露:
   - 配置错误的服务器在通过 IP 访问时可能会暴露目录、文件或其他不应公开访问的敏感信息。
3. 绕过安全控制:
   - 基于 IP 的访问可能绕过仅针对基于域名的访问执行的安全措施,从而导致未经授权的访问。

**审计:**
- 验证 Web 服务器是否已配置为仅响应基于域名的请求,而不是直接针对 IP 地址的访问。

**修复:**
- 配置 Web 服务器仅根据指定域处理请求,并适当地拒绝或重定向其他请求。

**配置步骤**
1. 默认 VirtualHost 配置
   - 创建一个默认 VirtualHost,捕获所有未指定的请求并返回 403 Forbidden 或重定向它们。

       **对于 Apache:**
       ```
        <VirtualHost _default_:80>
            DocumentRoot /var/www/html/yourwordpress
            ...
            <Location />
                Require all denied
            </Location>
    
        <VirtualHost _default_:443>
            DocumentRoot /var/www/html/yourwordpress
            ...
            SSLEngine on
            SSLCertificateFile /path/to/ssl/certificate.crt;
            SSLCertificateKeyFile /path/to/ssl/private.key;
            ...
            <Location />
                Require all denied
            </Location>
        </VirtualHost>     
       ```
       **对于 Nginx:**
       ```
       server {
           listen 80 default_server;
           return 403;
       }
    
       server {
           listen 443 ssl default_server;
           ...
           ssl_certificate /path/to/ssl/certificate.crt;
           ssl_certificate_key /path/to/ssl/private.key;
           ...
           return 403;
       }
       ```

2. 基于域名的 VirtualHost 配置
   - 确保您已为您的域名配置了 VirtualHost。
   
    **对于 Apache:**
    ```
    <VirtualHost *:80>
        ServerName yourwordpress.com
        ...
        Redirect permanent / https://yourwordpress.com/
    </VirtualHost> 
   
    <VirtualHost *:443>
        ServerName yourwordpress.com
        DocumentRoot /var/www/html/yourwordpress
        ...
        SSLEngine on
        SSLCertificateFile /etc/httpd/to/ssl/certificate.crt;
        SSLCertificateKeyFile /etc/httpd/to/ssl/private.key;
        ...
    </VirtualHost>    
    ```
    **对于 Nginx:**
    ```
    server {
        listen       443 ssl;
        server_name  yourwordpress.com;
        root         /var/www/html/wordpress;
        ...
        ssl_certificate /path/to/ssl/certificate.crt;
        ssl_certificate_key /path/to/ssl/private.key;
        ... 
    ```

3. 测试
   - 这是为 `yourwordpress.com` 创建默认 VirtualHost 和基于域名的 VirtualHost 的过程。
   - 在为 `yourwordpress.com` 创建默认 VirtualHost 和基于域名的 VirtualHost 后,非基于域名的请求(https://ip)将被拒绝(403 错误),显示 403 错误页面。
  

    ```
     $ curl -i -k http(s)://10.10.66.88
       
     HTTP/1.1 403 Forbidden
     Server: nginx
     Date: Mon, 03 Jun 2024 23:23:13 GMT
     Content-Type: text/html
     Content-Length: 162
     Connection: keep-alive
        
     <html>
     <head><title>403 Forbidden</title></head>
     <body bgcolor="white">
     <center><h1>403 Forbidden</h1></center>
     <hr><center>nginx</center>
     </body>
     </html>
    
       
     $ curl -i -k https://yourwordpress.com
     HTTP/1.1 200 OK
     Server: nginx
     Date: Mon, 03 Jun 2024 23:32:12 GMT
     Content-Type: text/html; charset=utf-8
     Content-Length: 9
     Connection: keep-alive
        
     Hello, yourwordpress.com
    ```

   - 如果需要在服务器之间或同一 IP 子网内进行通信,您可以配置默认 VirtualHost 以允许来自特定 IP 地址的访问。

通过实施这些配置,Web 服务器将仅响应指向您域名的请求。

### 8.10. 完整的 Web 服务器配置
以下是一个包含安全指南的完整 Web 服务器配置示例。请根据您的 WordPress Web 服务器环境进行调整和使用。

1. Apache
    ```
    <VirtualHost _default_:80>
        DocumentRoot /var/www/html/yourwordpress
   
        ErrorLog /var/log/httpd/http.ip.error.log
        CustomLog /var/log/httpd/http.ip.access.log combined
   
        <Location />
            Require all denied
        </Location>

    <VirtualHost _default_:443>
        DocumentRoot /var/www/html/current/public
   
        ErrorLog /var/log/httpd/https.ip.error.log
        CustomLog /var/log/httpd/https.ip.access.log combined
   
        # SSL Configuration
        SSLEngine on
        SSLCertificateFile /etc/httpd/conf.d/cert/yourwordpress.com_ssl.crt
        SSLCertificateKeyFile /etc/httpd/conf.d/cert/yourwordpress.com_ssl.key
        SSLSessionTimeout 1d
        SSLSessionCache shared:MozSSL:10m
        SSLSessionTickets off
    
        SSLProtocol TLSv1.2 TLSv1.3
        SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305
        SSLHonorCipherOrder off
   
        <Location />
            Require all denied
        </Location>
    </VirtualHost>    
   
    <VirtualHost *:80>
        ServerName yourwordpress.com
        Redirect permanent / https://yourwordpress.com/
    </VirtualHost> 
    
    <VirtualHost *:443>
        ServerName yourwordpress.com
        Protocols h2 http/1.1
        DocumentRoot /var/www/html/current/public
   
        ErrorLog /var/log/httpd/https.yourwordpress.com.error.log
        CustomLog /var/log/httpd/https.yourwordpress.com.access.log combined
    
        # SSL Configuration
        SSLEngine on
        SSLCertificateFile /etc/httpd/conf.d/cert/yourwordpress.com_ssl.crt
        SSLCertificateKeyFile /etc/httpd/conf.d/cert/yourwordpress.com_ssl.key
        SSLSessionTimeout 1d
        SSLSessionCache shared:MozSSL:10m
        SSLSessionTickets off
    
        SSLProtocol TLSv1.2 TLSv1.3
        SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305
        SSLHonorCipherOrder off
    
        <Directory /var/www/html/current/public>
            Options -Indexes FollowSymLinks
            AllowOverride All
            Require all granted
        </Directory>

        # Deny PHP execution in uploads directory
        <Directory "/var/www/html/current/public/wp-content/uploads">
            <FilesMatch "\.php$">
                SetHandler none
                Require all denied
            </FilesMatch>
        </Directory>
   
        # PHP Serving 
        ProxyPassMatch ^/(?!wp-content/uploads/.*\.php$)(.*\.php(/.*)?)$ unix:/var/run/php-fpm/php-fpm.sock|fcgi://localhost/var/www/html/current/public
        #ProxyPassMatch ^/(?!wp-content/uploads/.*\.php$)(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/var/www/html/current/public
    
        # Favicon
        <Location "/favicon.ico">
            ErrorDocument 404 "Not Found"
            SetEnvIf Request_URI "^/favicon\.ico$" no_log
        </Location>
    
        # Robots.txt
        <Location "/robots.txt">
            Require all granted
            SetEnvIf Request_URI "^/robots\.txt$" no_log
        </Location>
    
        # Restrict access to wp-cron.php
        <Files "wp-cron.php">
            Require all denied
            Require ip 127.0.0.1
        </Files>
    
        # Restrict access to wp-json
        <Location "/wp-json/">
            Require all denied
            Require ip 127.0.0.1 
            Require ip 10.10.77.49
            Require ip 10.10.71.20
        </Location>
    
        # Restrict access to wp-admin
        <Location "/wp-admin">
            Require all denied
            Require ip 10.10.77.49
            Require ip 10.10.71.20
        </Location>
    
        <Files "wp-login.php">
            Require all denied
            Require ip 10.10.77.49
            Require ip 10.10.71.20
        </Files>
    
        # Deny access to hidden files
        <FilesMatch "^\.">
            Require all denied
        </FilesMatch>
    </VirtualHost>
    ```
2. Nginx
    ```
    server {
        listen       80 default_server;
        listen       443 default_server ssl http2;
    
        error_log    /var/log/nginx/http.ip.error.log;
        access_log   /var/log/nginx/http.ip.access.log  main;
    
        ssl_certificate /etc/nginx/conf.d/cert/yourwordpress.com_ssl.crt;
        ssl_certificate_key /etc/nginx/conf.d/cert/yourwordpress.com_ssl.key;
        ssl_session_timeout 1d;
        ssl_session_cache shared:MozSSL:10m;  # about 40000 sessions
        ssl_session_tickets off;
    
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305;
        ssl_prefer_server_ciphers off;
    
        location / {
             deny all;
        }
    }
    
    server {
        listen       443 ssl http2;
        server_name  yourwordpress.com;
        root         /var/www/html/wordpress;
    
        error_log    /var/log/nginx/https.yourwordpress.com.error.log;
        access_log   /var/log/nginx/https.yourwordpress.com.access.log  main;
    
        ssl_certificate /etc/nginx/conf.d/cert/yourwordpress.com_ssl.crt;
        ssl_certificate_key /etc/nginx/conf.d/cert/yourwordpress.com_ssl.key;
        ssl_session_timeout 1d;
        ssl_session_cache shared:MozSSL:10m;  # about 40000 sessions
        ssl_session_tickets off;
    
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305;
        ssl_prefer_server_ciphers off;
    
    
        location = /favicon.ico {
            log_not_found off;
            access_log off;
        }
    
        location = /robots.txt {
            allow all;
            log_not_found off;
            access_log off;
        }
    
        # Restrict to access Wordpress Cron
        location = /wp-cron.php {
            allow 127.0.0.1;
            deny all;
            access_log off;
            log_not_found off;
        }
    
       # Restrict to access json rest-api
       location ~ ^/wp-json/ {
            allow 127.0.0.1;    		# Allow localhost
            allow 10.10.77.49;		    # Allow myip
            allow 10.10.71.20;       # Allow myip
            deny all;
            access_log off;
            log_not_found off;
        }

        # Restrict to access Wordpress Admin
        location = /wp-admin {
            allow 10.10.77.49;		    # Allow myip
            allow 10.10.71.20;       # Allow myip
            deny all;
        }
        
        location ~* \wp-login.php {
            allow 10.10.77.49;		    # Allow myip
            allow 10.10.71.20;       # Allow myip
            deny all;
        }
    
        # Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac).
        # Keep logging the requests to parse later (or to pass to firewall utilities such as fail2ban)
        location ~ /\. {
            deny all;
        }
    
        # Deny access to any files with a .php extension in the uploads directory
        location /wp-content/uploads {  
            location ~ \.php$ {
                deny all;
            }
        }
        # Other example
        # location ~* /(?:uploads|files)/.*\.php$ {
        # 		deny all;
        # }
    
        # Rewrite rules, sends everything through index.php and keeps the appended query string intact
        location / {
            try_files $uri $uri/ /index.php$is_args$args;
        }
    
        # Serving PHP
        location ~ \.php$ {
            try_files $uri =404;
            fastcgi_split_path_info ^(.+\\.php)(/.+)$;
            # fastcgi_pass   127.0.0.1:9000; 					 # With php-cgi (or other tcp sockets):
            fastcgi_pass   unix:/var/run/php-fpm/php-fpm.sock;   # With php-fpm (or other unix sockets):
            fastcgi_index index.php;
            include /etc/nginx/fastcgi_params;
            fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
        }
    
        location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
            expires max;
            log_not_found off;
        }
    
    }
    ```


## 9. 确保 WordPress 安全更新
WordPress 通过在发现漏洞时发布新版本更新来解决安全漏洞。

例如,如果在 WordPress 6.5.2 中发现了一个安全漏洞,它将在 6.5.3 版本中得到解决和分发。

由于安全更新不是按版本逐个管理的,因此需要定期进行版本更新以解决安全漏洞。

有关更新,请参考官方 WordPress 发布信息:
[WordPress 发布](https://wordpress.org/download/releases/)

**修复:**
- 定期更新 WordPress。
- WordPress 不按版本逐个管理更新(包括安全更新)。
- 截至 2024 年 5 月 20 日,只有 6.5 版本处于维护状态。

**注意:**
- 不支持 Beta、Nightly 版本以及其他 Subversion 签出版本。
- 避免使用不是官方 WordPress 版本的派生产品或版本。
- 受支持版本的文档:[受支持版本](https://wordpress.org/documentation/article/supported-versions/) 


## 10. 确保定期检查 WordPress 安全漏洞

WordPress 是一个内容管理系统(CMS)软件。
由于它是打包软件,安全漏洞主要出现在其组件(核心文件、插件、主题等)中。

与根据特定需求定制的自定义开发的 Web 应用程序不同,识别和解决安全漏洞必须使用适合 WordPress 的方法。

如果 WordPress 构建的网站没有进行大量自定义,并且保留了 WordPress 的性质,则可以使用 WPScan 轻松检查安全漏洞。

WPScan 是部分付费的软件,但基本免费层没有功能限制。它允许定期检查和响应 WordPress 安全漏洞。

**修复:**
- 使用 WPScan(或类似的可以扫描 WordPress 的工具)定期进行漏洞检查。
- 如果发现漏洞,请验证并执行必要的操作以消除它们。在大多数情况下,这可以通过更新来解决。
- 请参考 [WPScan 用户文档](https://github.com/wpscanteam/wpscan/wiki/WPScan-User-Documentation)。
- 有关 WordPress 中常见漏洞的更多信息:[扩展 WordPress 常见安全漏洞](https://learn.wordpress.org/tutorial/extending-wordpress-common-security-vulnerabilities/)

**WPScan:**```
_______________________________________________________________
         __          _______   _____
         \ \        / /  __ \ / ____|
          \ \  /\  / /| |__) | (___   ___  __ _ _ __ ®
           \ \/  \/ / |  ___/ \___ \ / __|/ _` | '_ \
            \  /\  /  | |     ____) | (__| (_| | | | |
             \/  \/   |_|    |_____/ \___|\__,_|_| |_|

         WordPress Security Scanner by the WPScan Team
                         Version 3.8.22
       Sponsored by Automattic - https://automattic.com/
       @_WPScan_, @ethicalhack3r, @erwan_lr, @firefart
_______________________________________________________________

[+] URL: https://yourwordpress.com/ [192.168.10.100]
[+] Started: Fri May 24 14:39:06 2024

Interesting Finding(s):

[+] Headers
..
...
 |  - content-security-policy: upgrade-insecure-requests
 | Found By: Headers (Passive Detection)
 | Confidence: 100%

..
...
[+] XML-RPC seems to be enabled: https://yourwordpress.com/xmlrpc.php
 | Found By: Link Tag (Passive Detection)
 | Confidence: 30%
 | References:
 |  - http://codex.wordpress.org/XML-RPC_Pingback_API
 |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_ghost_scanner/
 |  - https://www.rapid7.com/db/modules/auxiliary/dos/http/wordpress_xmlrpc_dos/
 |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_xmlrpc_login/
 |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_pingback_access/

..
...

[+] Finished: Fri May 24 14:39:48 2024
[+] Requests Done: 187
[+] Cached Requests: 7
[+] Data Sent: 56.32 KB
[+] Data Received: 605.595 KB
[+] Memory used: 276.602 MB
[+] Elapsed time: 00:00:42

继续阅读

  • 使用安全最佳实践设置Squid代理
下载工具
序号角色描述管理职员
1管理员拥有所有 WordPress 功能的完全访问权限,可以管理网站上的所有内容。系统管理员
2编辑可以管理和发布其他用户的文章,也可以编辑和发布内容。运营服务经理、内部内容贡献者
3作者可以撰写和发布自己的文章,并有权编辑自己的文章。内部内容贡献者
4贡献者可以撰写内容但不能发布。文章需由管理员审核并发布。内部内容贡献者
5订阅者可以登录网站并管理个人资料,但不能撰写或编辑内容。内部内容贡献者
root@kitploit:~
; 使会话 Cookie 无法被 JavaScript 访问

session.cookie_httponly = On
  • open_basedir:

    • 限制 PHP 只能访问指定目录内的文件。
    • 这可以防止攻击者访问服务器上的敏感文件。
      root@kitploit:~
      ; 将 PHP 文件访问限制到指定目录
      open_basedir = "/path/to/your/web/root"
      

    示例:

    • 如果你的 web 根目录是 /var/www/html,请如下设置 open_basedir:
      root@kitploit:~
      open_basedir = "/var/www/html:/tmp"
      
      此配置允许 PHP 仅访问 /var/www/html 目录和临时目录 /tmp 内的文件。
      
  • disable_functions:

    • 攻击中常被利用的 PHP 函数。
    • 禁用这些函数可降低多种攻击(包括命令注入和远程代码执行)的风险。
      root@kitploit:~
      ; 禁用潜在危险的 PHP 函数
      
      disable_functions = "system, exec, shell_exec, passthru, mysql_list_dbs, ini_alter, dl, symlink, link, chgrp, leak, popen, apache_child_terminate, virtual, mb_send_mail"
      

    已禁用函数的说明:

    • system, exec, shell_exec, passthru:

      • 允许执行系统命令,可能被用于命令注入攻击。
    • mysql_list_dbs:

      • 从 MySQL 服务器获取数据库列表,可用于收集信息以发动进一步攻击。
    • ini_alter:

      • 在运行时更改 PHP 配置,可能改变安全设置。
    • dl:

      • 动态加载 PHP 扩展,可能用于引入恶意代码。
    • symlink, link:

      • 创建符号链接或硬链接,可能被利用来不当操作文件和目录。
    • chgrp:

      • 更改文件的组所有权,可能改变访问权限。
    • leak:

      • 用于测试内存泄漏,但可能被利用来消耗服务器资源。
    • popen:

      • 打开一个进程管道,可能被用于命令执行。
    • apache_child_terminate:

      • 终止 Apache 进程,可能导致服务中断。
    • virtual:

      • Apache 专用,可用于包含其他 URL,存在安全风险。
    • mb_send_mail:

      • 发送邮件,可能被用于发送垃圾邮件。