Post

iron CTF 2024

Inaugural edition of IRON CTF (Intrusion Reconnaissance and Offensive Navigation CTF)! Team 1nf1n1ty from SASTRA Deemed University invites all to embark on an exciting online Jeopardy-style Capture the Flag challenge.

Random Pixels [Forensics]

Solves: 141 Points: 375 Author: OwlH4x

Description: My Image accidently fell into a pixel mixer can you help me recover it?

We are provided with two files, an encrypted png image and python encryption script.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import random, time, numpy
from PIL import Image
from secret import FLAG

def randomize(img, seed):
	random.seed(seed)
	new_y = list(range(img.shape[0]))
	new_x = list(range(img.shape[1]))
	random.shuffle(new_y)
	random.shuffle(new_x)

	new = numpy.empty_like(img)
	for i, y in enumerate(new_y):
		for j, x in enumerate(new_x):
			new[i][j] = img[y][x]
	return numpy.array(new)


if __name__ == "__main__":
	with Image.open(FLAG) as f:
		img = numpy.array(f)
		out = randomize(img, int(time.time()))
		image = Image.fromarray(out)
		image.save("encrypted.png")

alt text

The decryption was done using the following python script. Notice the fixed UTC epoch seed extracted from exiftool encrypted.png’s modification time (File Modification Date/Time : 2024:10:02 22:02:40+01:00)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import random, time, numpy
from PIL import Image

def randomize(img):
    random.seed(1727902960)
    old_y = list(range(img.shape[0]))
    old_x = list(range(img.shape[1]))
    
    random.shuffle(old_y)
    random.shuffle(old_x);print(old_y);print(old_x)
    new = numpy.empty_like(img)
    for i, y in enumerate(old_y):
        for j, x in enumerate(old_x):
            new[y][x] = img[i][j]
    return numpy.array(new)


if __name__ == "__main__":
    with Image.open('encrypted.png') as f:
        img = numpy.array(f)
        out = randomize(img)
        image = Image.fromarray(out)
        print(image)
        image.save("dec.png")

It decrypts the image and gets us a qr code which when is read gives the flag.

alt text

Flag: ironCTF{p53ud0_r4nd0m_f0r_4_r3450n}

Game of Hunt [Forensics]

Solves: 113 Points: 420 Author: tasarmays

Description: A Cryptic Voyage

We are provided with a txt file with binary data in it. It can be decoded reversably since it’s name is upsidedown.txt

alt text

We get ilovepdfs.zip file containing multiple pdf files.

alt text

One particular pdf file has brainfuck message.

alt text

Using dcode, it is readable and shows the flag.

alt text

Flag: ironCTF{You_are_the_finest}

Uncrackable Zip [Forensics]

Solves: 26 Points: 496 Author: AbdulHaq

Description: I forgot to ask my friend for the password to access the secret webpage, and now he's unavailable. I've tried guessing the password, but it's been unsuccessful. My friend is very security-conscious, so he wouldn't use an easy-to-guess password. He's also an Emmet enthusiast who relies heavily on code generation shortcuts. Can you help me figure out how to access the secret webpage?

This is a similar challenge to last CTF (BuckeyeCTF), which takes into account the weak zip encryption method; ZipCrypto Store. This allows anyone to crack the zip using knwon plain bytes of the zipped file. Using bkcrack, we get the keys of the zipfile provided by the challenge. We provide an index.html file having first bytes of a html file, <!DOCTYPE html> then zip it with same weak enc method then run bkcrack.

1
bkcrack-1.7.0-Linux/bkcrack --cipher-zip ./website.zip --cipher-index 0 --plain-zip ./index.zip --plain-index 0

Then we use those same keys to extract the index.html inside of website.zip

1
bkcrack-1.7.0-Linux/bkcrack -C website.zip -c index.html -k a18ba181 a00857dd d953d80f -d index1.html

Flag is inside of html file.

1
2
3
4
5
6
7
8
9
10
11
12
└─$ cat index1.html 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Flag</title>
</head>
<body>
    ironCTF{Wh0_us35_Z1pCrypt0_wh3n_kn0wn_PlA1nt3xt_a7t4cks_ex1s7?}
</body>
</html>

Flag: ironCTF{Wh0_us35_Z1pCrypt0_wh3n_kn0wn_PlA1nt3xt_a7t4cks_ex1s7?}

Fire in the Base Camp [Mobile]

Solves: 85 Points: 455 Author: p3rplex3d

Description: I was playing with the dice when I heard about the fire in the base camp. Can you get there on time?

We are provided with an apk file.

1
2
└─$ file Fire_in_the_Base_Camp.apk 
Fire_in_the_Base_Camp.apk: Android package (APK), with gradle app-metadata.properties, with APK Signing Block

Opening it in Jadx-gui reveals a main activity.

alt text

The app looks like this when installed on an emulator.

alt text

The source code shows that there is a firebase URL that can be used for something, also some string variables are truncated then concatenated to construct the URL. These values can be seen on strings.xml file.

alt text

Sending a request to the firebase URL using the concatenated values retrieves parts of the flag.

1
2
└─$ curl https://app3-7d107-default-rtdb.firebaseio.com/please/give/me/the/flag.json
{"f1":"ironCTF{","f2":"y0u_pu","f3":"7_0u7_t","f4":"h3_f1","f5":"r3_1n_t","f6":"h3_b4s","f7":"3_c4mp","f8":"_1f84a5","f9":"c66ff5}"}

