WACTF 2020 (0x04) Writeups 🦒

πŸ”— https://capture.tf/

Another year of a fantastic WA based CTF made by the community for the community. As always, a lot was enjoyed, keyboards were mashed, and much was learnt. Thanks to all the organisers for making this so special. Only regret is not being able to play in person at Perth 😒.


0. Is serverless, is secure (20pts)

To impress his agile DevOps friends, Batman has moved his BatCave computer to a β€œserverless”. Oh no, someone has managed to write to his intel folders and retrieve all of his intel. Can you work out which user is the naughty agent? Luckily he's got logs enabled and has been identifying his BatCave computer on all requests, so you can rule out BatCaveSuperComputer as the flag.

We are provided with a CloudWatch log file supposedly for the serverless application where data exfil occured (json).

Since I am not too familiar with cloudwatch logs, I devised a quick and dirty way to find the flag:

jq ".events[]"  forensics-0.json | jq .message | grep User-Agent | grep -v "BatCaveSuperComputer" | grep WACTF

The above searches through the json file within β€œmessage” that excludes all UserAgent=BatCaveSuperComputer. Turns out we can find the flag this way 😊.

// TODO: learn how to filter or structure these logs. Perhaps uploading them in AWS and using the CloudWatch search UI would allow to make a fancy query.


0. It's always the same (20pts)

Crypto is quite tricky, and this is hard for a lvl 0 flag, but such is life. The flag was XORed with the value 0xab, then converted to hex. Can you get the flag out of the ciphertext?

Ciphertext: fceae8ffedd0fce3f2f4e2f8f4e2fff4eae7fceaf2f8f4f3e4f9d6

The ciphertext was produced via plaintext –> XOR(0xab) –> hex. Let's try to reverse this using CyberChef:

Input = fceae8ffedd0fce3f2f4e2f8f4e2fff4eae7fceaf2f8f4f3e4f9d6


  1. From Hex
  2. XOR with HEX key ab


1. It's always the same... again (100pts)

The flag was XORed with an unknown value, then converted to hex. Can you get the flag out of the ciphertext

Ciphertext: 16000215073a0e0f041e031815041e08121e0f0e151e001e0d001306041e1204001302091e12110002043c

Similar to the previous example but we don't know the XOR key. CyberChef has a XOR Brute Force function we can use!

Input = 16000215073a0e0f041e031815041e08121e0f0e151e001e0d001306041e1204001302091e12110002043c


  1. From Hex
  2. XOR Brute Force w/ Crib=β€œWACTF”



0. Git Good (50pts)

You really have to be good to git this flag. Note: A SMALL amount of directory bruteforcing is required for this challenge.

Service: http://web-0

Search for hidden directories and git files:

ffuf -w /usr/share/wordlists/SecLists/Discovery/Web-Content/common.txt -u http://web-0/FUZZ


env                     [Status: 301, Size: 225, Words: 14, Lines: 8]

env looks interesting. We'd expect to see some interesting files in this directory potentially. Since the status is 403 we can't see a directory listing. Let's run ffuf again:

ffuf -w /usr/share/wordlists/SecLists/Discovery/Web-Content/common.txt -u http://web-0/env/FUZZ


.git/HEAD               [Status: 200, Size: 23, Words: 2, Lines: 2]


I'll use gitjacker to obtain the relevant git files: gitjacker http://web-0/env/

 β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ  β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ   β–ˆβ–ˆ  β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ   β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ   β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ  
β–ˆβ–ˆ       β–ˆβ–ˆ    β–ˆβ–ˆ      β–ˆβ–ˆ β–ˆβ–ˆ   β–ˆβ–ˆ β–ˆβ–ˆ      β–ˆβ–ˆ  β–ˆβ–ˆ  β–ˆβ–ˆ      β–ˆβ–ˆ   β–ˆβ–ˆ 
β–ˆβ–ˆ   β–ˆβ–ˆβ–ˆ β–ˆβ–ˆ    β–ˆβ–ˆ      β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ      β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ   β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ   β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ  
β–ˆβ–ˆ    β–ˆβ–ˆ β–ˆβ–ˆ    β–ˆβ–ˆ β–ˆβ–ˆ   β–ˆβ–ˆ β–ˆβ–ˆ   β–ˆβ–ˆ β–ˆβ–ˆ      β–ˆβ–ˆ  β–ˆβ–ˆ  β–ˆβ–ˆ      β–ˆβ–ˆ   β–ˆβ–ˆ 
 β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ  β–ˆβ–ˆ    β–ˆβ–ˆ  β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ  β–ˆβ–ˆ   β–ˆβ–ˆ  β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ   β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ   β–ˆβ–ˆ
https://github.com/liamg/gitjacker                         v0.0.2

Target:     http://web-0/env/
Local Git:  2.29.2
Output Dir: /tmp/gitjacker299979449

Gitjacking in progress...ls
Operation complete.

Status:            Success
Retrieved Objects: 207
Missing Objects:   0
Pack Data Listed:  true
Remotes:           n/a
Branches:          n/a
User Info:         
  - Name:         wactf
  - Email:        wactf@capture.tf/

You can find the retrieved repository data in /tmp/gitjacker299979449

Git Analysis


1.2. Bird-House (100pts)

IDOR challange

  1. create account
  2. go to gallery
  3. click on first image
  4. notice URI: http://web-1-2/images/view/2
  5. de-increment the image no. : http://web-1-2/images/view/1
  6. Get flag!

2. Hardcoded secrets (150pts)

You have managed to obtain part of the source of this nodejs app. It contains secrets! Use the secrets to to obtain the flag!

Filedrop: web-2.7z Service: http://web-2:3000

function auth (key, fn) {
  if ('SuperSecurePasswordforuseradmin' === key)
    fn(null, { id: '1', name: 'superuser'})
    fn(null, null)

app.get('/flag', function(req,res) {
  1. Go to web page
  2. For the loginprompt, enter SuperSecurePasswordforuseradmin as the username; leave pw empty
  3. sucessfull login!
  4. browse to /flag to get our flag


0. Strings2Flag

cat encryptor β€” we find our flag.

1. Springfield Nuclear Power Station (100pts)

  1. open the application
  2. try some creds out, we can't login
  3. notice that it says β€œdebug mode is disabled”
  4. try running the application with --debug flag. Debug mode enabled!
  5. try logging in again with any creds – still denied.
  6. strings exploit-1
  7. Notice that login is done via homer user under debug mode.
  8. Run program in debug mode, username=homer, password=
  9. We're logged in as homer!
  10. Press '6' to get flag.