OTORI - FAQ
This article describes security testing-related software whose use may be restricted or prohibited in your place of residence or your workplace. The penalties for violating laws and regulations regarding security testing-related tools can be severe. Ensuring that you are allowed to use this software is your responsibility.
The software described is a "preview release" which is not yet feature-complete and which is has not been tested on a variety of systems. Even if you are allowed to use the software, you should do so with caution, on systems which can be easily restored to their previous state if they are damaged.
Table of contents
Why a New Tool?
Initially, I had planned on building this functionality as a set of auxiliary modules for Metasploit. While I am a big fan of Metasploit and use it frequently, I quickly discarded this idea.
Metasploit's core purpose (at least in my mind) is remote code-execution on target systems. While it can do other things, the further away any tool gets from its primary function, the less effective and harder to maintain it will become, in my experience.
Basic XXE exploitation can be done using a client/server model, but many systems (especially PHP-based systems) require the use of techniques like those described by Timur Yunusov and Alexey Osipov, where a third system is necessary to "bounce" parts of the exploit and exfiltrated data off of. This could potentially be emulated or approximated using Metasploit, but it would be difficult and probably not make me any friends among Metasploit's developers. For a tool written and used by hackers, Metasploit sure does have a lot of rules regarding contributions.
Even if the Metasploit developers welcomed this type of functionality with open arms, the flexibility of having the "co-conspirator" service (in this case, She Wore A Mirrored Mask) be decoupled from the main attack tool provides much more flexibility:
|Example Attack Configurations|
A few examples of possible ways to deploy the two components necessary for an out-of-band XXE attack.
Finally, I feel like it's been too long since any significant new general-purpose security tools were released. Maybe everyone is chasing bug bounties instead of showing how individual flaws can be combined to compromise entire organizations?
Why Are You Reinventing The Wheel?
At first glance it might seem like I've reinvented the wheel in some places. Why did I make a new library called libdeceitfulhttp instead of using the standard Python httplib library? Why didn't I borrow mitmproxy so I would have proxy functionality already?
Unfortunately, while httplib is very useful for most Python-based HTTP clients and servers, it has some very significant limitations when it comes to generating and handling traffic that is intended to mimic as closely as possible traffic from other systems, or which intentionally does not comply with standards in the interest of revealing or taking advantage of security flaws.
The main issue I ran into early on is that httplib rigidly adheres to certain aspects of the protocol and does not allow for a way to override that functionality. A simple example is that not only will it only accept an HTTP version of 1.0 or 1.1, its creators chose to represent those values as 0 and 1. Want to work with a client that expects something unusual like 0.9, intentionally leave out the version entirely, or see what happens if you send an HTTP -37.7' OR 1=1 OR '12 request to a server? Well, you're out of luck.
Presumably in the interest of making the library easier to work with quickly, other design decisions were also made. The set of headers for a request is represented as a hashtable (sorry, "dictionary") indexed by header name. This immediately prevents interesting requests from being sent where the same header name is included multiple times with different values, to see if e.g. one tier within the target environment will interpret the first value, while another will use the second value.
Making things worse (from an accuracy perspective), the hashtable keys are normalized to all-lowercase. This means that if I am writing (for example) an iOS application and a corresponding web API, I can easily detect the presence of a Python-based intermediate system by sending a request header such as X-HaRD-tO-reaD-heADEr: canary and see if the server receives that request unchanged, or if it has been normalized to x-hard-to-read-header: canary, X-Hard-To-Read-Header: canary, etc.
mitmproxy seems like a very well-written piece of software, but as far as I can tell it is based on httplib, and so brings those limitations along.
The next major hurdle to overcome for On The Outside, Reaching In and She Wore A Mirrored Mask is to rebuild libdeceitfulhttp as a 1:1 replacement for httplib, in which the two main differences are that every parameter is a string (allowing for maximum, dangerous flexibility), and that the headers are represented as a list of tuples with some utility functions to handle accessing them by name.