Skip to content

Instantly share code, notes, and snippets.

@pich4ya
Created June 24, 2018 20:13
Show Gist options
  • Save pich4ya/f2a7859f816665be6ddcbc26be1479a7 to your computer and use it in GitHub Desktop.
Save pich4ya/f2a7859f816665be6ddcbc26be1479a7 to your computer and use it in GitHub Desktop.
Google CTF 2018 - Cat Chat (catchat.js)
// Set name
let color = ['brown', 'black', 'yellow', 'white', 'grey', 'red'][Math.floor(Math.random()*6)];
let breed = ['ragamuffin', 'persian', 'siamese', 'siberian', 'birman', 'bombay', 'ragdoll'][Math.floor(Math.random()*7)];
if (!localStorage.name) localStorage.name = color + '_' + breed;
// Utility functions
let cookie = (name) => (document.cookie.match(new RegExp(`(?:^|; )${name}=(.*?)(?:$|;)`)) || [])[1];
let esc = (str) => str.replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&apos;');
// Sending messages
let send = (msg) => fetch(`send?name=${encodeURIComponent(localStorage.name)}&msg=${encodeURIComponent(msg)}`,
{credentials: 'include'}).then((res) => res.json()).then(handle);
let display = (line) => conversation.insertAdjacentHTML('beforeend', `<p>${line}</p>`);
let recaptcha_id = '6LeB410UAAAAAGkmQanWeqOdR6TACZTVypEEXHcu';
window.addEventListener('load', function() {
messagebox.addEventListener('keydown', function(event) {
if (event.keyCode == 13 && messagebox.value != '') {
if (messagebox.value == '/report') {
grecaptcha.execute(recaptcha_id, {action: 'report'}).then((token) => send('/report ' + token));
} else {
send(messagebox.value);
}
messagebox.value = '';
}
});
send('Hi all');
});
// Receiving messages
function handle(data) {
({
undefined(data) {},
error(data) { display(`Something went wrong :/ Check the console for error message.`); console.error(data); },
name(data) { display(`${esc(data.old)} is now known as ${esc(data.name)}`); },
rename(data) { localStorage.name = data.name; },
secret(data) { display(`Successfully changed secret to <span data-secret="${esc(cookie('flag'))}">*****</span>`); },
msg(data) {
let you = (data.name == localStorage.name) ? ' (you)' : '';
if (!you && data.msg == 'Hi all') send('Hi');
display(`<span data-name="${esc(data.name)}">${esc(data.name)}${you}</span>: <span>${esc(data.msg)}</span>`);
},
ban(data) {
if (data.name == localStorage.name) {
document.cookie = 'banned=1; Path=/';
sse.close();
display(`You have been banned and from now on won't be able to receive and send messages.`);
} else {
display(`${esc(data.name)} was banned.<style>span[data-name^=${esc(data.name)}] { color: red; }</style>`);
}
},
})[data.type](data);
}
let sse = new EventSource("receive");
sse.onmessage = (msg) => handle(JSON.parse(msg.data));
// Say goodbye
window.addEventListener('unload', () => navigator.sendBeacon(`send?name=${encodeURIComponent(localStorage.name)}&msg=Bye`));
// Admin helper function. Invoke this to automate banning people in a misbehaving room.
// Note: the admin will already have their secret set in the cookie (it's a cookie with long expiration),
// so no need to deal with /secret and such when joining a room.
function cleanupRoomFullOfBadPeople() {
send(`I've been notified that someone has brought up a forbidden topic. I will ruthlessly ban anyone who mentions d*gs going forward. Please just stop and start talking about cats for d*g's sake.`);
last = conversation.lastElementChild;
setInterval(function() {
var p;
while (p = last.nextElementSibling) {
last = p;
if (p.tagName != 'P' || p.children.length < 2) continue;
var name = p.children[0].innerText;
var msg = p.children[1].innerText;
if (msg.match(/dog/i)) {
send(`/ban ${name}`);
send(`As I said, d*g talk will not be tolerated.`);
}
}
}, 1000);
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Cat Chat</title>
<script src="/catchat.js"></script>
<script src="https://www.google.com/recaptcha/api.js?render=6LeB410UAAAAAGkmQanWeqOdR6TACZTVypEEXHcu"></script>
<link rel="stylesheet" type="text/css" href="/style.css">
</head>
<body>
<div id="panel">
<div id="conversation">
<p>Welcome to Cat Chat! This is your brand new room where you can discuss anything related to cats. You have been assigned a random nick name that you can change any time.</p>
<p>Rules:</p>
<p>- You may invite anyone to this chat room. Just share the URL.</p>
<p>- Dog talk is strictly forbidden. If you see anyone talking about dogs, please report the incident, and the admin will take the appropriate steps. This usually means that the admin joins the room, listens to the conversation for a brief period and bans anyone who mentions dogs.</p>
<p>Commands you can use: (just type a message starting with slash to invoke commands)</p>
<p>- `/name YourNewName` - Change your nick name to YourNewName.</p>
<p>- `/report` - Report dog talk to the admin.</p>
<!--
Admin commands:
- `/secret asdfg` - Sets the admin password to be sent to the server with each command for authentication. It's enough to set it once a year, so no need to issue a /secret command every time you open a chat room.
- `/ban UserName` - Bans the user with UserName from the chat (requires the correct admin password to be set).
-->
<p>Btw, the core of the chat engine is open source! You can download the source code <a href="/server.js">here</a>.</p>
<p style="margin-bottom: 5em">Alright, have fun!</p>
</div>
<input id="messagebox" autofocus>
</div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment