This lab has a "Check stock" feature that parses XML input but does not display the result.
To solve the lab, trigger an error message containing the contents of the /etc/passwd
file.
You'll need to reference an existing DTD file on the server and redefine an entity from it.
Like previous labs, the XXE vulnerability is present in the POST /product/stock
request:
In this lab, I noted that out-of-band interactions were blocked, preventing data exfiltration via external connections and the loading of external DTDs from remote servers. Without access to an external DTD, I decided to utilize a local one. After searching for common DTD files in Linux GNOME systems, I discovered a of local DTD files, including /usr/share/yelp/dtd/docbookx.dtd
. Now, the challenge was to invoke a preexisting ENTITY from the docbookx.dtd
file.
In this scenario, we're constrained from nesting entities directly within one another due to XML parser limitations. However, there's a workaround: if a document's DTD combines internal and external DTD declarations, the internal DTD can redefine entities declared in the external DTD. This relaxation of restrictions enables nesting of parameter entities.
The next step involved crafting a payload to exfiltrate data. With out-of-band connections off-limits, error messages were the only avenue to retrieve data.
I began by loading the local DTD file:
Redefining the chosen entity and constructing multiple entities within it.
This entity comprises two key entities:
file
: This parameter entity points to the system file /etc/passwd
.
eval
: This entity contains a nested parameter entity definition which is used to dynamically create an entity called error
. This is a technique to bypass certain restrictions.
%
represents the percent sign %
in XML character entity encoding.
%
represents also the percent sign %
in XML character entity encoding.*
'
represents the percent sign '
in XML character entity encoding.
And the reason for using XML character entity encoding in the payloads is because I want the XML parser to interpret these characters as data rather than as part of the XML markup.
As in the previous lab, the error is triggered by attempting to access a non-existent file, using its name as the content of the /etc/passwd
file. Consequently, when the error is invoked, it inadvertently exposes the content of the /etc/passwd
file.
The final step involves invoking the local
entity to integrate all elements of the payload. Thus, the ultimate payload resembles the following:
Submitting this refined payload initiates the desired outcome:
As anticipated, an error response is received, followed by the contents of /etc/passwd
, effectively resolving the lab challenge.
After identifying the need for a predefined ENTITY from the DTD file, I embarked on a quick Google search and stumbled upon the GNOME repository on , which divulged the contents of the docbookx.dtd
file. From there, I selected the ISOamsb
entity to proceed to the next phase: