diff --git a/README.md b/README.md index 5502e50..d01ed27 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,16 @@ WSSSnoop =============== -play with websockets intercept and inject data \ No newline at end of file +Play with websockets intercept and inject data + +![WSSSnoop main screen](WSSSnoop.png) + +# Installing +Simply clone the repo, make the bash scripts executable, run "simple-php-webserver.sh" and browse to the correct URL to get started: + + + $> git clone https://rossmarks.uk/git/git/0xRoM/WSSSnoop.git + $> cd WSSSnoop + $> chmod -v +x simple-php-webserver.sh proxy-to-php-server.sh + $> ./simple-php-webserver.sh + diff --git a/README.md b/README.md index 5502e50..d01ed27 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,16 @@ WSSSnoop =============== -play with websockets intercept and inject data \ No newline at end of file +Play with websockets intercept and inject data + +![WSSSnoop main screen](WSSSnoop.png) + +# Installing +Simply clone the repo, make the bash scripts executable, run "simple-php-webserver.sh" and browse to the correct URL to get started: + + + $> git clone https://rossmarks.uk/git/git/0xRoM/WSSSnoop.git + $> cd WSSSnoop + $> chmod -v +x simple-php-webserver.sh proxy-to-php-server.sh + $> ./simple-php-webserver.sh + diff --git a/WSSSnoop.html b/WSSSnoop.html new file mode 100755 index 0000000..dc49e96 --- /dev/null +++ b/WSSSnoop.html @@ -0,0 +1,65 @@ + + + WSSSnoop + + + + +
+
+ WSSSnoop +
+
+ + + +
+
+ Status:
Offline
+
+
+
+ +
+ + + +
+ +
+ + + +
+
By Ross Marks
+
/inject.php?payload=[inject here]
+
+ +
+
+ + + + + diff --git a/README.md b/README.md index 5502e50..d01ed27 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,16 @@ WSSSnoop =============== -play with websockets intercept and inject data \ No newline at end of file +Play with websockets intercept and inject data + +![WSSSnoop main screen](WSSSnoop.png) + +# Installing +Simply clone the repo, make the bash scripts executable, run "simple-php-webserver.sh" and browse to the correct URL to get started: + + + $> git clone https://rossmarks.uk/git/git/0xRoM/WSSSnoop.git + $> cd WSSSnoop + $> chmod -v +x simple-php-webserver.sh proxy-to-php-server.sh + $> ./simple-php-webserver.sh + diff --git a/WSSSnoop.html b/WSSSnoop.html new file mode 100755 index 0000000..dc49e96 --- /dev/null +++ b/WSSSnoop.html @@ -0,0 +1,65 @@ + + + WSSSnoop + + + + +
+
+ WSSSnoop +
+
+ + + +
+
+ Status:
Offline
+
+
+
+ +
+ + + +
+ +
+ + + +
+
By Ross Marks
+
/inject.php?payload=[inject here]
+
+ +
+
+ + + + + diff --git a/WSSSnoop.png b/WSSSnoop.png new file mode 100755 index 0000000..fb18c44 --- /dev/null +++ b/WSSSnoop.png Binary files differ diff --git a/README.md b/README.md index 5502e50..d01ed27 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,16 @@ WSSSnoop =============== -play with websockets intercept and inject data \ No newline at end of file +Play with websockets intercept and inject data + +![WSSSnoop main screen](WSSSnoop.png) + +# Installing +Simply clone the repo, make the bash scripts executable, run "simple-php-webserver.sh" and browse to the correct URL to get started: + + + $> git clone https://rossmarks.uk/git/git/0xRoM/WSSSnoop.git + $> cd WSSSnoop + $> chmod -v +x simple-php-webserver.sh proxy-to-php-server.sh + $> ./simple-php-webserver.sh + diff --git a/WSSSnoop.html b/WSSSnoop.html new file mode 100755 index 0000000..dc49e96 --- /dev/null +++ b/WSSSnoop.html @@ -0,0 +1,65 @@ + + + WSSSnoop + + + + +
+
+ WSSSnoop +
+
+ + + +
+
+ Status:
Offline
+
+
+
+ +
+ + + +
+ +
+ + + +
+
By Ross Marks
+
/inject.php?payload=[inject here]
+
+ +
+
+ + + + + diff --git a/WSSSnoop.png b/WSSSnoop.png new file mode 100755 index 0000000..fb18c44 --- /dev/null +++ b/WSSSnoop.png Binary files differ diff --git a/data_recv b/data_recv new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/data_recv diff --git a/README.md b/README.md index 5502e50..d01ed27 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,16 @@ WSSSnoop =============== -play with websockets intercept and inject data \ No newline at end of file +Play with websockets intercept and inject data + +![WSSSnoop main screen](WSSSnoop.png) + +# Installing +Simply clone the repo, make the bash scripts executable, run "simple-php-webserver.sh" and browse to the correct URL to get started: + + + $> git clone https://rossmarks.uk/git/git/0xRoM/WSSSnoop.git + $> cd WSSSnoop + $> chmod -v +x simple-php-webserver.sh proxy-to-php-server.sh + $> ./simple-php-webserver.sh + diff --git a/WSSSnoop.html b/WSSSnoop.html new file mode 100755 index 0000000..dc49e96 --- /dev/null +++ b/WSSSnoop.html @@ -0,0 +1,65 @@ + + + WSSSnoop + + + + +
+
+ WSSSnoop +
+
+ + + +
+
+ Status:
Offline
+
+
+
+ +
+ + + +
+ +
+ + + +
+
By Ross Marks
+
/inject.php?payload=[inject here]
+
+ +
+
+ + + + + diff --git a/WSSSnoop.png b/WSSSnoop.png new file mode 100755 index 0000000..fb18c44 --- /dev/null +++ b/WSSSnoop.png Binary files differ diff --git a/data_recv b/data_recv new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/data_recv diff --git a/data_send b/data_send new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/data_send diff --git a/README.md b/README.md index 5502e50..d01ed27 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,16 @@ WSSSnoop =============== -play with websockets intercept and inject data \ No newline at end of file +Play with websockets intercept and inject data + +![WSSSnoop main screen](WSSSnoop.png) + +# Installing +Simply clone the repo, make the bash scripts executable, run "simple-php-webserver.sh" and browse to the correct URL to get started: + + + $> git clone https://rossmarks.uk/git/git/0xRoM/WSSSnoop.git + $> cd WSSSnoop + $> chmod -v +x simple-php-webserver.sh proxy-to-php-server.sh + $> ./simple-php-webserver.sh + diff --git a/WSSSnoop.html b/WSSSnoop.html new file mode 100755 index 0000000..dc49e96 --- /dev/null +++ b/WSSSnoop.html @@ -0,0 +1,65 @@ + + + WSSSnoop + + + + +
+
+ WSSSnoop +
+
+ + + +
+
+ Status:
Offline
+
+
+
+ +
+ + + +
+ +
+ + + +
+
By Ross Marks
+
/inject.php?payload=[inject here]
+
+ +
+
+ + + + + diff --git a/WSSSnoop.png b/WSSSnoop.png new file mode 100755 index 0000000..fb18c44 --- /dev/null +++ b/WSSSnoop.png Binary files differ diff --git a/data_recv b/data_recv new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/data_recv diff --git a/data_send b/data_send new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/data_send diff --git a/inject.php b/inject.php new file mode 100644 index 0000000..710e437 --- /dev/null +++ b/inject.php @@ -0,0 +1,60 @@ + \ No newline at end of file diff --git a/README.md b/README.md index 5502e50..d01ed27 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,16 @@ WSSSnoop =============== -play with websockets intercept and inject data \ No newline at end of file +Play with websockets intercept and inject data + +![WSSSnoop main screen](WSSSnoop.png) + +# Installing +Simply clone the repo, make the bash scripts executable, run "simple-php-webserver.sh" and browse to the correct URL to get started: + + + $> git clone https://rossmarks.uk/git/git/0xRoM/WSSSnoop.git + $> cd WSSSnoop + $> chmod -v +x simple-php-webserver.sh proxy-to-php-server.sh + $> ./simple-php-webserver.sh + diff --git a/WSSSnoop.html b/WSSSnoop.html new file mode 100755 index 0000000..dc49e96 --- /dev/null +++ b/WSSSnoop.html @@ -0,0 +1,65 @@ + + + WSSSnoop + + + + +
+
+ WSSSnoop +
+
+ + + +
+
+ Status:
Offline
+
+
+
+ +
+ + + +
+ +
+ + + +
+
By Ross Marks
+
/inject.php?payload=[inject here]
+
+ +
+
+ + + + + diff --git a/WSSSnoop.png b/WSSSnoop.png new file mode 100755 index 0000000..fb18c44 --- /dev/null +++ b/WSSSnoop.png Binary files differ diff --git a/data_recv b/data_recv new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/data_recv diff --git a/data_send b/data_send new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/data_send diff --git a/inject.php b/inject.php new file mode 100644 index 0000000..710e437 --- /dev/null +++ b/inject.php @@ -0,0 +1,60 @@ + \ No newline at end of file diff --git a/proxy-to-php-server.sh b/proxy-to-php-server.sh new file mode 100755 index 0000000..0b1ff6d --- /dev/null +++ b/proxy-to-php-server.sh @@ -0,0 +1,25 @@ +#!/bin/bash -x + +# Taken from: https://gist.github.com/Jiab77/4d3c1abeb9be4119f33031750cf580d4 +# Increasing local web server performances as possible +# https://stackoverflow.com/questions/39842170/load-balancing-php-built-in-server/47103758#47103758 + +# get a random port -- this could be improved +port=$(shuf -i 2048-65000 -n 1) + +# start the PHP server in the background +if [[ -d "$(realpath ${1:?Missing path to serve})" ]]; then + php -S localhost:"${port}" -t "$(realpath ${1:?Missing path to serve})" & +else + php -S localhost:"${port}" "$(realpath ${1:?Missing path to serve})" & +fi +pid=$! + +# try to adjust delay to improve performances +sleep 0.2 + +# proxy standard in to nc on that port +nc localhost "${port}" + +# kill the server we started +kill "${pid}" diff --git a/README.md b/README.md index 5502e50..d01ed27 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,16 @@ WSSSnoop =============== -play with websockets intercept and inject data \ No newline at end of file +Play with websockets intercept and inject data + +![WSSSnoop main screen](WSSSnoop.png) + +# Installing +Simply clone the repo, make the bash scripts executable, run "simple-php-webserver.sh" and browse to the correct URL to get started: + + + $> git clone https://rossmarks.uk/git/git/0xRoM/WSSSnoop.git + $> cd WSSSnoop + $> chmod -v +x simple-php-webserver.sh proxy-to-php-server.sh + $> ./simple-php-webserver.sh + diff --git a/WSSSnoop.html b/WSSSnoop.html new file mode 100755 index 0000000..dc49e96 --- /dev/null +++ b/WSSSnoop.html @@ -0,0 +1,65 @@ + + + WSSSnoop + + + + +
+
+ WSSSnoop +
+
+ + + +
+
+ Status:
Offline
+
+
+
+ +
+ + + +
+ +
+ + + +
+
By Ross Marks
+
/inject.php?payload=[inject here]
+
+ +
+
+ + + + + diff --git a/WSSSnoop.png b/WSSSnoop.png new file mode 100755 index 0000000..fb18c44 --- /dev/null +++ b/WSSSnoop.png Binary files differ diff --git a/data_recv b/data_recv new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/data_recv diff --git a/data_send b/data_send new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/data_send diff --git a/inject.php b/inject.php new file mode 100644 index 0000000..710e437 --- /dev/null +++ b/inject.php @@ -0,0 +1,60 @@ + \ No newline at end of file diff --git a/proxy-to-php-server.sh b/proxy-to-php-server.sh new file mode 100755 index 0000000..0b1ff6d --- /dev/null +++ b/proxy-to-php-server.sh @@ -0,0 +1,25 @@ +#!/bin/bash -x + +# Taken from: https://gist.github.com/Jiab77/4d3c1abeb9be4119f33031750cf580d4 +# Increasing local web server performances as possible +# https://stackoverflow.com/questions/39842170/load-balancing-php-built-in-server/47103758#47103758 + +# get a random port -- this could be improved +port=$(shuf -i 2048-65000 -n 1) + +# start the PHP server in the background +if [[ -d "$(realpath ${1:?Missing path to serve})" ]]; then + php -S localhost:"${port}" -t "$(realpath ${1:?Missing path to serve})" & +else + php -S localhost:"${port}" "$(realpath ${1:?Missing path to serve})" & +fi +pid=$! + +# try to adjust delay to improve performances +sleep 0.2 + +# proxy standard in to nc on that port +nc localhost "${port}" + +# kill the server we started +kill "${pid}" diff --git a/script.js b/script.js new file mode 100644 index 0000000..d5a04cc --- /dev/null +++ b/script.js @@ -0,0 +1,238 @@ + var dataSendUsed = false; + var checkSend = false; + + function clearPage(){ + $('#cswsh-output').empty(); + $('html, body').scrollTop($(document).height()); + } + + function startSnooping(){ + $('#startSnoop').hide(); + $('#stopSnoop').show(); + $('.sendBar').show(); + $('#wssSendText').focus(); + writeToScreen("Start snooping: " + $("#cswshURL").val()); + checkCSWSH(); + checkSend = true; + checkDataSend(); + } + + function stopSnooping(){ + $('#startSnoop').show(); + $('#stopSnoop').hide(); + $('.sendBar').hide(); + websocket.close(); + checkSend = false + writeToScreen("Stop snooping"); + } + + function checkCSWSH(){ + var wsUri = $("#cswshURL").val(); + + statusWaiting(); + 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) }; + } + + function onOpen(evt){ + writeToScreen(''+getTimestamp()+' '+"CONNECTED"); + statusConnected() + //doSend("origin policy unchecked!"); + } + + function onClose(evt){ + writeToScreen(''+getTimestamp()+' '+"DISCONNECTED"); + statusOffline() + if( $('#stopSnoop').css('display') != 'none' ){ + checkCSWSH() + } + } + + function onMessage(evt) { + var encodedData = encodeToHtmlEntities(evt.data); + writeToScreen(''+getTimestamp()+' '+'RECV: ' + encodedData + ''); + + var recvValue = encodedData.trim(); + if (dataSendUsed) { + sendToInjectPHP(recvValue); + } + var sendValue = getSendValueForRecv(recvValue); + if (sendValue) { + doSendAuto(sendValue); + } + } + + // Function to get the corresponding "send" value for a "recv" value + function getSendValueForRecv(recvValue) { + var valueTable = document.getElementById("valueTable"); + var rows = valueTable.getElementsByTagName("tr"); + for (var i = 0; i < rows.length; i++) { + var cells = rows[i].getElementsByTagName("td"); + if (cells.length === 3 && cells[0].innerText.trim() === recvValue) { + return cells[1].innerText.trim(); + } + } + return null; + } + + function onError(evt){ + writeToScreen(''+getTimestamp()+' '+'ERROR: ' + encodeToHtmlEntities(evt.data)); + } + + function doSend(message){ + writeToScreen(''+getTimestamp()+' '+"SENT: " + encodeToHtmlEntities(message)); + websocket.send(message); + } + + function doSendAuto(message){ + writeToScreen(''+getTimestamp()+' '+'AUTO: ' + encodeToHtmlEntities(message)); + websocket.send(message); + } + + function doSendPayload(message){ + writeToScreen(''+getTimestamp()+' '+'INJT: ' + encodeToHtmlEntities(message)); + websocket.send(message); + } + + var sentData = null; +function checkDataSend() { + if(checkSend == true){ + $.ajax({ + url: "/data_send", + method: "GET", + dataType: "text", + async:false, + contentType: "text", + beforeSend: function( xhr ) { + xhr.overrideMimeType( "text/plain; charset=x-user-defined" ); + }, + success: function (data) { + if (data && data !== sentData) { + console.log(data); + doSendPayload(data); + sentData = data; + dataSendUsed = true; // Set the variable to true if data_send is used + //sendToInjectPHP(recvValue); // Call sendToInjectPHP unconditionally + } + } + }); + + // Check again after a delay + setTimeout(checkDataSend, 2000); + } + return false; +} + +function sendToInjectPHP(data) { + if (dataSendUsed) { + dataSendUsed = false; + var url = "/inject.php?response=" + encodeURIComponent(data); + + $.ajax({ + url: url, + method: "GET", + dataType: "text", + contentType: "text", + beforeSend: function( xhr ) { + xhr.overrideMimeType( "text/plain; charset=x-user-defined" ); + }, + success: function (response) { + // Handle success if necessary + } + + }); + } +} + + + + function writeToScreen(message){ + output = document.getElementById("cswsh-output"); + var pre = document.createElement("div"); + pre.style.wordWrap = "break-word"; + pre.innerHTML = message; + output.appendChild(pre); + $('html, body').scrollTop($(document).height()); + } + + $("#wssCommand").submit(function(e) { + doSend( $('#wssSendText').val() ); + $('#wssSendText').val(""); + $('#wssSendText').focus(); + e.preventDefault(); + }); + + function statusConnected(){ + $('#status').html("Connected"); + $('#status').css("color","lightgreen"); + } + function statusOffline(){ + $('#status').html("Offline"); + $('#status').css("color","red"); + } + function statusWaiting(){ + $('#status').html("Waiting..."); + $('#status').css("color","yellow"); + } + + // Function to store recv and send values + function storeValues() { + var recvValue = document.getElementById("recvInput").value; + var sendValue = document.getElementById("sendInput").value; + + if (recvValue && sendValue) { + var newRow = document.createElement("tr"); + newRow.innerHTML = + "" + + recvValue + + "" + + sendValue + + '[x]'; + document.getElementById("valueTableBody").appendChild(newRow); + + // Clear input fields + document.getElementById("recvInput").value = ""; + document.getElementById("sendInput").value = ""; + } + } + + // Function to remove a row from the table + function removeRow(button) { + var row = button.parentNode.parentNode; + row.parentNode.removeChild(row); + } + + function encodeToHtmlEntities(str) { + var encodedStr = ""; + for (var i = 0; i < str.length; i++) { + var charCode = str.charCodeAt(i); + if (charCode > 127 || /[&<>"'`]/.test(str[i])) { + encodedStr += "&#" + charCode + ";"; + } else { + encodedStr += str.charAt(i); + } + } + return encodedStr; + } + + function getTimestamp() { + var now = new Date(); + var day = now.getDate(); + var month = now.getMonth() + 1; // Adding 1 because months are zero-based + var hours = now.getHours(); + var minutes = now.getMinutes(); + + // Pad single digits with leading zeros + day = day < 10 ? '0' + day : day; + month = month < 10 ? '0' + month : month; + hours = hours < 10 ? '0' + hours : hours; + minutes = minutes < 10 ? '0' + minutes : minutes; + + var timestamp = '[' + day + '/' + month + ' ' + hours + ':' + minutes + ']'; + return timestamp; + } + + //setTimeout(checkDataSend(), 1000); \ No newline at end of file diff --git a/README.md b/README.md index 5502e50..d01ed27 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,16 @@ WSSSnoop =============== -play with websockets intercept and inject data \ No newline at end of file +Play with websockets intercept and inject data + +![WSSSnoop main screen](WSSSnoop.png) + +# Installing +Simply clone the repo, make the bash scripts executable, run "simple-php-webserver.sh" and browse to the correct URL to get started: + + + $> git clone https://rossmarks.uk/git/git/0xRoM/WSSSnoop.git + $> cd WSSSnoop + $> chmod -v +x simple-php-webserver.sh proxy-to-php-server.sh + $> ./simple-php-webserver.sh + diff --git a/WSSSnoop.html b/WSSSnoop.html new file mode 100755 index 0000000..dc49e96 --- /dev/null +++ b/WSSSnoop.html @@ -0,0 +1,65 @@ + + + WSSSnoop + + + + +
+
+ WSSSnoop +
+
+ + + +
+
+ Status:
Offline
+
+
+
+ +
+ + + +
+ +
+ + + + + + + + + diff --git a/WSSSnoop.png b/WSSSnoop.png new file mode 100755 index 0000000..fb18c44 --- /dev/null +++ b/WSSSnoop.png Binary files differ diff --git a/data_recv b/data_recv new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/data_recv diff --git a/data_send b/data_send new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/data_send diff --git a/inject.php b/inject.php new file mode 100644 index 0000000..710e437 --- /dev/null +++ b/inject.php @@ -0,0 +1,60 @@ + \ No newline at end of file diff --git a/proxy-to-php-server.sh b/proxy-to-php-server.sh new file mode 100755 index 0000000..0b1ff6d --- /dev/null +++ b/proxy-to-php-server.sh @@ -0,0 +1,25 @@ +#!/bin/bash -x + +# Taken from: https://gist.github.com/Jiab77/4d3c1abeb9be4119f33031750cf580d4 +# Increasing local web server performances as possible +# https://stackoverflow.com/questions/39842170/load-balancing-php-built-in-server/47103758#47103758 + +# get a random port -- this could be improved +port=$(shuf -i 2048-65000 -n 1) + +# start the PHP server in the background +if [[ -d "$(realpath ${1:?Missing path to serve})" ]]; then + php -S localhost:"${port}" -t "$(realpath ${1:?Missing path to serve})" & +else + php -S localhost:"${port}" "$(realpath ${1:?Missing path to serve})" & +fi +pid=$! + +# try to adjust delay to improve performances +sleep 0.2 + +# proxy standard in to nc on that port +nc localhost "${port}" + +# kill the server we started +kill "${pid}" diff --git a/script.js b/script.js new file mode 100644 index 0000000..d5a04cc --- /dev/null +++ b/script.js @@ -0,0 +1,238 @@ + var dataSendUsed = false; + var checkSend = false; + + function clearPage(){ + $('#cswsh-output').empty(); + $('html, body').scrollTop($(document).height()); + } + + function startSnooping(){ + $('#startSnoop').hide(); + $('#stopSnoop').show(); + $('.sendBar').show(); + $('#wssSendText').focus(); + writeToScreen("Start snooping: " + $("#cswshURL").val()); + checkCSWSH(); + checkSend = true; + checkDataSend(); + } + + function stopSnooping(){ + $('#startSnoop').show(); + $('#stopSnoop').hide(); + $('.sendBar').hide(); + websocket.close(); + checkSend = false + writeToScreen("Stop snooping"); + } + + function checkCSWSH(){ + var wsUri = $("#cswshURL").val(); + + statusWaiting(); + 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) }; + } + + function onOpen(evt){ + writeToScreen(''+getTimestamp()+' '+"CONNECTED"); + statusConnected() + //doSend("origin policy unchecked!"); + } + + function onClose(evt){ + writeToScreen(''+getTimestamp()+' '+"DISCONNECTED"); + statusOffline() + if( $('#stopSnoop').css('display') != 'none' ){ + checkCSWSH() + } + } + + function onMessage(evt) { + var encodedData = encodeToHtmlEntities(evt.data); + writeToScreen(''+getTimestamp()+' '+'RECV: ' + encodedData + ''); + + var recvValue = encodedData.trim(); + if (dataSendUsed) { + sendToInjectPHP(recvValue); + } + var sendValue = getSendValueForRecv(recvValue); + if (sendValue) { + doSendAuto(sendValue); + } + } + + // Function to get the corresponding "send" value for a "recv" value + function getSendValueForRecv(recvValue) { + var valueTable = document.getElementById("valueTable"); + var rows = valueTable.getElementsByTagName("tr"); + for (var i = 0; i < rows.length; i++) { + var cells = rows[i].getElementsByTagName("td"); + if (cells.length === 3 && cells[0].innerText.trim() === recvValue) { + return cells[1].innerText.trim(); + } + } + return null; + } + + function onError(evt){ + writeToScreen(''+getTimestamp()+' '+'ERROR: ' + encodeToHtmlEntities(evt.data)); + } + + function doSend(message){ + writeToScreen(''+getTimestamp()+' '+"SENT: " + encodeToHtmlEntities(message)); + websocket.send(message); + } + + function doSendAuto(message){ + writeToScreen(''+getTimestamp()+' '+'AUTO: ' + encodeToHtmlEntities(message)); + websocket.send(message); + } + + function doSendPayload(message){ + writeToScreen(''+getTimestamp()+' '+'INJT: ' + encodeToHtmlEntities(message)); + websocket.send(message); + } + + var sentData = null; +function checkDataSend() { + if(checkSend == true){ + $.ajax({ + url: "/data_send", + method: "GET", + dataType: "text", + async:false, + contentType: "text", + beforeSend: function( xhr ) { + xhr.overrideMimeType( "text/plain; charset=x-user-defined" ); + }, + success: function (data) { + if (data && data !== sentData) { + console.log(data); + doSendPayload(data); + sentData = data; + dataSendUsed = true; // Set the variable to true if data_send is used + //sendToInjectPHP(recvValue); // Call sendToInjectPHP unconditionally + } + } + }); + + // Check again after a delay + setTimeout(checkDataSend, 2000); + } + return false; +} + +function sendToInjectPHP(data) { + if (dataSendUsed) { + dataSendUsed = false; + var url = "/inject.php?response=" + encodeURIComponent(data); + + $.ajax({ + url: url, + method: "GET", + dataType: "text", + contentType: "text", + beforeSend: function( xhr ) { + xhr.overrideMimeType( "text/plain; charset=x-user-defined" ); + }, + success: function (response) { + // Handle success if necessary + } + + }); + } +} + + + + function writeToScreen(message){ + output = document.getElementById("cswsh-output"); + var pre = document.createElement("div"); + pre.style.wordWrap = "break-word"; + pre.innerHTML = message; + output.appendChild(pre); + $('html, body').scrollTop($(document).height()); + } + + $("#wssCommand").submit(function(e) { + doSend( $('#wssSendText').val() ); + $('#wssSendText').val(""); + $('#wssSendText').focus(); + e.preventDefault(); + }); + + function statusConnected(){ + $('#status').html("Connected"); + $('#status').css("color","lightgreen"); + } + function statusOffline(){ + $('#status').html("Offline"); + $('#status').css("color","red"); + } + function statusWaiting(){ + $('#status').html("Waiting..."); + $('#status').css("color","yellow"); + } + + // Function to store recv and send values + function storeValues() { + var recvValue = document.getElementById("recvInput").value; + var sendValue = document.getElementById("sendInput").value; + + if (recvValue && sendValue) { + var newRow = document.createElement("tr"); + newRow.innerHTML = + "" + + recvValue + + "" + + sendValue + + '[x]'; + document.getElementById("valueTableBody").appendChild(newRow); + + // Clear input fields + document.getElementById("recvInput").value = ""; + document.getElementById("sendInput").value = ""; + } + } + + // Function to remove a row from the table + function removeRow(button) { + var row = button.parentNode.parentNode; + row.parentNode.removeChild(row); + } + + function encodeToHtmlEntities(str) { + var encodedStr = ""; + for (var i = 0; i < str.length; i++) { + var charCode = str.charCodeAt(i); + if (charCode > 127 || /[&<>"'`]/.test(str[i])) { + encodedStr += "&#" + charCode + ";"; + } else { + encodedStr += str.charAt(i); + } + } + return encodedStr; + } + + function getTimestamp() { + var now = new Date(); + var day = now.getDate(); + var month = now.getMonth() + 1; // Adding 1 because months are zero-based + var hours = now.getHours(); + var minutes = now.getMinutes(); + + // Pad single digits with leading zeros + day = day < 10 ? '0' + day : day; + month = month < 10 ? '0' + month : month; + hours = hours < 10 ? '0' + hours : hours; + minutes = minutes < 10 ? '0' + minutes : minutes; + + var timestamp = '[' + day + '/' + month + ' ' + hours + ':' + minutes + ']'; + return timestamp; + } + + //setTimeout(checkDataSend(), 1000); \ No newline at end of file diff --git a/simple-php-webserver.sh b/simple-php-webserver.sh new file mode 100755 index 0000000..b9c0ad4 --- /dev/null +++ b/simple-php-webserver.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +# Taken from: https://gist.github.com/Jiab77/4d3c1abeb9be4119f33031750cf580d4 +# Increasing local web server performances as possible +# https://stackoverflow.com/questions/39842170/load-balancing-php-built-in-server/47103758#47103758 +# https://www.php.net/manual/en/features.commandline.webserver.php + +# Config +LISTEN_INTERFACE="127.0.0.1" +LISTEN_PORT=8082 +ENTRY_POINT=$1 + +# Detect server type to use +PHP_SRV_TYPE=$(php -r "if (version_compare(phpversion(), '7.4', '<')) { echo 'tcpserver'; } else { echo 'embedded'; }") + +# Run detected server type +if [[ $PHP_SRV_TYPE == 'embedded' ]]; then + if [[ -d $ENTRY_POINT ]]; then + PHP_CLI_SERVER_WORKERS=$(nproc) php -S ${LISTEN_INTERFACE}:${LISTEN_PORT} -t $ENTRY_POINT + else + PHP_CLI_SERVER_WORKERS=$(nproc) php -S ${LISTEN_INTERFACE}:${LISTEN_PORT} $ENTRY_POINT + fi +else + tcpserver -v -1 0 ${LISTEN_PORT} ./proxy-to-php-server.sh $ENTRY_POINT +fi diff --git a/README.md b/README.md index 5502e50..d01ed27 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,16 @@ WSSSnoop =============== -play with websockets intercept and inject data \ No newline at end of file +Play with websockets intercept and inject data + +![WSSSnoop main screen](WSSSnoop.png) + +# Installing +Simply clone the repo, make the bash scripts executable, run "simple-php-webserver.sh" and browse to the correct URL to get started: + + + $> git clone https://rossmarks.uk/git/git/0xRoM/WSSSnoop.git + $> cd WSSSnoop + $> chmod -v +x simple-php-webserver.sh proxy-to-php-server.sh + $> ./simple-php-webserver.sh + diff --git a/WSSSnoop.html b/WSSSnoop.html new file mode 100755 index 0000000..dc49e96 --- /dev/null +++ b/WSSSnoop.html @@ -0,0 +1,65 @@ + + + WSSSnoop + + + + +
+
+ WSSSnoop +
+
+ + + +
+
+ Status:
Offline
+
+
+
+ +
+ + + +
+ +
+ + + + + + + + + diff --git a/WSSSnoop.png b/WSSSnoop.png new file mode 100755 index 0000000..fb18c44 --- /dev/null +++ b/WSSSnoop.png Binary files differ diff --git a/data_recv b/data_recv new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/data_recv diff --git a/data_send b/data_send new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/data_send diff --git a/inject.php b/inject.php new file mode 100644 index 0000000..710e437 --- /dev/null +++ b/inject.php @@ -0,0 +1,60 @@ + \ No newline at end of file diff --git a/proxy-to-php-server.sh b/proxy-to-php-server.sh new file mode 100755 index 0000000..0b1ff6d --- /dev/null +++ b/proxy-to-php-server.sh @@ -0,0 +1,25 @@ +#!/bin/bash -x + +# Taken from: https://gist.github.com/Jiab77/4d3c1abeb9be4119f33031750cf580d4 +# Increasing local web server performances as possible +# https://stackoverflow.com/questions/39842170/load-balancing-php-built-in-server/47103758#47103758 + +# get a random port -- this could be improved +port=$(shuf -i 2048-65000 -n 1) + +# start the PHP server in the background +if [[ -d "$(realpath ${1:?Missing path to serve})" ]]; then + php -S localhost:"${port}" -t "$(realpath ${1:?Missing path to serve})" & +else + php -S localhost:"${port}" "$(realpath ${1:?Missing path to serve})" & +fi +pid=$! + +# try to adjust delay to improve performances +sleep 0.2 + +# proxy standard in to nc on that port +nc localhost "${port}" + +# kill the server we started +kill "${pid}" diff --git a/script.js b/script.js new file mode 100644 index 0000000..d5a04cc --- /dev/null +++ b/script.js @@ -0,0 +1,238 @@ + var dataSendUsed = false; + var checkSend = false; + + function clearPage(){ + $('#cswsh-output').empty(); + $('html, body').scrollTop($(document).height()); + } + + function startSnooping(){ + $('#startSnoop').hide(); + $('#stopSnoop').show(); + $('.sendBar').show(); + $('#wssSendText').focus(); + writeToScreen("Start snooping: " + $("#cswshURL").val()); + checkCSWSH(); + checkSend = true; + checkDataSend(); + } + + function stopSnooping(){ + $('#startSnoop').show(); + $('#stopSnoop').hide(); + $('.sendBar').hide(); + websocket.close(); + checkSend = false + writeToScreen("Stop snooping"); + } + + function checkCSWSH(){ + var wsUri = $("#cswshURL").val(); + + statusWaiting(); + 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) }; + } + + function onOpen(evt){ + writeToScreen(''+getTimestamp()+' '+"CONNECTED"); + statusConnected() + //doSend("origin policy unchecked!"); + } + + function onClose(evt){ + writeToScreen(''+getTimestamp()+' '+"DISCONNECTED"); + statusOffline() + if( $('#stopSnoop').css('display') != 'none' ){ + checkCSWSH() + } + } + + function onMessage(evt) { + var encodedData = encodeToHtmlEntities(evt.data); + writeToScreen(''+getTimestamp()+' '+'RECV: ' + encodedData + ''); + + var recvValue = encodedData.trim(); + if (dataSendUsed) { + sendToInjectPHP(recvValue); + } + var sendValue = getSendValueForRecv(recvValue); + if (sendValue) { + doSendAuto(sendValue); + } + } + + // Function to get the corresponding "send" value for a "recv" value + function getSendValueForRecv(recvValue) { + var valueTable = document.getElementById("valueTable"); + var rows = valueTable.getElementsByTagName("tr"); + for (var i = 0; i < rows.length; i++) { + var cells = rows[i].getElementsByTagName("td"); + if (cells.length === 3 && cells[0].innerText.trim() === recvValue) { + return cells[1].innerText.trim(); + } + } + return null; + } + + function onError(evt){ + writeToScreen(''+getTimestamp()+' '+'ERROR: ' + encodeToHtmlEntities(evt.data)); + } + + function doSend(message){ + writeToScreen(''+getTimestamp()+' '+"SENT: " + encodeToHtmlEntities(message)); + websocket.send(message); + } + + function doSendAuto(message){ + writeToScreen(''+getTimestamp()+' '+'AUTO: ' + encodeToHtmlEntities(message)); + websocket.send(message); + } + + function doSendPayload(message){ + writeToScreen(''+getTimestamp()+' '+'INJT: ' + encodeToHtmlEntities(message)); + websocket.send(message); + } + + var sentData = null; +function checkDataSend() { + if(checkSend == true){ + $.ajax({ + url: "/data_send", + method: "GET", + dataType: "text", + async:false, + contentType: "text", + beforeSend: function( xhr ) { + xhr.overrideMimeType( "text/plain; charset=x-user-defined" ); + }, + success: function (data) { + if (data && data !== sentData) { + console.log(data); + doSendPayload(data); + sentData = data; + dataSendUsed = true; // Set the variable to true if data_send is used + //sendToInjectPHP(recvValue); // Call sendToInjectPHP unconditionally + } + } + }); + + // Check again after a delay + setTimeout(checkDataSend, 2000); + } + return false; +} + +function sendToInjectPHP(data) { + if (dataSendUsed) { + dataSendUsed = false; + var url = "/inject.php?response=" + encodeURIComponent(data); + + $.ajax({ + url: url, + method: "GET", + dataType: "text", + contentType: "text", + beforeSend: function( xhr ) { + xhr.overrideMimeType( "text/plain; charset=x-user-defined" ); + }, + success: function (response) { + // Handle success if necessary + } + + }); + } +} + + + + function writeToScreen(message){ + output = document.getElementById("cswsh-output"); + var pre = document.createElement("div"); + pre.style.wordWrap = "break-word"; + pre.innerHTML = message; + output.appendChild(pre); + $('html, body').scrollTop($(document).height()); + } + + $("#wssCommand").submit(function(e) { + doSend( $('#wssSendText').val() ); + $('#wssSendText').val(""); + $('#wssSendText').focus(); + e.preventDefault(); + }); + + function statusConnected(){ + $('#status').html("Connected"); + $('#status').css("color","lightgreen"); + } + function statusOffline(){ + $('#status').html("Offline"); + $('#status').css("color","red"); + } + function statusWaiting(){ + $('#status').html("Waiting..."); + $('#status').css("color","yellow"); + } + + // Function to store recv and send values + function storeValues() { + var recvValue = document.getElementById("recvInput").value; + var sendValue = document.getElementById("sendInput").value; + + if (recvValue && sendValue) { + var newRow = document.createElement("tr"); + newRow.innerHTML = + "" + + recvValue + + "" + + sendValue + + '[x]'; + document.getElementById("valueTableBody").appendChild(newRow); + + // Clear input fields + document.getElementById("recvInput").value = ""; + document.getElementById("sendInput").value = ""; + } + } + + // Function to remove a row from the table + function removeRow(button) { + var row = button.parentNode.parentNode; + row.parentNode.removeChild(row); + } + + function encodeToHtmlEntities(str) { + var encodedStr = ""; + for (var i = 0; i < str.length; i++) { + var charCode = str.charCodeAt(i); + if (charCode > 127 || /[&<>"'`]/.test(str[i])) { + encodedStr += "&#" + charCode + ";"; + } else { + encodedStr += str.charAt(i); + } + } + return encodedStr; + } + + function getTimestamp() { + var now = new Date(); + var day = now.getDate(); + var month = now.getMonth() + 1; // Adding 1 because months are zero-based + var hours = now.getHours(); + var minutes = now.getMinutes(); + + // Pad single digits with leading zeros + day = day < 10 ? '0' + day : day; + month = month < 10 ? '0' + month : month; + hours = hours < 10 ? '0' + hours : hours; + minutes = minutes < 10 ? '0' + minutes : minutes; + + var timestamp = '[' + day + '/' + month + ' ' + hours + ':' + minutes + ']'; + return timestamp; + } + + //setTimeout(checkDataSend(), 1000); \ No newline at end of file diff --git a/simple-php-webserver.sh b/simple-php-webserver.sh new file mode 100755 index 0000000..b9c0ad4 --- /dev/null +++ b/simple-php-webserver.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +# Taken from: https://gist.github.com/Jiab77/4d3c1abeb9be4119f33031750cf580d4 +# Increasing local web server performances as possible +# https://stackoverflow.com/questions/39842170/load-balancing-php-built-in-server/47103758#47103758 +# https://www.php.net/manual/en/features.commandline.webserver.php + +# Config +LISTEN_INTERFACE="127.0.0.1" +LISTEN_PORT=8082 +ENTRY_POINT=$1 + +# Detect server type to use +PHP_SRV_TYPE=$(php -r "if (version_compare(phpversion(), '7.4', '<')) { echo 'tcpserver'; } else { echo 'embedded'; }") + +# Run detected server type +if [[ $PHP_SRV_TYPE == 'embedded' ]]; then + if [[ -d $ENTRY_POINT ]]; then + PHP_CLI_SERVER_WORKERS=$(nproc) php -S ${LISTEN_INTERFACE}:${LISTEN_PORT} -t $ENTRY_POINT + else + PHP_CLI_SERVER_WORKERS=$(nproc) php -S ${LISTEN_INTERFACE}:${LISTEN_PORT} $ENTRY_POINT + fi +else + tcpserver -v -1 0 ${LISTEN_PORT} ./proxy-to-php-server.sh $ENTRY_POINT +fi diff --git a/style.css b/style.css new file mode 100644 index 0000000..4c312f6 --- /dev/null +++ b/style.css @@ -0,0 +1,160 @@ + body{ + background-color: #333; + color:#bbb; + margin:0; + + } + .topBar { + background-color: #444; + position:fixed; + top:0; + width:100%; + z-index:100; + padding: 10px; + } + .topTitle{ + position:absolute; + top:10px; + left:10px; + color:#7fffd4; + } + .topcorner{ + position:absolute; + top:10px; + right:30px; + } + #cswsh-output{ + margin-top: 50px !important; + font-family: 'Source Code Pro', + sans-serif;font-size: 0.7em; + padding-bottom: 65px; + padding-left: 10px; + z-index: 80; + } + .sendBar { + background-color: #333; + position:fixed; + bottom:30px; + width:80%; + z-index:100; + padding: 0px; + height: 30px; + font-family: 'Source Code Pro', sans-serif; + z-index: 80; + } + .sendBar #label { + margin-right: 20px; + width: 110px; + } + /*.sendBar #wssCommand { + width: 100%; + }*/ + .sendBar #wssSendText { + display: flex; + width:100%; + flex-grow: 1; + margin-left: -20px; + margin-top: -20px; + padding-left: 45px; + background-color: #333; + color:#DDD; + font-family: 'Source Code Pro', sans-serif; + border:none; + text-decoration: none; + } + *:focus { + outline: none; + } + .sidebar { + position: fixed; + float: right; + top: -5px; + right: 0; + width: 20%; + height: 100%; + background-color: #555; + margin-top: 45px; + margin-left: 5px; + padding-left: 5px; + padding-top: 5px; + text-align: center; + z-index: 99; + } + .auto-header{ + font-family: 'Source Code Pro', sans-serif; + font-weight: 900; + } + .auto-input{ + font-family: 'Source Code Pro', sans-serif; + width: 95%; + } + .sidebar #valueTable{ + width:100%; + font-family: 'Source Code Pro', sans-serif; + } + .sidebar #valueTableBody{ + font-size: 0.9em; + } + .sidebar #valueTableBody tr{ + margin-bottom:5px; + } + .container { + display: flex; + height: calc(100vh - 30px); /* Adjust the height as needed */ + overflow: auto; + } +.bottomBar { + background-color: #444; + position: fixed; + bottom: 0; + width: 100%; + z-index: 100; + padding: 10px; + height: 20px; /* Increased height to accommodate the text */ + display: flex; + align-items: center; +} + +.bottomBy { + color: #00ccff; + +} + +.bottomBy a:link, +.bottomBy a:visited { + color: #00ccff; + text-decoration: none; +} + +.bottomBy a:hover, +.bottomBy a:active { + color: #99ebff; + text-decoration: none; +} + +.bottomText { + color: #00ccff; + font-family: 'Source Code Pro', sans-serif; + font-size: 0.7em; + margin-left: auto; + margin-right: auto; +} + +.bottomClear { + position: absolute; + bottom: 10px; + right: 30px; +} + +a:link, +a:visited { + color: #00ccff; + text-decoration: none; +} + +/* mouse over link */ +a:hover, +a:active { + color: #99ebff; + text-decoration: none; +} \ No newline at end of file