1 00:00:03,960 --> 00:00:05,100 Yep, cool. 2 00:00:05,100 --> 00:00:07,540 So, hello everyone. 3 00:00:08,400 --> 00:00:11,860 Welcome to our talk and thank you for the introduction. 4 00:00:11,980 --> 00:00:18,680 And in this talk, we'll be talking about how we're exploring secure cryptocurrency wallet applications. 5 00:00:19,060 --> 00:00:20,920 So, my name is Pei-Yu Wang. 6 00:00:20,920 --> 00:00:23,520 Here's what with my colleague Ming-Jie He. 7 00:00:23,780 --> 00:00:26,060 We're security engineers at CertiK. 8 00:00:26,060 --> 00:00:29,000 So, CertiK is a blockchain security company. 9 00:00:29,000 --> 00:00:35,640 We provide a variety of security services such as smart contract audit, chain audit, and penetration testing. 10 00:00:35,800 --> 00:00:47,820 I'm personally responsible for internal security review for our own product, as well as the external pen test, focus on wallet, Explorer, Exchange, and Dapp. 11 00:00:47,920 --> 00:00:54,600 So, outside of client work, we also do security research on different applications in the blockchain space. 12 00:00:54,600 --> 00:00:56,920 And that's how we come up with this talk. 13 00:00:56,920 --> 00:01:02,540 We also do bug bounty huntings over the weekend when we have time. 14 00:01:02,700 --> 00:01:06,560 This is the first time we speak at Defcon Blockchain Village. 15 00:01:06,560 --> 00:01:08,840 Thank you so much for having us here. 16 00:01:09,460 --> 00:01:11,160 So, what is crypto wallet? 17 00:01:11,160 --> 00:01:16,460 I'm sure most people here know what crypto wallet is, but in case someone don't. 18 00:01:16,460 --> 00:01:23,580 So, crypto wallet is a device, a program, or a service that stores the private key and the public key. 19 00:01:24,320 --> 00:01:30,360 So, crypto currency is virtual, like a wallet cannot physically hold the coins. 20 00:01:30,520 --> 00:01:39,060 And when you want to do the transactions, the wallet applications will use your private key to sign the transaction and broadcast that to the blockchains. 21 00:01:39,880 --> 00:01:42,260 There are different forms of crypto wallets. 22 00:01:42,260 --> 00:01:44,800 There's software wallets and hardware wallets. 23 00:01:45,000 --> 00:01:48,760 In this talk, we'll be focused on web wallet and desktop wallets. 24 00:01:49,400 --> 00:01:54,000 We believe there's two core functionalities for crypto wallets. 25 00:01:54,000 --> 00:01:55,400 One is account management. 26 00:01:55,400 --> 00:02:02,020 It allows users to create accounts, import accounts, and the other one is make transactions. 27 00:02:02,020 --> 00:02:04,160 It sends and receives coins. 28 00:02:06,180 --> 00:02:15,680 And for certain protocols, it will have additional features, such as for Cosmos-based wallets. 29 00:02:15,680 --> 00:02:22,520 They will provide the stacking features, allow users to delete coins to validators, and claim rewards. 30 00:02:23,500 --> 00:02:30,740 And looking at different wallets, we also find some, I don't know how to call them, maybe call them fancy features. 31 00:02:30,780 --> 00:02:34,020 For example, you can view newsletters in a desktop wallet. 32 00:02:34,020 --> 00:02:37,880 You can add third-party plugins in a desktop wallet. 33 00:02:37,880 --> 00:02:41,320 You can create a coin giveaway on Twitter in a web wallet. 34 00:02:41,920 --> 00:02:49,620 And there's one desktop wallet, the backend server allows users to upload any type of files to the backend server with the API. 35 00:02:50,200 --> 00:02:56,240 And then there's a desktop wallet that uses the WebView to implement a browser in it, which is mind-blowing. 36 00:02:56,240 --> 00:03:00,540 I don't know why people would want to use their desktop wallet to be as a browser. 37 00:03:02,440 --> 00:03:07,180 So we look at 45 different wallets, and we kind put them into two categories. 38 00:03:07,180 --> 00:03:08,700 One is host wallet. 39 00:03:08,700 --> 00:03:13,780 Host wallet is that the server manages your private keys. 40 00:03:14,020 --> 00:03:24,700 If you want to use the wallet, you need to authenticate, log into the application, authenticate with the server, and the server returns you session tokens or JWT tokens. 41 00:03:26,660 --> 00:03:31,040 Those secrets will either be stored in cookies or local session storage. 42 00:03:31,040 --> 00:03:39,440 And so most of what I will look at are decentralized wallets, which means the user manages the private key, the store, the key store, and their passwords. 43 00:03:39,960 --> 00:03:49,140 And after users create an account or import an account, those things will be stored in local or session storage or in the JavaScript variables. 44 00:03:51,240 --> 00:03:58,420 So in the 45 wallets, 27 of them are web wallets and 18 of them are desktop wallets. 45 00:03:58,420 --> 00:04:02,020 We think the logo for those projects are really cool. 46 00:04:02,020 --> 00:04:03,960 So we collect them and put it here. 47 00:04:05,800 --> 00:04:07,760 So let's start with the web wallet. 48 00:04:07,760 --> 00:04:11,420 This is a typical interface for a web wallet. 49 00:04:11,420 --> 00:04:15,160 This is our 30-bit wallet for 30 chains. 50 00:04:15,160 --> 00:04:18,600 In this interface, you can check your balance. 51 00:04:18,660 --> 00:04:22,180 It has the UI for sending tokens. 52 00:04:22,320 --> 00:04:24,580 And this is because it's a cost-based chain. 53 00:04:24,580 --> 00:04:27,480 It has the staking feature as well. 54 00:04:27,900 --> 00:04:34,160 So when we talk about web applications security, the thing that comes to my mind is OAuth's top 10. 55 00:04:34,160 --> 00:04:40,020 Here's some statistics on OAuth's top 10 in the 27 wallets we look at. 56 00:04:40,020 --> 00:04:42,940 We find Crystalscripting in three wallets. 57 00:04:42,940 --> 00:04:46,020 We'll do a case study for two of them. 58 00:04:46,020 --> 00:04:49,920 We find one SQL ingestion in a decentralized wallet. 59 00:04:50,220 --> 00:04:55,260 So the database only contains those transaction data. 60 00:04:55,260 --> 00:05:05,740 And because the transaction data in blockchain is already public, and we don't have a way to escalate that SQL ingestion to, say, command code executions. 61 00:05:05,740 --> 00:05:10,520 So that SQL ingestion is kind of just useless in this case. 62 00:05:10,800 --> 00:05:13,940 We found one broken authorization. 63 00:05:14,240 --> 00:05:19,120 An unauthorized user can mess around with other people's 2FA settings. 64 00:05:19,300 --> 00:05:25,520 But we cannot use this vulnerability to compromise a user account. 65 00:05:25,680 --> 00:05:29,360 A lot of web wallets are missing security headers. 66 00:05:29,360 --> 00:05:37,960 For example, CSP, the content security policy, and expert option headers, and make the wallet vulnerable to clear-checking. 67 00:05:38,140 --> 00:05:51,640 We see a few wallets using outdated JavaScript libraries, or outdated Nginx, Apache hosting, but we are not able to directly export them. 68 00:05:53,020 --> 00:06:01,700 So we have not seen any wallets dealing with XML, or find them doing any type of DCR audations. 69 00:06:01,700 --> 00:06:05,700 For the login and monitoring, we just don't know. 70 00:06:06,080 --> 00:06:08,780 So jumping to the first case study. 71 00:06:09,520 --> 00:06:14,800 So this is a DOM SSS in a decentralized web wallet. 72 00:06:14,800 --> 00:06:17,600 The wallet supports single protocols. 73 00:06:17,600 --> 00:06:21,720 It has all the basic functionalities for a wallet. 74 00:06:21,880 --> 00:06:24,260 It doesn't really have any fancy things there. 75 00:06:24,940 --> 00:06:36,500 So the vulnerable feature is the application saves the last location, the user visit, and it redirects the user to that page after the user unlocks his wallet with his password. 76 00:06:36,900 --> 00:06:44,400 In this URL, it will redirect the user to the valid data page after the user unlocks his wallet. 77 00:06:44,400 --> 00:06:47,160 And here's the co-implementations. 78 00:06:47,380 --> 00:07:00,740 The object return to equal to the parsing result of the window.location.search, and the return to variable pass into the window.location.href. 79 00:07:01,000 --> 00:07:11,160 If you have some experience about web app testing and stuff, you might realize this might be vulnerable to DOM SSS. 80 00:07:11,240 --> 00:07:12,720 And that is the case. 81 00:07:12,720 --> 00:07:15,960 So DOM SSS requires source and sync. 82 00:07:15,960 --> 00:07:23,980 So source is the location where untrusted data, the user input, is taken by the application and passed to the sync. 83 00:07:24,580 --> 00:07:32,420 So when user visits this URL, the window.location.search will return question mark, return to equal to slash validators. 84 00:07:32,700 --> 00:07:39,920 And the return to object will later becomes, will contain the streams slash validators. 85 00:07:40,140 --> 00:07:41,600 And here's the sync. 86 00:07:41,600 --> 00:07:48,260 Sync is the place where untrusted data coming from the source is actually getting executed. 87 00:07:48,340 --> 00:07:55,780 So the sync here is the window.location.href, and it's taking the user input inside the return to. 88 00:07:56,160 --> 00:08:01,780 So when it returns to slash validators, it goes to slash validator page. 89 00:08:01,780 --> 00:08:09,920 But if it's JavaScript, JavaScript, colon alert one, it's going to pop alert in the browser. 90 00:08:09,920 --> 00:08:17,860 So we have the DOM SSS here, but how can we export this to causing bigger damage? 91 00:08:18,520 --> 00:08:21,620 So this is a decentralized web wallet. 92 00:08:21,620 --> 00:08:30,760 The key store and the passwords are stored in the local storage after user creating account or import his account. 93 00:08:31,560 --> 00:08:41,080 So if you're not familiar with local storage or JavaScript, so JavaScript is able to read the content inside the local storage. 94 00:08:41,080 --> 00:08:46,780 In this example, there's a key value pair, hello world store in local storage. 95 00:08:46,780 --> 00:08:52,420 JavaScript can just do local storage.get item, hello, and we just get the contents. 96 00:08:53,680 --> 00:09:00,800 So now the attack plan is to steal the key store and password in the local storage with the DOM SSS. 97 00:09:00,800 --> 00:09:03,120 And that's exactly what this payload does. 98 00:09:03,120 --> 00:09:09,660 It reads the content of the key store and password and sends it to my web server. 99 00:09:09,700 --> 00:09:14,960 And in my SS log, I can see the key store contents and the passwords. 100 00:09:15,080 --> 00:09:20,420 And after I have those contents, I basically just own the account. 101 00:09:20,420 --> 00:09:25,500 I can use those information, log into the wallet and transfer all the money out. 102 00:09:26,020 --> 00:09:34,700 So for the fix here, the fix here is after user unlock his wallet, I just always redirect to the portfolio page. 103 00:09:34,700 --> 00:09:41,080 It just doesn't give the chance for attacker to inject any payloads here. 104 00:09:41,440 --> 00:09:46,320 So the second case study is reflect SSS in a host web wallet. 105 00:09:46,320 --> 00:09:48,460 So it has host web wallet. 106 00:09:48,460 --> 00:09:52,040 The server manage all the your private key. 107 00:09:52,220 --> 00:09:59,380 And to log into the applications, you will use your email and the one time passcode you receive in the email. 108 00:09:59,520 --> 00:10:02,000 The wallet supports 16 different coins. 109 00:10:02,000 --> 00:10:06,800 It has all the basic functionalities and one additional feature called Twitter giveaway. 110 00:10:07,920 --> 00:10:09,940 This is the API handling. 111 00:10:09,940 --> 00:10:14,860 So the API format is like the slash API slash endpoint. 112 00:10:14,860 --> 00:10:18,780 And the one to get user transaction is slash API users. 113 00:10:18,780 --> 00:10:30,320 And if you visit the non-existing endpoint, for example, slash API slash test, it will return the error message like this one. 114 00:10:30,320 --> 00:10:35,340 Translate to English, it's failed to resolve the request test. 115 00:10:35,380 --> 00:10:41,420 So what we're seeing here is the content in the URL is reflect bad in the response. 116 00:10:41,940 --> 00:10:54,480 And this is kind of signal that indicating that this if the backend doesn't do any standardizations or encoding, that might have the reflect scripting vulnerabilities. 117 00:10:54,880 --> 00:10:57,920 And that's exactly the case. 118 00:10:57,920 --> 00:11:06,760 So by putting slash SVG unload equal to alert document domains, the application just very happily popped the alert for me. 119 00:11:06,780 --> 00:11:09,900 And as I mentioned, this is a host web wallet. 120 00:11:10,020 --> 00:11:13,060 The private key is owned by the server. 121 00:11:13,200 --> 00:11:19,460 You cannot just directly steal them like the one in the first case study. 122 00:11:19,520 --> 00:11:27,780 So the plan here is to use these vulnerabilities to compromise either take over user's account or take over his sessions. 123 00:11:28,320 --> 00:11:37,640 So by looking around, I found that this session token is stored in the PHP SCSSID cookies. 124 00:11:37,940 --> 00:11:44,580 And what's special here is it does not have the that token does not have the HTTP only flag. 125 00:11:44,580 --> 00:11:54,560 So if you are not a website guy or web developer, HTTP only flag, if that has that flag set, it will stop JavaScript from accessing that cookies. 126 00:11:54,600 --> 00:12:02,100 In other words, you say it is it prevents attacker from stealing the session tokens in the cookies with the cross-site scripting attack. 127 00:12:02,220 --> 00:12:06,240 But in this case, there's no HTTP only. 128 00:12:06,240 --> 00:12:13,820 So I can just craft a payload that read the content with the cookie content and send to my web servers. 129 00:12:14,400 --> 00:12:20,800 So after I get the session tokens, I can use the session token, log in to the victim's account. 130 00:12:22,080 --> 00:12:27,380 So, you know, when you're going to compromise the wallet, the end goal will always try to steal the money. 131 00:12:27,400 --> 00:12:29,280 So I take over the session. 132 00:12:29,280 --> 00:12:31,140 Now it's time to take all the money. 133 00:12:31,140 --> 00:12:38,840 But wait, I can't because for the money transactions actions in that wallet, it requires a 2FA. 134 00:12:39,200 --> 00:12:42,200 So I kept looking around to see what I can do. 135 00:12:42,480 --> 00:12:45,680 I was not able to reset the 2FA. 136 00:12:45,680 --> 00:12:48,280 I was not able to disable the 2FA. 137 00:12:49,340 --> 00:12:50,740 But I found a feature. 138 00:12:50,740 --> 00:12:52,580 There's a feature called giveaway. 139 00:12:52,580 --> 00:13:03,080 How it works is you go into the interface, it asks you what kind of coin you want to give away, and how many of them you want to give away, and how many people you want to give it to. 140 00:13:03,420 --> 00:13:07,920 In this case, here in the screenshot, you can give away up to two bitcoins. 141 00:13:07,920 --> 00:13:09,460 I think that's a lot. 142 00:13:11,200 --> 00:13:17,540 And after you create a giveaway, what people will need to do is they need to follow you, text your friends, retweet. 143 00:13:17,660 --> 00:13:21,660 Once you have done that, you can go to the URL and claim the reward. 144 00:13:21,660 --> 00:13:26,780 And what's special about this feature is this feature doesn't require 2FA. 145 00:13:27,620 --> 00:13:39,740 So I can use the reflect-quota-scripting to steal users session tokens and use these features to create a bunch of giveaways and claim those rewards myself. 146 00:13:39,740 --> 00:13:44,060 And this way, I can just transfer all the money coins out from the bitcoins account. 147 00:13:45,200 --> 00:13:49,720 So on May 28, I reported these issues to the company by email. 148 00:13:49,720 --> 00:13:51,560 They act on these issues. 149 00:13:52,220 --> 00:13:56,380 And it was silenced for almost two months. 150 00:13:56,380 --> 00:14:04,620 And last month, their response to the issue is fixed and reward me $20 worth of coins. 151 00:14:05,080 --> 00:14:10,100 They don't really have a formal bug bounty program, so I'm fine with the $20. 152 00:14:11,240 --> 00:14:16,140 So the fix is the HTML encode output, so no more cross-site scripting. 153 00:14:16,140 --> 00:14:22,500 And they said HTTP only flag for the cookies that contains the session tokens. 154 00:14:22,500 --> 00:14:33,880 In this way, if the application is vulnerable to cross-site scripting later, then the attacker would not be able to directly steal the session tokens. 155 00:14:34,600 --> 00:14:37,620 So that's all about the case study on WebWallet. 156 00:14:37,620 --> 00:14:40,040 Let's go move on to DesktopWallet. 157 00:14:40,040 --> 00:14:49,060 So DesktopWallet is the desktop application as it's a wallet that runs on Windows, macOS, and sometimes Linux. 158 00:14:49,600 --> 00:14:52,740 So what kind of text that people use to build a DesktopWallet? 159 00:14:52,740 --> 00:14:56,460 So we look at 18 DesktopWallets. 160 00:14:56,580 --> 00:15:03,760 So one is Qt, C++, one is .NET, C Sharp, and one Java, and 15 Electrons. 161 00:15:05,000 --> 00:15:17,120 In the DesktopWallet case study, we'll first talk about a server-side RCE in a .NET DesktopWallet, and the second one is a client-side RCE in an Electron wallet. 162 00:15:17,120 --> 00:15:26,800 Now I'm going to mute myself and let my colleague Mingzhi walk you guys through the server-side RCE in the .NET DesktopWallet. 163 00:15:30,670 --> 00:15:31,790 Thanks, Pei. 164 00:15:31,790 --> 00:15:33,170 So hi, everyone. 165 00:15:33,170 --> 00:15:34,310 I'm Mingzhi. 166 00:15:34,310 --> 00:15:39,230 So I'm going to talk about a remote code execution vulnerability found in a DesktopWallet. 167 00:15:39,330 --> 00:15:42,010 So first, I'll give some background about the wallet. 168 00:15:42,030 --> 00:15:44,970 The wallet is a decentralized single protocol wallet. 169 00:15:44,970 --> 00:15:48,310 It is written in C Sharp, and it uses .NET framework. 170 00:15:48,310 --> 00:15:55,570 It contains many common wallet functionalities like account management, making transactions, and deploying and interacting with smart contracts. 171 00:15:55,590 --> 00:16:00,190 What's interesting is that it allows users to upload files to a server. 172 00:16:00,190 --> 00:16:04,410 This is not quite common in a wallet, so we decided to look into this feature more. 173 00:16:04,750 --> 00:16:16,290 As mentioned previously, this application uses .NET, so for .NET application, it is very easy to retrieve the source code by decompiling the executables if code obfuscation is not deployed. 174 00:16:16,510 --> 00:16:22,270 So this is exactly the case of the wallet, so we're able to recover the source code for further analysis. 175 00:16:22,470 --> 00:16:30,130 So after decompiling the executables, we found the source code that implements the file upload, as shown in the snippet. 176 00:16:30,390 --> 00:16:35,870 The wallet sends a HTTP post request to the server, and it returns with the file upload URL. 177 00:16:36,150 --> 00:16:43,130 So we saw file upload.php is the file that handles the file upload on the server side. 178 00:16:43,250 --> 00:16:49,610 So as a pen tester, this is very fascinating, as now we know that the server probably uses PHP as the backend. 179 00:16:49,850 --> 00:16:57,270 So if we could upload a PHP WebGL to the server and open it in a browser, we might get remote code execution on the server. 180 00:16:58,870 --> 00:17:01,110 So that's exactly what we did. 181 00:17:01,110 --> 00:17:08,150 So we are able to successfully upload the file using the wallet and access the file in the browser. 182 00:17:08,310 --> 00:17:13,130 So after clicking on the upload shell, we are able to gain a web shell on the server. 183 00:17:13,150 --> 00:17:20,350 We also discovered that the web server runs under the administrator user, so we are able to execute commands with administrator privilege. 184 00:17:20,590 --> 00:17:27,150 So at this point, we are able to gain full control of the server, and we are able to manipulate files uploaded by other users. 185 00:17:27,490 --> 00:17:34,630 However, as mentioned previously, since it's a decentralized wallet, the server does not store any user private keys. 186 00:17:34,630 --> 00:17:39,890 So you are not you cannot directly compromise user account by exploiting this vulnerability. 187 00:17:41,230 --> 00:17:43,490 So the fix is actually pretty simple. 188 00:17:43,490 --> 00:17:49,690 The developer just removes the file upload functionality in their further application so that they do not have to deal with it. 189 00:17:49,690 --> 00:17:55,770 This is actually a good idea, as the critical wallet is supposed to keep as simple as possible to avoid security issues. 190 00:17:55,950 --> 00:18:00,330 So now I will hand over to Pei Yu to talk about security in Electron Wallet. 191 00:18:04,680 --> 00:18:06,560 Yeah, thanks, Minji. 192 00:18:06,560 --> 00:18:09,140 So right now, let's jump to Electron. 193 00:18:10,700 --> 00:18:13,440 What is Electron and why Electron? 194 00:18:13,440 --> 00:18:22,200 Electron is an open source framework that allows developers to build cross-platform desktop applications with HTML, CSS, and JavaScript. 195 00:18:22,500 --> 00:18:26,740 Electron combines the core and render engine Node.js into a single runtime. 196 00:18:26,740 --> 00:18:35,200 So the benefit of using Electron is developers can reuse web application codes to build desktop applications. 197 00:18:35,200 --> 00:18:37,540 They don't need to have a separate codebase. 198 00:18:37,540 --> 00:18:40,340 They don't need to learn new languages. 199 00:18:40,780 --> 00:18:46,120 And debugging the Electron application is pretty easy with the Chrome dev tools. 200 00:18:46,220 --> 00:18:49,080 And Electron applications run on major OS. 201 00:18:49,100 --> 00:18:59,220 And because it can access to the Node.js modules, it can build a more powerful app compared to the web app in the browsers. 202 00:18:59,900 --> 00:19:01,200 So Electron security. 203 00:19:01,200 --> 00:19:06,560 So for most vulnerabilities that exist in a web app, you can basically find them in the Electron app. 204 00:19:06,580 --> 00:19:24,720 And for Electron's specific security issues, the Electron official security guidance provides very detailed information about what mistakes that people make that will make the application vulnerable and how to not make those mistakes. 205 00:19:24,720 --> 00:19:40,500 And in BlackHat USA 2017, a talk called a study of Electron security talked about advanced technique that you bypass the building Electron security protections to achieve core executions. 206 00:19:40,500 --> 00:19:47,180 But in this talk, we will be simply talking about one configuration called Node integration. 207 00:19:47,560 --> 00:19:56,000 So the definition for Node integration is it refers to the ability of assessing Node.js resources in the applications. 208 00:19:56,000 --> 00:20:08,290 So why Electron application can, although it's using web technology, but can build more powerful app than application running in the browser because it can import so many Node.js modules. 209 00:20:09,110 --> 00:20:13,130 But it does come with a greater security risk. 210 00:20:13,130 --> 00:20:24,510 So aside from the Electron official security doc is disabling Node.js integration help prevent cross-scripting from escalating to a so-called remote core execution RCE attack. 211 00:20:24,510 --> 00:20:26,330 So what does it really mean? 212 00:20:26,970 --> 00:20:31,930 So this is the latest version of the MyCrypto desktop wallet. 213 00:20:31,930 --> 00:20:39,310 In the configuration, it has the Node integration set to false, which has the Node.js disabled. 214 00:20:39,310 --> 00:20:45,150 And if you type require in the dev console, it will just say require is not defined. 215 00:20:45,690 --> 00:20:49,730 This is the early version of the MyCrypto desktop wallet. 216 00:20:49,790 --> 00:20:55,490 It has the Node integration set to choose and Node.js enabled. 217 00:20:55,490 --> 00:21:00,950 In the dev console, if you type require, it will show the require functions. 218 00:21:01,610 --> 00:21:10,090 So by copy pasting some malicious code into the dev consoles, this behavior causes cross-scripting. 219 00:21:10,230 --> 00:21:18,670 And this is what you will see if you open the dev console when you're in the Electron, in the desktop core application. 220 00:21:18,670 --> 00:21:27,650 It says if someone told you to copy paste something here, you have 11 out of 10 chance being scanned and you shouldn't do that. 221 00:21:27,770 --> 00:21:43,650 So normally in a web application, if victim exported by the self-SSS, attacker can probably compromise his account or do some damage to his account within the application. 222 00:21:43,770 --> 00:21:50,850 However, for Electron wallet, it might get from self-SSS to calculator. 223 00:21:50,850 --> 00:21:57,350 So to open a dev console in Electron application on macOS, it's option plus command plus I. 224 00:21:57,350 --> 00:22:04,630 And if you copy paste the following code into the console, you can see calculators. 225 00:22:05,250 --> 00:22:16,670 So if you're not familiar what calculator means, it's the way to show the successful of co-executions. 226 00:22:16,670 --> 00:22:23,250 So you see, I paste that into the console and the calculator pop up. 227 00:22:24,610 --> 00:22:44,010 So what if the victim... so if you want to use way to export a victim, the victim, you will probably will construct some really long weird things and ask the victim to paste into dev console and the victim be like, hey, I'm not going to paste this weird thing into my dev console. 228 00:22:44,010 --> 00:22:45,510 So how about this one? 229 00:22:45,750 --> 00:22:48,470 I'll paste this, it will allow you to claim one BTC. 230 00:22:48,710 --> 00:22:57,250 Just paste window location to href equal to HTTPS BTC giveaway dot sign. 231 00:22:57,650 --> 00:22:59,830 So by the way, that domain is available. 232 00:22:59,830 --> 00:23:03,190 It only cost $0.99 on GoDaddy. 233 00:23:04,770 --> 00:23:14,050 Yeah, so the victim is like, oh sure, this short command, I'm just going to paste into console, what will happen? 234 00:23:14,110 --> 00:23:22,390 So what happens, you're going to see the calculators again, because what the line is doing is it will redirect you to another page. 235 00:23:22,390 --> 00:23:31,090 And if that page has the malicious code, it will just go to SQL in your desktop wallet in the electronic locations. 236 00:23:31,870 --> 00:23:36,170 So here's a statistic on electron wallet we look at. 237 00:23:36,170 --> 00:23:42,030 So we look at 15 electron wallet that's in active development. 238 00:23:42,310 --> 00:23:46,130 So 11 out of 15 has Node.js enabled. 239 00:23:46,130 --> 00:23:57,350 This can either cause by they, in the configuration file, they set the node integration to choose or they use the electron version less than 5.0. 240 00:23:57,350 --> 00:24:05,550 So the electron framework later than 5.0, it has Node.js disabled by default for security reasons. 241 00:24:05,610 --> 00:24:12,110 And 5 out of 15 has Node.js enabled and have the dev console enabled. 242 00:24:12,110 --> 00:24:18,450 So it might just escalate self cross-site scripting to client-side co-execution. 243 00:24:18,450 --> 00:24:29,010 So this is one example that the attacker can trigger the co-execution directly without using self cross-site scripting. 244 00:24:29,150 --> 00:24:35,810 And that brings us to our last case study on client-side RCE on a simple desktop wallet. 245 00:24:35,810 --> 00:24:40,790 So the simple desktop wallet is an open source decentralized single-coin wallet. 246 00:24:40,790 --> 00:24:43,370 It's the application from where it's built. 247 00:24:43,370 --> 00:24:44,290 It's electron. 248 00:24:44,290 --> 00:24:51,990 It has all the functionalities, basic wallet functionality, and as an addition, future code view news. 249 00:24:52,130 --> 00:24:54,450 They have bug bounty programs on HackerOne. 250 00:24:54,450 --> 00:24:58,390 That's how I discovered them and start hacking the wallet. 251 00:24:59,430 --> 00:25:03,550 So since it's open source, I start with the code view. 252 00:25:03,970 --> 00:25:09,650 This is their, the build.js is their electron configuration file. 253 00:25:09,890 --> 00:25:13,730 What the here does is the process the platform is storing. 254 00:25:13,730 --> 00:25:17,470 It starts the application with the create Mac functions. 255 00:25:17,490 --> 00:25:22,250 Otherwise, it creates the start application with the create Windows functions. 256 00:25:23,170 --> 00:25:29,430 So, and in the create Windows functions, I see that node integration is set to choose. 257 00:25:29,430 --> 00:25:36,030 That means if the application is running on Windows, the node.js is enabled. 258 00:25:36,730 --> 00:25:39,650 So how can we export this? 259 00:25:39,650 --> 00:25:43,250 So my goal will be to inject arbitrary JavaScript. 260 00:25:43,610 --> 00:25:45,350 Self-cursor scripting? 261 00:25:45,350 --> 00:25:49,670 No, bug bounty program does not pay for self-cursor scripting. 262 00:25:49,670 --> 00:25:51,410 How about legitimate cursor scripting? 263 00:25:51,410 --> 00:25:54,410 No, I was not able to find one. 264 00:25:54,410 --> 00:25:59,470 But how about node untrusted remote content into the application? 265 00:25:59,690 --> 00:26:01,810 So, all right, let's do some news. 266 00:26:01,810 --> 00:26:06,570 So in the simple desktop wallet, it provides the view news features. 267 00:26:06,610 --> 00:26:18,850 And when you click that link into in the news, it actually read the redirect out the wallet and go to another website. 268 00:26:18,850 --> 00:26:24,150 In this case, it just opened up GitHub on inside the desktop wallet. 269 00:26:25,110 --> 00:26:32,210 So the exportation plan is I will host the webpage with malicious JavaScript. 270 00:26:32,270 --> 00:26:35,850 I will place the URL then point to my malicious page on GitHub. 271 00:26:35,850 --> 00:26:37,990 It can be a GitHub issues on the repo. 272 00:26:37,990 --> 00:26:41,930 I can create a repo and put it in the README. 273 00:26:41,950 --> 00:26:50,190 Or I can put it on my GitHub profile and then visit that URL in the desktop applications. 274 00:26:51,270 --> 00:26:54,750 This is a very easy, simple proof-of-concept code. 275 00:26:54,750 --> 00:26:56,870 What it does is there's a button. 276 00:26:56,870 --> 00:27:01,730 And when the button is clicked, it triggers the RCE count functions. 277 00:27:01,730 --> 00:27:04,850 What a function does, it just pops the calculators. 278 00:27:05,590 --> 00:27:07,770 And here's a proof-of-concept video. 279 00:27:09,570 --> 00:27:12,730 So I opened up the desktop wallet. 280 00:27:15,390 --> 00:27:17,930 I unlock wallet with my password. 281 00:27:23,350 --> 00:27:27,230 And I go ahead and verify the version. 282 00:27:27,230 --> 00:27:28,670 It's a very early version. 283 00:27:28,670 --> 00:27:31,590 This is the version back in April, I think. 284 00:27:33,330 --> 00:27:36,610 And I click the link in the news. 285 00:27:36,930 --> 00:27:38,810 I'm now on GitHub. 286 00:27:38,810 --> 00:27:46,230 And in this case, you ask the victim to go to certain GitHub page with a phishing attack. 287 00:27:46,230 --> 00:27:51,050 But for the demonstration, I just go to my personal GitHub account. 288 00:27:51,050 --> 00:27:54,490 And I have the URL hosted on my profile. 289 00:27:55,070 --> 00:27:56,490 And I click that. 290 00:27:56,490 --> 00:27:59,430 I go to the page that contains my POC. 291 00:27:59,490 --> 00:28:01,470 And I click the close. 292 00:28:01,570 --> 00:28:03,470 Calculator just pop up. 293 00:28:03,750 --> 00:28:08,690 So in this example, the POC script requires user to click a button. 294 00:28:08,690 --> 00:28:15,570 But in reality, attacker can just execute those malicious code automatically. 295 00:28:15,570 --> 00:28:27,810 And of course, attacker can use JavaScript to steal the key stores, steal the passwords, or it can, you know, use have like creating a reversal and control the victim's computers. 296 00:28:29,330 --> 00:28:31,870 So timeline must submit these reports on HackerOne. 297 00:28:31,870 --> 00:28:35,530 They triage and give me 2,500 bounties. 298 00:28:35,530 --> 00:28:39,010 And they fix in the next release. 299 00:28:39,010 --> 00:28:41,210 The simple team and the name team are really nice. 300 00:28:41,210 --> 00:28:45,570 I really appreciate they allow me to talk about this being public. 301 00:28:45,830 --> 00:28:55,690 So and the fix was they set the no integration to false in the build.js file and update the build news feature. 302 00:28:55,710 --> 00:29:05,870 So right now, if you click the link in the news, it will open up in the external browser instead of inside the desktop wallet. 303 00:29:05,870 --> 00:29:11,690 So again, I want to thank the team and they really value the security they use. 304 00:29:12,070 --> 00:29:13,870 Yeah, really fixed. 305 00:29:14,310 --> 00:29:22,520 So the takeaway here is attacker can compromise the victim's wallet or even the computer. 306 00:29:23,800 --> 00:29:24,440 And 307 00:29:36,280 --> 00:29:46,680 have you had a security audit before you allow users to have an internal security team? 308 00:29:46,680 --> 00:29:51,020 Definitely ask the security team for a security review. 309 00:29:51,020 --> 00:29:56,800 And if you don't have the internal security team, you have to hire a security professional for a security review. 310 00:29:58,920 --> 00:30:09,500 If you have any questions, comments, you can post it on the text channel or email us after you're welcome to follow us on our Twitter. 311 00:30:09,500 --> 00:30:12,480 This slide will be posted on my Twitter account. 312 00:30:13,780 --> 00:30:18,500 And you can, if you're interested, you can check out our company blog post. 313 00:30:18,500 --> 00:30:27,890 There's a lot of interesting blog posts that we talk about some hacks that happened recently or some technical articles. 314 00:30:28,370 --> 00:30:29,290 Thanks. 315 00:30:34,520 --> 00:30:37,640 Yeah, if you have any questions, just drop in the channel.