Skip to content

Instantly share code, notes, and snippets.

@noraj
Created September 22, 2018 19:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save noraj/fcc44fd409917bd2da7f3b22c729998f to your computer and use it in GitHub Desktop.
Save noraj/fcc44fd409917bd2da7f3b22c729998f to your computer and use it in GitHub Desktop.
chat (Web) from D-CTF Quals 2018
const io = require('socket.io-client')
const socket = io.connect('https://chat.dctfq18.def.camp')
if(process.argv.length != 4) {
console.log('name and channel missing')
process.exit()
}
console.log('Logging as ' + process.argv[2] + ' on ' + process.argv[3])
var inputUser = {
name: process.argv[2],
};
socket.on('message', function(msg) {
console.log(msg.from,"[", msg.channel!==undefined?msg.channel:'Default',"]", "says:\n", msg.message);
});
socket.on('error', function (err) {
console.log('received socket error:')
console.log(err)
})
socket.emit('register', JSON.stringify(inputUser));
socket.emit('message', JSON.stringify({ msg: "hello" }));
socket.emit('join', process.argv[3]);//ps: you should keep your channels private
socket.emit('message', JSON.stringify({ channel: process.argv[3], msg: "hello channel" }));
socket.emit('message', JSON.stringify({ channel: "test", msg: "i own you" }));
var helper = require('./helper')
var exports = module.exports = {
clients: {},
getUserByClient: function(client) {
return this.clients[client.id]
},
registerClient: function (client, user) {
this.clients[client.id] = { 'c': client,
'u': user,
'ch': {}
};
},
removeClient: function (client) {
var client_old = this.clients[client.id]
if(client_old === undefined)
return client_old
delete client_old.c
client_old = helper.clone(client_old)
delete this.clients[client.id];
return client_old
},
isUserAvailable: function (userName) {
for (var [key, user] of Object.entries(this.clients)) {
if(user.u.name == userName) {
return false;
}
}
return true;
},
getUsername: function (client) {
return this.clients[client.id].u.name;
},
getLastname: function (client) {
return this.clients[client.id].u.lastname;
},
getCountry: function (client) {
return this.clients[client.id].u.country;
},
getLocation: function (client) {
return this.clients[client.id].u.location;
},
getStatus: function (client) {
return this.clients[client.id].u.status;
},
joinChannel: function (client, channel) {
this.clients[client.id].ch[channel] = true;
},
leaveChannel: function (client, channel) {
this.clients[client.id].ch[channel] = false;
},
getSubscribedToChannel: function(channel) {
var subscribed = [];
for (var [key, user] of Object.entries(this.clients)) {
if(user.ch[channel] === true) {
subscribed.push(user.c);
}
}
return subscribed;
},
isSubscribedTo: function(client, channel) {
var user = this.getUserByClient(client)
for (var [chs, state] of Object.entries(user.ch)) {
if(state === true && chs === channel) {
return true;
}
}
return false;
},
};
{
"name": "Default",
"lastname": "Username",
"status": "Status Text",
"location": "127.0.0.1",
"country": "No Man`s Land",
"source": "Website",
"port": "3000"
}
var exports = module.exports = {
clone: function(obj) {
if (typeof obj !== 'object' ||
obj === null) {
return obj;
}
var newObj;
var cloneDeep = false;
if (!Array.isArray(obj)) {
if (Buffer.isBuffer(obj)) {
newObj = new Buffer(obj);
}
else if (obj instanceof Date) {
newObj = new Date(obj.getTime());
}
else if (obj instanceof RegExp) {
newObj = new RegExp(obj);
}
else {
var proto = Object.getPrototypeOf(obj);
if (proto &&
proto.isImmutable) {
newObj = obj;
}
else {
newObj = Object.create(proto);
cloneDeep = true;
}
}
}
else {
newObj = [];
cloneDeep = true;
}
if (cloneDeep) {
var keys = Object.getOwnPropertyNames(obj);
for (var i = 0; i < keys.length; ++i) {
var key = keys[i];
var descriptor = Object.getOwnPropertyDescriptor(obj, key);
if (descriptor &&
(descriptor.get ||
descriptor.set)) {
Object.defineProperty(newObj, key, descriptor);
}
else {
newObj[key] = this.clone(obj[key]);
}
}
}
return newObj;
},
validUser: function(inp) {
var block = ["source","port","font","country",
"location","status","lastname"];
if(typeof inp !== 'object') {
return false;
}
var keys = Object.keys( inp);
for(var i = 0; i< keys.length; i++) {
key = keys[i];
if(block.indexOf(key) !== -1) {
return false;
}
}
var r =/^[a-z0-9]+$/gi;
if(inp.name === undefined || !r.test(inp.name)) {
return false;
}
return true;
},
getAscii: function(message) {
var e = require('child_process');
return e.execSync("cowsay '" + message + "'").toString();
}
}
{
"name": "chat",
"version": "1.0.0",
"description": "DCTF",
"main": "NA",
"dependencies": {
"socket.io": "^2.1.1"
},
"devDependencies": {},
"scripts": {
"test": "NA"
},
"repository": {
"type": "git",
"url": "NA"
},
"keywords": [
"DCTF"
],
"author": "Andrei",
"license": "UNLICENSED"
}
var fs = require('fs');
var server = require('http').createServer()
var io = require('socket.io')(server)
var clientManager = require('./clientManager')
var helper = require('./helper')
var defaultSettings = JSON.parse(fs.readFileSync('default_settings.json', 'utf8'));
function sendMessageToClient(client, from, message) {
var msg = {
from: from,
message: message
};
client.emit('message', msg);
console.log(msg)
return true;
}
function sendMessageToChannel(channel, from, message) {
var msg = {
from: typeof from !== 'string' ? clientManager.getUsername(from): from,
message: message,
channel: channel
};
if(typeof from !== 'string') {
if(!clientManager.isSubscribedTo(from, channel)) {
console.log('Could not send message',msg,' from',
clientManager.getUsername(from),'to',channel,'because he is not subscribed.')
return false;
}
}
var clients = clientManager.getSubscribedToChannel(channel);
for(var i = 0; i<clients.length;i++) {
if(typeof from !== 'string') {
if(clients[i].id == from.id) {
continue;
}
}
clients[i].emit('message', msg);
}
console.log(msg)
return true;
}
io.on('connection', function (client) {
client.on('register', function(inUser) {
try {
newUser = helper.clone(JSON.parse(inUser))
if(!helper.validUser(newUser)) {
sendMessageToClient(client,"Server",
'Invalid settings.')
return client.disconnect();
}
var keys = Object.keys(defaultSettings);
for (var i = 0; i < keys.length; ++i) {
if(newUser[keys[i]] === undefined) {
newUser[keys[i]] = defaultSettings[keys[i]]
}
}
if (!clientManager.isUserAvailable(newUser.name)) {
sendMessageToClient(client,"Server",
newUser.name + ' is not available')
return client.disconnect();
}
clientManager.registerClient(client, newUser)
return sendMessageToClient(client,"Server",
newUser.name + ' registered')
} catch(e) { console.log(e); client.disconnect() }
});
client.on('join', function(channel) {
try {
clientManager.joinChannel(client, channel);
sendMessageToClient(client,"Server",
"You joined channel", channel)
var u = clientManager.getUsername(client);
var c = clientManager.getCountry(client);
sendMessageToChannel(channel,"Server",
helper.getAscii("User " + u + " living in " + c + " joined channel"))
} catch(e) { console.log(e); client.disconnect() }
});
client.on('leave', function(channel) {
try {
client .join(channel);
clientManager.leaveChannel(client, channel);
sendMessageToClient(client,"Server",
"You left channel", channel)
var u = clientManager.getUsername(client);
var c = clientManager.getCountry(client);
sendMessageToChannel(channel, "Server",
helper.getAscii("User " + u + " living in " + c + " left channel"))
} catch(e) { console.log(e); client.disconnect() }
});
client.on('message', function(message) {
try {
message = JSON.parse(message);
if(message.channel === undefined) {
console.log(clientManager.getUsername(client),"said:", message.msg);
} else {
sendMessageToChannel(message.channel, client, message.msg);
}
} catch(e) { console.log(e); client.disconnect() }
});
client.on('disconnect', function () {
try {
console.log('client disconnect...', client.id)
var oldclient = clientManager.removeClient(client);
if(oldclient !== undefined) {
for (const [channel, state] of Object.entries(oldclient.ch)) {
if(!state) continue;
sendMessageToChannel(channel, "Server",
"User " + oldclient.u.name + " left channel");
}
}
} catch(e) { console.log(e); client.disconnect() }
})
client.on('error', function (err) {
console.log('received error from client:', client.id)
console.log(err)
})
});
server.listen(3000, function (err) {
if (err) throw err;
console.log('listening on port 3000');
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment