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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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