niedziela, 29 listopada 2015

[CTF] 9447 CTF web200 "nicklesndimes" write-up

That was really cool challenge on 9447 CTF from Web category. Task description:

Nick's been eating your grandmother's strombomi. Head over to http://nicklesndimes-wq3mhu8l.9447.plumbing. Gain access to his admin account.




So the task is to takeover admin account with user_id = 1.



We are able to register new accounts and login (with Remember me functionality) or request for password reset. After digging a bit with password reset I noticed, that reset token is the same for my userid... and it's md5 hash for my team name ;-)



00:31 zoczus@ropchain[~]$ echo -n "zoczus" | md5sum
5580aed6ac917f2cd6fc08c9581e1ca2  -

So we can simply create password reset link for admin user this way: http://nicklesndimes-wq3mhu8l.9447.plumbing/reset_password?action=choose_password&auth_key=21232f297a57a5a743894a0e4a801fc3&id=1

And first problem - we know team name, but what's e-mail to login? Answer can be found by clicking small icon near to Users, which responds with json with scores, and near our admin account we can find additional field called admin_contact ;) Link was: http://nicklesndimes-wq3mhu8l.9447.plumbing/json?view=scoreboard





Got e-mail, got password, challenge solved... nope!



Tried X-Forwarded-for, X-Real-IP for 127.0.0.1 , 10.43.18.4 (from e-mail headers), etc... and then my team mate (thanks Dawid!) gave me idea to try this one:

00:38 zoczus@ropchain[~]$ host nicklesndimes-wq3mhu8l.9447.plumbing
nicklesndimes-wq3mhu8l.9447.plumbing has address 104.28.12.28
nicklesndimes-wq3mhu8l.9447.plumbing has address 104.28.13.28

Setting X-Forwarded-For to 104.28.13.28 gave me this result after login: 



środa, 22 kwietnia 2015

[PL] Bypassing Same-Origin Policy - slajdy z 4Developers 2015

W poniedziałek 20.04.2015r. miałem przyjemność bycia prelegentem na konferencji 4Developers w ścieżce Security organizowanej przez SecuRing .

Slajdy z prezentacji: https://drive.google.com/file/d/0B7U6Q1zbqTkyOEY3TmRXWl8tODQ/view?usp=sharing

Nagranie będzie dostępne w przyszłości. :)

plupload - Same-Origin Method Execution [Wordpress 3.9 - 4.1.1]

This January I've found and reported XSS vulnerability in plupload, that affects Wordpress from 3.9 to 4.1.1.  As far as there was no ability to control arguments of function called - the "only" thing we could do with this issue was Same-Origin Method Execution.

Before you start reading technical details - you should update your Wordpress / plupload first.

If you will dig a bit in Flash plupload 2.1.2 source code, you can notice interesting thing in _init() function:


...and _fireEvent()


So we can manipulate with target GET parameter to execute javascript functions, but we can use only alphanumeric characters and dot. Still can be useful, the scenario goes like this:

1. In first tab create new window with target _blank and URL http://hostname/proxy.php
2. Then redirect first tab to http://target-wordpress/wp-admin/plugin-install.php?tab=plugin-information&plugin=google-analytics-dashboard-for-wp&section=description - of course you can use any other plugin install page.
3. The second's tab proxy.php sleeps for few seconds and then redirect to vulnerable plupload on target-wordpress calling this function:


window.opener.document.body.lastChild.previousElementSibling.previousElementSibling.previousElementSibling.lastChild.click()

4. ....aaaand plugin is installed now. ;-)

This one can be of course more automated and faster to install malicious, vulnerable plugins, that after successful exploit will give us webshell or anything we need to own the machine. In my opinion - this can be really dangerous.

PoC: http://ropchain.org/poc/wordpress/

wtorek, 3 lutego 2015

evercookie.swf - Stored Cross-Site Scripting

Today @samykamkar released new version of evercookie that fixes Stored Cross-Site Scripting issue that I reported. Here is how it works in details.

First of all - we should check vulnerable code: evercookie.as

So - the flash file takes flashVar parameter everdata and puts it to SharedObject (something like Local Storege but for Flash). If some data already was in SharedObject - it pass its value to javascript function called _evercookie_flash_var() without any checks. So the proof of concepts for this version looks simple:

http://vulnerable-hostname/evercookie.swf?everdata=f');alert('XSS');// 

After visiting this and then visiting page that embeds evercookie.swf - we'll see wonderful alert box ;-) and the best part - it's stored one.

Few weeks ago someone made pull request for fixing some issues (not security related) with QQBrowser and simply replaced getURL() function with ExternalIterface.call(). So - someone accidentally fixed old bug and created new one ;-) Here's the code: evercookie2.as

+ 2nd PoC:

http://vulnerable-hostname/evercookie.swf?everdata=f\\"))}catch(e){}alert(1);//

...and life goes on. :)

If you're using evercookie - please update to newest version. You can also check the video demonstration: https://www.youtube.com/watch?v=kWAiV6Bjm2s


środa, 7 stycznia 2015

yammer.com - Same Origin Method Execution

SOME ;-) time ago@BenHayak talked about Same-Origin Method Execution on BlackHat EU. At the time of posting this article, there's no public whitepaper yet (only leaked slides) - that's why I'd love to share one of first posts that show this attack in action.

Yammer.com is part of Microsoft Bug Bounty for Online Services. During some research in used Flash files I found this one: video-js.swf (source).

Take a look to this piece of code:



As far as you probably know - the ExternalInterface is ActionScript class that allows (for example) to communicate Flash object with browser’s Javascript. First parameter is function name, that we want to call. As you can see - it’s readyFunction parameter (from GET), but it’s also sanitized with cleanEIString which looks like this:


So - only chars we are able to use is alphanumeric, underscore and a dot - to prevent Cross-Site Scripting. For example - if we’ll provide readyFunction=alert - our flash file will execute alert function, but we have no control over arguments (because we can't use brackets), so it’s useless for XSS purposes.

...and here is the place where we can start talking about Same-Origin Method Execution :-) Let take evil.com, that have hyperlink to vulnerable videoplayer. After clicking to this link, it opens the flash file in new tab, and next - redirect evil.com to yammer.com (in the same tab). From now on - newly opened tab have access to previous tab by window.opener (because they are both in Same Origin - yammer.com), and it’s also able to access DOM and execute functions in context of opened yammer.com page. 

The goal is to authorize user to some malicious application without his knowledge. Attack scenario will look this way:

1. User is visiting evil PoC site
2. He/she clicks on link which -in the end - redirect user to video player with readyFunction param described later
3. We’re redirecting Poc site to our yammer.com application - all we need to know is client_id - link example here: 


4. We need to wait few seconds to be 100% sure that redirect from point 3 happend (that's why I used proxy.php that sleeps and then returns 30x).
5. Flash Video Player will execute this readyFunction:

window.opener.new_message_popup.nextElementSibling.lastElementChild.firstChild.nextElementSibling.click()

...which is simply the “Allow” button + click() function :->

As you can imagine - this will cause clicking on the button and authorizing application to victim’s account, which is dangerous. :)

Proof of Concept goes here: http://ropchain.org/poc/yammer-some.html

...and demo:


niedziela, 21 września 2014

CSAW CTF Web300 writeup

In this post I want to show my solution for CSAW CTF - Web300. This is the service, where we are able to post some links, that are parsed by bot, and looks like this:



There are two important things about this task. First of all, we can notice that page using jquery 1.6.1 (which prone to XSS - CVE-2011-4969) - and serving this kind of code:

The other thing is that bot is based on PhantomJS, so there's a chance, that it interprete javascript on page just like normal browser. ;)

My first shot after connecting those two facts was to exploit XSS on bot, and steal the cookies. It was correct and gave me a flag - these_browser_bots_are_annoying :-)




Pretty simple. doesn't it? :)

piątek, 5 września 2014

GetClouder domain takeover

GetClouder is cloud hosting service having bug bounty program. In Administration Panel we have some domain management tool for hosting our own domain names. After adding ANY domain - zone is configured on two DNS servers: nimbus.getclouder.com and cumulus.getclouder.com - even if we are not owner of the domain. 



