Unicode Trick, Level Injection
| Event Name | [CTF Event Name] |
| GitHub URL | [Challenge Repo/Code URL] |
| Challenge Name | [Specific Challenge Name] |
Attachments
References
Unicode trick
source code
app.use((req, res, next) => {
const nonce = rand();
res.locals = { nonce };
res.set('X-Frame-Options', 'SAMEORIGIN');
res.set('Cross-Origin-Opener-Policy', 'same-origin');
res.set('Cross-Origin-Resource-Policy', 'same-origin');
res.set('Content-Security-Policy', `script-src 'nonce-${nonce}'`);
next();
});
...
app.use((req, res, next) => {
function clean(obj) {
if (!obj) return;
for (const [key] of Object.entries(obj)) {
if (obj[key].includes('\'')) return next('Hack detected');
obj[key] = Buffer.from(obj[key], 'utf-8').toString('ascii');
}
}
clean(req.body);
clean(req.query);
clean(req.params);
next();
});
...
app.use('/register', require('./routes/register'));
app.use('/bot', require('./routes/bot'));
app.use('/', require('./routes/index'));we can input this to get single quote ȧ><h1>123</h1>
source code
const path = require('path');
const { Level } = require('level');
const db = new Level(path.join(__dirname, 'database', process.env.NODE_ENV));
const dbPost = db.sublevel('posts');
const dbAccount = db.sublevel('account');
const dbSession = db.sublevel('session');
async function get(db, key) {
try {
return await db.get(key);
} catch {
return null;
}
}
module.exports = {
db,
get,
dbPost,
dbAccount,
dbSession,
}source code
route.get('/post/:id', async (req, res) => {
const { id } = req.params;
if (!id || typeof id !== 'string') return res.send('Invalid data');
let content = (await get(db, id)) || '';
if (content.length > 200) content = content.slice(0, 200) + '...';
res.render('post', { content });
});level js library injection because the code uses db to read/write post instead of dbPost.
Final Solution
!account![username]window.top.length