added web challenge
This commit is contained in:
200
bi0sctf23/web/src/index.js
Normal file
200
bi0sctf23/web/src/index.js
Normal file
@@ -0,0 +1,200 @@
|
||||
const express = require('express');
|
||||
const fs = require('fs');
|
||||
const protobuf = require('protobufjs');
|
||||
const glob = require('glob');
|
||||
const { healthCheck } = require('./bot');
|
||||
const app = express();
|
||||
const port = 3000;
|
||||
|
||||
function generateNoteId(length) {
|
||||
const characters = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
||||
let result = '';
|
||||
for (let i = 0; i < length; i++) {
|
||||
const randomIndex = Math.floor(Math.random() * characters.length);
|
||||
result += characters.charAt(randomIndex);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
let noteList = [];
|
||||
let flag = process.env.FLAG;
|
||||
if(!flag){
|
||||
flag='{"title":"flag","content":"bi0sctf{fake_flag}"}';
|
||||
}
|
||||
else{
|
||||
flag=`{"title":"flag","content":"${flag}"}`;
|
||||
}
|
||||
const flagid = generateNoteId(16);
|
||||
const healthCheckId='Healthcheck';
|
||||
fs.writeFileSync(`./notes/${flagid}.json`, flag);
|
||||
fs.writeFileSync(`./notes/${healthCheckId}.json`, '{"title":"Healthcheck","content":"success"}');
|
||||
|
||||
app.use(express.json());
|
||||
|
||||
app.set('view engine', 'ejs');
|
||||
app.set('views', __dirname + '/views');
|
||||
|
||||
const restrictToLocalhost = (req, res, next) => {
|
||||
const remoteAddress = req.connection.remoteAddress;
|
||||
if (remoteAddress === '::1' || remoteAddress === '127.0.0.1' || remoteAddress === '::ffff:127.0.0.1') {
|
||||
next();
|
||||
} else {
|
||||
res.status(403).json({ Message: 'Access denied' });
|
||||
}
|
||||
};
|
||||
|
||||
const cleanserver = () => {
|
||||
Object.keys(require.cache).forEach(i => {
|
||||
delete require.cache[i];
|
||||
});
|
||||
};
|
||||
|
||||
app.use('/search', restrictToLocalhost);
|
||||
|
||||
app.get('/delete', (req,res) => {
|
||||
cleanserver();
|
||||
return res.json({Message: 'Notes deleted successfully!'});
|
||||
});
|
||||
|
||||
app.get('/search/:noteId', (req, res) => {
|
||||
const noteId = req.params.noteId;
|
||||
const notes=glob.sync(`./notes/${noteId}*`);
|
||||
if(notes.length === 0){
|
||||
return res.json({Message: "Not found"});
|
||||
}
|
||||
else{
|
||||
try{
|
||||
fs.accessSync(`./notes/${noteId}.json`);
|
||||
return res.json({Message: "Note found"});
|
||||
}
|
||||
catch(err){
|
||||
return res.status(500).json({ Message: 'Internal server error' });
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
app.get('/customise', (req, res) => {
|
||||
return res.render('customise');
|
||||
});
|
||||
|
||||
app.post('/customise',(req, res) => {
|
||||
try {
|
||||
const { data } = req.body;
|
||||
|
||||
let author = data.pop()['author'];
|
||||
|
||||
let title = data.pop()['title'];
|
||||
|
||||
let protoContents = fs.readFileSync('./settings.proto', 'utf-8').split('\n');
|
||||
|
||||
if (author) {
|
||||
protoContents[5] = ` ${author} string author = 3 [default="user"];`;
|
||||
}
|
||||
|
||||
if (title) {
|
||||
protoContents[3] = ` ${title} string title = 1 [default="user"];`;
|
||||
}
|
||||
|
||||
fs.writeFileSync('./settings.proto', protoContents.join('\n'), 'utf-8');
|
||||
|
||||
return res.json({ Message: 'Settings changed' });
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).json({ Message: 'Internal server error' });
|
||||
}
|
||||
})
|
||||
|
||||
app.get('/create', (req, res) => {
|
||||
return res.render('create', { noteList, Message: false });
|
||||
});
|
||||
|
||||
app.post('/create', (req, res) => {
|
||||
requestBody=req.body
|
||||
try{
|
||||
schema = fs.readFileSync('./settings.proto', 'utf-8');
|
||||
root = protobuf.parse(schema).root;
|
||||
Note = root.lookupType('Note');
|
||||
errMsg = Note.verify(requestBody);
|
||||
|
||||
if (errMsg){
|
||||
return res.json({ Message: `Verification failed: ${errMsg}` });
|
||||
}
|
||||
buffer = Note.encode(Note.create(requestBody)).finish();
|
||||
decodedData = Note.decode(buffer).toJSON();
|
||||
|
||||
const noteId = generateNoteId(16);
|
||||
fs.writeFileSync(`./notes/${noteId}.json`, JSON.stringify(decodedData));
|
||||
noteList.push(noteId);
|
||||
|
||||
return res.json({Message: 'Note created successfully!',Noteid: noteId });
|
||||
}
|
||||
catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).json({Message: 'Internal server error' });
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
app.get('/view/:noteId', (req, res) => {
|
||||
const noteId = req.params.noteId;
|
||||
|
||||
try {
|
||||
let note=require.resolve(`./notes/${noteId}`);
|
||||
if(!note.endsWith(".json")){
|
||||
return res.status(500).json({ Message: 'Internal Server Error' });
|
||||
}
|
||||
|
||||
let noteData = require(`./notes/${noteId}`);
|
||||
for (var key in module.constructor._pathCache) {
|
||||
if (key.startsWith("./notes/"+noteId)){
|
||||
if (!module.constructor._pathCache[key].endsWith(noteId+".json")){
|
||||
if (noteId===healthCheckId){
|
||||
cleanserver();
|
||||
}
|
||||
delete module.constructor._pathCache[key];
|
||||
return res.status(500).json({ Message: 'Internal Server Error' });
|
||||
}
|
||||
}
|
||||
}
|
||||
if(req.query.temp !== undefined){
|
||||
fs.unlink(`./notes/${noteId}.json`, (unlinkError) => {
|
||||
if (unlinkError) {
|
||||
console.error('File missing');
|
||||
}
|
||||
noteList=noteList.filter((value)=>value!=noteId);
|
||||
});
|
||||
}
|
||||
return res.render('view', { noteData });
|
||||
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
return res.status(500).json({ Message: 'Internal Server Error' });
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
app.get('/healthcheck',async(req,res)=>{
|
||||
try {
|
||||
await healthCheck();
|
||||
|
||||
return res.json({ Message: 'healthcheck successful' });
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return res.json({ Message: 'healthcheck failed' });
|
||||
}
|
||||
});
|
||||
|
||||
app.get('/', (req, res) => {
|
||||
return res.redirect('/create');
|
||||
});
|
||||
|
||||
|
||||
app.use((err, req, res, next) => {
|
||||
console.error(err.stack);
|
||||
res.status(500).json({ error: 'Internal Server Error' });
|
||||
});
|
||||
|
||||
app.listen(port, () => {
|
||||
console.log(`Server running on port ${port}`);
|
||||
});
|
||||
Reference in New Issue
Block a user