start	end	text
14130	18770	Welcome back and thanks for hanging with us here at AppSecVillage at DEF CON 2020.
19270	24790	Before we get to our next speaker, I'd like for you to take a moment and take a look at appsecvillage.com.
25050	30050	Out there you can find this year's t-shirt, which is incredible. This is last year's t-shirt.
30050	35170	This year's has got more color, it's got an awesome design. I just got mine in the mail a couple of days ago.
35350	41750	Check it out. It's a great way to support AppSecVillage and make sure that we can bring you the same kind of content
41750	47750	and application developer security focus that we've brought the last two years.
47750	50270	So, that's appsecvillage.com.
50270	56750	And now for our next talk. It's entitled Local Ghost, Escaping the Browser Sandbox Without Zero Days.
56910	61470	Parsia Hakimian is a senior security engineer at Electronic Arts.
61470	65890	He works mostly in video games and their surprise mechanics.
65990	68910	On a different continent, he was a C developer.
68910	77070	You can find his rants over at parsia.net or on Twitter at at sign crypto gangsta.
77070	83330	Now remember, crypto stands for cryptography, as everybody over in the cryptography village would tell you.
83330	87650	So with that, welcome Parsia to the AppSecVillage stage.
90910	94050	Hello everyone. Thanks for giving me your time.
94050	101450	Today I'm going to talk to you about how we can jump the browser sandbox using localhost web servers without any sort of ODAs.
101450	109250	This is part of the AppSecVillage on DEF CON 28 in the year 2020, which has been a very, very long year.
109930	114550	My name is Parsia. I am a security engineer at Electronic Arts.
114730	119890	Mostly work with video games. I'm the shorter guy in the picture, not the other one.
119890	125270	I'm not here representing EA, user of my own, you know, the usual boilerplate.
125270	130210	Similar to the boilerplate you see on the coffee cups, you know, that says caution, contents are hot.
130270	137450	When I moved to Canada last year from the US, people told me they don't have it in Canada, but they do.
137450	139390	So I would like my money back.
139650	143770	This is my second time at DEF CON. First time at the village.
143770	148030	I was here on DEF CON 2018 where I talked about enterprise blockchain.
148030	152990	I play a lot of video games, which is good because I work for a video game company.
153390	156630	Now, this is a slide that I put on all my presentations.
156630	162650	It is here to tell you what I'm going to talk about.
162710	167250	So you can decide if this is a talk for you.
167310	169050	So your time is valuable.
169050	175730	I don't want you to sit to the end of it and say, this is useless or I already knew this.
175730	182690	You know, I would consider this a favor if everyone else did it too.
183130	191790	So I'm going to talk about why modern desktop applications use local host servers to do inter-process communications.
191810	198970	And how this is bad from a security perspective, because JavaScript and browsers can connect to these websites.
199510	204950	Usually there's no authentication and you can get some really easy remote code executions using this.
204950	209530	I was also discussing browser concepts and bugs related to them.
209530	213850	And finally, I will talk about remediation and how we can fix things.
214010	217530	And not just point and say something is bad.
217830	221710	So these local web servers are like ghosts in your machine.
221810	228830	You think you don't have any, but go to your machine, run netstat and check.
228830	231990	And you will have at least a dozen of these.
231990	234930	I cropped the screenshot, there were more.
234930	243410	As you can see, these are like normal, typical everyday use apps like Discord and Dropbox and Apple and iTunes and NVIDIA.
243410	249630	I mean, all of these have them. Why would Discord or Dropbox have a local web server?
249730	252850	It's usually used for inter-process communications.
252890	255190	Usually you have an Electron frontend.
255250	260150	And the Electron frontend talks to a local web server that serves content to it.
260290	263930	Sometimes you have a Windows service running a system. Those are fun.
263930	268230	And then there's a frontend app that talks to them and they talk with each other.
268230	275030	Sometimes you have a local host server that allows you to talk to different applications.
275030	277710	Discord and Overvolt talk with each other.
278710	284110	Another use case is using seamless transition from a website to a desktop app.
285070	287450	Video conferencing apps used to do this.
287450	291030	You would go to a meeting page.
291030	297270	The JavaScript in the meeting page would talk to the local server from the desktop app.
297270	303870	And the web desktop app would bring up the video conferencing app and connect to the meeting.
303870	307270	Seamless interaction. Great for user experience.
307590	309590	Dropbox also does this.
309590	315230	If you have the Dropbox desktop application on your machine and you go to the web interface,
315230	318990	sometimes you have an open button in front of a file.
318990	323690	Let's say it's a Microsoft Office, like a doc file.
324290	328550	You click on the open button in the website.
328790	332690	The website talks to the local Dropbox app on your machine.
332690	336770	The Dropbox app opens Microsoft Office and opens that doc.
336770	339510	Great again. Great user experience.
339510	343630	But is this really secure? Let's see.
344410	350350	Another thing that websites do and gain a lot of traction was port scanning.
350850	356230	Someone went to the eBay website and saw that it's scanning a lot of local ports.
356230	362370	For example, to see if you have running a local VNC server or the remote desktop application.
362370	363650	Like certain ports.
363790	365950	Banks have been doing it for like four or five years.
365950	368890	I remember I went to a bank website in 2018.
369010	370450	It was doing the same.
370450	373930	This is part of the fraud detection thing.
373930	382550	They grab the results and feed it to a complex fraud detection algorithm.
382550	391670	And it decides if your machine connected to the website is part of a botnet or is being remotely accessed or not.
391670	393710	Should they let the transactions go through?
393710	396010	Should they lock your account? So on and so forth.
396010	397410	Typical stuff.
397410	402750	If these websites are doing it, what prevents bad websites from doing it?
403310	407290	Your app is internet connected because of that.
407810	411650	Raymond Chen is a Microsoft employee.
411650	416430	And he has been writing this very, very useful blog called The Old New Think.
416890	421470	And one of his blogs, which starts with that quote.
421470	425210	It's rather involved beings on the other side of this airtight hatchway.
425210	430470	And by the way, this is a quote from Douglas Adams' book, Hitchhiker's Guide to the Galaxy.
430670	432450	It's an amazing book.
432530	438350	So Raymond talks about three privileged levels on a typical Windows machine.
438350	441170	You have a remote attacker who is not on the machine.
441190	443890	You have a local attacker who is a standard user.
443890	447010	And then finally you have the local admin or system.
447190	452170	Now browsers can be remote attackers, although they are running on your machine.
452170	457750	So the JavaScript in the browser can talk to the local web server or talk to the local WebSocket server.
457830	460890	And then a remote attacker can gain privilege on your machine.
460910	464070	He also talks about how your app is internet connected.
464070	466090	And this is from 2006.
466310	471170	He says, if you have an app and it handles files,
471750	475170	people can create network shares on a remote machine somewhere else.
475210	478030	And then they can pass it to your app.
478030	482290	And now your app is internet connected because it's grabbing a resource from a different site.
482290	484370	Although it wasn't in your threat model.
484890	491090	We've talked a lot about browsers and how browsers can be remote attackers.
491090	497250	Let's talk about how browsers want to keep us safe, but they can, but they cannot.
497310	501270	And what protections are there and how we can bypass them.
501730	504290	The first thing is called same-origin policy.
504290	508750	It's probably the most important part of the browser security model.
508770	510550	So an origin has three parts.
510550	515330	You have a protocol, which is HTTP, HTTPS.
515330	519890	You have a domain, which is something like example.net.
519990	522890	And then finally, you have a port, which is optional.
522910	526610	If you don't include the port, the default port is used.
527310	532970	Some browsers, for example, Internet Explorer, don't care about the port in the origin.
532970	536290	The path is almost always ignored.
536290	542230	Usually, one origin cannot talk to a different origin and grab resources and read them.
542230	549370	So for example, if you open example.net, example.net sends a request to facebook.com and grabs some data.
549370	552970	Browser doesn't let example.net read the response.
553590	558290	Absent some other things are cores, but we're not going to talk about cores today.
558850	563790	And that's a really good thing, because otherwise example.net would have all my Facebook data.
564130	568230	So reads are usually not okay, but writes are.
568350	574470	So if I open example.net and send a POST request to Facebook to change something,
574470	577950	if there's no C-SERV protection, it goes through.
578270	581950	As a result, C-SERV exists, which is not really so great for us.
581950	586290	So the SOP protects us in some cases, but not in every case.
587190	596130	But SOP also has this problem that just because the browser doesn't let you see the response to the request,
596130	598890	doesn't mean the request is not sent.
599230	602330	So browser sends simple requests.
602330	606210	Simple request is a request that has some requirements.
606370	609710	The HTTP verb can only be GET, HEAD, and POST.
609890	611970	It cannot have any custom headers.
612530	615690	And it cannot have every header.
616070	618010	Only some headers are allowed.
618030	621070	And of those headers, the most important one is content type.
621210	624050	The content type for those headers can only be one of those.
624110	627510	So one of the tricks that we usually use when bypassing this,
627510	630630	if you have an application slash JSON request,
630630	633250	you change the content type to text slash plain,
633250	635790	see if it becomes a simple request and goes through.
635790	639610	And now you have bypassed a bunch of protections in the app.
639670	641190	And that brings us to our first bug.
642370	646270	This is a bug by Tavish Romandy from 2016.
646450	649090	Tavish Romandy is a really smart dude.
649090	651330	He's part of the Google Project Zero.
651330	654210	He installs Trend Micro Antivirus,
654210	657270	and that antivirus has a password manager.
657390	659790	So the way password managers usually work
659790	662550	is that you have an extension in the browser,
662550	665290	and you have a local web server, a WebSocket server.
665290	670170	The local server is responsible for storing the passwords,
670170	672490	updating, and a bunch of those.
672490	674510	The extension in the browser,
674510	676550	when, for example, you go to facebook.com,
676550	679890	the extension in the browser talks to the web server and says,
679890	682530	give me my username and password for facebook.com.
682530	685090	And the web server gives it to it.
685090	689090	And then the extension fills up the username and password.
690190	692430	In the case of Trend Micro,
692430	695730	the local web server was unauthenticated,
695730	698370	and you could basically do remote code execution
698370	702610	with a simple GET request, as you can see on this slide.
702830	707910	You could say, OK, run this URL in the default browser,
707910	710870	which in this case opens up the calc,
710870	714430	runs the calc manually instead of opening it in a browser.
714830	717990	If you go and read the bug from the URL,
717990	720350	from the link in this slide,
720350	722770	you can see that Tavisor says,
722770	724730	yeah, we can see the response,
724730	727030	but the GET request goes through
727030	728910	because it's a simple GET request.
729330	731350	So damage is already done.
731350	733830	We can't see the response, but who cares about that?
734510	739030	Another thing that is used for local IPC are WebSockets.
739170	743970	A WebSocket is different from your typical HTTP request.
743970	745810	In a typical HTTP request,
745810	747950	you create a connection to a server,
747950	750590	you send a request, get a response back,
750590	752250	and then you close the connection.
752250	756910	In a WebSocket, you create a WebSocket
756910	758850	and you keep it alive.
758850	761210	You can write to it, you can read from it.
761210	763270	It's great for real-time data things,
763270	765230	real-time data updates,
765230	767790	like, you know, chats and video games
768430	771330	and, like, stock trackers, I guess.
772030	774590	But the WebSocket doesn't come out of the blue.
775090	779810	It starts with a GET request
779810	782090	that is a normal handshake.
782410	784530	So the GET request is your typical GET request
784530	786070	with some special headers.
786390	788990	Now, remember, the GET request for a WebSocket
788990	793010	is a simple request, so it always goes through.
793050	794550	On the response side,
794550	796790	the other side basically says,
796790	798870	here are the things I agreed on.
798870	800830	Yes, we can make a connection.
800830	802250	Here's our protocol.
802250	805190	One mistake that developers usually make
805190	808070	is that they think that SEC WebSocket key
808990	810110	in the request
810110	813050	and the WebSocket ACCEPT key in the response
813050	815010	are based on security.
815110	816150	They're not.
816310	818990	You can usually put something, anything in there
818990	820390	and it usually goes through.
820390	821570	It doesn't really matter.
821570	823410	That's not a security control.
823770	828030	So don't care about that.
828030	829690	It's always there. It goes through.
829690	831030	It doesn't really matter.
831030	833070	And if you can see the response, you can see that
833070	836490	there's nothing really needed there
836490	839050	apart from how we can make a connection.
839110	840850	And as a result,
840850	844290	the browsers are not bound by the same-origin policy
845090	846930	because there's nothing in the response
847420	849450	that the browser doesn't already know.
850070	851830	So if you send a GET request
852370	854250	and there's no cores,
854250	855490	you can't see the response,
855490	857950	but the browser makes the connection for you anyway.
858150	860510	So if you have a local WebSocket server,
860510	862510	everyone can connect to it and talk to it.
862510	865990	You can't rely on SOP or cores or whatever, any of that.
865990	869010	And that brings us to our second Aviso bug.
870690	872930	As I said, this guy is smart.
873090	878370	This is from 2018, and he wanted to re-bind his mouse key.
878370	879630	It was a Logitech mouse,
879630	882030	so he installs an app called Logitech Options.
882490	885070	Logitech Options runs a local WebSocket server,
885070	887530	some port 10134.
888030	891070	As I said, WebSockets are not bound by the SOP,
891070	893510	and the WebSocket server didn't have any checks.
893530	895110	The only authentication it had
895110	897010	was when you sent a message to it,
897010	901130	you had to provide a process ID of a process that the user owns.
901230	905470	A process ID that are like three, four or five digit numbers.
905770	908430	And you can brute force them quite easily in a few minutes
908430	910990	until you find one that works for you.
911270	913610	Fortunately for Logitech Options,
913610	916110	you couldn't get remote code execution,
916110	918170	you could create crashes.
918730	921610	So imagine you have this app running on your machine,
921610	924050	and it's always running because you have a Logitech mouse.
924050	926730	You go to a website, and the app crashes.
926730	928730	You go to the other website, the app crashes.
928730	930550	That's not really useful,
930550	933910	and that makes your experience really bad.
933910	937010	On the plus side, you couldn't get remote code execution,
937010	938630	so that's really great.
938630	941310	The next iteration of the app, similar app,
941310	942650	called Logitech Hub.
942650	944650	It runs two local WebSocket servers,
944650	947470	on port 9010 and 9100.
948590	952430	Now, this iteration checks the origin header,
952430	953650	which is really great.
953650	957230	The origin header is a forbidden header,
957230	960090	which means the JavaScript in the app cannot set it,
960090	961710	only the browser can.
961710	962970	There are other forbidden headers,
962970	964750	like the host header, for example.
965730	968050	And the origin header is always set
968050	970830	by the browser for every cross-origin request.
970830	973950	A request goes from one origin to a different origin,
973950	975250	the browser sets the origin header
975250	977550	to tell the server on the other side
977550	979730	where this request comes from.
979890	982810	So what Logitech Hub does in the WebSocket servers
982810	984690	is if you send a request with an origin
984690	986770	that is not part of their allow list,
986770	989970	then they just say, we can't connect.
990030	991990	And when the browser sees a response like this,
991990	994370	which is not a 200 OK response,
994370	997070	it says, well, I can't create a WebSocket connection.
997230	1000830	So websites cannot talk to Logitech Hub WebSockets,
1000830	1002490	so this is a great thing,
1002490	1005730	and this is a good thing that Logitech has done.
1006170	1009790	We've talked about local WebSockets servers,
1009790	1011350	but we also want to talk about
1011350	1016190	how frameworks can help us get remote code execution.
1016190	1017770	And I'm going to talk about one of them,
1017770	1019130	which is called Electron.
1019130	1021870	Electron is probably the most popular
1024170	1028170	desktop application framework out there.
1028170	1030110	It is based on Chromium.
1030110	1032990	Chromium is the open source version,
1032990	1036490	I'm sorry, the open source base for a bunch of browsers
1036490	1039990	like Google Chrome and Microsoft Edge.
1039990	1043990	So everything in an Electron app is a browser window.
1044090	1045970	So if you open Visual Studio Code,
1045970	1048010	you're looking at a browser window.
1048750	1051650	Yeah, I know, it's silly like that.
1052490	1054690	And Electron is very popular.
1054750	1056310	You can see these apps on this.
1056310	1058110	There are so many of these apps.
1058110	1060830	And these apps that you see on the slide,
1060830	1063610	you probably have at least one of them on your machine.
1063650	1068590	Slack or Discord or Visual Studio Code or Skype or whatever.
1069190	1072410	The problem with Electron apps is that
1072410	1075870	if you get a cross-site scripting,
1075870	1078650	it might lead to remote code execution.
1078870	1081950	So in an Electron app, you can write Node.js code
1081950	1085550	that is run in the browser and can do stuff.
1085830	1088370	The way for this Node.js code to run is
1090550	1092630	you want this Node.js code to run,
1092630	1094070	so you flip a switch.
1094070	1095830	The switch is called node integration,
1095830	1098950	which is off by default for a good reason.
1099150	1101790	So if you set it to true,
1101790	1105790	the JavaScript in your browser window in the Electron app
1105790	1108070	can now talk to the Node.js APIs
1108070	1113350	and, for example, spawn processes on your machine.
1113590	1115970	And as a result, if you have this switch set to true
1115970	1118050	and you get cross-site scripting,
1118050	1120070	now you have remote code execution,
1120070	1121130	which is really bad.
1121130	1122650	If you have an open redirect,
1122650	1124670	which means that you can click on a link
1124670	1126430	and the browser goes to a different link,
1126430	1128370	or you can do something like that.
1128370	1132850	You can embed remote code execution payloads
1132850	1135090	on your website that you control,
1135090	1136630	and then you have remote code execution
1136630	1140770	on someone's machine through an Electron app.
1140770	1143790	This is by default set to off,
1144370	1147290	and as we saw, it's great for a good reason.
1147690	1150090	Now I'm going to talk about one of my own bugs.
1150090	1153650	It's a remote code execution in a Tagged Surface Analyzer,
1153650	1156690	which is an open-source Microsoft application.
1156710	1158410	And we're going to talk about version two of it
1158410	1161310	because it has two versions.
1161490	1164210	When the second version was released,
1164210	1166370	our CISO, who was one of the people
1166370	1168330	who created the original app, said,
1168330	1171450	oh, I worked on the original app,
1171450	1174470	and I went and looked at it and see what kind of app it is.
1174470	1177850	And it's a very useful app for desktop security research.
1178670	1182490	What you can do is you can create runs,
1182490	1184470	which are basically snapshots.
1184630	1188650	So you can tell a Tagged Surface Analyzer
1188650	1192350	to create a snapshot before you install an application
1192350	1195390	on your machine, and then you install the application,
1195390	1198190	and then you create a snapshot or run
1198190	1200850	after you install the application.
1200850	1203950	And now you can compare these two.
1203950	1207450	And you can see what files were added,
1207450	1210830	what registry keys were added, if there were any open ports,
1210830	1213090	if there were any new Windows services.
1213330	1218770	So again, it's very useful for this kind of security research.
1219090	1220870	It comes in two flavors.
1220890	1223510	There's a command line interface, and there's a GUI.
1223590	1225850	I usually want to run it as admin.
1226030	1229330	In fact, if you don't run it as admin,
1229330	1231910	it basically tells you you're not running as admin.
1231910	1233330	You should be running as admin.
1233330	1234970	Because if you're not running as admin,
1234970	1238190	you can't see everything that happens in the computer.
1238350	1240770	You can't see what the application does.
1240770	1242490	You can't get the big picture.
1243430	1244590	It's open source.
1244770	1247910	The GUI is based on electron.net,
1247910	1250410	which is, again, another open source project,
1250410	1254130	which is basically electron, but for .net.
1255930	1258170	Which is... I mean, it works, right?
1259170	1261670	So after I created the... I'm sorry,
1261670	1264670	after I installed the app and ran it for the first time,
1264670	1266190	I saw this pop-up.
1266190	1269690	And this is a Windows firewall pop-up that says,
1269690	1272510	oh, this app wants to listen on all interfaces
1272510	1274430	and open ports in the firewall.
1274530	1277270	And I was wondering, why would a local application,
1277370	1279890	a tag surface analyzer, want to do that?
1279890	1282090	So I looked at the console logs for the app,
1282090	1285670	and I saw that, yeah, it is listening on all interfaces,
1285670	1288870	0, 0, 0, 0, port 8001.
1289470	1291550	That sounds really great.
1291690	1293790	So I started to dig further.
1293790	1295790	I mean, this was the cue to tell me that
1295790	1298810	there might be something wrong with this application.
1298810	1303850	So I go to port 8001 on my own, on the...
1303850	1308690	I'm sorry, on the machine that is running the tag surface analyzer app,
1308690	1309890	and I see the GUI.
1309890	1313310	So the way the app works is it has an Electron frontend
1313310	1315530	and a web server in the back.
1315530	1318610	Electron frontend just opens this website,
1318610	1321470	similar to what is in the browser, as you can see,
1321470	1324050	and it does REST,
1324050	1328790	which is, I guess, normal for Electron applications.
1328790	1332390	Next thing I did, I tried to connect to it from outside,
1332390	1336190	because it's opening the port and listening on all interfaces.
1336190	1337790	I might be able to talk to it.
1337790	1340770	So this is from the virtual machine host.
1341050	1346170	I went to the virtual machine on 8001, and it didn't work.
1346370	1349150	I saw this error that says invalid hosting.
1349730	1353010	So I was looking at it, what is wrong with that?
1353010	1360930	I went and saw it's because the web server that is serving content is a Kestrel web server,
1360930	1363210	which is an ASP.NET web server.
1363210	1366650	I'm sorry, a web server written in ASP.NET.
1366830	1370690	It has a host header filtering.
1370950	1373870	So when you see the request, it looks at the host header.
1373870	1377710	If it's not local host, it says, I can't do it.
1377710	1381670	But here's the thing, because we are connecting from outside,
1381670	1385590	and we are not bound by being in a browser on the machine,
1385590	1390070	I can change the host header because I can create a tool that talks to this
1390070	1391470	and changes the host header.
1391470	1396870	To do this, to simulate this, I added a match-replace ruling verb
1396870	1401130	that whenever it saw the host header, it would replace it with local host.
1401230	1404410	And that means I would be able to connect to it.
1404870	1410950	So this is me connecting to the app from outside.
1410950	1413590	And doing quest.scripting.
1413590	1417630	The next thing I did is I wanted to check if there was a way that I can do
1417630	1421150	inject JavaScript, because I want to get remote code execution.
1421550	1426570	Fortunately, the app only has one place to do user input,
1426570	1429270	and that's the name of the run or snapshot.
1429390	1434470	Again, fortunately for me, it was vulnerable to vanilla script,
1434470	1436910	alert one script JavaScript.
1436910	1442170	So when you start a run, you type the name of the run,
1442170	1446410	script alert one script, and then you start it.
1446410	1448830	At the bottom of the picture, you can see where it says
1448830	1450890	status report for dot.
1451030	1454490	The place before dot is where the script was injected,
1454490	1456270	and the alert pops up.
1457370	1460950	So this is in the web application from outside,
1460950	1465290	but I want to run JavaScript code on the Electron app inside,
1465290	1467230	and I got really lucky.
1467650	1474830	Because when you go to the Electron GUI inside the app,
1474830	1477470	and someone has already started a run from outside,
1477930	1482470	the alert pops up, which is really interesting
1482470	1486490	and really useful for us, because I can start a run from outside,
1486490	1489750	and I can get a pop-up on a user inside.
1490090	1493230	And the way to create a run is a simple GET request.
1493230	1496890	And as you can see, it's a simple request, so it always goes through,
1496890	1499490	which is really great again for me.
1499490	1502470	So I started looking at it, and I was like, okay,
1502470	1506450	so what can I do? How can I use this?
1506590	1509430	So I created a payload and a proof of concept.
1510110	1513830	I start the Electron app in the virtual machine,
1513830	1517530	then I go to it from the virtual machine host from outside.
1517530	1522150	I start a new run, I paste the payload, that pops calc,
1522150	1524290	which is, again, a simple GET request.
1524450	1527730	Now the run is completed, I go to the Electron app,
1527730	1531610	and I click on scan, and the calc pops up,
1531610	1535030	which is the payload that I injected into it.
1535030	1539730	And now, remember, attack surface analyzer is running as admin.
1539730	1542110	That means someone from outside can connect to your machine
1542110	1544150	and get remote code execution.
1545010	1550330	Nice, right? So I reported it to Microsoft.
1550330	1554070	I did responsible disclosure, they fixed it,
1554070	1558050	and then I did a write-up after they said something is fixed,
1558050	1560190	and it gained a little bit of traction.
1561130	1564890	But what happened is Taviso replied to the tweet and said,
1564890	1568630	I hope they actually fixed the injection point,
1568630	1570790	and not just the single null interfaces,
1570790	1573350	because the browser can connect to it.
1573490	1579450	And I was thinking and said, yeah, that is exactly it.
1579450	1583670	So I created a web page that sends this GET request,
1583670	1589010	which is basically a way to pop calc in Node.js,
1589010	1593250	and I want to do another proof of concept and see what is up.
1593330	1596430	So I created a web page with that payload,
1596430	1600250	and then opened the web page in the browser on the virtual machine.
1600250	1604230	To the right you have the browser, to the left you have the Electron GUI.
1604230	1607570	I open it, and the browser says, oh, I can't see the response
1607570	1611070	because there's no cores. It doesn't really matter, does it?
1611070	1613950	The GET request has already gone through, the damage is done,
1613950	1615830	the run has been started.
1615830	1619750	And now you click on the Electron app and go to scan,
1620130	1622110	and calc pops up. Yay!
1622150	1625290	So if the injection hadn't been fixed,
1625290	1631050	and only the listening on all interfaces had been fixed,
1631050	1633170	then we would have had a problem.
1633170	1636510	Imagine you're running a tag surface analyzer on a machine,
1636510	1639170	running it as admin, you open a website,
1639170	1640970	and that website runs code on your machine,
1640970	1645430	literally jumping the browser sandbox and getting back to your machine.
1646070	1647410	So really fun.
1648310	1651210	One of the funnest bugs I have found.
1651390	1658050	Fortunately, I found a different bug that was much better than this.
1658050	1660190	Unfortunately, it hasn't been disclosed yet,
1660190	1662190	so I cannot talk about it today.
1662370	1664870	But life is full of disappointments anyway,
1664870	1667550	so that's one on top of the other ones.
1668050	1672610	As a product security engineer, I do a lot of remediation.
1672610	1675950	We have talked a lot about bugs and pointing at things and saying,
1675950	1678250	this is bad, this is bad, and this is bad.
1678910	1683710	But half of my job is talking to developers and telling them how to fix things.
1683710	1687890	Or better yet, how we can eliminate an entire class of bugs together.
1689010	1693670	This picture is from a YouTube video from a game design college.
1693670	1695310	This is pretty old.
1695310	1698250	These two guys are playing video games,
1698250	1700410	and the boss comes in and says,
1700410	1704510	have you guys finished this game? I need another video game designed.
1704510	1707410	This guy says, we just finished level 3,
1707410	1710310	so we need to tighten up the graphics a little bit.
1711470	1713930	I don't know, for some reason I love it.
1713930	1717670	Every time someone asks me what I do at my job,
1717670	1724770	I tell them that I write how to tighten up the graphics a little bit of level 3.
1724830	1726230	So it's a great thing.
1726230	1729670	It's from Westwood College, which has nothing to do with the Westwood studios
1730230	1732710	who made the Command & Conquer applications.
1732750	1735750	I'm sorry, Command & Conquer games, which are now part of EA.
1736190	1738390	So what can help us?
1738670	1742550	Our most trustworthy friend, in this case, is the browser.
1742990	1745690	I talked about how the browser doesn't help us,
1745690	1748890	but the browsers can help us through the origin header.
1748890	1753150	So origin header is set by the browsers on every cross-origin request.
1753250	1756210	Example.net to facebook.com, you have an origin header.
1756210	1759490	Example.net to example.net, don't have an origin header.
1759490	1763750	It's a forbidden header, so JavaScript in the browsers cannot change it.
1764290	1768410	So if you're a local web server, you see a request that comes in,
1768410	1771790	you do not process the request before checking the origin header.
1771790	1775350	You have an allow list of headers that are good.
1775350	1779210	You check. If it works, then you get to let the request go through.
1779210	1781410	Do not rely on same-origin policy.
1781410	1785950	We already know that the simple GET requests are not going to go through.
1785950	1788450	Do not learn cross-origin resource sharing.
1788450	1790330	We don't need to see the response.
1790330	1793950	We sent a GET request, we got remote code execution.
1794430	1798190	Check the origin header before processing the request.
1798290	1800910	Same thing can help us with WebSockets.
1800910	1804090	Again, with WebSockets, they are not bound by the same-origin policy,
1804090	1807550	but the handshake was a GET request.
1807550	1811790	So when you see a handshake in your WebSocket server,
1811790	1814250	you do not process it, you do not respond.
1814250	1817210	You check the origin header. If it's something that you want,
1817650	1820070	then you send a correct response.
1820070	1823810	If it's not, do something like what Logitech Hub did,
1823810	1826370	return a 403, 404, or whatever.
1826370	1830230	Anything that tells the browser that this request was not successful.
1830230	1835530	That means the WebSocket is not going to get created.
1835870	1838830	One thing that I've seen developers do that is not useful
1838830	1840690	is checking the remote address.
1840690	1844270	That's where the request is coming from.
1844270	1848090	This works to some extent if you have something listening along interfaces
1848090	1851730	and don't want local address, you only want local addresses.
1851730	1854490	But that's not useful in browsers,
1854490	1857230	because if a request is coming from your browser,
1857230	1859250	the browser is running on your machine,
1859250	1862930	the JavaScript is running in the browser,
1862930	1865890	and as a result, the remote address of the request
1865890	1868990	coming from the browser from a website, example.net,
1868990	1872950	is actually local host because the browser is running on your machine.
1873770	1876190	That's really useful. Don't do that.
1876750	1881150	I know, it took a little bit of time to wrap my head around this,
1881150	1882850	but I finally got it.
1883130	1885990	It's a simple check, so check the origin header.
1885990	1889130	With Electron, there's a lot of advice,
1889130	1891870	but I'm going to give you some generic XSS advice.
1891870	1895010	Don't trust user input because you don't want XSS.
1895690	1902230	But more importantly, in order to eliminate an entire class of bugs,
1902230	1906070	you set node integration to false, which is off by default.
1906070	1909230	Don't set it to true if you don't absolutely need it.
1909350	1911130	A lot of developers set it to true
1911130	1916230	because the Electron app needs to run Node.js code in the back.
1918130	1921370	And I don't really blame them because it's very convenient.
1921770	1927510	But what you can do is you can run your Node.js code in preload.
1927510	1930670	So preload is a script that gets loaded in the browser window
1930670	1932590	before everything else.
1932590	1936130	Even if you have set node integration to false,
1936910	1940370	the JavaScript in the preload has access to the Node.js API.
1940370	1944470	So that means that you can't run your own Node.js code
1944470	1948350	and you can't have node integration set to false.
1948350	1950970	Even if you have XSS in this case,
1950970	1954190	you have XSS, which is really not great.
1954190	1957650	But on the plus side, you won't have remote code execution.
1957710	1961430	If you click on the link in the Electron.js website,
1961430	1965570	they have a lot of useful information on how to prevent these attacks,
1965570	1967810	how to do things properly.
1967810	1969510	If you use a local web server
1969510	1974850	to serve content to an Electron app,
1974850	1976790	disable cores.
1976990	1978490	So if you have a local web server,
1978490	1981670	so there was this app I was looking at, a third-party app,
1981670	1983890	and it was running a local web server system
1983890	1986370	that had a front-end Electron.
1986370	1990530	They had enabled cores on the web server,
1990530	1994470	so basically access control allow origin was star,
1994470	1996990	which is not really great, because that means any browser
1996990	1999950	could talk to the web server and grab the results.
1999950	2002970	There was no sort of checking the path,
2002970	2006410	so any website could read all files on your machine.
2006410	2008190	And the server was running a system,
2008190	2010590	which means that it could read everything,
2010590	2013890	and that's not really great. That's not something you want to do.
2013890	2017930	So disable cores, that means you are not leaking information
2017930	2020370	to websites when they talk to it.
2020370	2024390	And last but not least, you want to add browsers to your thread models.
2025250	2027030	So this is Crypto.
2027030	2029370	He's a hacker character
2030370	2032630	in Apex Legends, the video game.
2034350	2037050	Crypto doesn't need to be in an internet cafe somewhere
2037050	2038910	and directly connected to a machine
2038910	2041910	to be enabled as a hacker machine.
2042290	2045210	If you have one of these servers on your machine,
2045210	2049050	and you go to a website where Crypto controls,
2049050	2052370	or if Crypto has injected JavaScript into,
2052370	2055030	and he might get remote code execution on your machine,
2055030	2058170	and as a result, he's now listening to what you are
2058170	2061470	saying on the machine, listening to a Discord conversation,
2061470	2063770	so on and so forth. So don't do that.
2063770	2067230	If you have a local server, think browsers can
2067230	2069630	connect to it and add them to a thread model,
2069630	2071270	have your proper checks.
2071990	2075850	As I said, checks are really simple and we can defeat it
2075850	2078570	and we'll be fine. So I've talked a lot about
2078570	2082210	how to find things,
2082210	2084670	how to fix things, but your
2084670	2087770	next question is, how do I get started in this
2087770	2090530	niche? Practice is the
2090530	2093850	best thing. Start a virtual machine,
2094410	2097450	install a bunch of these client apps, run Headstat,
2097450	2100910	see what servers you have. Start poking at those servers,
2100910	2102770	look at the cores, look at the
2105750	2106870	APIs they
2108810	2109930	expose.
2110330	2113430	The peripheral utility apps
2113430	2116630	are really great candidates. If you have a mouse that comes
2116630	2117930	with a utility to
2120470	2122730	control it, they are usually good
2122730	2125790	candidates. Or you can go to that link on
2125790	2128610	Electron.js website, which has all the Electron apps.
2128610	2131430	Electron apps are usually to have the same thing.
2131430	2136350	If you want to learn more about hacking Electron, there is a
2136350	2138230	GitHub repository with a bunch of
2138230	2141310	links, a lot of useful information, a lot of
2141310	2144110	great research, a lot of great books.
2144110	2147670	And last but not least, read Taviso books.
2147670	2149990	The awesome book that I told you about that hasn't
2149990	2152430	been disclosed, it was
2153530	2156410	two Taviso books mixed together.
2156410	2159030	So I combined two of them and it
2159030	2162330	worked. So that was great.
2163510	2165870	And finally, thanks for giving
2165870	2169010	me your time. Because this is recorded, so I can't
2169010	2172350	answer your questions on the fly in this presentation.
2172350	2174530	What's going to happen is I'm going to be on the Discord
2174530	2177910	and I will answer your questions there and then.
2177910	2181330	To find more about me or if you want to ask questions,
2181330	2183530	you can contact me on those social
2183530	2186650	media links, Twitter
2186650	2189590	or my website or on GitHub.
2189610	2192970	If you have any questions, I'll be happy to answer.
2192990	2195950	Again, thanks for listening to
2195950	2199010	my presentation and giving me your time.
2199090	2201790	And fingers crossed, 2020 won't get worse
2201790	2205610	than this. We can get through this. Have a great day.
