# Json2csv (350pts) ![image](https://hackmd.io/_uploads/BkpPVegN6.png) ## Introduction 1. This is a JSON to CSV service, utilizing the nodejs json2csv package (cli version) 2. You can find the source code [here](https://github.com/juanjoDiaz/json2csv/tree/main/packages/cli) 3. Help (`-h`) output (you can run locally / on the chal server): ``` Usage: json2csv [options] Options: -V, --version output the version number -i, --input <input> Path and name of the incoming json file. Defaults to stdin. -o, --output <output> Path and name of the resulting csv file. Defaults to stdout. -c, --config <path> Specify a file with a valid JSON configuration. -n, --ndjson Treat the input as NewLine-Delimited JSON. -s, --no-streaming Process the whole JSON array in memory instead of doing it line by line. -f, --fields <fields> List of fields to process. Defaults to field auto-detection. -v, --default-value <defaultValue> Default value to use for missing fields. -d, --delimiter <delimiter> Character(s) to use as delimiter. Defaults to ','. (default: ",") -e, --eol <eol> Character(s) to use as End-of-Line for separating rows. Defaults to '\n'. (default: "\n") -H, --no-header Disable the column name header. -a, --include-empty-rows Includes empty rows in the resulting CSV output. -b, --with-bom Includes BOM character at the beginning of the CSV. -p, --pretty Print output as a pretty table. Use only when printing to console. -q, --quote <quote> Character(s) to use as quote mark. Defaults to '"'. -Q, --escaped-quote <escapedQuote> Character(s) to use as a escaped quote. Defaults to a double `quote`, '""'. -E, --excel-strings Wraps string data to force Excel to interpret it as string even if it contains a number. --unwind [paths] Creates multiple rows from a single JSON document similar to MongoDB unwind. --unwind-blank When unwinding, blank out instead of repeating data. Defaults to false. (default: false) --flatten-objects Flatten nested objects. Defaults to false. (default: false) --flatten-arrays Flatten nested arrays. Defaults to false. (default: false) --flatten-separator <separator> Flattened keys separator. Defaults to '.'. (default: ".") -h, --help display help for command ``` ## Write-to-anywhere Vulnerability 1. From the help text above, you can observe that we can write the result CSV to anywhere with `-o`. (Subject to permission, of course) 2. We can also define the EOL character and (escaped) quote character. **This means we can use this as a write-to-anywhere on the file system, if we craft a specific JSON-compliant text and remove EOL and quotes from CSV.** ## Write-to-Where? The user account that the nodejs process running is `node`, and the JS code that copied into the docker container is under `root`. This means that we cannot modify existing Node JS file or directories. However, we found out that we can write to `/home/node` and `/opt/yarn-v1.22.19/`, and of course, `/tmp`. So if we can write to these places, how can we achieve RCE? ## RCE 1. From the help text, we can observe that `-s` allows *"process the whole JSON array in memory"*. 2. Cross referencing the source code of `json2csv`: a. In`processInMemory` function (where `-s` is supplied), `getInput` is used to fed to `inputData` ![image](https://hackmd.io/_uploads/rJx5txgV6.png) b. In `getInput`, if a file path is specified and it's not a ndjson (i.e. `-n` not supplied), `getInputJSON` will be called. ![image](https://hackmd.io/_uploads/S13aYllNa.png) c. In `getInputJSON`, `import` is used! This means that not only JSON can be "imported", but also JS contents! ![image](https://hackmd.io/_uploads/SkWo5llNT.png) 3. Now we have a way to execute Node JS code from any file, and we have a write-to-anywhere vulnerability, it is time to exploit and get a shell! ## Pwn The flow to get shell (and get flag) are as follows: 1. Write a valid JSON with Node JS code and convert to CSV to `/tmp`. Remove all newlines and quotes and stuff. `;` is used as EOL and the `"name field"` in json. a. Just use a random node js revshell found online (e.g. [This one](https://medium.com/dont-code-me-on-that/bunch-of-shells-nodejs-cdd6eb740f73)) b. Just to be safe, convert to `base64` c. (Redacted my server IP :P) ![image](https://hackmd.io/_uploads/HJPFhggVa.png) d. `json2csv` cmdline: `-d' ' -e; -q'' -Q'' -o /tmp/nutty5hell_purple.js` e. This will output our shell code to `/tmp/nutty5hell_purple.js` f. Resulting file content: ![image](https://hackmd.io/_uploads/By9_6xg4p.png) 2. Execute this file with the following `json2csv` cmdline, we can just put empty JSON here: `-i /tmp/nutty5hell_purple.js -s` 4. ??? (I forgot to start my revshell listener....lol) 5. Profit? ## Flag ![image](https://hackmd.io/_uploads/r1DuAgx4p.png) ![image](https://hackmd.io/_uploads/rkwqAgeE6.png) **⚠️...AND THIS IS NOT A CORRECT FLAG!!!⚠️** **🔴To the challenge author: Yes I am being trolled and a f'ing joke :(🔴** **Correct flag:** ![image](https://hackmd.io/_uploads/B1s8yblE6.png) `hkcert23{Y_not_ju$tuse_za--N0DE_package?!}`