 Hi everyone, welcome to our talk. How are you addressing deserialization in order to send your money on the blockchain? I'm Rony, and my co-speaker, Wu Zheke, will be present at Part 2. We are from Tencent Security Shenwu Lab. Our research fields include Android, Web, IoT, browser, blockchain, etc. and our Shenwu Lab outputs many outstanding achievements that are such as Bat-Tanel. Here is the outline of our talk. First of all, I will introduce FastJSON briefly. FastJSON is a widely used open-source JSON parser with 23,000 stars on the tab, it's known for fast-passing speed. There are 3,600 artifacts using FastJSON on the mill, and as a basic module of centralized Java web service, it serves hundreds of millions of users. In this part, I will detail the deserialization process and the security check in FastJSON, and the vulnerability to bypass the check. First of all, there is a demo for JSON serializer and serializer using FastJSON. At the left side is a Java bin-named user with a string field named name and the gator and center phone name. On the right, use the object and send the name to phone. Using method json.to-json-stream with flag-serializer a feature.redclassname to serialize the user object to json-stream and you can see the output json. The key add tab has a value user, this is the class name of the object and the following is the field name. And then, use method setAutoTypeSpot to enable the AutoType feature. Then, using json.pass method to deserialize the json-stream to use the object with the name phone. Take note of this line of code. Passer config setAutoTypeSpot. AutoType is a very important feature of FastJSON digitalization. It's a flag about whether FastJSON can deserialize any non-presupposed classes automatically without other configuration. It falls in default. If you don't enable AutoType, method json.pass will throw a json exception about AutoType is not supported when you pass the json with the add type user class. Next, I will detail the deserialized process inside the FastJSON. When the scanner catches the token key add type, the deserialized process will be started. First, the tagged class name will be checked by the method check AutoType. If the check is passed, method getDeserializer will return the deserialization constructor. The deserializer will be selected by the tagged type and finally, use the method current instance of the object deserializer to get the object from json fields. Next, I will detail next let's focus on the defense method check AutoType and how to bypass it to deserialize attribute classes. The method check AutoType has three parameters. Parameter type name is the tagged class you want to deserialize and you can specify it explicitly in the json. For example, add type user. The parameter expect class is the super class or interface of the tagged class and it can be none. And the last parameter feature is the deserialized flag. It's always default. Before we start detailing the check process inside check AutoType, we need to know how to input a parameter of type class as the second parameter expect class. As we said, the expect class means inheritance. There are two forms of inheritance in the first json. The first one is a split inheritance. You can start a json object string with two except keys. The first except value is the expect class and the second one following is the subclass which inherit from the expect class and the fields following are the properties of the subclass. Another form is implicit inheritance. There is a demo. Class user has a field ID with interface 4 and the class for input implements the interface 4. So you can set the ID to a json object with type 4 import that will trigger the implicit inheritance. The interface 4 is expect class and the full import is the subclass. Okay, go back to the check AutoType. This section I will detail the control flow of the method check AutoType and show you how to bypass it. The first line is the function prototype. First, if the tagged class is in the weather list or in the deserializer cache or has a function json annotation json type it will pass the check. The tagged class will be returned and saved to the deserializer cache next. If not, if the tagged class is in the blacklist or inherit from Java SQL rule set data source or class loader the method will throw error and exit. If not, if the incoming parameter expect class is not known and is not those types object, serializable, cloneable, closeable, event listener, collection and the tagged class is a sendable from expect class it will pass the check return add cache. If not, finally it can't pass the check unless the global flag AutoType spot is true but it always falls in the default configuration. To intuitively observe the case it passed the AutoType check and listed them as follows. First, enable the AutoType spot flag it's a rare situation. Next, classes with annotation json type those classes are not universal we can't use them anywhere. Next, classes in the weather list weather list is initialized as a final static hash code list with about 60 classes which are merely related to Java abstract window toolkit and spring framework those classes in weather list are at high level which are not easy to be extended so the first three cases are not our first choice for bypass. Next, the classes in the deserializer cache the last one, the second parameter of check AutoType, expect class and the subclasses of it especially note that the expect class is a parameter with type class instead of type string that means the expect class has already passed the AutoType check it's converted from string type name to a text class so the source of the expect class are the classes in the weather list and deserializer cache so we focus on the deserializer cache the cache is named type UTS mappings it's initialized in the method type UTS and base class mappings for preloading the deserializer of basic types otherwise, it's a part of the source code you can see the class byte in tabularly class object and it is cloneable cloneable are added to the cache mappings although there are many low-level class and interface in the cache those types have their own specified deserializer for example expect exception and class error will be handled by throwable deserializer class hash map and hash table will be handled by map deserializer but except the two types java utl-bit site and java run auto-closebo fastjson will create a default java bin deserializer for them so any classes extended bit site or auto-closebo can pass the auto-type check and create an instant family so we can inherit from those classes to bypass the auto-type check the auto-closebo is a very low-level interface since jtk7 is the super interface of the most of stream classes channel classes and connection classes, etc the picture at the bottom is the sub-interface and implementing classes listed in the jtk document those classes provide us with broad search space to derive our gated chain so finally we bypass the auto-type check by java run auto-closebo this is a poke for the bug adjacent stream with two other type keys the first one is the expect class auto-closebo and the second one is the target class java iorider because reader inherit from auto-closebo so it will pass the check in the previous section I detailed how to bypass the security check by auto-closebo in the next section I will detail how to find some interesting gadgets to achieve remote code execute and more now we need to find out which classes we can derive and what we can do by those classes the second question can be described as which methods can be called during desalization we call those methods magic methods the method creates java bin desalizer is the main process of desalization and inside it the main method of creating desalizer is java bin info build the parameter is the target class and type first in this method we will select the constructor by the two methods get default constructor and get creator constructor the order of choosing constructor is as following after constructor adjacent will iterate and call other setter method of the target class and next there are some getter method we will be called automatically during desalization depends on the written type now we can answer the first question about derivation except directly inherit from the interface auto-closebo there are four cases that classes will be added to the cache during desalization at first the class itself second the types of the selected constructor parameters next the types of the parameters of the setter methods including the types of public fields and the last a part of return types of getters there is a very flexible feature named json path in the fact json you can use it as an object query language and what's even more amazing is that you can use it in the desalization by the token key dollar reference following is a demo json the key username has a value with key reference which is dollar dot use object dot name the dollar means the root element is the entire json object itself the use object is the first key and the name is the field name in the use object it will call the getter method getname to get the value from the use object so json path will not only allows us to call arbitrary getters but also allows us to cross reference and access their properties on multiple generated instance when constructing objects during json passing this feature greatly explains our magic method space there are some conditions for getters classes first it must can be derived from auto-cluzable second it must have default constructor or contract service symbols otherwise it can't be initialized correctly and third it must not in the blacklist in addition to those necessary conditions we also have some quality requirements for getters the getters should call the RCE, arbitrary, file, read and write or other high risk effects and the dependence of getters should be in native JDK or in the whether they use the third party libraries there are almost hundreds of third party packages whether they use the java double E and we need to search getters in nearly a million classes it's impossible to pure manual search so I write a tool based on the reflection to search the derivation of classes space I rewrite the photogenicization process to check the derivation conditions and create a graph about derivation relations between classes it's helpful when you reverse the chunk from the sync class and in addition the tool can getters class in the JDK and the specified set of javas and I crawl common third party libraries from mailman and input that is a view shows how it generates almost 5,000 classes from the interface autoclosable at the beginning the yellow node is the interface autoclosable and the green node is class JDK natural URL reader the arrow and line mean derivation relation and you can see the URL reader inherit from autoclosable and then start searching there are many colors of nodes different colors represent different types the green node is class the blue node is interface the pink node is abstract class the purple node is member class object here are some Harris gadgets we found in the third party packages by the tool such as using messager connector to RCE using Apache commons I.O. to read and write files use jt to SSI etc I will detail the gadget's comments I.O. read and write files in the next section about exploiting the blockchain nodes there are some fast json payloads to use messager connectors to RCE due to the difference between versions and the limitation of blacklist you need to use different gadgets for different messager versions now we can control many important websites and affect millions of users by the fast json vulnerability let's make things more interesting we found that this fast json vulnerability is a blockchain with multi-million dollar market value and I will detail the RCE on the silver nodes of blockchain Toron in the next Toron is a public blockchain with a native pro corrupt currency nodes as TRX the market value of TRX is 5 billion dollars and it has 14 million holders besides 1,400 of the apps are on the Toron network with a daily transaction volume of over 12 million dollars and the Java Toron is the Java implementation of the public blockchain protocol launched by Toron it underlies all the decentralized application in the Toron ecosystem it's an open source Java application with 2,000 stars on github Java Toron can enable HTTP service on the Toron node to allow users and developers to interact with the blockchain we will detail the Java Toron in the next section in this section we just need to know it's an HTTP service using fast json to pass json ported data now we have a vulnerability can RCE or read and write any file on the on some conditions but those conditions are not always met first of all, there is no remote dvc driver in the Java Toron so we can use the gadgets of mass-circle connector and there are some problems we need to be solved for exploited by read and write file gadgets the Java Toron is an independent independent blockchain so we can write a web shell directly we should think about what to write and the json can run with arbitrary user with network permissions so we should think about what are where are writeable paths and the json was using fast json to decode a post in the HTTP API request however, there is no direct response by HTTP the HTTP response just only shows the states of the API request so if we read files from server node how to get contents returned furthermore, the blockchain is decentralized that means you take over mall nodes you get more control of the blockchain so our exploit should really on as few preconditions as possible there are some common ways to get shell on the spring bootfast json server when you can write files for example, you can or write system leaves or write class file in the jvm plus path such as traffic jam but as I said above root formation is not required those files can only be or write them by root and or writing the system or jvm leave is dangerous without the exact versions that is a feature of jni in the jav package the binary library files need to be released to the file system before it can be loaded this operation is usually in the static block triggered when the class is loaded for the first time the binary library is always released to the directory specified by the system property java.io temp directory and the java method system load will load the jisso file by function dr open so or reading the jisso file will be the best choice java torrent use the leveldb as local story driver for blockchain data leveldb is the fastest key value story library and is used by bitcoin therefore it is inherited by many public chain leveldb sees the blockchain metadata which needs to be used frequently for reading and writing so java torrent use the jni driver as I said java.io needs to extract jni library leveldb jni extracts the so library in the library extract and load it extracts the jisso file with a random suffix to the temp directory so if we want to alright the jisso at runtime we need to get the random file name extracted by the java the most directory is to list the temp directory but we don't want those information to be casted on the pvp network and the last problem is that we need to write binary bytes instead of string with encoding there are two things that can cause encoding confusion the input json is read as a string with encoding instead of bytes and the autostream and file writer should use bytes we finally solved those problems by the gadgets apache.com.io this gadget chan can be combined with other classes to not overly write but also read file. Let's start with red file gadget is more clear. Look at the left side the class.com.io input boom input stream inherits from auto close ball so it can pass the auto type check it has three parameters in the constructor input stream delegate boolean include and a variable parameters of class byte order mark booms there is a getter method for field boom in the boom input stream get boom will call the delegate read we can set the field delegate to the class.com.io input t input stream the method read of t input stream will write the input bytes to the field branch the field branch can be set to an auto stream in the constructor so, using the class.com.io boom input stream we can choose proper input and auto stream classes to achieve read file for writing encoding stream we can find out those gadgets just in comm.io package package set the source input stream field input to char sequence input stream set the field cis to the input stream you want to write to file and set the auto stream field branch to writer auto stream with class file writer with encoding add for writing binary bytes besides Apache comm.io we need to use two other packages in the java toron set the field input of t input stream to Apache comms codec binary string and output its bytes and set the field branch of boom input stream to eclipse internal local cis file auto stream with which is from aspect.jai next, this is how to use Apache comms.io read files the entry of gadgets is also the class boom input stream and it's geter method get boom it calls method matches in the get boom the method matches will iterate the field and compare every boom with the with the bytes read from the input stream delegate if there is one boom in the same and the bytes read from delegate it will return the same boom otherwise it will return none so that will let us get read content according to the different written states it's a way of boundary there is a payload for reading the time directory to get the read them file name first look at the number one at the red side we use the class jdkin natural ui reader as the input stream the parameter url supports file schedule file scheme the parameter url supports file file folder and the listing directory the number three the field booms is set to multiple bytes blocks to be compared with reader output and the number four use the json path reference dollar abc.boom to call the geter method get boom of the object abc which is the first field in the json with the class boom input stream and the number five let this reference value be the field address and send this json ported data to the java.tron.http api wallet validate address and if the address is long it will receive nothing if the address is bad format it will return validate field message so we can use apache.com's iot to read the time directory byte by byte and finally get the random file name of jnlibrary now we can write the jnlibrary at runtime the last question is how to hijack pointer the java.tron will register a timer task for level dbwrite on initialization the method dbwrite will call the jnm method native buffer jnmalloc so we can inject shellcode set address of jnmalloc when the timer task is execute.pun this is the form process of exploit and the last step is requiring the program context to prevent the crash for the sixth step post-patteration for real money turn to my co-speaker Wu Zekai next I will introduce a creation exploit method that affects the security of blockchain user size after we successfully RCE on tron's HTTP node we need to test whether it will cause losses to the user's size for the blockchain the first approach we think of is a 51% tag a 51% tag is a tag on blockchain by a group of miners who control more than 50% of the networks mining has reached attackers with majority control of network can interrupt the recording of the new blocks by preventing other miners from completing blocks and tron use the super representative Magnifico any account can apply to be a super representative candidate every account can vote for super representative candidate top 27 candidates with the most votes are the super representative super representative generate blocks, package transactions and get the block and voting reverse therefore we need to RCE at least one half of the super representative nodes to cause a 51% tag but the actual rotation is somewhat unexpected not all nodes have HTTP service enabled in other words we can't attack all nodes of Tron this picture shows the location and IP of all the nodes of the Tron network this data is provided by the TronScan.org website as shown by TronScan.org Tron has 1332 nodes in total we scanned this IP and found that only a quarter of nodes can be accessed through the HTTP service therefore there is no guarantee that more than half of the super representatives have enabled HTTP service unfortunately we can use this vulnerability to cause a 51% attack on the Tron network we need to find another way now let's focus on the Tron HTTP node itself let's study what the role of the HTTP node plays in the Tron network the Tron HTTP node has a variety of API cards to allow users to interact with the blockchain some of the API cards serve as one of the more requests to get in wide-rooted pieces of information the most important thing is that there are also many API cards which modify the transaction resulting in a need to sign and broadcast the transaction we mainly focus on the second type of API these APIs will be used when users trade on the blockchain when the user want to send some PRX token to other users in the Tron network three steps are required first of all the user need to make a transaction and can call the all-it transaction API to compare this type the HTTP node will return a role transaction in Jensen's light the second type is to sign the transaction the user can call the all-it transaction sign API the HTTP node will use the private key provided by the user to sign the role transaction the last step is to broadcast the transaction the user can call the all-it transaction API the HTTP node will broadcast the signed transaction to the blockchain therefore after we RCE HTTP node if the user use the HTTP node to make a transaction we can return a role transaction which will be executed after the user signs and broadcast it if the user use the HTTP node to sign the transaction it seems that we can only prevent transactions from being broadcast to cause DOS obviously stealing private keys is more harmful than forged transactions and forged transactions are more harmful than DOS in the Tron network almost all users use wallet programs for transactions Tron link is firstly launched as Tron's official website and backed by Tron Foundation it is Tron wallet with the most users Tron link has three versions including Chrome wallet extension LS Android among them Chrome wallet extension alone has more than 300,000 users after testing three versions of Tron link wallet we found that all three wallets use HTTP nodes to broadcast the transactions in addition Chrome wallet extension also use HTTP nodes to make transactions and directly sign and broadcast the transaction without checking the returned role transaction so we can try to attack the wallet by returning for the transaction when the wallet send the request to make a transaction to the HTTP node we control we return for the transaction then the wallet sends the transaction locally and finally broadcast the signed transaction to the blockchain we recorded a video to demonstrate this attack method first the victim treats normally and I left 100 TRS token after that the attacker executed the exploit program and successfully RCE the HTTP node and run the malicious program on the node the victim makes the transaction again and the attacker returned before to the role transaction finally the attacker receives the TRS token instead of ball the attack is not over yet let's think about it micro wallet extension has different behavior from iOS and the Joy after analyzing the first code of micro wallet extension we found that it uses the TronWeb library TronWeb is to deliver a unified, similar development experience influenced by Ethereum's Web3 implementation TronWeb uses the TronWeb. Tron's transaction builder. Tron uses the TRS method to make transactions which will request HTTP nodes as you can see in the source code when calling this method the wallet transaction API of HTTP node will be requested to make a transaction we realized that the TronWeb library would be a key point so we investigated some unrelated applications and made some new discoveries we found that in addition to TronLink current wallet extension from multi-currency wallet and the DAX also uses the TronWeb library and they also didn't check the role transaction returned by the HTTP node multi-currency wallet is a wallet that stores multiple crypto currency transactions M-Token is a multi-currency wallet that stores Tron M-Token has 12 million users and they use the TronWeb library After testing we found that when M-Token wallet generates Tron-related transactions it does request the HTTP node as you can see in the picture we successfully forwarded the returned transaction replacing to address with another address and then signed and broadcast the forwarded transaction DAX is a computer application that runs on a distributed computing system as of December 17, 2020 when 1,400 DAX have been created on the Tron network with a daily transaction volume over 12 million dollars for developer DAX is a combination of front-end and smart contracts TronWeb for front-end developer take a Polynex DAX as an example when Tron has token ascended in this DAX it will request the HTTP nodes to make a transaction we also successfully forwarded the returned transaction with another address and then signed and broadcast the forwarded transaction in summary the Tron linker wallet extension with more than 300,000 users the Tron part of the M-Token multi-currency wallet with 12 million users and DAX with a daily transaction volume of over 12 million will all be affected finally we make a conclusion although distributed and decentralized structure improves the credibility and fault tolerance of the system blockchain is not a bullet proof of security and we hope our work can notify blockchain developers and users to more careful about security our research on the future blockchain security will include traditional web security cloud and edge computing and both the patricians exploit here is a vulnerability timeline special thanks to Zhou Junyu, Liu Guiming and Yu Yang thanks