We found out that it was possible to insert Javascript code in the calculator. Oops! We found an awesome module to prevent against this abuse. Hopefully it is all better now. The flag is in flag.txt.
Visit https://19.adventofctf.com to start the challenge.
## Recon
Upon opening the challenge website, we're greeted with an input field which asks us to "enter the nr of days until christmas".
When opening the source of the page we also find some javascript code:
```js
function send() {
let calc = $("#calc")[0].value;
if (calc.length > 0) {
$.ajax({
url: "/calc",
type: "POST",
data: '{"calc": "' + calc + '" }',
contentType: "application/json; charset=utf-8",
dataType: "json",
}).always(function (data) {
text = data;
if (data.responseText) {
text = data.responseText;
}
$("#msg")[0].innerHTML = "<b>" + text + "</b>";
});
}
}
```
As the description tells us it's a calculator, let's try entering `3+4` in the input field. It will make a `POST` request to `/calc`, which will return `7`.
The description also states it was possible to enter javascript code, which we saw in the [previous challenge]({{% ref "posts/adventofctf/challenge_18.md" %}}), but that it has been fixed now.
## Finding the vulnerability
To verify what the description says, let's try to enter `res` in the input field. Sadly, it looks like it actually has been fixed as we now get the following error:
```text
evalmachine.<anonymous>:11
SAFE_EVAL_521493=res
^
ReferenceError: res is not defined
at evalmachine.<anonymous>:11:3
at Script.runInContext (vm.js:133:20)
at Script.runInNewContext (vm.js:139:17)
at Object.runInNewContext (vm.js:322:38)
at safeEval (/opt/app/node_modules/safe-eval/index.js:24:6)
at /opt/app/server.js:13:11
at Layer.handle [as handle_request] (/opt/app/node_modules/express/lib/router/layer.js:95:5)
at next (/opt/app/node_modules/express/lib/router/route.js:137:13)
at /opt/app/node_modules/body-parser/lib/read.js:130:5
at invokeCallback (/opt/app/node_modules/raw-body/index.js:224:16)
```
When looking at this output, we can see that it uses the `safe-eval` module to evaluate the input.
I personally don't know this module so let's Google around a bit. Eventually, I found [this Github Issue](https://github.com/hacksparrow/safe-eval/issues/16#issuecomment-554301596) which talks about safe-eval not being so safe. Exactly what we need.
When scrolling down on the issue, we can see a comment with the following code:
_Note: Sorry this code is not highlighted. If I do so, my formatter will mess it up..._
The comment has no further text in it so let's try entering the code. Don't forget to replace the double quotes (`"`) with single ones (`'`) though as, otherwise, the JSON will no longer be valid.
After making the request, the server returns the following string: `[object process]`. This means the code worked, and we can build an exploit on it.
## Exploit
Because we now have the `process` object, we can use it to require modules and execute code.
To read the directory contents of the sever, we can use the following code:
_Note: Again, not formatted as my formatter will replace the single quotes with double ones._
In this code, I used the `process` to get the `require` function. I did this so I could get access to the `fs` module to read the directory contents. This, in turn, is all wrapped by a [self-executing anonymous function](https://developer.mozilla.org/en-US/docs/Glossary/Self-Executing_Anonymous_Function) so I could use variables to make it easier.