 Yeah, cool. So, hello, everyone, welcome to our talk and thank you for the introduction edge. And in this talk, we'll be talking about how we explore in secure cryptocurrency wallet applications. So my name is Pei Yu-Wen. Here's what we might call the main jihad. We're a security engineer at CERD-K. So CERD-K is a blockchain security company. We provide a variety of security services such as smart contract audit, train audit and penetration testing. I personally responsible for internal security review for our own product as well as the external pen test, focus on wallet, export, exchange, and the app. So outside of client work, we also do security research on different applications in the blockchain space. And that's how we come up with this talk. We also do bug bounty hunting over the weekend when we have time. This is the first time we speak at DevCon Blockchain Village. Thank you so much for having us here. So what is crypto wallet? I'm sure most people here know what crypto wallet is, but in case someone don't. So crypto wallet is a device, a program, or a service that stores the private key and the public key. So crypto currency is virtual. Like a wallet cannot physically hold a coin. 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 blockchain. There are different form of crypto wallets as software wallets and hardware wallets. In this talk, we'll be focused on web wallet and desktop wallets. We believe there's a two core functionality for crypto wallet. One is account management, allows user to create account, import account, and the other one is make transactions. It sends the received coins. And for wallet for certain protocols, it will have additional features such as for Cosmos base wallet. They will provide the stacking features, allow user to delegate coins to validators, and claim rewards. And looking at different wallets, we also find some, I don't know how to call it, maybe called fancy features. For example, you can view newsletters in a desktop wallet. You can add certain third party plugins in a desktop wallet. You can create a coin giveaway on Twitter in a web wallet. And there's a one desktop wallet. The backend server allows user to upload any type of files to the backend server with the API. And then there's a desktop wallet. Use the web view to implement a browser in it, which is mind blowing. I don't know why people will want to use their desktop wallet to be as a browser. So we look at 45 different wallets and we kind of put them into two categories. One is host wallet. Host wallet is that the server manage your private keys. If you want to use the wallet, you need to authenticate, log into the application, authenticate with the server. And the server return you like a session tokens or JWT tokens. Either those secret were either being stored in cookies or local session storage. And so most of what I would look at are decentralized wallet, which means the user manage the private key, the store, the key store, and the passwords. And those after user created account or imported account, those things will be stored in local or session storage or in the JavaScript variables. So in the 45 wallets, 27 of them are web wallets and 18 of them are desktop wallets. We think the logo for those projects are really cool. So we collect them and put it here. So let's start with the web wallet. This is a typical interface for a web wallet. This is our deep wallet for dirty trains. In the interface, you can check your balance. It has the UI for sending tokens. And this is because it's a Cosmo base train. It has the staking feature as well. So when we talk about web applications, security, then come to my mind's OS top 10. Here's some statistic on OS top 10 in the 27 wallets we look at. We find process scripting in three wallets. We will do a case study for two of them. We find one SQL ingestion in a decentralized wallet. So the database only contains those transaction data. And because the transaction data in blockchain is already public, and we don't have way to escalate that SQL ingestion to say command code executions. So that SQL ingestion is kind of just useless in this case. We find one broken authorizations. An unauthorized user can mess around with other people's 2FA settings. But we cannot use this vulnerability to cover my user account. A lot of web wallets missing security headers, for example, CSP, the content security policy, and expert option headers, and make the wallet vulnerable to click jacking. We see a few wallets using outdated JavaScript libraries or outdated nginx Apache hosting, but we are not able to directly export them. So we have not seen any wallets dealing with XML or find them doing any type of DCR auditions. For the login and monitoring, we just don't know. So jump into the first case study. So this is DOM as it says in a decentralized web wallet. The wallet supports single protocols. It has all the basic functionalities for a wallet. It doesn't really have any fancy things there. So the vulnerable feature is the application saved the last locations of the user visit and redirect the user to that page after user unlock his wallet with his password. In this URL, it will redirect to the user to the valid data page after user unlock his wallet. And here's the coin implementations. The object returned to equal to the parsing result of the window.location.search. And the return to variable passed into the window.location.etra. If you have some experience about web app testing and stuff, you might realize this might be my vulnerable to DOM as it says. And that is the case. So DOM as it says requires source and sync. So source is the location where untrusted data, the user input, is taken by the application and passed to the sync. So when user visits this URL, the window.location.search will return question mark return to equal to slash validators. And the return to object will later contain the streams slash validators. And here's the sync. Sync is the place where untrusted data coming from the source is actually getting executed. So the sync here is the window.location.etra. And it's taking the user input inside the return to. So when it's returned to slash validators, it goes to slash validator page. But if it is a JavaScript column alert one, it's going to pop alert in the browser. So we have the DOM as it says here. But how can we export this to causing bigger damage? So this is a decentralized web wallet. The key store and the password are stored in the local storage using creating account or import his account. So if you're not familiar with local storage or JavaScript, so JavaScript is able to read the content inside the local storage. In this example, there's a key value pair, hello world, storing local storage. JavaScript can just do local storage.getItem, hello, and we just get the contents. So now the attack plan is to steal the key store and password in the local storage with the DOM as it says. And that's exactly what this payload does. It read the content of the key store and then password and send it to my web server. And in my SS log, I can see the key store contents and the passwords. And after I have those contents, I basically just own the account. I can use those information, log into the wallet and transfer all the money out. So for the fix here, the fix here is after user log unlock his wallet. It just always read directly to the portfolio page. It just doesn't give the chance for attacker to inject any payloads here. So the second case study is a reflect SSS in a host web wallet. So it has host web wallet. The server manage all the, your private key and to log into the applications, you will use your email and the one-time passcode you receive in the email. The wallet supports 16 different coins. It has all the basic functionalities and the one additional feature called Twitter giveaway. This is the API handling. So the API format is like the slash API slash endpoints and the one to get user transaction is slash API users slash Cloud Champs. And if you visit the non-existing endpoints, for example, slash API slash test, it will return the error message like this one. Translate to English, it's failed to resolve the request test. So what we're seeing here is the content in the URL is reflect bad in the response. 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 cross-scripting vulnerabilities. And that's exactly the case. So by putting slash SVG on load equal to alert document domains, the application just very happily popped the alert for me. And as mentioned, this is a host web wallet. The private key is owned by the server. You cannot just directly steal them like the one in the first case study. So the thing, the plan here is to use these vulnerabilities to compromise, either take over users account or take over his sessions. So by looking around, I found that this session token is stored in the PHP SCSSID cookies. And what's special here is it does not have the, that token does not have the HTTP only flag. 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. In other way to say it is it prevents attacker from stealing the session tokens in the cookies with the cross-scripting attack. But in this case, there's no HTTP only. So I can just grab the payload that read the content with the cookie content and send to my web servers. So after I get the session tokens, I can use the session token logging to the victims account. So when you're going to compromise the wallet, the end goal will always try to steal the money. So I take over the session. Now it's time to take all the money. But wait, I count because for the money transactions in that wallet, it requires a true FA. So I keep looking around to see what I can do. I was not able to reset the 2FA. I was not able to disable the 2FA. But I found a feature. There's a feature called giveaway. How to work is you're going to that interface. You ask you how many, 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. In this case, you're in a screenshot. You can give away up to 2B coin. I think that's a lot. And after you create a giveaway, what people will need to do is they need to follow you, text to your friends, retweet. Once you are done that, you can go to the URL and claim the rewards. And what's special about this feature is this feature doesn't require 2FA. So I can use the reflected course I'm scripting to still use the session tokens and use these features to create a bunch of giveaway and claim those rewards myself. And this way I can just transfer other money coins out from the victim's account. So on May 28, I reported these issues to the company by email. They act on these issues. And it won't silence for like almost two months. And last month, they response the issue is fixed and they reward me $20 worth of coins. They don't really have a full mobile grounded program. So I'm fine with the $20. So the fix is the HTML encode output. So no more cross-scripting. And they said HTTP only flag for the session tokens, for the cookies that contains the session tokens. In this way, if the application is vulnerable to cross-scripting, later that attacker would not able to directly steal the session tokens. So that's all about the case study on Web Wallet. Let's go move on to Desktop Wallet. So Desktop Wallet is the desktop applications as is the wallet that runs on Windows, Mac OS, and sometimes Linux. So what kind of text that people use to build a Desktop Wallet? So we look at 18 Desktop Wallets. So one is QT, C++, one is .NET C-Sharp, and one Java, and 15 Electrons. In the Desktop Wallet case study, we'll first talk about server-side RCE in the .NET Desktop Wallet, and the second one is client-side RCE in the Electron Wallet. Now I'm going to mute myself and let my colleague Mingzhi while you guys through the server-side RCE in the .NET Desktop Wallet. Thanks, Pei. So hi, everyone. I'm Mingzhi. So I'm going to talk about our remote code execution vulnerability found in a Desktop Wallet. So first I'll give some background about the wallet. The wallet is a decentralized single protocol wallet. It is written in C-Sharp, and it uses .NET framework. It contains many common water-found naturalities like account management, making transactions, and deploying and interacting with smart contracts. What's interesting is that it allows users to upload files to the server. This is not quite common in a wallet, so we decided to look into this feature more. As mentioned previously, this application is .NET. So for a .NET application, it is very easy to retrieve the source code by decompiling the executables if code of use execution is not deployed. So this is exactly the case of the wallet. So we're able to recover the source code for further analysis. So after decompiling the executables, we found a source code that implements the file upload as shown in the following code snippet. The wallet sends an HTTP post request to the server and returns with the file upload URL. So this upload.png is the file that handles the file upload on the server side. So as a contestor, this is very fascinating. As now we know that the server probably uses PHP at the backend. So if we could upload a PHP WebGL to the server and open it in a browser, we may get a remote code execution on the server. So that's exactly what we did. So we are able to successfully upload the file using the wallet and access the file in the browser. So after clicking on the uploaded shell, we are able to gain a web shell on the server. We also discovered that the web server runs under the administrator user. So we are able to execute commands with administrator privilege. So at this point, we are able to gain full control of the server and we are able to manually file uploaded by other user. However, as mentioned previously, since it's a decentralized wallet, the server does not store any user private keys. So you cannot directly compromise the user account by exploiting this vulnerability. So the fix is actually pretty simple. The developer just removes the file upload functionality in their further application so that they do not have to deal with it. This is actually a good idea as the critical wallet is supposed to keep as simple as possible to avoid security issues. So now I have a handover to pay you to talk about security in Electron wallet. Yeah, thanks Minji. So right now let's jump to Electrons. What is Electron and why Electrons? Electron is an open source framework that allows developers to build cross-platform desktop applications with actual amounts, CSS and JavaScript. Electron combines the current render engine and node address into a single runtime. So the benefit of using Electron is developer can reuse web application codes to build desktop applications. They don't need to have a separate code base. They don't need to learn new languages. And debugging the Electron application is pretty easy with the Chrome DevTools and Electron application run on major OS. And because it can access to the node address modules, it can build a more powerful app compared to the web app in the browsers. So Electron security. So for most vulnerabilities that exist in a web app, you can basically find them in the Electron app. 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. And in Black Hat USA 2017, a talk called a study of Electron security talked about advanced technique that to bypass the building Electron security protections to achieve co-executions. But in this talk, we will be simply talk about one configuration called node integration. So the definition for node integration is it refers to the ability of assessing node JS resources in the applications. 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. But it does come with greater security risk. So site from the Electron official security doc is disabling node JS integration help prevent cross-executing from be escalating to a so-called remote co-execution RCE attack. So what does it really mean? So this is the latest version of the MyCrypto desktop wallet. In the configuration, it has the node integration set to false, which has the node of JS disabled. And if you type require in the dev console, it will just say require is not defined. This is the early version of the MyCrypto desktop wallet. It has the node integration set to choose and node JS enabled. In the dev console, if you type require, it will show the require functions. So by copy-pasting some malicious code into the dev consoles, this behavior cross-executing. And this is what you will see if you open the dev console when you're in the Electron, in the dev Discord application. It says, if someone tells you to copy-paste something here, you have another chance being scanned and you shouldn't do that. So normally in web applications, if victim explored by the self-assessed attacker can probably compromise his account or do some damage to his account within the application. However, for Electron wallet, it might get from self-assessed to calculated. So to open a dev console in Electron application on macOS is option plus command plus i. And if you copy-paste the following code into the console, you can see a calculated. So if you don't know what calculated means, it's a way to show the successful of co-executions. So you see, I paste that into the console and I'll calculate the pop-up. So what is the victim? So if you want to use a way to explore a victim, the victim will probably construct some really long, weird things and ask the victim to paste into the dev console and the victim will be like, hey, I'm not going to paste this weird thing into my dev console. So how about this one? Paste this, it will allow you to claim one BDC. Just paste window location natural equal to hdbs bdc-giveaway.sign. So by the way, that domain is available. It only costs 0.99 dollars on GoDaddy. Yeah, so the victim is like, oh, sure, it's short commands. I'm just going to paste into the console what will happen. So what will happen, you're going to see the calculator again, because what that line is doing is it redirects you to another page and if that page has the malicious code, it will just go to execute in your desktop wallet in the electrical applications. So here's a statistic on the electrical wallet we look at. So we look at 15 electrical wallets. That's the active development. So 11 out of 15 has Node.js enabled. This can either caused by in the configuration file they set the node integration to choose or they use the electric version less than 5.0. So the electric firmware later than 5.0 has Node.js disabled by default for security reasons and 5 out of 15 has Node.js enabled and have the dev console enabled. So it might just masculine self-corsus scripting to client-side co-execution. So this is one example that the attacker can trigger the co-execution directly without using self-corsus scripting to our last case study on client-side RCE on the same-bow desktop wallet. So the same-bow desktop wallet is open-source decentralized single-coin wallet. It's the application firmware is built. It's electronic. It has all the functionalities basic wallet functionality and that's the addition of future compute news. They have background programs on Hacker 1. That's how I discovered them and start hacking the wallet. So since it's open-source, I start with the code view. This is their the build.js is their electron configuration file. What the kid does is the process.platform is started is start application with the CrayMAC functions. Otherwise, they create start application with the CrayWindows functions. So and in the CrayWindows functions I see that Node integration is set to choose. That means if the application is running on Windows, then Node.js is enabled. So how can we export this? So my goal will be to do JavaScript. Self-created scripting? No, but the program does not pay for self-created scripting. How about legitimate scripting? No, I was not able to find one. But how about node on trusted remote content into the application? So let's view some news. So in the simple desktop wallet it provides the build news features. And when you click that link in the news, it actually redirects out the wallet and go to another website. In this case it just opens up GitHub on inside the desktop wallet. So the exportation plan is I would host the webpage with malicious JavaScript. I will place the URL that points to my malicious page on GitHub. It can be a GitHub issues on the repo. I can create a repo and put it in the review or I can put it on my GitHub profile. And then visit that URL in the desktop applications. This is a very easy simple proof-of-concept code. What it does is there's a button. And when the button is clicked, it triggers the rc-cout function. What that function does is just pop the calculators. And here's a proof-of-concept video. So I open up the desktop wallet. I unlock wallet with my password and I go ahead and verify the version. It's a very early version. This is the version back in April, I think. And I click the link in the news. I'm now on GitHub. And in this case, you might ask a bit of time to go to a certain GitHub page which is a feature attack. For the demonstration, I just go to my personal GitHub account and I have the URL hosted on my profile. And I click that. I go to the page that contains my P.O.C. and I click the close calculator just pop up. So in this example, the P.O.C. script requires you to click a button. But in reality, attacker can just execute those relations co-automatically. And of course, attacker can use JavaScript to steal the key stores, steal the passwords, or it can use, like, creating a reversal and control of the victim's computers. So TimeLine submit these reports on HackerOne. They give it $2,500 and they fix in the next release. The simple team and the name team are really nice. I really appreciate they allow me to talk about this being public. So and the fix was they set the node integration to false in the build.js file and update the user's feature. 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. So again, I want to thank the team and they really value the security they use. Yeah, they fixed it. So the takeaway here is attacker can compromise the victim's wallet or even the computer if you have any questions, just drop in the channel.