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 π’.
Forensics
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.
Crypto
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
Recipe:
- From Hex
- XOR with HEX key
ab
Output = WACTF{WHY_IS_IT_ALWAYS_XOR}
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
Recipe:
- From Hex
- XOR Brute Force w/ Crib=βWACTFβ
Output = Key = 41: WACTF{ONE_BYTE_IS_NOT_A_LARGE_SEARCH_SPACE}
Web
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
Output:
<snip>
env [Status: 301, Size: 225, Words: 14, Lines: 8]
<snip>
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
Output:
.git/HEAD [Status: 200, Size: 23, Words: 2, Lines: 2]
Bingo.
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
Repository:
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
Within
.git
all that is visible isfoo.txt
Gather list of commits via:
git shortlog | grep flag
- from this we see there was a flag create commit
git log --grep=flag
gives us the commit hash for when the flag was createdgit checkout b97c2a177567ae7d55eb12c3b65a6b74b1198d0a
we now see
flag.txt
β yay!
WACTF{isnt_git_great}
1.2. Bird-House (100pts)
IDOR challange
- create account
- go to gallery
- click on first image
- notice URI:
http://web-1-2/images/view/2
- de-increment the image no. :
http://web-1-2/images/view/1
- 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'})
else
fn(null, null)
}
app.get('/flag', function(req,res) {
res.sendFile(__dirname+"/views/flag.html");
});
- Go to web page
- For the loginprompt, enter
SuperSecurePasswordforuseradmin
as the username; leave pw empty - sucessfull login!
- browse to
/flag
to get our flag
Exploit
0. Strings2Flag
cat encryptor
β we find our flag.
1. Springfield Nuclear Power Station (100pts)
- open the application
- try some creds out, we can't login
- notice that it says βdebug mode is disabledβ
- try running the application with
--debug
flag. Debug mode enabled! - try logging in again with any creds β still denied.
strings exploit-1
- Notice that login is done via
homer
user under debug mode. - Run program in debug mode, username=homer, password=
- We're logged in as homer!
- Press '6' to get flag.