start	end	text
9460	13440	Hi, welcome. Thanks for attending our talk. This is Room for Escape,
13440	16100	Scribbling Outside the Lines of Template Security.
16460	20140	So, my name is Alvaro Munoz, also known as Pwntested in the social media.
20420	23520	I'm a security researcher with the GitHub security lab.
23560	27960	And with me, my colleague, Alexander Mirosh, also known as Oleg Mirosh in Twitter.
27960	31760	And he is a security researcher with Micro Focus Fortify team.
31840	36600	So, today, we will be reviewing the security of content management systems, or CMS.
36600	41720	And, basically, we will be focusing on the security of the template systems
41720	48040	that are used by CMSs. So, a content management system is basically an application that is used
48040	53940	to manage different types of web content, so that users can actually create, upload,
53940	59480	and publish different types of content. So, normally, this content is based on some
59480	65500	structures and some kind of documents called templates, which are used to generate and
65500	72120	create dynamic content. So, these templates normally allow a subset of different programming
72120	78060	language capabilities. So, they are powerful in the sense that they can be used to run arbitrary
78060	83620	code. Because of that, they are normally sandboxed in order to prevent arbitrary code execution and
83620	91340	remote code execution. So, our research will focus on both .NET and Java-based content
91340	97340	management systems, because these are the languages that are more prevalent across enterprises.
97460	103900	And our assumption is that the attacker can control the templates, right? So, we don't really
103900	108520	care about how the attacker gets control of these templates in the first place, if it's through
109000	114640	a server-side template injection, or if it's maybe through our cross-site scripting that allows him
114640	121680	to submit arbitrary templates in behalf of someone else. Or maybe they have permissions,
121680	126660	like if you are a user, for example, in SharePoint, if you have an account in SharePoint, you are
126660	134720	allowed to create your own sites and content. So, no matter how the attacker can edit the content
134720	142520	of a template, our research will focus on escaping and breaking all the mitigations put in place to
142520	150240	prevent arbitrary code execution. So, we will first start with .NET. Basically, we will focus
150240	156540	on SharePoint. We will present five different ways we were able to break the sandbox used by
156540	161660	SharePoint to prevent arbitrary code execution. And then we will move into the Java part, where
161660	168080	we will present four different template engines, including the most popular ones, such as Velocity
168080	173340	and FreeMarker. And then we will present 10 different content management systems, and we will
173340	178160	try our bypasses on them. So, we will wrap up with some takeaways and conclusions, and then open the
178160	185500	floor for Q&A. So, let's start with the .NET part. Thank you, Alvaro. In this part of our presentation,
185500	190680	we will present different types of security problems in content management systems, and give
190680	196480	examples of them in SharePoint. But before that, we need to explain some basics of SharePoint
196480	205000	security. SharePoint has two types of ASPx pages. The first type is application pages. Each of these
205000	210820	pages are the part of SharePoint server and implement some application logic. They are stored
210820	216500	in specific folders on the file system. Of course, users are not able to change them. They are regular
216500	223160	ASPx pages and are processed by server without any restrictions. In opposite to them, there are
223160	229320	side pages. They are stored in database and they can be customized even by users. SharePoint parses
229320	234840	them in special mode, also known as safe mode. Actually, they are more like some sort of templates
234840	241860	for presenting dynamic content. On this slide, we can see a diagram how server works with these
241860	249560	pages. Virtual provider can fetch content from file system or database. Based on the virtual path of
249560	256980	the current page, ASP page parse filter will decide either it is side page and safe mode should be
256980	263180	applied, or it is an application page and it will be processed without any restrictions. So, page
263180	273280	filter is a critical element from security design. Let's have a look on a simple ASPx page.
273280	278900	For our attacks, we are only interested in server-side components. For example, directives.
278900	284120	There are special instructions on how server should process the current page. Often, they have
284120	290660	some number of attributes. We can include server-side code either in special blocks or as
290660	297380	embedded server-side code. To be processed by server, control should have the runout server
297380	304780	attribute. The next element is server-side common block. It is ignored by server. And
304780	309890	server-side include directives allow us to include raw content of arbitrary file.
310760	317620	Now, we can better understand what safe mode means. Side page will not be compiled, so we cannot use
317620	324060	server-side code. We are not able to include files from file system. We can only use allowed
324060	330880	controls. This list is defined in safe control section of web config file. Page filter also
330880	337240	applies an allow list for directives and even for attributes of most of them. There are many
337240	343940	other restrictions. For example, event binding is blocked as well. As we can see, it is a set of
343940	352480	quite strong restrictions how it can be bypassed. As we know, safe mode is enforced by page filter.
352820	359920	So, our first question was, is there any place where SharePoint does not use it? And answer yes,
359920	366760	there are such places. Page filter will not be applied for the content argument of the parse
366760	372560	control method if it's called only with one argument or if the second one that actually has
372560	380040	name ignoreParseFilter is true. In addition, page filter is used at rendering time but is ignored
380040	389080	at design time. But even if page filter is not applied, SharePoint uses another way to verify
389080	397360	the input. It is a verify control on safe list method from editing page parse type that aims to
397360	405260	do the same task at the original page filter, block markup with unsafe elements. But let's
405260	410780	imagine for a second that we are able to bypass either this method or page filter. By the way,
410780	415760	each such bypass is separate vulnerability and we will present them in a few minutes.
415760	422120	So, how could we get remote code execution after escaping the safe mode? Remember,
422120	426360	since parse control method never calls compilation, we are not able to use
426360	433520	server-side code or perform any other attack that require compilation. But if we escape
434300	440080	safe mode, we can use unsafe controls or directives. Let's review several of them.
441000	448420	One of the most interesting unsafe controls is object data source. It allows us to invoke public
448420	454200	methods from arbitrary public type. We can see an example of payload that uses start method from
454200	460140	process type to launch calculator. So, actually, it is arbitrary code execution, jackpot. But let's
460140	467380	review a couple other unsafe controls. XML data source and XML controls allow us to get content
467380	472640	of arbitrary XML files. The similar results we can get by server-side include directives
472640	479140	that return us content of any text files. Let's see how we can escalate from arbitrary file read
479140	485820	to arbitrary code execution. If we can access web.config file, we will be able to get validation
485820	493260	key from machine key section. By the way, this value may be present in other places such as
493260	499240	internal SharePoint properties. We will see this example a bit later. With validation key,
499240	506840	we can generate a valid view state that will execute arbitrary code commands on the target
506840	515660	server. We can use tools such as userserial.net for this. Now, when we know what safe mode is and
515660	521500	how we can compromise SharePoint server if it is bypassed, we can move to our next part of this
521500	527220	talk. Here we will present five different types of security problem in content management system.
527540	534160	We will show examples of each type in SharePoint. We would like to stress here that our target is
534160	539080	SharePoint server with default configuration. All vulnerabilities allowed us to execute arbitrary
539080	546300	code on the target and all attacks were performed by regular user. No admin rights were needed.
546860	553780	Let's start. The first type of security problems is access to resources with sensitive information.
553780	559560	It can be configuration or business information in various files, logs, database, or even process
559560	565880	memory. Of course, proper sandbox should prevent this problem, but it is not always the case.
566220	570260	We already mentioned that page filter blocks server-side includes directives
570260	575820	and verify control on safe list method should do this as well, and actually it does.
575980	582360	But if it's called with false in block server-side includes argument, it will not block them.
582540	587220	And we found such usage of this method. It was used for design mode.
588060	594540	The next building block for our talk, how we can provide our markup for this mode. We can send it
594540	601480	in web part XML parameter of the render web part for edit method of the web page services.
601480	607600	So we can try to include web config file there. Here we can see the full payload for the mentioned
607600	613260	parameter and address to relevant web services. Server returned us the entire web config with
613260	618560	validation key. We use it for view state-based deserialization attack, which led us to
618560	621120	executing arbitrary OS command on the server.
622740	627180	Time for our next type of security problems in content management system.
627640	630500	Allow dangerous element that can be used for attacks.
631600	634840	We have found an example in SharePoint safe control list,
635340	639880	or should we call it not so safe control list in this case.
642100	648280	It is contact link suggestion micro view control. We can see snippet with interesting code from
648280	654060	implementation where request parameter is passed to data set read XML method.
654160	659160	If we can control input for this method, we can get our data deserialized by XML serializer
659160	664840	with control type. We already showed in one of our previous work that in this case we can get
664840	669840	arbitrary code execution. Unfortunately, this payload is too big for slides, but you can find
669840	677580	it in our white paper. The last piece of the puzzle is our site page with this dangerous control.
677580	683320	You can see it on this slide. For the attack, we just need to place the payload into the text box
683320	688370	and click on submit button and desired command will be executed on the SharePoint server.
689820	695020	For us, the next type of security problems looks quite interesting, so we will explain it with
695020	701460	more details and present two separate examples from SharePoint server. Dynamic content usually
701460	707160	means that we will have at least read access to some properties or attributes of some objects.
707580	714500	For some system like SharePoint, we can even write values there. Of course, some box should filter out
714500	720560	the access to dangerous property or attributes. Let's review basic type of such filtering.
720960	725580	The first case is when only one level of properties or attributes is allowed.
725580	731360	We can see examples on the slide. Name property of user object of select value from menu.
731360	736500	We can imagine the object and its properties like a branch with only leaves.
737740	742460	If an allow list is applied, it's relatively easy to review all elements. And after such review,
742460	747940	we can make sure that there is no dangerous elements. What if block list is used instead?
748100	752320	We still need to verify available objects and it can be a bit difficult.
752600	756500	So in general, we do not consider a block list a safe approach because of potential
756500	761340	gaps there. We will see in Java part a couple of examples of such bypasses.
762300	767300	The most interesting case for us is where access to nested properties or attributes
767300	774520	is allowed. For example, request.authUser.name or menu.selectedItem.text.
774700	780460	Because of branch-leaves analogy, many developers may imagine this case as branch with branches
780460	788040	and leaves. And they may apply a filter only for the first level objects. But it is not true.
788040	794200	It is a network. And we may jump from one branch to another branch or even to the trunk.
794200	799460	For example, on this slide, we can see how we can access application instance from a new web
799460	805140	control. Let's illustrate this problem by examples from SharePoint.
805660	811660	There is wikiContentWebParseControl. It is allowed and can pass our markup into the
811660	817640	parseControl method. Please note, it is called with false value in ignoreParseFilter argument.
817640	824480	So, PageFilter will not be ignored. The following snippet shows that in this case,
824480	828620	the virtual path will be created from AppRelativeVirtualPath property.
828900	833110	And if you remember, PageFilter will apply restriction based on this virtual path.
833440	839700	So, if we are able to change it, we can fool the PageFilter to not apply any restriction to our
839700	848200	markup. Let's try to graph such payload. First snippet fails, because when ASPxParser tries to
848200	854760	assign a new value to AppRelativeVirtualPath, the Page property of our control is not defined yet.
854760	861040	So, we need to delay this assignment a little bit. We can do this by data binding. So, by the time
861040	866620	the property is bound, the Page property will be already defined.
867340	875860	Here is our final payload. We can notice that our new path points to application page setting ASPx.
876240	882960	It is assigned to ToolTip property and later will be transferred to AppRelativeVirtualPath.
883020	888360	So, the PageFilter will think that this is system page and will allow any unsafe markup.
888360	891960	For example, we can use ObjectDataSource control to start calculator.
892860	895480	Let's see how the real attack may look.
899240	904720	We can see a site page with our payload. Path to system page. It will be assigned to
905500	910680	AppRelativeVirtualPath. Unsafe markup contains ObjectDataSource control.
911080	919400	We will invoke start method of the process type and we'll start calculator. Let's save it here.
920360	924760	For our attack, we need to upload it to the target server. In our case, it's SharePoint
924760	930100	with default configuration. That means regular users have access to their own personal sites
930100	936120	and we can use them to host our site page. We are notificated as regular user with name attacker.
936400	943340	Sneaky, isn't it? And here is his personal site. Let's upload our page here.
944100	950220	Now, to trigger our attack, we just need to click on it. But before that, let's take a look on the
950220	956500	right slide of our screen. We can see task manager on our SharePoint server and we will notice if
956500	962680	calculator start. Now, let's start our attack and here is our calculator.
963680	969360	Let's move to our next vulnerability in SharePoint. Now, we will try to exploit read access to nested
969360	975260	properties. We will use control parameter. It allows to bind value of property from another
975260	982440	control to select prop parameter. Also, it supports nested properties. We need to deliver value of
982440	990040	target property back to us. To do this, we will use XML URL data source control that sends value
990040	997180	of select parameters to external server. Now, we need to find accessible property with sensitive
997180	1002980	information. Here, we should explain a little bit configuration process of SharePoint online
1002980	1008060	servers. Obviously, they are installed and configured automatically. But what about
1008060	1013680	configuration parameters that are unique for each installation? They will be provided in special
1013680	1020280	file that will be used for unintended configuration. What is important for our attack? All such
1020280	1027060	parameters, including validation key, will be stored in initialization setting property. So, we just need
1027060	1034940	to find a path of nested property to it from any allowed control. And here it is. Here is the whole
1034940	1041820	page that will send value of validation key to attackers.server.com. With this value, we
1041820	1046970	successfully got arbitrary code execution by unsafe deserialization in view state.
1048220	1053980	Now, let's move to the next type of security problems. It is connected with our previous work
1053980	1060940	on unsafe deserialization. Such kind of problem is relevant when text or binary data is converted
1060940	1069340	to an object and the type or class of this object is under attacker control. Plus, it is not properly
1069340	1076880	limited. Actually, it doesn't really matter what mechanism is used. Classical deserializers,
1076880	1083480	JSON unmarshalers, type converters, or even some custom approach. All of them are potentially
1083480	1089560	dangerous. For successful exploitation, attacker just may need to find proper gadget on the system.
1090240	1095980	We have found examples of such problems in SharePoint and were able to perform arbitrary
1095980	1102320	code execution attack using it. But patch is not available yet. So, we are going to publish all
1102320	1108740	details of this problem when fix is released. The last type of security problems in this part
1108740	1115640	is the classical time of check to time of use problems. They occur when the server invalidates
1115640	1122540	some input, but this input is later changed before the server uses it. We have found such problem in
1122540	1128580	web part editing surface page. User input is validated by the already mentioned verify control
1128580	1136200	on safe list method, but later the server may modify the input and remove substring that match
1136200	1145760	specific regex pattern. Let's look on the next input. For validation control on safe list, it is
1145760	1153220	just one server-side comment block, so it will pass validation. But SharePoint removes the highlighted
1153220	1161020	yellow substring and pass control will see two comments and some markup. Note, pass control has
1161020	1168100	only one argument, so patch filter will be ignored. Time for our payload. We can notice our unsafe
1168100	1175100	object data source control and calculator command. In this part of our talk, we saw multiple ways
1175540	1181160	to achieve arbitrary code execution on the SharePoint server by regular user.
1181720	1187180	These vulnerabilities revealed five different types of security problems in content management
1187180	1193340	system. Now let's switch back to Alvaro and he will present even more vulnerabilities with
1193340	1199740	templates for dynamic content in different Java frameworks and products. Thank you, Alexander.
1199740	1204860	So switching to the Java part, we will be reviewing four of the most popular Java template engines,
1204860	1210680	including FreeMarker, Velocity, Pebble, and GeneJava. And also we will be reviewing 10 different
1210680	1217100	content management systems that are using these engines and then we will be trying our bypasses on
1217100	1222300	these content management systems. So a brief introduction into what template engines are.
1222300	1227340	Basically these are systems that take two different inputs. One is the template where
1227340	1234020	we are mixing static and dynamic expressions and also the template context where we store objects
1234020	1239920	that are required by the engine in order to resolve the dynamic expressions in the template.
1239920	1246220	For example, here we have the user.name expression. In order to resolve it, we need to get access to
1246220	1252380	the user object in the context and then invoke the getName method. So because it's invoking Java
1252380	1257820	methods, it's basically dangerous in the sense that attackers can execute arbitrary Java code
1257820	1263500	and that's the reason why most of them are sandboxed in order to prevent arbitrary code execution.
1264460	1269500	So apart from the objects that are normally and directly used by the template,
1269500	1274780	there are a number of other objects that are exposed as part of a template API that is normally
1274780	1282440	provided by the content management systems, which basically provides objects such as, for example,
1282440	1288220	the request, the response, the separate context, or even the HTTP session. So those objects are
1288220	1294960	available in most of the template APIs and also many more that are part of this API.
1295440	1301500	So we will be discussing first some generic bypasses. That means that are independent
1301500	1308340	of which engine is used, no matter if it's FreeMarker, Velocity, Pebble, or GeneJava, right?
1308340	1317120	So those bypasses are based on finding different objects that we can use to get arbitrary code
1317120	1322800	execution. So we need to inspect the template context and look for this kind of objects.
1322800	1327360	In order to do that, if we have access to the JVM, we can basically debug it or we can
1327360	1333980	instrument it, dump the template context, and inspect and analyze all the objects in there.
1334040	1341920	However, if we don't have access to the JVM, we will have to read the template API documentation,
1341920	1347540	maybe do some brute forcing in order to guess names like, for example, request or rec or
1347540	1352440	response resp and things like that. And also in some of the engines, like, for example,
1352440	1358660	FreeMarker, it is possible to list all the variables or objects that are exposed in the
1358660	1365400	context. So apart from those objects that are directly exposed to the context, we have some
1365400	1370600	objects that are indirectly exposed. Like, for example, if we are exposing the HTTP session
1370600	1376760	because it contains some attributes, all of those attributes will be available for the users and
1376760	1382080	attackers to access and use. Same thing with the servlet request and same thing with the servlet
1382080	1388100	context. So those are stores of attributes, stores of objects that the attacker can get access to
1388100	1394180	and use to look for interesting objects. So let's see how many objects we can find in one
1394180	1399000	simple content management systems. In this case, it will be LiveArray. And in order to do that,
1399000	1407540	we will be generating this template that I'm showing you, which basically is listing all of
1407540	1415740	the context variables, then all of the request attributes, then we will show all the request,
1415740	1420940	sorry, the session attributes, then the servlet context attributes. And because the servlet
1420940	1429120	context will expose the Spring framework context, we will be also listing all of the Spring bins,
1429120	1436260	all the objects registered in the Spring context. So if we render that,
1436960	1442000	you will see that we have a bunch of objects directly exposed to the context. Those are part
1442000	1448200	of the template API. And some of them are very interesting. Others are exposed as part of the
1448200	1453840	request attributes, session attributes, and servlet context attributes. So as we can see here,
1453840	1459840	we have interesting objects like an instance manager or, for example, the web application
1459840	1465640	context for Spring that we use to list and access all the Spring bins. So as you can see, there are
1465640	1472000	hundreds and thousands of objects here. There is a total of almost 900 objects. And because
1472000	1477260	some of them will have public fields that we can get access to, then this number will increase to
1477260	1483880	thousands of objects. So back to the slides. This is why we call it object dumpster diving,
1483880	1490040	because this is how we felt when trying to find very few interesting objects that can lead to
1490040	1496520	remote code execution among, you know, thousands and thousands of objects. So now we will be
1496520	1502400	reviewing the top three objects that we found that lead to remote code execution. So for example,
1502400	1507480	the first one, the class loaders, was available in 10 out of the 10 content management systems
1507480	1513320	that we analyzed. So normally you can get access to this class loader instance through the get
1513320	1520460	class loader method in the class type. But that is normally blocked by any block list by any
1520460	1525300	sandbox. So you can still get access if you get access to a protection domain or a servlet context
1525300	1531780	as we saw before. So once that you get access to a class loader, you can obviously load arbitrary
1531780	1538100	classes and then also load arbitrary resources from the class path. But apart from that, you get
1538100	1544280	access to a URL object and then from there you can access any file from the file system that the
1544280	1550660	application server has permissions to access. So here you have an example. You get the URL using
1550660	1556280	the get resource method and then you point the URL to the password file and then you open a
1556280	1566560	connection and read all the bytes from that file. So apart from the standard class loaders,
1566560	1572100	because content management systems are normally deployed on top of servlet containers or
1572100	1578440	application servers, the instance of the class loader that you will be able to access is normally
1578440	1583180	an instance of a web application class loader that are slightly different because of the way that
1583180	1589620	class loading delegation work, but also because they expose a number of additional methods that
1589620	1595560	are not part of the abstract class loader class. So here are just some examples. Just mentioned
1595560	1599840	because we don't have time to cover them in this talk, although it's explained in the white paper
1599840	1605560	that we are publishing as part of this talk, there are different ways of using these
1605560	1610420	methods in this web application class loader to get remote code execution. Just to mention some of
1610420	1617820	the vectors, we will be able to upload web cells, instantiate arbitrary objects, perform JNDI
1617820	1630280	injections, or even initialize attacker-controlled classes. So we were able to find web application
1630280	1635400	class loaders in nine out of the ten content management systems that we analyzed. And then
1635400	1643280	the second object, the second most easy to find object in this template context was the instance
1643280	1649960	manager or the object factory. So this was found in nine out of the ten content management systems
1649960	1656240	and is normally found as part of the self-led context attributes, but also it can be accessed
1656240	1661300	through one of these web application class loaders. So if you get access to an instance manager,
1661300	1666580	what you can do is basically instantiate arbitrary types. So with that, it's very easy to
1666580	1672500	escalate to remote code execution. Here we have an example using the script engine manager, but
1672500	1677920	there are a bunch of classes that can lead to remote code execution, ones that you can instantiate
1677920	1686200	them and then invoke arbitrary methods on them. So the number three object was a Spring application
1686200	1693580	context. It was only available in four out of the ten CMSs that we analyzed. Actually, the only four
1693580	1698620	that were using the Spring framework underneath. And it's normally accessible through one of the
1698620	1705760	self-led context attributes, but also if the content management system is using a Spring MVC
1705760	1712600	framework for the model, controller, and view layers, then Spring will inject some additional
1712600	1720180	objects in the template context, like this Spring macro request context that will provide access to
1720180	1725400	the Spring application context. So once that we have access to the Spring context, we can get an
1725400	1730980	instance of a class loader and initiate a class loader-based attacks like we saw before. We can
1730980	1736300	access the Spring environment that will give us access to the system environment and also the
1736300	1741660	system properties and also Spring properties, including things like encryption keys and so on.
1741660	1747380	But probably more interesting, it will give us access to the Spring bins registered in this
1747380	1753420	Spring application context. So being able to access and manipulate those bins, we can basically
1753420	1760500	control the application logic and do things like register new users, delete users, perform
1760500	1766420	transactions, anything that the application is normally doing. So that's normally behind an
1766420	1771060	authorization layer. So no matter what roles we have, we will be able to perform
1774200	1780800	this kind of application logic control. So apart from that, we will also be able to disable the
1780800	1786240	template engine sandboxes if we are able to get access to the template engine configuration bins
1786240	1793340	and also instantiate arbitrary objects, like we will see later, by accessing JSON or XML and
1793340	1801360	marshalers. So those were like genetic bypasses, independent of what template engine was used
1801360	1807020	underneath. And now we will be reviewing some specific sandboxes bypasses for each of these
1807020	1811720	four different template engines. So we will start with FreeMarker because it's probably the most
1811720	1819500	popular one and also because, well, it was analyzed and researched by different researchers in the
1820020	1825460	Like, for example, James Kettle back in 2015, when he presented server-side template injection
1826060	1831120	vulnerability class. By the way, if you haven't watched this talk, it's highly recommended.
1831120	1838040	He presented a bypass that is based on a kind of add-on or module that is deployed on the
1838380	1844080	default configuration of FreeMarker. So Tony Torralba last year presented a different bypass,
1844080	1849360	but this one is not universal in the sense that it depends on a non-default configuration
1849360	1856940	and also being able to find gadgets in third-party libraries that may or may not be
1856940	1864240	available in a specific target. Then Ryan Hanson this year, probably at the same time that we were
1864240	1868900	doing this research, presented a vector that leads to remote code execution by uploading
1869560	1874320	a web shell, but this is not universal in the sense that it only works with Tomcat servers.
1874320	1882780	So FreeMarker sandbox is a method-based block list, which basically means that, for example,
1882780	1887780	methods like the getClassLoader method in the java.lang class is blocked and you cannot
1887780	1891420	get an instance of a class loader using this method. But as we mentioned before,
1891420	1895620	you can still use the separate context or the protection domain to get access to these
1895620	1900600	class loaders. Once you get access to a class loader, the class loader methods are not blocked
1900600	1906460	by the block list, so you can still interact with them, load classes, get resources,
1906460	1911620	or initiate remote code execution attacks that we saw before. And also reflection is
1911620	1918320	forbidden to set fields values, but is allowed to get and read field values.
1918960	1924420	So we use that to perform an attack, but this attack is not universal in the sense
1924420	1928540	that it depends on being able to find an instance of a URL class loader.
1928540	1933760	So this is normally the case in Tomcat, GlassFish, and Jetty, but it's not universal for other
1933760	1938880	application servers. So in this case, we are basically getting the URL class loader from
1938880	1945540	the protection domain or from the separate context. And then we are basically instantiating,
1945540	1951200	by invoking this new instance method, a new URL class loader that is pointing to the attacker
1951200	1957280	control jar file, in this case the pawn.jar file. Once we get access to this class loader,
1957280	1963600	we can load arbitrary classes from our own jar file, and we will be loading the pawn class.
1963600	1969820	And now the class is loaded, but it's not initialized. If we want to run arbitrary code,
1969820	1975260	we need to initialize the class. We cannot instantiate the class, we cannot invoke static
1975260	1981720	methods. So those vectors, those ways of initializing the class, are not a possibility
1981720	1988200	for us, but we can get access to public static fields. So just by adding a public static field
1988200	1992500	and getting access to that, the class will be initialized and the payload will be executed.
1993240	1999600	So that was not a universal bypass in the sense that we are required to find an instance of a URL
1999600	2005120	class loader, and we want to find something that works no matter if we are able to find that kind
2005120	2011060	of class loader or not. So we are interested in finding some classes that contains public static
2011060	2018180	fields of a given type, which contains a method that we can use to instantiate arbitrary types.
2018180	2024160	To find them, we use CodeQL, which is a language that you can use to query your source code in the
2024160	2031360	same way that you use, for example, SQL to query a database. And what we wrote was this query that
2031360	2036260	basically says, okay, find me all the public static fields which are of a given type that
2036260	2042160	can instantiate arbitrary types. We run this query on FreeMarker source code, and we found
2042160	2049260	four different results. Those are four different fields of different types, but all those types
2049260	2056040	extend from the bins wrapper type, which contains a new instance method, which we can use to
2056040	2063840	instantiate arbitrary types. Now, this is the universal remote code execution bypass for
2063840	2068980	FreeMarker. Basically, we need to get us access to any type of class loader from either the
2068980	2076700	protection domain, separate context, and then load the object wrapper interface and get the default
2076700	2082920	wrapper field from this interface. And then we can use that to instantiate arbitrary classes.
2082920	2088440	Since we want to have this payload basically contained in FreeMarker classes, we are using
2088440	2093680	the execute class in order to run arbitrary system commands. But you can use other payloads,
2093680	2100220	to get arbitrary code execution. This was fixed in version 2.30 of FreeMarker.
2101280	2106520	And also, if you get access to the Spring Bins, and you can get access to the FreeMarker
2106520	2110580	configuration, as we saw in some of the content management systems that we analyzed,
2110580	2115740	you can basically disable the sandbox. For example, you can get the class resolver for
2115740	2120960	the default configuration that is non-sandboxed, and then set that class resolver as the class
2120960	2126000	resolver for the current and sandboxed configuration. So effectively disabling
2126000	2133520	the sandbox and being able to execute the old payload from JamesKettle once again.
2133900	2138740	So now we will be reviewing eight different ways to escape the sandbox
2138740	2144460	and get remote code execution in LiveArray. So let's see
2147560	2152080	our LiveArray instance here. And what we will be doing is basically
2154360	2163650	using this template. And here, what we are going to do basically is, first of all, we are going to
2163650	2170970	use the class loader payload, which will allow us to read the password file using the URL trick
2170970	2176050	that we explained before. Then, because the instance of the class loader is a web application
2176050	2182010	class loader, we will be using that class loader to upload a web cell by using the write method.
2182790	2190270	This will be available in the shell JSP file. Then we will be also using the web application
2190270	2196950	class loader to get access to an instance manager and then instantiate arbitrary classes. In this
2196950	2203010	case, we are instantiating an expression language processor and then running the ID process.
2203010	2209570	Then we will be also showing a different payload that depends on using an instance manager. This
2209570	2215410	time is taken from the self-led context. And again, we are using the EL processor to run the ID
2215410	2221230	command. And then we will be using a JSON deserializer as an instance manager in the sense
2221230	2228230	that we will be using that to instantiate arbitrary types. We will be getting access to the
2228230	2233730	JSON deserializer from the Spring application context. And because this JSON deserializer uses
2234110	2239890	a while list and allow list here, we need to register or we can actually register any arbitrary
2239890	2248990	types for us to use in the JSON payload. So, now by deserializing this JSON payload,
2248990	2255490	we are effectively instantiating an EL processor and then again running the ID command.
2255490	2261410	Same thing, but instead of getting the JSON deserializer from the Spring context,
2262110	2268610	LiveRay directly exposed this JSON factory util, which we can use to create a JSON deserializer
2268610	2273730	and then once again use that to instantiate arbitrary types. And then we will see the two
2273730	2280370	free market specific bypasses that we explained a few minutes ago. The first one is using the URL
2280370	2286490	class loader that is the case here because LiveRay is deployed on Tomcat. And then we can
2287010	2292850	basically access our own jar file, load it, and then by getting a public static field,
2292850	2298410	the class will be initialized and the payload will be executed. And we will be able to check
2298410	2305710	the output of this payload by checking the standard output. And the last payload that worked
2305710	2312450	in LiveRay, actually there's a couple more, but eight was more than enough,
2312450	2319430	is this universal RC. So we are loading the object wrapper interface, loading the default
2319430	2323770	wrapper field, and then using that field to instantiate arbitrary types, in this case
2323770	2330610	the execute type that we will be using to run the ID. So now if we save this template and
2331910	2339590	we will be showing the results of these payloads. The first one was reading the password file,
2339590	2345390	the second one was deploying a web cell that we can now access and run arbitrary commands.
2345550	2351590	The third one was using different methods to run the ID command, as you can see here,
2351590	2359170	all of them worked. So also the URL class loader was basically running the static initializer
2359170	2364870	block of this class, which is basically printing pound in the standard output console. We can
2364870	2373230	check that. And here it is, so it worked. And back to the payloads, the universal RC
2373230	2378910	payload also worked, as we can see here. So switching to the Velocity Sandbox,
2378910	2383890	this one is based on a class and package-based block list. So things like, for example,
2383890	2389730	the whole Java lang reflect package is forbidden and you can get access to it.
2389790	2395650	All the methods in Java lang class and class loader are also blocked and you cannot use them.
2395650	2401650	But when we reviewed the implementation, we found that there is a flaw in the way that
2401650	2407770	this sandbox is checking the block list. So, for example, when you run the request
2407770	2413050	and then you get access to a class loader and run the load class method,
2413050	2419290	basically the execution of this method will be checked against the block list.
2419290	2424670	And the class name of the current class loader will be checked against the block list.
2424670	2431370	Instead of checking the whole hierarchy of classes, only the current object class will
2431370	2435870	be checked against the block list, which means that because Java lang class loader is an abstract
2435870	2442690	class, it won't never be the case that the current object class will be a Java lang class loader.
2442690	2447110	In this case, it's a parallel web app class loader, which is not present in the block list,
2447110	2451150	and therefore class loader methods are effectively allowed.
2451330	2458230	There is a feature in Velocity, which allows you to invoke a static method from a Java lang
2458230	2464250	class object. So once that we are able to load a class, we can just invoke any static method and
2464250	2471130	use that to get remote code execution easily. So now moving to GeneJava sandbox. This one is
2471130	2477270	based on a method block list. This is actually very short, only nine methods.
2477330	2483190	And what it contains is a piece of code that is pretty effective in protecting the sandbox.
2483190	2488350	So every time that method invocation happens as part of the evaluation of the template,
2488350	2492590	the result type will be checked. And if it's an instance of a Java lang class,
2492590	2498690	then it will throw an exception and it will refuse to return a Java lang class instance.
2498690	2504630	By not being able to get in access to arbitrary classes, we are normally not able to get
2505290	2512130	or to be able to instantiate arbitrary types. However, we found a flaw. As you can see here,
2512130	2518190	the invocation of a class cannot return a Java lang class instance, but it can return an array
2518190	2523790	of Java lang classes or a map including Java lang classes. So what we can do is find a method
2523790	2528990	returning an array of classes and then accessing any arbitrary item of this array.
2529550	2536850	So the second part of this bypass was basically being able to access a secret or hidden variable
2536850	2544810	in the context that is called __interpreter in lit speech. So by using this hidden variable,
2544810	2550570	we were able to access a bunch of different objects, including all the context objects.
2550570	2557150	And we were able to use those two parts to get an instance of a class loader.
2557150	2561710	So as you can see here, we use the interpreter to get the context. And from the context,
2561710	2566990	we got all the functions. And from the functions, we got the underlying methods,
2566990	2573410	which are instances of Java lang reflect method. And this class contains this get parameter types
2573410	2581010	method, which returns an array of Java lang classes. So as I explained before,
2581010	2588750	we are able to get an instance of any individual item of this array. And by doing that, we are
2588750	2594110	finally getting an instance of a Java lang class. From there, we can get the protection domain,
2594110	2599150	get the class loader, and then initiate any class loader-based attack.
2599850	2604930	So last, Pebbles and Box, we were able to find a couple of bypasses that we reported
2604930	2610230	to the maintainers. Unfortunately, they didn't have time to fix them on time. So we decided
2610230	2617010	not to leak these bypasses yet. And we are keeping them classified for a few months.
2617890	2624230	So with that, we will switch back to Alexander, who will wrap up the talk with some conclusions.
2624230	2629230	Thank you, Arvara. First of all, let's summarize our results after this research.
2629230	2633630	More than 30 new vulnerabilities were found and reported to the vendor.
2633630	2639690	More than 20 different products are affected. We can see their names on this slide. Based on
2639690	2646670	these results, we can make the next conclusions. These are not the problems of specific product
2646670	2653370	or framework. And content management system as a class should be on Red Team radar. Templates for
2653370	2659150	dynamic content that can be managed by user is the main target for such system. There are specific
2659150	2665050	areas with higher risk from security point of view. It's a good idea to perform security review and
2665050	2672930	testing for such places. Always try to reduce attack surface as much as you can. And stay safe!
