Hey, today I’ll talk about security and more specifically pentest once again. I feel lucky these days because I feel I learn new things every weeks at least. Today I’ll talk about server-side JavaScript but not on MongoDB, rather I’ll speak about GatewayScript, which is a proprietary language by IBM.
GatewayScript
GatewayScript is used mainly on Datapower Gateway, which is a “purpose-built security and integration platform for mobile, web, API, SOA, B2B and cloud”. Basically, GS is a fork of Server-Side JavaScript (and I think Node) with some modifications. For example, the file system is not accessed entirely but rather by using shortcuts such as “temporary://” or “local://”, which will point to specific folders where it is not possible to get to the root directory.
The process object is not present either in this case, so it was not possible to do a load module using the main process object as we could’ve done in Node.
RCE and ideas
So, I got an RCE in my assessment but I’m not too sure how they implemented it and why I was able to get RCE on GatewayScript. Anyway, I could close a function call then throw an error to get the output I wanted.
?param=');eval(String.fromCharCode(<Code to throw an error>))//
At first I thought it was a nodejs rce and I was pretty excited but touching a new technology, even if capabilities are not the same is exciting in its own right as well. Anyway, to know it was GatewayScript, I tried to require(‘unknown’), googled the error message and the first google result was for IBM GatewayScript.
Accessible objects
So, without using require, there are a few interesting object accessible in the global context. To list them you can do a simple “Object.getOwnPropertyNames(global)”. Inside it, we could see things such as an object for WebAssembly (which could be useful since there were a few WebAssembly jailbreak found these last few months), or things to parse XML for example. What was interesting is that the “apim” object was available, which is an object used when developing an application with “IBM API Connect”, using “apim” you are able to list information about the current context.
Requiring other stuff
So, the first idea I had was to simply get system command execution by using “require(‘child_process’)”, unfortunately it was not available. ‘fs’ which should’ve been available was not either but the most interesting module I had available was “urlopen”, which can open files depending on the specific wrappers I told you earlier (local://, store:// or temporary://) or you could do a SSRF by using (http://) which worked as well.
I was not able to do directory traversal with these techniques to get out of the current folder however.
By checking a little bit through the documentation of NodeJS, I found an interesting message that said that you could theoretically require a module compiled from C++. My idea was to write a file somewhere with that compiled node form then require it using local:// or another wrapper (http didn’t seem to work). Unfortunately I wasn’t able to do it during the assessment since I had only one and a half day on that vulnerability.
Ideas to push
It is only now that I can’t test that I just saw that IBM DataPower is available on docker, so I’ll probably give it a shot to try to get a working exploit. I had other ideas I couldn’t push when I was doing the pentest as well. There are a few XSLT processing functions which could be available that could do SQL requests or write files on the FS in the temporary folder. I’m pretty sure that if I was able to use XSLT, I would’ve been able to write my node module somewhere to load it and get RCE.