# 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?!}`