Created
September 22, 2018 19:45
-
-
Save noraj/fcc44fd409917bd2da7f3b22c729998f to your computer and use it in GitHub Desktop.
chat (Web) from D-CTF Quals 2018
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" })); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
}, | |
}; | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "Default", | |
"lastname": "Username", | |
"status": "Status Text", | |
"location": "127.0.0.1", | |
"country": "No Man`s Land", | |
"source": "Website", | |
"port": "3000" | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"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" | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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