If you get NS records for getclouder.com domain, you'll see that it's hosted on same servers:

zoczus@hell:~$ host -t ns getclouder.com
getclouder.com name server nimbus.getclouder.com.
getclouder.com name server cumulus.getclouder.com.

So my first try was trying to add getclouder.com domain - of course it failed. ;)


Then - I tried to search if GetClouder have any other interesting domains. Here's what I found:


In short - yes, they have other domains. One of interesting - clouder.us or getclouder.info are hosted on ns1.clev1.net and ns2.clev1.net. Now - just check the IP addresses of this servers:

zoczus@hell:~$ host ns1.clev1.net
ns1.clev1.net has address 181.224.128.6
zoczus@hell:~$ host ns2.clev1.net
ns2.clev1.net has address 198.20.77.76
zoczus@hell:~$ host nimbus.getclouder.com
nimbus.getclouder.com has address 181.224.128.6
zoczus@hell:~$ host cumulus.getclouder.com
cumulus.getclouder.com has address 198.20.77.76


So we have few other possibilities to check. I tried to add clev1.net, it failed - but adding ns1.clev1.net - not. :) Win?



Yup - it was deffinetly win. 

zoczus@hell:~$ host wow.ns1.clev1.net
wow.ns1.clev1.net has address 1.2.3.4
zoczus@hell:~$ dig +trace ns1.clev1.net

; <<>> DiG 9.8.3-P1 <<>> +trace ns1.clev1.net
;; global options: +cmd
. 85638 IN NS l.root-servers.net.
. 85638 IN NS b.root-servers.net.
. 85638 IN NS k.root-servers.net.
. 85638 IN NS j.root-servers.net.
. 85638 IN NS i.root-servers.net.
. 85638 IN NS a.root-servers.net.
. 85638 IN NS m.root-servers.net.
. 85638 IN NS h.root-servers.net.
. 85638 IN NS e.root-servers.net.
. 85638 IN NS f.root-servers.net.
. 85638 IN NS d.root-servers.net.
. 85638 IN NS c.root-servers.net.
. 85638 IN NS g.root-servers.net.
;; Received 241 bytes from 62.21.99.94#53(62.21.99.94) in 122 ms

net. 172800 IN NS d.gtld-servers.net.
net. 172800 IN NS b.gtld-servers.net.
net. 172800 IN NS g.gtld-servers.net.
net. 172800 IN NS e.gtld-servers.net.
net. 172800 IN NS k.gtld-servers.net.
net. 172800 IN NS l.gtld-servers.net.
net. 172800 IN NS i.gtld-servers.net.
net. 172800 IN NS f.gtld-servers.net.
net. 172800 IN NS j.gtld-servers.net.
net. 172800 IN NS m.gtld-servers.net.
net. 172800 IN NS h.gtld-servers.net.
net. 172800 IN NS c.gtld-servers.net.
net. 172800 IN NS a.gtld-servers.net.
;; Received 488 bytes from 202.12.27.33#53(202.12.27.33) in 132 ms

clev1.net. 172800 IN NS ns1.clev1.net.
clev1.net. 172800 IN NS ns2.clev1.net.
;; Received 95 bytes from 192.55.83.30#53(192.55.83.30) in 167 ms

ns1.clev1.net. 86400 IN A 8.8.4.4
ns1.clev1.net. 86400 IN A 8.8.8.8
ns1.clev1.net. 86400 IN NS cumulus.getclouder.com.
ns1.clev1.net. 86400 IN NS nimbus.getclouder.com.
;; Received 152 bytes from 181.224.128.6#53(181.224.128.6) in 174 ms

We have full control of ns1.clev1.net - so everyone asking for - let's say - clouder.us will got response about it's hosted on ns1.clev1.net (and ns2.clev1.net) which points to IP addresses controled by us.

The second vulnerability was ability to add root-servers.net zone. 


After adding just 3 root servers (a,b,c), pointing it to IP with DNSChef on board, and waiting few minutes this is what I got:


As GetClouder told me - it was result of one tool for checking if customer's domains are still pointed to its nameservers.

I want to thank GetClouder security team for realy fast responses and the way how they did treat me as researcher. That was one of my best bounty experiences :)