solver.py
index.html
There are several steps to achieve RCE:
The first one is to bypass the admin.
Here, because there is a hyphen in the session name on the login route, we can work around it by adding a space at the end or prefixing the word "admin" to gain the same privileges as the admin session.
Since we have become an admin, when we create new content, [IMPORT ALERT]
will be added to every content we create.
With that, we can trigger the code below to gain access to the window with more lenient permissions. challenge/app/index.html
Where CreateViewer
will pop up a window with permissions in the code below:
The permissions sandbox: false
and contextIsolation: false
can be used to influence the context at the preload level, where functions like this.module
are available. We can utilize these functions to achieve Remote Code Execution (RCE).
For more information, you can check the Harmony challenge on HITCON CTF 2023.
https://github.com/maple3142/My-CTF-Challenges/tree/master/HITCON CTF 2023/Harmony#rce-using-client-side-prototype-pollution
We perform sandbox bypass by using the Prototype Pollution technique.
Here, I'm polluting two constructors: the Object constructor and the Function constructor.
Where I use the Function prototype to perform hooking on every call. By doing this hooking, there is an opportunity to obtain an object from another context, where the __webpack_require__
function may be present.
After that, we prototype the Object. So when an object accesses the array key x
, it will trigger the hooking we set up in the defineProperty
within our prototype pollution.
As a result, when we call x
with the __webpack_require__
function, it will be triggered, allowing us to leak the this.module
function.
Bypassing CSP using the meta refresh tag.
Since there is strict CSP when the popup is opened, we cannot execute JavaScript directly. Therefore, we need to bypass it. Here, we can bypass it by adding a ticket with the title <meta http-equiv="refresh" content="0; url=file:///tmp/{ticket}.html">
to redirect to the file we uploaded on the ticket form page. With this, we can execute JavaScript without being hindered by CSP.
Those are the steps required to work on this challenge. For the rest, you can refer to the solve script above to see the execution flow.
After the CTF ended, the author shared their solve script, and I discovered that you can simply import the module using __webpack_require__
to achieve Remote Code Execution (RCE):