 So this talk is by Parsi and Stark and they're going to be talking about enterprise blockchains. So let's give them a big DEF CON welcome! All right. Is this good? Can everyone hear me? Okay. Thank you. If I start speaking too quickly, please let me know. Throw something at me because I do that and have an accent so it's hard to understand me. So here we are at DEF CON. We are super excited. It's my first time at DEF CON. First time speaking at any conference. I mean, it's super big. Everyone's hacking each other. There are so many SQL injection payloads going around. Even Elon Musk dropped by to break up the unions. I'm so funny. So we have a great talk planned out for you. And you say, okay, what does this enterprise blockchain thing has anything to do with the theme of DEF CON, which is surveillance? So everyone is collecting data about you. And these data will end up on the enterprise blockchain sooner or later. So we might as well, you know, look at these things and see what these are. So we have a great talk planned out for you. The first part, I'm going to talk theory. I know theory is boring, but you will learn buzzwords. After you go back home, you go to your LinkedIn profile, add those buzzwords to it, talk to your boss and ask for a raise. I mean, it works. I mean, my boss is there. The second part, my co-presenter will show you our tool. We have created a tool to attack enterprise blockchain platforms and you will see things like defeating the blockchain to commit insurance fraud and also route shells to smart contracts. Take that, Ethereum. So we all work at Synopsys, software integrity group. There's four of us. I'm Parcia. I do application security. I am a very rabid Golang fan. I love smart contracts and my superpower is, they told me not to do this, but my superpower is getting selected at the airport every single time. You can see why. Any time spent with me is not harassing you, so you're welcome. And my co-presenter is this Schmuck who doesn't even like go. Hey, guys. My name is Stark. I work with this Schmuck. Anyway, I came to Black Hat last year for like the sixth time, but I finally got to hear about blockchains and smart contracts and I got interested because it sounded really easy to break. And it turns out that it is. Our customers have been talking to us about enterprise blockchain, which is apparently different, and I wanted to kind of move the conversation in that direction. So here we are. Great. Thank you, Stark. So Travis and Kun are there. There are team members and they're all amazing. I mean, they speak like 10 different languages between themselves. It's amazing. Okay. So we have our team together. The first thing we did, we started looking at the whole platform. So we have public blockchains and then we have private blockchains or enterprise one. Public blockchains are, you know, cryptocurrencies. There are a lot of ICOs. All of them are scams. So they go get banned from the cryptocurrency village. We should be careful not to say crypto as in cryptography because Matt Green will come and pummel you to death. And the enterprise part has been working very quietly. We have all been pointing and laughing at the latest John McAfee scam, right? Bitfire wallet, whatever it is. In the enterprise part, there are three major camps. It's been vulcanized. Now I always wanted to say vulcanized. There's hyper ledger. There is enterprise ethereum alliance and there is R3. Now a lot of companies are invested into this. I mean tech companies are already there. But they also change their JavaScript frameworks every three weeks. So that's not surprising. But there are other companies, there are healthcare companies and there are financial companies and financial companies are really hard to convince to do something new. That means the senior leadership of these companies has seen something in these platforms. So they're investing a lot of time and money into this. And as I said before, you would get flagged at the airport if the immigration officer didn't like you. What's going to happen in two years is some palantir smart contract is going to flag you before you even land. And you get a free physical. Amazing, right? And this healthcare is shit. So the blockchain world is like this election candidate. It says promises made and then promises kept, right? It says I'm immutable. Which means I'm non-hackable. Everything that gets on the ledgers or the blockchain stays there and you cannot change it. So hackers cannot do anything. It says I'm immutable. Which means you think, you know, what has been put on the blockchain by whom and when? You have tunable trust. I will give you authorization controls and authentication controls. You can give access to different groups of people. And finally, I will give you programmability to smart contracts. So we can codify the rules of the world into smart contracts which get there on the blockchain and cannot be modified. It will be an even playing field. What happens in the promises kept part is, of course, very familiar. None of them are kept. The ledger is immutable. Okay, we already knew that. But that means that if fraud happens, then you're SFIL. Sorry for your loss. Your Bitcoin wallet gets hacked. Sorry for your loss. But your bank cannot say the same to you, right? Your account is empty. You go to the bank. The other cannot laugh at you and say LOL. You're going to sue them. Another problem is they are not always mutable. There are bugs. And these bugs will make things different. You write something to the chain and you're like, okay, that's it. What happens in practice is there's some vulnerability out there and then something goes to return to the chain and then you are SFIL. Privacy is important. Before you put anything on the ledger, you should think really hard. Because when it goes there, it's there forever. It's like the Internet. You can't go back and delete your old tweets because someone archived it. And then GDPR comes along and you have to change things. So if you commit user names and password or credit cards or encryption keys to the chain, then don't do that. You're SFIL. These platforms, unfortunately, as it is, don't have enough throughput for real-world applications. So what they do is they sacrifice correctness for speed. Instead of running your smart contract on all notes and comparing the results, you run it on one note and call it a day. If that goes rogue, then SFIL. The execution environment is also important. I'm sorry, I laugh a lot at my own jokes. I'm the funniest person I know. The execution environment is also important. Smart contracts are, by default, remote code execution as a service. You're running someone else's code on your machine and you don't know what it is most of the time or you don't know what it ends up doing. So you need to be understanding. You need to secure these things. And then finally, these platforms are super complex. So every blockchain system is a distributed network. No joint leave. You need to make up for all of this. So promises kept. One. Great. So in order to progress more into these scene, we chose one platform. So we chose hyper leisure fabric. It's part of the hyper leisure ecosystem, which is owned by the Linux Foundation, with the exception that Linus is not yelling at you. It's great. It's written in Golang, which is great. Everyone should write and go. And it counts for roughly 50% of the deployments out there. It's our observation. If you've heard about this new mobile voting thing, application, it's based on hyper leisure fabric. So whether you like it or not, your votes are going to end up there. I know it's not important because we don't care about voting, but we should. So after that, we choose this guinea pig. And guinea pig is important because we learn by breaking things. Unless it's OSCP, in which case you, you know, pay someone. The application we have created is called the build blockchain insurance app. And that's the name. If you Google for it, you can find it. It's your typical insurance application. It looks pretty slick and works most of the time. There's a web application in front. As a customer, you go in, buy something, and then if something happens to it, which always will, you will say I want to claim and submit a claim. It will go in and look at your claim. And then if possible, they will pass it to the cops because they want to get out of it anyway. That's what insurance does. And then, finally, everything goes to the repair shop. The repair shop repairs it or doesn't and then gets paid. And that's what happens. So everything after this purple box is fabric. So looking at this application, we had some questions. So the first question is like, how do we hack this thing? In front is web application. And in this day and age, it's not a solved problem, but we know how to tackle this web application testing. I mean, everyone does it, right? You just pass it to Burp, I guess. Sorry. But everything after that is opaque blob, which is hyper-leisure fabric. So we created this tool that gives us insight into what's inside. We can do things. We will show you things. You can do shells. You're okay. And then the second question was like, okay, we have this insurance application. How do we hack it? And they say follow the money. So the only person who gets paid is the repair shop. So we want to commit insurance fraud. And that's what we're going to talk to you later. And so we have our platform. We have our guinea pig first. And then we need to learn about the platform. And I'm sorry I'm boring you out, but the buzzwords are important. So smart contracts in fabric are amazing. I love them. Because they're named chain code. And you can also write them in Golang. Gol is great. You can also write them in Node.js or Java, if you're an enterprise customer. And it interacts with the ledger in a very simple manner. There's an interface called shim. And the ledger is a key value store. You just call get state, pass a key, get the value. And then you update it. It works. And the main difference between these smart contracts and Ethereum smart contracts is that these are actual programs. So instead of just interacting with the ledger through EVM bytecode, you can do other things. Like call HTTP APIs. Spawn processes. Do encryption. Do decryption and all that things. So it gives you great power. But with great power also we need to inhibit this power. And it checks and balances things that is supposedly there. So you have what is called channels. And each channel has its own ledger. And on each channel we can have multiple chain code, one or more. Each chain code is only local to that channel. You can have copies of the same chain code and different channels. But they don't talk to each other. And each chain code has its own internal database which reflects the values of the ledger. And then what you do is you run something. You update your values and everything goes into some couch DB. And then everything gets updated. It gets minted as a new block on the chain and everything comes back and updates your. You cannot mess with other people's state DBs which is great. Now with that said, I'm out of buzzwords. So what I'm going to do is I want to pass the mantle to my friend who doesn't like go. Okay, so a little bit more theory. And then we'll hack something. So to really understand the security model of hyperledger fabric, we need to discuss how things change on the network, right? So we have immutability guarantees, but we can program it to change over time. So the first step of one of these changes is we have a peer that's going to submit a proposal, right? So a proposal just says invoke this chain code function, take some inputs, do something with it. It's going to send it to one or more endorsing peers. So the network who have the chain code itself, so step two, they're going to actually execute the chain code, right? So they're going to do something with a Golang code that's going to generate some output. That output is called an endorsement. So an endorsement is a group of all the key values that they read from and written to. It's called the read write set. It's going to sign it with its private key and then it's going to submit it back to the peer. So that's what we do. And for it's that along to a special peer called the orderer. So everything up until this point is really arbitrary, right? So we could have sent garbage data in and the endorsing peers could have sent garbage data back to us. The orderer's job is to enforce some rules about this data. So at a high level, it performs three types of validation. So the first type of validation is ensuring that all of the endorsements and write sets match each other so that the peers don't disagree on what's actually happening. The second step is to ensure that we meet some endorsement policy. So a policy can be set up to have maybe three out of five peers on the network agree to a transition. Right? And then the third type of validation is to ensure that we don't have conflicts with previous transactions. So the orderer does all this logic by itself and at the end of the day, if it validates it, it creates a new block. It mints that block, puts its private key on it, says this is now a valid set of transactions and broadcasts it to all the other peers on the network. At this point, we consider the global state of the network to have changed. Every peer will now know the new values of every key in the dataset and we've completely updated everybody. So that's cool. We want to get there and we want to bypass some of that logic by using constraints. So there are a few suspects in just this diagram. A few things that we can latch on to and talk about from a security perspective. First, on the far right, we have the endorsers. So we consider the endorsement policy to be a style of optional Byzantine fault tolerance. So for those of you who didn't get a master's degree, I think is the only place I learned about this in school was we have to do this. They're going to disagree with each other, they're going to lie, they're going to cheat. We need to figure out a way to equalize the playing field. Figure out who's lying, who's cheating and just ignore them. But if we have this style of endorsement policy where we can choose what level of validation we do, then we've dropped our guarantee down to an optional level. So we lose that guarantee from every transaction. And in fact, by default in hyperledger fabric, the endorsement policy is just one peer. So if you don't set one up, anyone can say anything and the order will trust it. It's not great. So on the left with the order, that's in orange, the order is ending up as a single point of failure for the whole system. So every transaction is going to go through this order. Now there might be multiple set of, it's a single organization within the network, so it's a single set of peers who are now party to every transaction on every channel. So that is completely nonfall tolerant by this definition. And in the middle we have the client. So the client's got an interesting property where it can transmit requests to be endorsed by endorsing peers without sending them for ordering. So it can cash and hold on to these things later or choose not to submit them at all. And if our chain code has side effects, which it can since it's just arbitrary Golang code, it can do anything, then this may have some very interesting properties in a real life system. So as we're writing code or as we're auditing a system we have to keep those side effects in mind for the effects of a peer that's not really performing what we expect on the network. So at this point we're completely done with theory and I get to introduce our tool. So when we first got started with fabric of getting started with it, we set up dev environments, we built threat models, we built some quick scripts to hack it and kind of figure out what it's doing behind the scenes. And we decided to package all of this up and release it as open source code. So it's called Tynola. And it's built by Red Teamers for Red Teamers. So if you're doing a penetration test or if you're doing a source code review in a live environment, this tool is going to let you see what's going on and try to interface with it more efficiently. There's a link at the end of the slides so you guys have to stick around. But we have our white paper up on there as well that talks about everything we're doing here if you want to share it with your friends. Okay, so we're done with theory completely. Let's talk about our demos or our attacks. So from now on my name is Tom. I work for the repair shop work. And we just signed up for this blockchain thing and I don't think it's as secure as all of the media headlines say and I want to do insurance fraud. And I have access to my own peer because I'm a member of this network because working for the repair shop. So I want to see what my peer can do and maybe I can get some ideas on how to perform some fraud. My initial idea was, okay, what if somebody bought an item got some insurance contract and then they submitted it for repair but it's not actually broken, right? And then I get the contract to repair it and then I repair it, right? And then they pay me to repair it. And then we just get cash. It's a great idea. So let's see how we could do this. So you may be asking about the slides. So we sent this deck to our marketing department and asked them to spice it up and they came back with those stock images that you see in the blog posts where the hacker and the black gloves is like picking locks and stuff. And we weren't a fan. So we sent it back and they gave us this deck because they're like people on the internet so you're welcome. Okay. Let's do a video demo because I didn't pray to the demo guy sufficiently. Okay. So to get started, we're just going to watch Carol. Carol's going to be our scapegoat because she's going to buy an item and we're going to do some fraud on that item. So she's buying a bike here. This is the insurance app that we're hacking, right? It's got a web front end. She's currently on the shop here and you can see she's filling out her information and at the end of this, she's going to get a contract. And like I said, my plan is to just fraudulently submit a repair claim on the contract. It should be pretty simple, right? But let's find out how we're supposed to do that. So we click through and we buy this very expensive bike and then, boom, we get a password in plain text so we can tell this is following all the best practices. This is example code, guys. People copy and paste this stuff. Anyway, so this is Tynola. It's a JavaScript application that runs on the command line. And so it has some commands. So first I'm going to connect up to my certificate authority server and authenticate. I'm going to use the default administrative credential which is admin-admin-pw. Again, it's in all of the examples. It's great. So I log in. I'm in. But I want to know what's going on in here. So the first thing I do is I ask the certificate authority, what are all the users on this box? And it goes, well, you've got the admin client, but that's it, right? So I'm the only person here and it's got some attributes that tell me what I can do on the system. It's pretty nifty. And then next up I might ask, okay, so let's connect to my peer, right? So I'm connecting out to the repair shop endpoint. I'm connected. I might say, give me some metadata about this peer. So what channels are I connected to? We've only got one channel. It's the default channel, so I connect up to that. I might say, okay, give me some metadata about the channel. So I ask for channel info. And it gives me some hash values. But what's important here is the height, right? So that tells me how many blocks exist on this channel. So that's great. So I know there's 11 blocks. I'm just going to ask for the last five, right? So I do channel history five. I see the last five blocks that hit this channel. So right there in block 10, that's Carol, right? And there's her password right there in plain text. So that's pretty nifty. So I've got the password. I'll discuss this in a moment. But we're just going to take that password back to the web interface. Throw it in. Yeah, this is, okay, this is me. Here I am. I'm going to go over to the claim self-service, throw in the password, and file that claim. So why was that data there? Well, it turns out that the blockchain needs a bunch of data to do its thing, right? Business logic is complicated, it needs inputs. And so although storing maybe plain text passwords on the blockchain is not great, chain code often needs private data to operate. It's just we need to do business here, right? But if we think about it, that particular value, this password, it's going to go on repeat, isn't it? That particular value wasn't needed by anybody except for Carol and the insurance company. So that's a perfect case for like what, a relational database, right? We store hash passwords in MySQL all the time. Maybe we should be doing that. So we see storage of private data on blockchain as a major security risk and not using in conjunction with relational databases is just an architectural anti-pattern. Okay, so we've got through what we can see on the network. Now that we can see it, let's play it with it, right? What can we do with it? Well, it turns out that, it turns out that I've made a mistake and that if I go to my repair shop here I don't have any repair orders. So what happened? And it occurs to me that the insurance company needs to approve this repair order. And I don't work for the insurance company. I don't have logins there. So let's see if we can just bypass the web app completely and just invoke stuff on the chain itself. So I'm going to connect back to that default channel just like I did before. I'm going to connect to an orderer this time. So now I have the capability of making changes to the network. And I'm going to just do a channel history command again because I don't know how to interact with this chain code yet. I'm going to think about it for a while. There we go. So here we are. And these are all the last blocks. So up in block 7 is a claim process command. So it turns out this is the command that this chain code uses to approve a repair request. And it takes some UUIDs and down in block 11 was the most recent claim file command which was my fraudulent claim. So I could just like transmit the UUIDs into that previous function call, right? So I'm going to use Tainola's channel query CC command. I'll tell it to do a claim process function call. I'm going to say I'm going to use one argument and I'm just going to paste in this JSON blob. I've already replaced the UUIDs here. I'm going to hit enter. So this first one is a dry run. I just want to make sure this actually works. So I'm not going to order it. I'm just going to tell the endorsing here go make sure this works. So I get a blank response. Turns out this chain code doesn't actually do anything like return code, it just returns blank. But I didn't get an error which means I'm running out of disk space. No. So anyway, I'm going to do it again with a dash dash invoke since it didn't error the first time. And this tells Tainola go order it. So again, no error. I think I might have changed the state of the blockchain. So I'm going to refresh the page and we have modified the blockchain folks. Okay. Cool. So this actually looked like, right? Like we can go ask Tainola to show us what the chain history looks like. So again, I'm just going to use the channel history command so we can see what this what happened. So in block 13, we see excuse me, block 12 was our fraudulent claim process that was me submitting. This is a function call that's only ever done by the insurance peer. But we can see in column three, the creator column, it's the repair shop organization who invoked that function call. So the lesson learned, right? Enterprise blockchain, these fabric and quorum and these other platforms, they refer to themselves as permissioned blockchains to differentiate themselves from open blockchains like bitcoin or ethereum where anybody can join. I don't like using that term because I feel like it's a big misnomer and it gives the wrong impression to chain code developers. The thing is you have to make it permissioned. Just access to the network is being blocked. So what does that mean? It means that since we're building a network, ideally of mutually competing parties, that's the value of blockchain, bringing together people who don't trust each other to share things and data and code. Since we don't trust everybody else, I can make this go away, can't I? So we don't trust these other people. We have to put authorization controls into our chain code. We have to do it explicitly. Okay. This code doesn't do it explicitly, right? So all the samples, none of them do authorization. It's great. There we go. So we're going to take a bit of a detour and we're going to talk what we can do with just this invocation stuff, right? So the blockchain doesn't operate by itself. It's not in a vacuum. Blockchains almost always have some sort of front-end component. May that be front-end API or SOAP API or web interface, like in this example, it doesn't matter. There's some front-end that's processing the data from the chain. So we asked ourselves, can we attack that front-end from the chain? Can we use the chain to attack that other front-end application? It turns out, yeah, definitely. So we had an idea, so we built Tynola with an HTTP proxy in it. And so whenever you post to Tynola, Tynola will turn that into a chain code command for you. So on the right I'm using burp, just regular application scanner. And I'm just going to demonstrate that I can invoke this function call directly. Now before I show that, I'm going to hop back over to my slide so we can see what's about to happen. So here, this is from the fabric samples repository. It's an official repository that shows how to write chain code. And we have a trivial JSON injection vulnerability due to string concatenation. This is really disappointing because the only way to go is that you can make JSON in the language. It supports it. So whatever. It's fine. But let's see, somebody's going to read this data, right? There's a reason we're formatting it as JSON because there's going to be a server that takes this error message and puts it someplace, right? And we can see even the JSON response data for a regular response is the same way. It just happens to be secure because the data they're pulling out is always a number, but don't worry about that. We'll focus on this one first. So let's see what this looks like. So first, I need to tell Burp to use localhost. That's where my port is open. Don't worry, it doesn't open a port on your machine to the internet. It's localhost. We'll tell it chain code example 02. That's the name of the chain code that we're tacking. We're using the query command. So on the right, we get ACP 200 okay. It does exist. We get the chain code output as a result. So we can use ACP to interact with the chain code. It's pretty helpful. Let's try an account that doesn't exist. Account 1234 does not exist. We get the server message and we see it's concatenating the name right in there. So we can try playing with it by hand first just to demonstrate for the video that it does concatenate. So I'm just going to break out of the string with an escaped double quote. I'm just going to add a second key. Just to show that it works. Put in a spiffy emoji there. We hit go. Okay, so we see that works. So we get ACP 500 because it's throwing an error, but the error message itself has a JSON injection. But we can use any of the features of Burp through Tynola. So we could use intruder or scanner. So I'm just going to demonstrate scanner. On the left in a moment, you're just going to see it scroll by as the scanner tries all these insane permutations of fuzzing. So the nice thing is I didn't want to write my own fuzzer because fuzzing is hard. So whatever fuzzing routines you guys are already using, whatever fuzzing routines you're already using, we'll work with Tynola. As long as it speaks HTTP, you can use Tynola. Again, this is not targeting chain code. We're targeting whatever is ingesting the data from the chain, because there will be upstream applications that take this data and do something with it. So we might find cross-site scripting vulnerabilities in a web app that displays data that's getting pulled from the chain. Why does this matter? Well, unlike databases, which you hold the keys to and there's a password on and only you can access it, the whole point of the chain code is to share the data, right? So you're sharing it with partners and that's the data coming in from the chain itself. So we've got to escape or validate or sanitize or whatever you're going to do with the data you're bringing out of fabric. Okay. So back to the insurance app. So I have a... I'm pretty comfortable with invoking stuff on the chain code. We figure out authorization doesn't exist. I can attack this chain code all day now. I have a cloud hosting blockchain as a service type deployment and it's really hard for me to interact with the other peers because I just have a single endpoint that I can hit that hits my peer. But I can't see the other peers. I can't see their internal network. There might be network services hiding in there. So I want to pivot through my peer, right? So how does this work? So chain code is running as a container, so I should be able to write some arbitrary code that runs in my container that gives me a shell or something, right? So Tynola ships with Tynola CC, our proprietary chain code that's open source. Anyway, so Tynola CC has pivoting options for it. So let's see what that looks like. Here we are. So on the right, I'm going to start just a Netcat listener on 31337. And on the left, I'm going to use the Tynola shell command, give it a name, and do who am I, and boom, root. There we go, easy. But we're in a container, right? What can we do in the container? This is a Ubuntu container, so I can use apt to install things. This is nice. If it doesn't have internet access, you can drop things using the Tynola HTTP dropper that works. But either way, we're going to get nmap on here, and I want to use that to scan the network, because I think it's going to work. And I'm going to give it the standard ports that Fabric uses. So there's two GRPC ports that the peer uses, an HTTPS port that's for the orderer and CouchDB. So this bottom one here is the orderer, it's got one port open. It's just a single GRPC port. And then we have four other peers who are listening on GRPC, HTTPS, and CouchDB. So about this, right? So there's not a whole lot you can figure out. Fabric was built to run arbitrary code. It's just what it does. So if your front model includes peers being compromised, which it always should, because people get compromised all the time, you have to account for this, right? You have to be aware that the network is not partitioned completely. And that a peer will always be able to communicate on whatever private networks it's located on. So even if you have a blockchain as a service platform, this is still possible. So for those of you who are familiar with CouchDB, this attack may be obvious. But CouchDB doesn't use authentication by default. And yesterday I was trolling through the most up-to-date fabric documentation and they're using CouchDB section doesn't even use the word password in it. This is very disappointing. They do have it in their configuration section, like CouchDB configuration, how to like customize it and everything, they're just like copy and pasting code off GitHub, come on. So what does this look like? What can we do with modifying CouchDB? Let's take a look. So I'm going to pick a value in the web app that cannot be changed. So this is theft insured column and I've picked this not included thing. And it turns out there's simply no chain code that ever modifies this value. Once this value has been set, it's set up. It's part of a JSON document but there's no way to change it using chain code. I'm going to use the Tynola SSH proxy command on the left. This does a reverse SSH proxy back to my machine and opens up a port that points to, in this case, the insurance app's CouchDB port. And CouchDB comes with a beautiful web interface and if there's no password on it it just drops you to a read write shell. So that's pretty sweet. I'm just loading some JSON and then I go to the slash underscore utils directory and we have this beautiful web interface. This is all the channels, all the chain code that's installed in the machine. We can see everything. I'm going to maximize it because it's kind of hard to read this. Make it big. Come on. There we go. And there's the contract type. So this is the value that we want to modify. There's theft insured. That's fine. So at this point the insurance peer, I'm not a member of the insurance company, I can't normally talk to this peer, has modified itself to say theft insured is present. So we've modified this peer's vision of the network. We've not transacted anything, there's no evidence of this on the chain. Just this one peer thinks that this value is true. To demonstrate this we can hop over to the shop peer, runs its own stack and its own CouchDB instance and its version of the network will be slightly different because we haven't attacked this one yet. I'm going to just show you here. Here it is. It's the same contract, the theft insured box has not checked yet. So we have conflict between multiple peers. So I've got an idea. So I could attack the shop peer as well in the same way, but maybe they were clever. Maybe they've got passwords there. So we're using the default endorsement policy. Just one peer needs to be compromised to affect the rest of the network. So I'm just going to disable and re-enable this contract. So that's all I'm doing here. I disabled it, now I'm going to hit enable again. I'm going to refresh this page and it turns out it read the JSON, modified the enabled flag and then wrote it back with the tainted value. So it's still there. But this time I'm going to go over to the shop peer, I'm going to go up and look, it's checked. So we've propagated a value that chain code says can never be changed by messing with couch TV due to a poor endorsement policy. So we'll go over to Tainola to see what happened and this is not even the right video. So we'll go over to Tainola and say, hey Tainola, what happened? Show me the channel history of what just happened. And these are the only two blocks that were written. It's a contract type set active and it's set in active false and active true. That's it. No trace of this theft insured flag changing, but we can really dig into it. So I mentioned read wide set, so let's take a look at what those look like. So here's the read right set. So in green we see this contract type that we modified was read from the JSON documents there. So that's how JSON documents work in a key value store. You can't modify a sub value in couch TV, you have to write back the whole thing. And we can see, I'm going to highlight it a second, that the theft insured flag is tainted. So we've got an endorsed right set with our tainted data written back to the chain. Now all the peers trust it and that's how we break it. Sweet. Okay. So we've got fabric. It's a brand new platform. No one knows how it works from a security perspective, but I think at least about 100 million dollars from what I understand has been pumped into this thing, either the development of the platform itself or development of apps on top of it. It's huge. It's coming. Your data will be on the blockchain very soon. We need to know about these problems because the developers are a lot of them. They're architectural or they're just a lot of it is chain code needs to be better, right? And so until we get the platforms to be better, we need to write our chain code better. We need to make awareness of these problems bigger. There are so many cryptocurrency talks now, I can't keep track of them all, but I haven't hurt anyone bringing this up. So we need to be talking about this more and I'm just going to start with this. Everything you've seen is open source. Please go get it. We've got it on GitHub. It's fresh. I committed it 20 minutes before I came out here. We've got a white paper on there. It explains everything we wanted to say here, but we didn't have time. So I think we have a little bit of time. I lost track of my goon. So if there are any questions, I'm more than happy to take them now if we have time or I'll be around.