start	end	text
3960	11860	Yep, cool. So, hello everyone. Welcome to our talk and thank you for the introduction.
11980	17540	And in this talk, we'll be talking about how we're exploring secure cryptocurrency wallet
17540	23520	applications. So, my name is Pei-Yu Wang. Here's what with my colleague Ming-Jie He.
23780	29000	We're security engineers at CertiK. So, CertiK is a blockchain security company.
29000	34140	We provide a variety of security services such as smart contract audit, chain audit,
34140	39300	and penetration testing. I'm personally responsible for internal security review
39300	44620	for our own product, as well as the external pen test, focus on wallet,
45320	51300	Explorer, Exchange, and Dapp. So, outside of client work, we also do security research on
51300	56920	different applications in the blockchain space. And that's how we come up with this talk.
56920	64660	We also do bug bounty huntings over the weekend when we have time. This is the first time we speak
64660	71160	at Defcon Blockchain Village. Thank you so much for having us here. So, what is crypto wallet?
71160	76640	I'm sure most people here know what crypto wallet is, but in case someone don't. So,
76640	83580	crypto wallet is a device, a program, or a service that stores the private key and the public key.
84320	90920	So, crypto currency is virtual, like a wallet cannot physically hold the coins. And when you
90920	96280	want to do the transactions, the wallet applications will use your private key to sign the transaction
96280	102400	and broadcast that to the blockchains. There are different forms of crypto wallets. There's
102400	107680	software wallets and hardware wallets. In this talk, we'll be focused on web wallet and desktop
107680	114680	wallets. We believe there's two core functionalities for crypto wallets. One is account
114680	120800	management. It allows users to create accounts, import accounts, and the other one is make
120800	130720	transactions. It sends and receives coins. And for certain protocols, it will have additional
130720	138060	features, such as for Cosmos-based wallets. They will provide the stacking features,
138060	142520	allow users to delete coins to validators, and claim rewards.
143500	148860	And looking at different wallets, we also find some, I don't know how to call them,
148860	154020	maybe call them fancy features. For example, you can view newsletters in a desktop wallet.
154020	159860	You can add third-party plugins in a desktop wallet. You can create a coin giveaway on Twitter
159860	166120	in a web wallet. And there's one desktop wallet, the backend server allows users to upload any
166120	172100	type of files to the backend server with the API. And then there's a desktop wallet that uses the
172100	177660	WebView to implement a browser in it, which is mind-blowing. I don't know why people would want
177660	185440	to use their desktop wallet to be as a browser. So we look at 45 different wallets, and we kind
185440	192680	put them into two categories. One is host wallet. Host wallet is that the server manages your
192680	198960	private keys. If you want to use the wallet, you need to authenticate, log into the application,
198960	204700	authenticate with the server, and the server returns you session tokens or JWT tokens.
206660	211040	Those secrets will either be stored in cookies or local session storage.
211040	214380	And so most of what I will look at are decentralized wallets,
214380	219440	which means the user manages the private key, the store, the key store, and their passwords.
219960	224080	And after users create an account or import an account,
224080	229140	those things will be stored in local or session storage or in the JavaScript variables.
231240	238420	So in the 45 wallets, 27 of them are web wallets and 18 of them are desktop wallets.
238420	243960	We think the logo for those projects are really cool. So we collect them and put it here.
245800	252300	So let's start with the web wallet. This is a typical interface for a web wallet. This is our
252300	260060	30-bit wallet for 30 chains. In this interface, you can check your balance. It has the UI for
260580	266720	sending tokens. And this is because it's a cost-based chain. It has the staking feature as
266720	272940	well. So when we talk about web applications security, the thing that comes to my mind is
272940	280020	OAuth's top 10. Here's some statistics on OAuth's top 10 in the 27 wallets we look at.
280020	286720	We find Crystalscripting in three wallets. We'll do a case study for two of them. We find one
286720	294060	SQL ingestion in a decentralized wallet. So the database only contains those transaction
294510	298740	data. And because the transaction data in blockchain is already public,
298740	305740	and we don't have a way to escalate that SQL ingestion to, say, command code executions.
305740	313940	So that SQL ingestion is kind of just useless in this case. We found one broken authorization.
314240	322320	An unauthorized user can mess around with other people's 2FA settings. But we cannot use this
322320	329360	vulnerability to compromise a user account. A lot of web wallets are missing security headers.
329360	335900	For example, CSP, the content security policy, and expert option headers, and make the wallet
335900	343760	vulnerable to clear-checking. We see a few wallets using outdated JavaScript libraries,
343760	351640	or outdated Nginx, Apache hosting, but we are not able to directly export them.
353020	360320	So we have not seen any wallets dealing with XML, or find them doing any type of
360320	368780	DCR audations. For the login and monitoring, we just don't know. So jumping to the first case study.
369520	377600	So this is a DOM SSS in a decentralized web wallet. The wallet supports single protocols.
377600	384260	It has all the basic functionalities for a wallet. It doesn't really have any fancy things there.
384940	391340	So the vulnerable feature is the application saves the last location, the user visit, and
391340	396500	it redirects the user to that page after the user unlocks his wallet with his password.
396900	404400	In this URL, it will redirect the user to the valid data page after the user unlocks his wallet.
404400	412480	And here's the co-implementations. The object return to equal to the parsing result of the
412480	420740	window.location.search, and the return to variable pass into the window.location.href.
421000	426880	If you have some experience about web app testing and stuff, you might realize this
426880	435960	might be vulnerable to DOM SSS. And that is the case. So DOM SSS requires source and sync.
435960	442500	So source is the location where untrusted data, the user input, is taken by the application and
442500	449000	passed to the sync. So when user visits this URL, the window.location.search will return
449000	454320	question mark, return to equal to slash validators. And the return to object will later
454320	462740	becomes, will contain the streams slash validators. And here's the sync. Sync is the place
462740	470000	where untrusted data coming from the source is actually getting executed. So the sync here is
470000	478900	the window.location.href, and it's taking the user input inside the return to. So when it returns to
478900	484600	slash validators, it goes to slash validator page. But if it's JavaScript, JavaScript,
484600	491940	colon alert one, it's going to pop alert in the browser. So we have the DOM SSS here,
491940	501620	but how can we export this to causing bigger damage? So this is a decentralized web wallet.
501620	508860	The key store and the passwords are stored in the local storage after user creating account
508860	514780	or import his account. So if you're not familiar with local storage or JavaScript,
515660	522540	so JavaScript is able to read the content inside the local storage. In this example,
522540	528080	there's a key value pair, hello world store in local storage. JavaScript can just do local
528080	536960	storage.get item, hello, and we just get the contents. So now the attack plan is to steal
536960	542140	the key store and password in the local storage with the DOM SSS. And that's exactly what this
542140	549660	payload does. It reads the content of the key store and password and sends it to my web server.
549700	556600	And in my SS log, I can see the key store contents and the passwords. And after I have those
557280	562940	contents, I basically just own the account. I can use those information, log into the wallet and
562940	572120	transfer all the money out. So for the fix here, the fix here is after user unlock his wallet,
572120	578500	I just always redirect to the portfolio page. It just doesn't give the chance for attacker
578500	586320	to inject any payloads here. So the second case study is reflect SSS in a host web wallet.
586320	593420	So it has host web wallet. The server manage all the your private key. And to log into the
593420	599380	applications, you will use your email and the one time passcode you receive in the email.
599520	605020	The wallet supports 16 different coins. It has all the basic functionalities and one additional
605020	611940	feature called Twitter giveaway. This is the API handling. So the API format is like the
611940	618780	slash API slash endpoint. And the one to get user transaction is slash API users.
618780	627540	And if you visit the non-existing endpoint, for example, slash API slash test,
627540	633600	it will return the error message like this one. Translate to English, it's failed to resolve the
633600	641420	request test. So what we're seeing here is the content in the URL is reflect bad in the response.
641940	649360	And this is kind of signal that indicating that this if the backend doesn't do any
649360	654480	standardizations or encoding, that might have the reflect scripting vulnerabilities.
654880	662500	And that's exactly the case. So by putting slash SVG unload equal to alert document domains,
662500	668660	the application just very happily popped the alert for me. And as I mentioned, this is a host
668660	675160	web wallet. The private key is owned by the server. You cannot just directly steal them
676380	682560	like the one in the first case study. So the plan here is to use these vulnerabilities
682560	689940	to compromise either take over user's account or take over his sessions. So by looking around,
689940	700140	I found that this session token is stored in the PHP SCSSID cookies. And what's special here is
700140	706520	it does not have the that token does not have the HTTP only flag. So if you are not a website guy
706520	713380	or web developer, HTTP only flag, if that has that flag set, it will stop JavaScript from accessing
713380	718960	that cookies. In other words, you say it is it prevents attacker from stealing the session tokens
718960	726240	in the cookies with the cross-site scripting attack. But in this case, there's no HTTP only.
726240	732760	So I can just craft a payload that read the content with the cookie content and send to my
732760	739980	web servers. So after I get the session tokens, I can use the session token, log in to the victim's
739980	745660	account. So, you know, when you're going to compromise the wallet, the end goal will always
745660	751140	try to steal the money. So I take over the session. Now it's time to take all the money.
751140	757240	But wait, I can't because for the money transactions actions in that wallet,
757240	765680	it requires a 2FA. So I kept looking around to see what I can do. I was not able to reset the 2FA.
765680	772580	I was not able to disable the 2FA. But I found a feature. There's a feature called giveaway.
772580	779240	How it works is you go into the interface, it asks you what kind of coin you want to give away,
779240	783080	and how many of them you want to give away, and how many people you want to give it to.
783420	789460	In this case, here in the screenshot, you can give away up to two bitcoins. I think that's a lot.
791200	795840	And after you create a giveaway, what people will need to do is they need to follow you,
795840	801660	text your friends, retweet. Once you have done that, you can go to the URL and claim the reward.
801660	806780	And what's special about this feature is this feature doesn't require 2FA.
807620	814480	So I can use the reflect-quota-scripting to steal users session tokens and use these features to
815420	820320	create a bunch of giveaways and claim those rewards myself. And this way,
820320	824060	I can just transfer all the money coins out from the bitcoins account.
825200	831560	So on May 28, I reported these issues to the company by email. They act on these issues.
832220	839340	And it was silenced for almost two months. And last month, their response to the issue is fixed
839340	847760	and reward me $20 worth of coins. They don't really have a formal bug bounty program,
847760	856140	so I'm fine with the $20. So the fix is the HTML encode output, so no more cross-site scripting.
856140	863240	And they said HTTP only flag for the cookies that contains the session tokens. In this way,
863240	870860	if the application is vulnerable to cross-site scripting later, then the attacker would not be
870860	877620	able to directly steal the session tokens. So that's all about the case study on WebWallet.
877620	882780	Let's go move on to DesktopWallet. So DesktopWallet is the desktop application
883420	890760	as it's a wallet that runs on Windows, macOS, and sometimes Linux. So what kind of text that
890760	899020	people use to build a DesktopWallet? So we look at 18 DesktopWallets. So one is Qt, C++,
899020	908340	one is .NET, C Sharp, and one Java, and 15 Electrons. In the DesktopWallet case study,
908340	912960	we'll first talk about a server-side RCE in a .NET DesktopWallet,
912960	918960	and the second one is a client-side RCE in an Electron wallet. Now I'm going to mute myself
918960	926800	and let my colleague Mingzhi walk you guys through the server-side RCE in the .NET DesktopWallet.
930670	936650	Thanks, Pei. So hi, everyone. I'm Mingzhi. So I'm going to talk about a remote code execution
936650	942010	vulnerability found in a DesktopWallet. So first, I'll give some background about the wallet.
942030	946910	The wallet is a decentralized single protocol wallet. It is written in C Sharp, and it uses
946910	952030	.NET framework. It contains many common wallet functionalities like account management,
952030	957150	making transactions, and deploying and interacting with smart contracts. What's interesting is that
957150	962770	it allows users to upload files to a server. This is not quite common in a wallet, so we decided to
962770	967730	look into this feature more. As mentioned previously, this application uses .NET,
967730	972210	so for .NET application, it is very easy to retrieve the source code by decompiling the
972210	979110	executables if code obfuscation is not deployed. So this is exactly the case of the wallet,
979110	983750	so we're able to recover the source code for further analysis. So after decompiling the
983750	988750	executables, we found the source code that implements the file upload, as shown in the
988750	995010	snippet. The wallet sends a HTTP post request to the server, and it returns with the file upload
995010	1003130	URL. So we saw file upload.php is the file that handles the file upload on the server side.
1003250	1008450	So as a pen tester, this is very fascinating, as now we know that the server probably uses PHP
1008450	1014650	as the backend. So if we could upload a PHP WebGL to the server and open it in a browser,
1014650	1017270	we might get remote code execution on the server.
1018870	1024770	So that's exactly what we did. So we are able to successfully upload the file using the wallet
1024770	1031150	and access the file in the browser. So after clicking on the upload shell, we are able to
1031150	1036150	gain a web shell on the server. We also discovered that the web server runs under the administrator
1036150	1041570	user, so we are able to execute commands with administrator privilege. So at this point,
1041570	1046110	we are able to gain full control of the server, and we are able to manipulate files uploaded by
1046110	1052210	other users. However, as mentioned previously, since it's a decentralized wallet, the server
1052210	1058050	does not store any user private keys. So you are not you cannot directly compromise user account
1058050	1064210	by exploiting this vulnerability. So the fix is actually pretty simple. The developer just
1064210	1068670	removes the file upload functionality in their further application so that they do not have to
1068670	1073330	deal with it. This is actually a good idea, as the critical wallet is supposed to keep as simple
1073330	1078530	as possible to avoid security issues. So now I will hand over to Pei Yu to talk about security
1078530	1089140	in Electron Wallet. Yeah, thanks, Minji. So right now, let's jump to Electron.
1090700	1096960	What is Electron and why Electron? Electron is an open source framework that allows developers to
1096960	1103560	build cross-platform desktop applications with HTML, CSS, and JavaScript. Electron combines the
1103560	1108560	core and render engine Node.js into a single runtime. So the benefit of using Electron is
1108560	1115720	developers can reuse web application codes to build desktop applications. They don't need to
1115720	1121660	have a separate codebase. They don't need to learn new languages. And debugging the
1121660	1127760	Electron application is pretty easy with the Chrome dev tools. And Electron applications run
1127760	1134440	on major OS. And because it can access to the Node.js modules, it can build a more powerful
1134960	1142380	app compared to the web app in the browsers. So Electron security. So for most vulnerabilities
1142380	1147800	that exist in a web app, you can basically find them in the Electron app. And for Electron's
1147800	1155580	specific security issues, the Electron official security guidance provides very detailed
1155580	1162100	information about what mistakes that people make that will make the application vulnerable and how
1162100	1169760	to not make those mistakes. And in BlackHat USA 2017, a talk called a study of Electron security
1170330	1176160	talked about advanced technique that you bypass the building Electron security
1177100	1183880	protections to achieve core executions. But in this talk, we will be simply talking about one
1183880	1190940	configuration called Node integration. So the definition for Node integration is it refers
1190940	1198640	to the ability of assessing Node.js resources in the applications. So why Electron application can,
1198640	1202620	although it's using web technology, but can build more powerful app than
1203320	1208290	application running in the browser because it can import so many Node.js modules.
1209110	1215710	But it does come with a greater security risk. So aside from the Electron official security doc is
1215710	1222050	disabling Node.js integration help prevent cross-scripting from escalating to a so-called
1222050	1226330	remote core execution RCE attack. So what does it really mean?
1226970	1234110	So this is the latest version of the MyCrypto desktop wallet. In the configuration, it has the
1234110	1241530	Node integration set to false, which has the Node.js disabled. And if you type require in the
1241530	1248290	dev console, it will just say require is not defined. This is the early version of the MyCrypto
1248290	1256750	desktop wallet. It has the Node integration set to choose and Node.js enabled. In the dev console,
1256750	1263650	if you type require, it will show the require functions. So by copy pasting some malicious
1263650	1273190	code into the dev consoles, this behavior causes cross-scripting. And this is what you will see if
1273190	1278670	you open the dev console when you're in the Electron, in the desktop core application.
1278670	1284770	It says if someone told you to copy paste something here, you have 11 out of 10 chance being scanned
1284770	1290770	and you shouldn't do that. So normally in a web application,
1290770	1299030	if victim exported by the self-SSS, attacker can probably compromise his account
1299030	1306450	or do some damage to his account within the application. However, for Electron wallet,
1306930	1313870	it might get from self-SSS to calculator. So to open a dev console in Electron application
1313870	1319930	on macOS, it's option plus command plus I. And if you copy paste the following code
1320580	1330630	into the console, you can see calculators. So if you're not familiar what calculator means,
1331670	1336670	it's the way to show the successful of co-executions.
1336670	1343250	So you see, I paste that into the console and the calculator pop up.
1344610	1351650	So what if the victim... so if you want to use way to export a victim, the victim,
1351650	1357550	you will probably will construct some really long weird things and ask the victim to paste
1357550	1363430	into dev console and the victim be like, hey, I'm not going to paste this weird thing into my dev
1363430	1368470	console. So how about this one? I'll paste this, it will allow you to claim one BTC.
1368710	1378490	Just paste window location to href equal to HTTPS BTC giveaway dot sign. So by the way,
1378490	1387330	that domain is available. It only cost $0.99 on GoDaddy. Yeah, so the victim is like, oh sure,
1387330	1394990	this short command, I'm just going to paste into console, what will happen? So what happens,
1394990	1400350	you're going to see the calculators again, because what the line is doing is it will
1400350	1405550	redirect you to another page. And if that page has the malicious code, it will just
1405550	1413390	go to SQL in your desktop wallet in the electronic locations. So here's a statistic
1413390	1422030	on electron wallet we look at. So we look at 15 electron wallet that's in active development.
1422310	1430010	So 11 out of 15 has Node.js enabled. This can either cause by they, in the configuration file,
1430010	1437350	they set the node integration to choose or they use the electron version less than 5.0.
1437350	1444390	So the electron framework later than 5.0, it has Node.js disabled by default for security
1444390	1454070	reasons. And 5 out of 15 has Node.js enabled and have the dev console enabled. So it might
1454070	1460030	just escalate self cross-site scripting to client-side co-execution. So this is one example
1460030	1469010	that the attacker can trigger the co-execution directly without using self cross-site scripting.
1469150	1475810	And that brings us to our last case study on client-side RCE on a simple desktop wallet.
1475810	1480790	So the simple desktop wallet is an open source decentralized single-coin wallet.
1480790	1486930	It's the application from where it's built. It's electron. It has all the functionalities,
1486930	1492630	basic wallet functionality, and as an addition, future code view news. They have
1492630	1498390	bug bounty programs on HackerOne. That's how I discovered them and start hacking the wallet.
1499430	1506650	So since it's open source, I start with the code view. This is their, the build.js is their
1507470	1513730	electron configuration file. What the here does is the process the platform is storing.
1513730	1519650	It starts the application with the create Mac functions. Otherwise, it creates the start
1519650	1526630	application with the create Windows functions. So, and in the create Windows functions, I see
1526630	1533330	that node integration is set to choose. That means if the application is running on Windows,
1533330	1542210	the node.js is enabled. So how can we export this? So my goal will be to inject arbitrary
1542210	1549670	JavaScript. Self-cursor scripting? No, bug bounty program does not pay for self-cursor scripting.
1549670	1555170	How about legitimate cursor scripting? No, I was not able to find one. But how about node
1556410	1562430	untrusted remote content into the application? So, all right, let's do some news. So in the
1562430	1568450	simple desktop wallet, it provides the view news features. And when you click that link
1568450	1578850	into in the news, it actually read the redirect out the wallet and go to another website.
1578850	1584150	In this case, it just opened up GitHub on inside the desktop wallet.
1585110	1592750	So the exportation plan is I will host the webpage with malicious JavaScript. I will place
1592750	1597990	the URL then point to my malicious page on GitHub. It can be a GitHub issues on the repo.
1597990	1605850	I can create a repo and put it in the README. Or I can put it on my GitHub profile and then
1606530	1614850	visit that URL in the desktop applications. This is a very easy, simple proof-of-concept code. What
1614850	1621730	it does is there's a button. And when the button is clicked, it triggers the RCE count functions.
1621730	1627770	What a function does, it just pops the calculators. And here's a proof-of-concept video.
1629570	1637930	So I opened up the desktop wallet. I unlock wallet with my password.
1643350	1648670	And I go ahead and verify the version. It's a very early version.
1648670	1658810	This is the version back in April, I think. And I click the link in the news. I'm now on GitHub.
1658810	1666230	And in this case, you ask the victim to go to certain GitHub page with a phishing attack.
1666230	1672430	But for the demonstration, I just go to my personal GitHub account. And I have the URL
1672430	1679430	hosted on my profile. And I click that. I go to the page that contains my POC.
1679490	1687190	And I click the close. Calculator just pop up. So in this example, the POC script requires
1687190	1695570	user to click a button. But in reality, attacker can just execute those malicious code automatically.
1695570	1701030	And of course, attacker can use JavaScript to steal the key stores, steal the passwords,
1701030	1707810	or it can, you know, use have like creating a reversal and control the victim's computers.
1709330	1715530	So timeline must submit these reports on HackerOne. They triage and give me 2,500 bounties.
1715530	1721610	And they fix in the next release. The simple team and the name team are really nice. I really
1721610	1728530	appreciate they allow me to talk about this being public. So and the fix was they set the no
1728530	1736450	integration to false in the build.js file and update the build news feature. So right now,
1736450	1743710	if you click the link in the news, it will open up in the external browser instead of inside the
1743710	1751690	desktop wallet. So again, I want to thank the team and they really value the security they use.
1752070	1759150	Yeah, really fixed. So the takeaway here is attacker can compromise the victim's
1759730	1762520	wallet or even the computer.
1763800	1786680	And have you had a security audit before you allow users to have an internal security team?
1786680	1792180	Definitely ask the security team for a security review. And if you don't have the
1792180	1796800	internal security team, you have to hire a security professional for a security review.
1798920	1805660	If you have any questions, comments, you can post it on the text channel or email us after
1806320	1812480	you're welcome to follow us on our Twitter. This slide will be posted on my Twitter account.
1813780	1819300	And you can, if you're interested, you can check out our company blog post. There's a lot of
1819300	1824580	interesting blog posts that we talk about some hacks that happened recently or some technical
1824580	1837640	articles. Thanks. Yeah, if you have any questions, just drop in the channel.
