start	end	text
1500	5240	Hi, everyone. My name is Feng Xiao from Georgia Tech.
5240	10300	It seems like I'm the first DEF CON safe mode main talk,
10300	14800	and I really hope everyone can enjoy attending my work.
14920	17940	So this is, of course, not only my work,
17940	22880	but also the work of my wonderful co-authors from Georgia Tech and Texas A&M.
22880	26000	Today, I'm going to talk about some interesting new vulnerabilities
26000	28480	in the Node.js ecosystems.
29360	31820	Before the talk normally begins,
32000	34840	please let me introduce myself a little more.
34920	38280	I am a CS PhD student at Georgia Tech.
38280	41180	My research goal is about building automatic systems
41180	44200	to detect and exploit vulnerabilities.
44300	46540	We want the tools to exploit vulnerabilities
46540	50600	because we want the people to know the existence
50600	53940	and the consequence of their security bugs.
54120	58040	And I do research in the web and application security.
58040	61780	But I'm also researching security problems in other areas,
61780	66340	such as the software defining networks and x86 virtualizations.
67100	70540	Okay, so this is the topic I'm going to cover today.
70540	73820	The talk will be divided into three parts.
74280	77620	First, I will introduce the technical details of the new vulnerabilities
77620	80480	and discuss their exploitation.
80840	84740	Then, I will talk more about the bug-finding parts,
84740	87360	which is about the lessons and the insights
87360	94660	from building one kind of a tool to detect and exploit HPA.
94960	100320	And in the last part, I will give an impact analysis of the new risk
100320	103800	and some evaluation data about the tools.
105300	107700	So first of all, let's take a quick look
107700	111140	at the vulnerabilities we found during our research.
111920	116380	So in total, we discovered 13 zero-day vulnerabilities
116380	118680	from widely used programs,
118680	122640	such as MongoDB official drivers, class validators.
122900	126900	And these bugs can be exploited to launch serious attacks,
126900	130660	such as leaking credential data, bypassing security checks,
130660	132640	and denial of services.
133120	137460	So before we touch the technical details of these vulnerabilities,
138180	143280	let's have a brief background introduction about Node.js.
144260	148480	Node.js is for executing JavaScript code outside of browsers.
148900	153140	The picture on the right is the overall system diagram of Node.js.
153260	156460	To interrupt and execute JavaScript,
156800	160360	the Node.js implements a runtime engine based on Chrome V8
160360	165300	to satisfy the needs of the server-side languages.
166160	169480	The runtime engine also provides a set of API
169480	172940	to let JavaScript interact with the host environments.
173280	176620	By providing such APIs,
176620	179340	the JavaScript code can access the host environments
179340	181980	like any other server-side languages.
181980	185000	For example, it can read and write file systems
185000	187980	or execute system commands.
188280	190560	So Node.js is pretty powerful.
192100	195520	Nowadays, many websites are deploying Node.js.
195520	198360	For example, Node.js are intensively used
198360	201300	in companies like PayPal and LinkedIn.
201300	205000	Also, we are all using a lot of electronic apps
205000	208740	such as Skype or Skogs, Discord.
208740	213280	And such electronic apps are also based on Node.js runtime.
214540	217640	We've seen so many Node.js applications.
217640	222580	The web-based apps are one of the most common types of Node.js programs.
222940	225620	For those web-based applications,
225960	229780	taking the communication data into object representations like JSON
229780	233560	is pretty common.
233780	236100	And this feature is convenient.
236660	239640	For example, Node.js can use this feature
239640	243660	to send and receive very complex data structure.
243760	247280	From the monthly download statistic picture on the right,
247280	251020	we can have an idea of how the object sharing is being supported
251020	254060	and used by the Node.js ecosystems.
255740	260200	The diagram demonstrates how the object sharing is being used
260200	262820	in the Node.js ecosystem.
262860	268880	There are two major methods of serialization of object data.
268880	272180	The first is the query-stream-based serialization,
272180	274920	and the second is the JSON-based serialization.
274940	276500	As shown in the picture,
276500	280940	if the user wants to update the age information in the Node.js web,
280940	285320	he can send his data either via a standard query stream in the URL
285740	289080	or a JSON stream in the request body.
289140	291120	Upon receiving the request,
291120	294580	the web application will convert the JSON data
294580	297580	or the query stream data into an object
297580	302720	so that the object can further propagate in the program logics.
303380	307060	Okay, so basically this is how the object sharing is carried out
307060	309280	in Node.js ecosystems.
309280	313380	Usually, if we want to evaluate the security of such a program,
313380	317220	we may want to inject different payloads into the age field
317220	321840	so that we can try to trigger certain vulnerabilities
321840	325680	such as SQL injections or cross-site scripts.
326660	332360	However, what if we choose not to test the existing data field?
332800	335940	Since we can pass an object into the program,
335940	338620	what will happen if we inject additional properties
338620	342860	that are not expected to be received by the server program?
342860	346580	In particular, if an attacker can send the properties
346580	351040	that forge or override the certain internal program states,
351040	353980	the attacker may easily obtain dangerous abilities
354360	358220	to manipulate the key program logics.
359500	364820	So we are going to introduce the hidden property abusing, HPA.
364820	368700	So the hidden property abusing leverages the object sharing in Node.js
368700	372680	to tamper or forge critical program states.
372680	376540	We call the additional properties we inject as the hidden properties
376540	380240	because these properties are kind of like some hidden parameters
380560	384200	which is valid to the endpoint user API.
384620	389480	These parameters are associated with certain internal program states.
389480	392160	However, nobody knows their existence
392160	396360	until an attacker leverages HPA to tamper the states.
397000	400480	In this talk, we mainly focus on the server-side scenarios
400480	404920	where a remote attacker wants to attack the Node.js web applications
404920	407240	or some microservices.
407420	409600	To explore the vulnerabilities,
409600	412580	the attacker will access the legitimate interfaces
412580	416980	such as the web API endpoint to send his payloads.
416980	420100	In most cases, the attacker payloads
420100	422600	should be in the form of planned object,
422600	427040	which is the simplest object representation in Node.js.
428860	435280	During our research, we discovered two types of typical attack vectors of HPA.
435660	440400	We call the first one as the app-specific attribute manipulation.
440520	444180	This one is for manipulating certain internal properties
444180	447000	defined by the application themselves.
447000	450200	Search internal properties are supposed to be initialized
450200	453180	and managed by their internal functions.
453180	459140	However, they usually represent certain internal states of the programs.
459240	460960	So as shown in the picture,
460960	464560	the INIT row is an internal function that is responsible
464560	469060	for maintaining the access right on the user object.
469300	471400	However, with HPA,
471400	476360	the attacker can propagate a conflicting name property to the user object.
476360	481720	And thus control the internal states of the program.
481900	483680	As shown in the picture,
483680	488260	the program also provides an API called update.
488260	490740	This is for external usage.
491060	496620	However, if a malicious user injects additional key-value pair,
496620	502160	which is access and admin in the picture to the API,
502160	509660	then the additional properties will override the existing access right.
510000	511800	So this payload is pretty useful
511800	517040	when we want to abuse certain concrete logics in large applications,
517040	522760	such as some older information or user-privileged any management logics.
523340	528000	Also, HPA can target some unique JavaScript schemes,
528000	530240	such as prototyping.
530240	535420	We call the second attack scenarios as prototype inheritance hijacking.
536220	540700	In JavaScript, every object has a link to a prototype object.
540860	545640	When the JavaScript code wants to access a property of an object,
545640	549200	the property will not only be searched on the object,
549200	551340	but also the prototype of the object,
551340	554000	and even the prototype of the prototype,
554000	557260	until a property with a matching name is found.
557740	559360	As shown in the picture,
559360	565140	when the JavaScript code wants to get the constructor property from the input object,
565140	569160	it will first search locally within the input object.
569160	572780	Since there is no property named constructor here,
572780	576240	the code will continually search to his prototype,
576240	580060	where the constructor is really located.
580760	584380	So with HPA, we can hijack the inheritance chain
584380	589700	and forge our own payloads as the internal properties on the chain.
589900	591400	As shown in the picture,
591400	594300	if we inject a property named constructor,
594300	597120	the search process will be very different.
597120	601980	Since there is already a property named constructor within the input object,
601980	603660	the search will immediately stop
605000	609180	and end up with retaining a user-controlled value.
609300	611620	As demonstrated in the red circle,
611620	614580	the value of the constructor will become a string,
614580	618600	rig and multi, rather than a normal JavaScript function.
619280	622140	So the second attack vector is really useful
622140	626100	because we found many JavaScript developers
626100	629640	tend to trust the properties inherited from prototypes
629640	634700	and make many security-sensitive decisions based on them.
634940	637400	Also, we should be aware of the differences
637400	642220	between these attack vectors with the prototype pollution.
642240	645900	The two attacks are totally different.
645900	648580	The prototype pollution, as the name suggests,
648580	652540	is about tampering the prototype object.
652540	658760	However, our attack vector does not modify the prototype object.
660650	663690	The root cause of the HPA is that
663690	667990	the Node.js fails to isolate the unsafe object,
667990	672610	such as the user input, from the critical internal states.
673030	676010	So, to make a clear classification,
676010	679030	the HPA can be seen as a new security risk
679030	682710	under the Common Weakness Category 915,
682710	686730	whose child variants are all about improper modification
686730	689770	of the dynamic object attributes.
690290	692910	As shown in the hierarchy tree on the right,
692910	696390	there are some similar issues on other language platforms,
696390	700730	such as Ruby Math Assignment, the PHP Object Injections.
700870	704330	Although these variants share the same behavior feature
704330	706150	dominated by 915,
706510	709850	they all have their own data patterns
709850	711930	due to the language differences.
712170	715010	For example, the Ruby Math Assignment
715010	717330	is a set of vulnerabilities discovered
717330	720790	in widely used Ruby web application framework
720790	722810	called Ruby on Rails.
723170	728190	Unlike HPA, the attacker does not pass objects into the program.
728190	730830	Instead, the attacker abuses
731970	735050	a framework-specific assignment feature in Ruby on Rails
735050	737530	to modify certain existing objects
737530	740110	on the right side of the assignment.
740170	744150	And the payloads between the two attacks are also different.
744190	747430	The Math Assignment payloads are literal value.
747430	750150	However, HPA can introduce hidden properties
750150	754810	with either literal value or nested object form.
754810	758290	More importantly, the Ruby is strongly typed,
758290	759950	so the Math Assignment vulnerabilities
759950	763210	cannot introduce new properties to the objects.
763210	768490	However, the HPA can inject arbitrary properties,
768490	772210	which make HPA really flexible and powerful.
773710	777540	OK, so with several pages of concept introduction,
777540	780940	I think it's time we can hack some real targets.
781440	786340	In this example, we target at a popular web framework
786340	788340	named Routing Controller.
788360	790840	We will attack its official example code
790840	795960	to demonstrate an end-to-end prototype inheritance hijack exploit,
795960	799500	from security check bypassing to cycle injection.
800340	803060	The figure on the right can give you a brief idea
803060	804820	on how our example works.
804820	808060	In the example, a server program is deployed
808060	810060	using Routing Controllers.
810680	814200	If a remote user wants to authenticate with the server,
814200	817300	his data will flow into the following components.
817420	819960	First, he will send his serialized data
819960	823140	into the authentication module.
823220	827800	Then, the authentication module will instantiate the objects
827800	829460	according to the JSON he provides
829460	832280	and send it to the param handler.
832280	837080	Here, we use the green box to demonstrate the user data objects.
837080	840340	The param handler is responsible for ensuring
840340	843320	user input object is not malicious.
843620	848180	The handler will first collect internal format specification object,
848180	850460	which is the blue box in the picture,
850460	854660	and he will merge the specification with the input object
855140	858320	and invoke the input validation API.
858320	862820	The input validation API will sanitize the user input data
862820	865220	according to the format specification.
865300	870020	In this case, it will check if the email field is legitimate or not.
870020	875320	If the check passes, the user object will flow into the database.
875600	878100	Okay, so this is the overall data flow.
878100	882140	Let's analyze how we can attack the logic step by step.
883000	887080	So, the first step is the hidden property injection,
887080	894420	in which the malicious attacker injects hidden properties in his request,
894420	897320	which is the constructor in this case.
897320	902720	As shown in the picture, when the server program instantiates the user object,
902720	907500	there will be an additional property named the constructor,
907500	913580	which is a payload for bypassing the input validation module.
913580	920820	So, in the second step, the program will prepare the parameters needed by the input validation API.
920820	929280	The server program will merge the user input, which is the param, with an object named the schema.
929280	936900	The merging operation is carried out by putting every property from the param objects into the schema object.
936900	941280	So, this process is very much like object assignment.
941280	947280	To simplify the demonstration, let's just use object assignment in this example.
947360	955060	By performing such merging operations, the hidden property constructor will also transform to the schema.
955540	962440	And after the transformation, we now can hijack the inheritance of the constructor on the schema.
962440	969460	Actually, the constructor of the schema plays a very important role in the input validation module.
969460	979120	As shown in the picture, the constructor actually stores the important format restriction information.
979120	987900	As a result, the merging operation enables us to hijack the inheritance of these important format restrictions.
987900	993500	As shown in the picture, when the constructor is read by the getSchema function,
993500	998860	our hidden property will be immediately matched and returned to the code.
998860	1005660	To bypass the input validation, we just need to set the format specification as an invalid value,
1005660	1009700	so that our SQL injection payload can escape the check.
1010020	1013740	Now, the last step is much more straightforward.
1013740	1019600	The validate payload then flows into the sensitive API to finish the entire attack.
1019720	1023960	So, this is how an entire HPA chain looks like.
1023960	1029040	Actually, the code logics behind vulnerability is much more complex.
1029040	1037320	For example, the input validation module contains 30,000 lines of code.
1037320	1043100	So, it would be helpful if we can find a tool that automatically track these data structures
1043100	1047980	and discover time for hidden properties exist in the program logics.
1048700	1051920	So, what are the challenges of building such a tool?
1051920	1054060	First of all, it is JavaScript.
1054060	1058180	Analyzing JavaScript is known to be hard due to the dynamic nature.
1059160	1066320	And second, HPA is a tech that creates unexpected and new data dependencies.
1066360	1076080	However, program analysis, such as data flow tracking, is mainly for analyzing the existing flows.
1076080	1082340	Third, from our run examples, we can observe that HPA tampers internal program states.
1082760	1088260	So, the attack effects highly depend on the roles of the compromised states.
1088260	1091020	This makes the detection more challenging.
1091440	1098660	To overcome these challenges, we design and implement Lynx, a hybrid JavaScript program analysis tool,
1098660	1102420	to detect and exploit HPA vulnerabilities.
1102700	1105300	Lynx mainly consists of two components.
1106160	1111980	The first component on the left is for identifying potential hidden properties.
1111980	1123440	It combines dynamic data flow tracking and static synthetics analysis to track all the user input and infer potential candidates.
1123440	1130400	And the component on the right is for detecting the harmful hidden properties and generating exploits for them.
1130400	1141360	To help future Node.js security research, we decided to open-source our Lynx project at the GitHub links in the bottom.
1142100	1148920	So, if you are interested in the technical details, you can check it in the GitHub report.
1149760	1154660	So, the very first thing Lynx will do is dynamic data flow tracking.
1154660	1162520	First of all, Lynx will generate a label object, which is a unique key and value piv.
1162980	1167880	Lynx will inject the label into the input data of the program.
1168300	1178040	Since different properties from the input object may flow into different program logics, we want to track all these propagations.
1178040	1183820	So, we perform the label injection in a recursive manner.
1183900	1193640	That is, as shown in the picture on the left, Lynx will generate three different inputs by label injecting the original test case.
1193640	1197980	In each time, Lynx will inject the label into our different properties.
1198740	1203280	After the injection, Lynx will observe the program execution.
1203280	1210380	We leverage a JavaScript analysis framework called Jalanki to instrument our test programs.
1210380	1218500	Since we are studying the data flow, we instrument the variable reads and writes, object property indexing and function calls.
1218500	1221060	Then, we execute the test program.
1221060	1226040	During the execution, Lynx will examine every object within the data flow.
1226040	1232520	If an object can't carry our property labels, we will record it for further analysis.
1233440	1237380	So now we have a list of property carriers.
1237580	1246080	Record that an object is flagged as a property carrier because we detect our injected label under his body.
1246080	1256420	So if we can propagate our label here, maybe we can also propagate another malicious property here also.
1256420	1265280	More specifically, if we can inject a property that has a conflicting name with certain internal properties the program has,
1265280	1269360	maybe we can control that property by overwriting them.
1270840	1282340	So now we want to extract all the child properties from the original programs of the property carriers and flag them as hidden property candidates.
1282340	1292040	To achieve this goal, we need static syntax analysis to extract the necessary syntactic information from the code.
1292040	1297460	The picture on the right demonstrates how we parse our statement from our running example.
1297460	1305500	Lynx will traverse the syntax tree until reaching a property carrier, which is circled by the red line in the graph.
1305500	1313800	Then it records all the properties under the carrier. In our case, the hidden property candidate is the constructor.
1315780	1321140	So here is an output screenshot of the first component.
1321140	1330800	As you can observe, the Lynx will first instrument the code base, and then we tracked 43 property carriers.
1330800	1337940	As indicated by the red circle, Lynx successfully detects a hidden property named constructor.
1339520	1345240	So in the previous component, we discovered the key name of the potential hidden properties.
1345240	1350440	By injecting the property with the same key, we might overwrite certain internal states.
1350440	1356240	However, we still don't know whether the candidates can be controlled or not.
1356240	1361200	And we also don't know how to introduce attack effects with these candidates.
1361220	1364340	So apparently, Lynx could do more.
1366060	1374260	Let's revisit our running example to see if there is any insights to help us to design such an exploitation component.
1374340	1378980	The figure on the left is the vulnerable code from our running example.
1378980	1384680	As we have discussed many times, hidden property tampers internal program states,
1384680	1389960	which means HPA exploitation highly relates it to the code context.
1390060	1395400	So it is important to conclude a set of vulnerable sensitive behaviors.
1395400	1399800	These behaviors should clearly indicate certain security consequences,
1399800	1404880	so that we can decouple the harmfulness detection from the code context.
1404880	1411760	Also, from the running example, the exploitation is mainly about manipulating the return result.
1412540	1416660	More specifically, there are two possible paths here.
1416660	1423400	If the execution enters the branch on line 19, we will get a validation failed.
1423400	1429100	But if we can go into the line 21, we can successfully pass the check.
1429100	1435860	So the exploitation point and the override point may not be the same place,
1435860	1440100	which means we shouldn't stop our analysis at line 11.
1440100	1447440	Instead, we should continue exploring all the possible paths that can be triggered by manipulating the hidden properties.
1448420	1453580	So we studied and concluded six general types of sensitive things.
1454560	1459960	Due to the time constraint, I will not introduce the details of each type.
1459960	1463600	If you want to know more, you can check our Git report.
1464960	1468160	So after defining our sensitive things,
1468160	1473300	we want the hidden property to trigger as many as possible branches,
1473300	1476420	and monitor whether we can hit a sink.
1476420	1482480	To achieve this goal, we use symbolic execution to explore all the hidden property value space.
1482480	1489920	Lynx first generates an exploit template that can reach the potential hidden vulnerable property.
1490080	1493680	We denote such data structure as an exploit template,
1494020	1501180	because Lynx does not specify a concrete value in the input.
1501180	1508840	Instead, we insert a special placeholder, which will be used by the symbolic execution later on.
1508840	1513880	Then, we run the test program with our constructed templates,
1513880	1518020	and symbolically execute the hidden property.
1518020	1525960	As shown in the picture, the Lynx will explore all the path constraints along the input path,
1525960	1531680	and if Lynx finds that it has hit a sink,
1531680	1535800	for example, in this example, it hit the sink i2,
1535800	1543860	then he will fetch the corresponding payload that can trigger the sink as the final exploit.
1544240	1555540	So a little background about the sink i2 is the sink we define to detect that whether our input can manipulate the return value of a module or not.
1557990	1561610	So this is the output of the exploit module.
1561610	1569790	From the circled area, we can observe that the key value pair constructN1 triggered the sink i2.
1569870	1579270	In the last line, we can find that the Lynx successfully bypassed the generator exploit that can lead to the successful validation.
1579710	1583010	So this is pretty much about how our system works.
1583010	1586850	Let's see some interesting new results of our research.
1586850	1593150	During our research, we choose 60 widely used programs from Node NPM.
1593150	1596690	There are 55 modules and 5 web applications.
1596990	1602910	And with the help of Lynx, we tracked more than 1,300 carriers,
1602910	1609330	and detected more than 300 hidden property candidates associated with those carriers.
1609330	1613130	In the end, we confirmed 13 zero-day vulnerabilities.
1613130	1619510	With the help of symbolic execution, Lynx even synthesized 10 exploits automatically.
1620310	1623630	So how is the impact of these vulnerabilities?
1623670	1627550	We found that HPA can introduce various attack effects,
1627550	1635030	such as leaking credential data, denial of services, or bypassing security checks.
1635030	1642530	Based on the impact analysis, we can observe that the HPA can compromise previously unreachable program states,
1642530	1646670	which effectively enlarge the attack surface.
1646850	1652110	Even more, we could notice that HPA is not a simple input validation issue,
1652110	1656730	and many input validators themselves are also vulnerable to HPA.
1657170	1665230	So in the following slides, I will pick up two interesting vulnerabilities from our results and case study them.
1665910	1669970	So the first case comes from MongoDB official driver.
1669970	1674930	We found that we can tamper an internal state named the BSON type.
1675090	1685270	Our background here is that the MongoDB leveraged the internal state BSON type to indicate the data type of the query object.
1685270	1693190	However, when serializing the query object, MongoDB will ignore the object with unknown BSON type.
1693330	1698270	So what if we abuse the logic for a query condition object?
1698270	1702530	The code on the right is from an open source online game.
1702530	1707610	The online game used a vulnerable API to implement the user management logics.
1707650	1712610	As shown in the picture, by injecting the unknown BSON type to the input,
1712610	1716990	the attacker can force the MongoDB not serializing the query object condition,
1716990	1722730	so that the MongoDB will always return the first user on top of the database.
1722730	1731190	With this ability, the attacker can log in or delete arbitrary accounts.
1732590	1737250	The second case is from another widely used in-memory database.
1737250	1742990	The hidden property is more like a backdoor which helps the user accessing the sensitive data.
1742990	1754010	In TafiDB, we discover a hidden property named id, which is an internal index for each database data item.
1754010	1764370	Once we specify our own id in the query, TafiDB will ignore other query conditions and directly return the result associated with the index.
1764370	1769510	As shown in the picture, even though we got wrong password and username,
1769510	1777670	we can still leak the valid user data from the database with our crafted hidden properties.
1778450	1783430	Thanks for attending our talk. I hope you guys keep safe in this special year.