Flag: ironCTF{y0u_pu7_0u7_th3_f1r3_1n_th3_b4s3_c4mp_1f84a5c66ff5}

Secure Vault [Mobile]

Solves: 20 Points: 498 Author: p3rplex3d

Description: Can you log in?

We are provided with an apk file.

1
2
└─$ file secure_vault.apk                                                                                                                   
secure_vault.apk: Android package (APK), with zipflinger virtual entry

I start by loading it in jadx-gui which reveals it’s a flutter app. Using blutter i get a Dart object pool. Meanwhile, installing the app on an emulator and running it only shows this password scaffold.

alt text

Once blutter finished extracting Dart objects, i immediatly inspect the dart files, only one is present (main.dart).

alt text

_checkPassword function reveals an encoded base64 value, when decoded it reveals the flag.

1
2
└─$ echo "aXJvbkNURnswaF9teV9nMGQhIV95MHVfYnIwazNfaW50MF90aDNfNHBwXzRmNmUyMmNiYX0="|base64 -d
ironCTF{0h_my_g0d!!_y0u_br0k3_int0_th3_4pp_4f6e22cba}

Flag: ironCTF{0h_my_g0d!!_y0u_br0k3_int0_th3_4pp_4f6e22cba}

Is this Android [Mobile]

Solves: 11 Points: 500 Author: AbdulHaq & p3rplex3d

Description: I built this calculator for my Computer Science Project and my professor was baffled because there is more it than meet's the eye.

We are provided with an apk file.

1
2
└─$ file Calculator.apk 
Calculator.apk: Android package (APK), with zipflinger virtual entry

Upon installation on genymotion rooted emulator, we get a calculcator application which weirdly doesn’t function properly and prints always Error!

alt text

Again, since this is a flutter app we can use blutter to get information from libapp.so. While checking the Dart objects strings pp.txt, i stumble across a url used in the app.

alt text

Also by checking calc.dart file

alt text

It it confirmed that there is a post request sent to https://calc.1nf1n1ty.team/calculate

I fire up burp proxy and launch first a get request which returns a python file path.

alt text

I make use of the _calculate function in calc.dart and launch this time a post request with a mathematecal expression.

alt text

We get the correct result, now, at this point, my theory was to somehow achieve remote code execution since this is the only lead i got, so i tried several ssti payloads and some other command injection payloads. They didn’t work, so i changed my approach, since this is probably a python web application which is hinting towards reading that source code of app.py, i was able to know that open() function is functional and it needs a file path argument.

alt text

At this point, i also tried to do a simple open(`/home/user/app.py`) and other variations but somehow nothing worked, as the word app and other chars were blacklisted, but there was a workaround which is using python’s chr to get charcode back to text. So i prepared the payload and sent it.

alt text

We are able to read the source code and the flag is in /flag, i repeat the previous step and get the flag!

alt text

Flag: ironCTF{aa4a7a86d4beb072c814af4400c7d1fbf09cf9b5}

Mango [Web, Warmup]

Solves: 81 Points: 460 Author: Vigneswar

Description: Mangoes are good for health! do you know what else are good for health? well, checkWarmup my website about nutritious fruits!.

This is a web warmup challenge, where it insinuates towards noSQL exploitation. First, heading into the web app reveals a fruits list and a login page.

alt text

Since this is about Mango, which can be interpreted into having MongoDB as a database system. A special noSQL payload can be prepared to take advantge of weak checks on the backend system.

alt text

Running the URL Encoded payload bypasses successfully the login page and reveals the flag.

alt text

Flag: ironCTF{I_Said_M@nG0_N0t_M0ngo!}

JWT Hunt [Web, Warmup]

Solves: 92 Points: 448 Author: BY73 B4ND17

Description: Scavenger hunts are a blast, so I've woven one into this challenge. Test your skills and see if you can uncover the treasure you seek!

This is a web warmup challenge which hints towards getting admin access via JWT forging using the secret_key. First by registering and loggin in to the dashboard, it welcomes us that the flag isn’t here.

alt text

So, the hunt for secret_key starts. We start by checking the famous robots.txt file and get the 1st part with the 2nd part being in cookie. It also hints towards fourth flag being in the disallowed path.

alt text

Doing Verb tampering on the disallowed path via the HEAD http verb returns the 4th part of secret_key. Now we only need the 3rd part.

alt text

A well known XML file for more efficient crawling returns the 3rd part.

alt text

Now, by tampering with the logged on JWT token using online JWT tools like jwt.io by providing the full sercet key 6yH$#v9Wq3e&Zf8LpRt1%Y4nJ^aPk7Sd2C@mQjUwEbGoIhNy0T!BxlVz5uMKA#Yp and changing username to admin, and finally refreshing the page reveals the flag.

alt text

Flag: ironCTF{W0w_U_R34lly_Kn0w_4_L07_Ab0ut_JWT_3xp10r4710n!}

Treasure Hunt [Mobile, Warmup]

Solves: 39 Points: 491 Author: p3rplex3d

Description: I like colors and solving puzzles. What is better than having an app that brings both of them together?

We are provided with an apk file. Opening it on Jadx-gui reveals several things. First, the application is started on first activity, which doesn’t help.

alt text

Second, the main activity has got a first part of flag in layout xml file.

alt text

The second part is in strings xml file for the second activity/screen.

alt text

Combining the two parts constructs the flag.

Flag: ironCTF{3ver_h3ard_0f_4ndro1d_r3v?}

This post is licensed under CC BY 4.0 by the author.

Trending Tags