diff --git a/convert/Export-Raw-Selection/Export-Raw-Selection.json b/convert/Export-Raw-Selection/Export-Raw-Selection.json new file mode 100644 index 0000000..6dd83f6 --- /dev/null +++ b/convert/Export-Raw-Selection/Export-Raw-Selection.json @@ -0,0 +1,106 @@ +{ + "description": "Exports raw content to a file with original format", + "edition": 2, + "graph": { + "edges": [ + { + "source": { + "exec_alias": "exec", + "node_id": 0 + }, + "target": { + "exec_alias": "exec", + "node_id": 2 + } + }, + { + "source": { + "exec_alias": "exec", + "node_id": 2 + }, + "target": { + "exec_alias": "exec", + "node_id": 1 + } + } + ], + "nodes": [ + { + "alias": "convert_start", + "definition_id": "caido/convert-start", + "display": { + "x": -10, + "y": -100 + }, + "id": 0, + "inputs": [], + "name": "Convert Start", + "version": "0.1.0" + }, + { + "alias": "convert_end", + "definition_id": "caido/convert-end", + "display": { + "x": -20, + "y": 190 + }, + "id": 1, + "inputs": [ + { + "alias": "data", + "value": { + "data": "$shell.data", + "kind": "ref" + } + } + ], + "name": "Convert End", + "version": "0.1.0" + }, + { + "alias": "shell", + "definition_id": "caido/shell-cmd", + "display": { + "x": -20, + "y": 10 + }, + "id": 2, + "inputs": [ + { + "alias": "shell", + "value": { + "data": "bash", + "kind": "string" + } + }, + { + "alias": "code", + "value": { + "data": "# Create exports directory\nexport_dir=\"$HOME/caido_exports\"\nmkdir -p \"$export_dir\"\n\n# Create temp file first to analyze content\ntmp_file=$(mktemp)\ntrap 'rm -f \"$tmp_file\"' EXIT\n\n# Save input to temp file first\ncat - > \"$tmp_file\"\n\n# Get file info\nfile_info=$(/usr/bin/file -b \"$tmp_file\")\n\n# Generate readable timestamp (Dec-20-2024_15-30-45)\ntimestamp=$(date \"+%b-%d-%Y_%H-%M-%S\")\n\n# Set output filename - always .bin for unrecognized types\noutput_file=\"$export_dir/raw_${timestamp}.bin\"\n\n# Copy from temp file to final location\ncp \"$tmp_file\" \"$output_file\"\n\n# Get file size\nfile_size=$(stat -f%z \"$output_file\" 2>/dev/null || stat -c%s \"$output_file\")\n\n# Output results\necho \"File exported successfully:\"\necho \"Location: $output_file\"\necho \"Size: $file_size bytes\"\necho \"Type: $file_info\"\n", + "kind": "string" + } + }, + { + "alias": "timeout", + "value": { + "data": 5000, + "kind": "integer" + } + }, + { + "alias": "data", + "value": { + "data": "$convert_start.data", + "kind": "ref" + } + } + ], + "name": "Shell", + "version": "0.1.0" + } + ] + }, + "kind": "convert", + "name": "Export Raw Content", + "id": "export-raw-content" +} diff --git a/convert/Export-Raw-Selection/README.md b/convert/Export-Raw-Selection/README.md new file mode 100644 index 0000000..bf56bd7 --- /dev/null +++ b/convert/Export-Raw-Selection/README.md @@ -0,0 +1,6 @@ + +# Deserialize MessagePack to json + +Author: craftysecurity + +Workflow to export selected content to a file in raw format, useful for raw formats that cannot be copy pasted. diff --git a/convert/GZIP Compress/GZIP Compress.json b/convert/GZIP Compress/GZIP Compress.json new file mode 100644 index 0000000..4cf0767 --- /dev/null +++ b/convert/GZIP Compress/GZIP Compress.json @@ -0,0 +1,225 @@ +{ + + "description": "Compresses data using GZIP", + + "edition": 2, + + "graph": { + + "edges": [ + + { + + "source": { + + "exec_alias": "exec", + + "node_id": 0 + + }, + + "target": { + + "exec_alias": "exec", + + "node_id": 2 + + } + + }, + + { + + "source": { + + "exec_alias": "exec", + + "node_id": 2 + + }, + + "target": { + + "exec_alias": "exec", + + "node_id": 1 + + } + + } + + ], + + "nodes": [ + + { + + "alias": "convert_start", + + "definition_id": "caido/convert-start", + + "display": { + + "x": -10, + + "y": -100 + + }, + + "id": 0, + + "inputs": [], + + "name": "Convert Start", + + "version": "0.1.0" + + }, + + { + + "alias": "convert_end", + + "definition_id": "caido/convert-end", + + "display": { + + "x": -20, + + "y": 190 + + }, + + "id": 1, + + "inputs": [ + + { + + "alias": "data", + + "value": { + + "data": "$shell.data", + + "kind": "ref" + + } + + } + + ], + + "name": "Convert End", + + "version": "0.1.0" + + }, + + { + + "alias": "shell", + + "definition_id": "caido/shell-cmd", + + "display": { + + "x": -20, + + "y": 10 + + }, + + "id": 2, + + "inputs": [ + + { + + "alias": "shell", + + "value": { + + "data": "bash", + + "kind": "string" + + } + + }, + + { + + "alias": "code", + + "value": { + + "data": "# Create temp file\ntmp_file=$(mktemp)\ntmp_out=$(mktemp)\ndebug_info=\"\"\ntrap 'rm -f \"$tmp_file\" \"$tmp_out\"' EXIT\n\n# Save input to file\ncat - > \"$tmp_file\"\n\n# Try Python's gzip module with configurable compression\npython3 - \"$tmp_file\" <<'EOF'\nimport sys\nimport gzip\nfrom io import BytesIO\n\ntry:\n with open(sys.argv[1], 'rb') as f:\n data = f.read()\n \n # Compress with highest speed setting\n compressed = gzip.compress(data, compresslevel=1)\n sys.stdout.buffer.write(compressed)\n sys.exit(0)\n\nexcept Exception as e:\n print(f\"Error during compression: {e}\", file=sys.stderr)\n sys.exit(1)\nEOF\n\n# If Python script failed, try gzip command\nif [ $? -ne 0 ]; then\n if gzip -c -1 \"$tmp_file\" > \"$tmp_out\" 2>/dev/null; then\n cat \"$tmp_out\"\n exit 0\n else\n echo \"Failed to compress data\"\n exit 1\n fi\nfi\n", + + "kind": "string" + + } + + }, + + { + + "alias": "init", + + "value": { + + "data": "", + + "kind": "string" + + } + + }, + + { + + "alias": "timeout", + + "value": { + + "data": 5000, + + "kind": "integer" + + } + + }, + + { + + "alias": "data", + + "value": { + + "data": "$convert_start.data", + + "kind": "ref" + + } + + } + + ], + + "name": "Shell", + + "version": "0.1.0" + + } + + ] + + }, + + "id": "gzip-compress-workflow", + + "kind": "convert", + + "name": "GZIP Compress" + +} diff --git a/convert/GZIP Compress/README.md b/convert/GZIP Compress/README.md new file mode 100644 index 0000000..cd231d2 --- /dev/null +++ b/convert/GZIP Compress/README.md @@ -0,0 +1,11 @@ +# Compress to GZIP + +Author: craftysecurity + +Workflow to compress data to gzip for linux using shell and pyton. + +### Requirements +pip3 install gzip + +# Important +The gzip data format cannot be reliably copy and pasted as it contains non-printable characters and binary data that text editors and clipboards do not support properly. You should use 'replace' feature instead so the binary data is directly placed into caido intact. diff --git a/convert/GZIP Decompress/GZIP Decompress.json b/convert/GZIP Decompress/GZIP Decompress.json new file mode 100644 index 0000000..7a944e0 --- /dev/null +++ b/convert/GZIP Decompress/GZIP Decompress.json @@ -0,0 +1,225 @@ +{ + + "description": "Decompresses GZIP encoded data using Python's gzip module", + + "edition": 2, + + "graph": { + + "edges": [ + + { + + "source": { + + "exec_alias": "exec", + + "node_id": 0 + + }, + + "target": { + + "exec_alias": "exec", + + "node_id": 2 + + } + + }, + + { + + "source": { + + "exec_alias": "exec", + + "node_id": 2 + + }, + + "target": { + + "exec_alias": "exec", + + "node_id": 1 + + } + + } + + ], + + "nodes": [ + + { + + "alias": "convert_start", + + "definition_id": "caido/convert-start", + + "display": { + + "x": -10, + + "y": -100 + + }, + + "id": 0, + + "inputs": [], + + "name": "Convert Start", + + "version": "0.1.0" + + }, + + { + + "alias": "convert_end", + + "definition_id": "caido/convert-end", + + "display": { + + "x": -20, + + "y": 190 + + }, + + "id": 1, + + "inputs": [ + + { + + "alias": "data", + + "value": { + + "data": "$shell.data", + + "kind": "ref" + + } + + } + + ], + + "name": "Convert End", + + "version": "0.1.0" + + }, + + { + + "alias": "shell", + + "definition_id": "caido/shell-cmd", + + "display": { + + "x": -20, + + "y": 10 + + }, + + "id": 2, + + "inputs": [ + + { + + "alias": "shell", + + "value": { + + "data": "bash", + + "kind": "string" + + } + + }, + + { + + "alias": "code", + + "value": { + + "data": "# Create temp file\ntmp_file=$(mktemp)\ndebug_info=\"\"\ntrap 'rm -f \"$tmp_file\"' EXIT\n\n# Save input to file\ncat - > \"$tmp_file\"\n\n# Get file info\ndebug_info+=\"=== Debug Info ===\\n\"\ndebug_info+=\"Input type: $(/usr/bin/file -b \"$tmp_file\")\\n\"\ndebug_info+=\"Size: $(wc -c < \"$tmp_file\") bytes\\n\"\ndebug_info+=\"First bytes: $(xxd -p -l 16 \"$tmp_file\")\\n\"\n\n# Try Python's gzip module with error handling\npython3 - \"$tmp_file\" <<'EOF'\nimport sys\nimport gzip\nfrom io import BytesIO\n\ntry:\n with open(sys.argv[1], 'rb') as f:\n data = f.read()\n \n # Try direct decompression first\n try:\n with gzip.open(BytesIO(data), 'rb') as gz:\n result = gz.read()\n sys.stdout.buffer.write(result)\n sys.exit(0)\n except Exception as e:\n print(f\"Standard decompression failed: {e}\", file=sys.stderr)\n\n # Try with wbits=-15 for raw deflate\n try:\n import zlib\n decomp = zlib.decompressobj(-zlib.MAX_WBITS)\n result = decomp.decompress(data[10:]) # Skip gzip header\n sys.stdout.buffer.write(result)\n sys.exit(0)\n except Exception as e:\n print(f\"Raw deflate failed: {e}\", file=sys.stderr)\n\n print(\"All decompression attempts failed\", file=sys.stderr)\n sys.exit(1)\nexcept Exception as e:\n print(f\"Error: {e}\", file=sys.stderr)\n sys.exit(1)\nEOF\n\n# If Python script failed, show debug info and error\nif [ $? -ne 0 ]; then\n echo \"$debug_info\"\n echo \"Failed to decompress data\"\nfi\n", + + "kind": "string" + + } + + }, + + { + + "alias": "init", + + "value": { + + "data": "", + + "kind": "string" + + } + + }, + + { + + "alias": "timeout", + + "value": { + + "data": 5000, + + "kind": "integer" + + } + + }, + + { + + "alias": "data", + + "value": { + + "data": "$convert_start.data", + + "kind": "ref" + + } + + } + + ], + + "name": "Shell", + + "version": "0.1.0" + + } + + ] + + }, + + "id": "gzip-decompress-workflow", + + "kind": "convert", + + "name": "GZIP Decompress" + +} diff --git a/convert/GZIP Decompress/README.md b/convert/GZIP Decompress/README.md new file mode 100644 index 0000000..76f36d1 --- /dev/null +++ b/convert/GZIP Decompress/README.md @@ -0,0 +1,8 @@ +# Decompress GZIP data + +Author: craftysecurity + +Workflow to Decompress GZIP data for linux using shell and pyton. + +### Requirements +pip3 install gzip diff --git a/convert/JSON to MsgPack/JSON to MsgPack.json b/convert/JSON to MsgPack/JSON to MsgPack.json new file mode 100644 index 0000000..b4e6ba5 --- /dev/null +++ b/convert/JSON to MsgPack/JSON to MsgPack.json @@ -0,0 +1,183 @@ +{ + + "description": "Serializes JSON to MessagePack data", + + "edition": 2, + + "graph": { + + "edges": [ + + { + + "source": { + + "exec_alias": "exec", + + "node_id": 0 + + }, + + "target": { + + "exec_alias": "exec", + + "node_id": 2 + + } + + }, + + { + + "source": { + + "exec_alias": "exec", + + "node_id": 2 + + }, + + "target": { + + "exec_alias": "exec", + + "node_id": 1 + + } + + } + + ], + + "nodes": [ + + { + + "alias": "convert_start", + + "definition_id": "caido/convert-start", + + "display": { + + "x": 0, + + "y": 0 + + }, + + "id": 0, + + "inputs": [], + + "name": "Convert Start", + + "version": "0.1.0" + + }, + + { + + "alias": "convert_end", + + "definition_id": "caido/convert-end", + + "display": { + + "x": -20, + + "y": 200 + + }, + + "id": 1, + + "inputs": [ + + { + + "alias": "data", + + "value": { + + "data": "$javascript.data", + + "kind": "ref" + + } + + } + + ], + + "name": "Convert End", + + "version": "0.1.0" + + }, + + { + + "alias": "javascript", + + "definition_id": "caido/code-js", + + "display": { + + "x": -10, + + "y": 100 + + }, + + "id": 2, + + "inputs": [ + + { + + "alias": "data", + + "value": { + + "data": "$convert_start.data", + + "kind": "ref" + + } + + }, + + { + + "alias": "code", + + "value": { + + "data": "export function run(input, sdk) {\n let bytes = [];\n \n function writeUInt8(value) {\n bytes.push(value & 0xff);\n }\n\n function writeUInt16(value) {\n bytes.push((value >>> 8) & 0xff);\n bytes.push(value & 0xff);\n }\n\n function writeUInt32(value) {\n bytes.push((value >>> 24) & 0xff);\n bytes.push((value >>> 16) & 0xff);\n bytes.push((value >>> 8) & 0xff);\n bytes.push(value & 0xff);\n }\n\n function writeString(str) {\n const utf8Array = Array.from(str).map(char => char.charCodeAt(0));\n \n if (utf8Array.length <= 31) {\n // fixstr\n writeUInt8(0xa0 | utf8Array.length);\n } else if (utf8Array.length <= 255) {\n // str 8\n writeUInt8(0xd9);\n writeUInt8(utf8Array.length);\n } else if (utf8Array.length <= 65535) {\n // str 16\n writeUInt8(0xda);\n writeUInt16(utf8Array.length);\n } else {\n // str 32\n writeUInt8(0xdb);\n writeUInt32(utf8Array.length);\n }\n \n bytes.push(...utf8Array);\n }\n\n function writeNumber(num) {\n if (Number.isInteger(num)) {\n if (num >= 0) {\n if (num < 128) {\n // positive fixint\n writeUInt8(num);\n } else if (num <= 255) {\n // uint 8\n writeUInt8(0xcc);\n writeUInt8(num);\n } else if (num <= 65535) {\n // uint 16\n writeUInt8(0xcd);\n writeUInt16(num);\n } else if (num <= 4294967295) {\n // uint 32\n writeUInt8(0xce);\n writeUInt32(num);\n }\n } else {\n if (num >= -32) {\n // negative fixint\n writeUInt8(0xe0 | (num + 32));\n } else if (num >= -128) {\n // int 8\n writeUInt8(0xd0);\n writeUInt8(num & 0xff);\n } else if (num >= -32768) {\n // int 16\n writeUInt8(0xd1);\n writeUInt16(num & 0xffff);\n } else if (num >= -2147483648) {\n // int 32\n writeUInt8(0xd2);\n writeUInt32(num & 0xffffffff);\n }\n }\n } else {\n // For now, treat all non-integers as 32-bit floats\n // Could be extended to support doubles if needed\n writeUInt8(0xca);\n const buffer = new ArrayBuffer(4);\n new Float32Array(buffer)[0] = num;\n const view = new Uint8Array(buffer);\n bytes.push(...Array.from(view));\n }\n }\n\n function writeArray(arr) {\n if (arr.length <= 15) {\n // fixarray\n writeUInt8(0x90 | arr.length);\n } else if (arr.length <= 65535) {\n // array 16\n writeUInt8(0xdc);\n writeUInt16(arr.length);\n } else {\n // array 32\n writeUInt8(0xdd);\n writeUInt32(arr.length);\n }\n \n for (const item of arr) {\n encode(item);\n }\n }\n\n function writeMap(obj) {\n const keys = Object.keys(obj);\n \n if (keys.length <= 15) {\n // fixmap\n writeUInt8(0x80 | keys.length);\n } else if (keys.length <= 65535) {\n // map 16\n writeUInt8(0xde);\n writeUInt16(keys.length);\n } else {\n // map 32\n writeUInt8(0xdf);\n writeUInt32(keys.length);\n }\n \n for (const key of keys) {\n encode(key);\n encode(obj[key]);\n }\n }\n\n function encode(value) {\n switch (typeof value) {\n case 'string':\n writeString(value);\n break;\n \n case 'number':\n writeNumber(value);\n break;\n \n case 'boolean':\n writeUInt8(value ? 0xc3 : 0xc2);\n break;\n \n case 'object':\n if (value === null) {\n writeUInt8(0xc0);\n } else if (Array.isArray(value)) {\n writeArray(value);\n } else {\n writeMap(value);\n }\n break;\n \n default:\n throw new Error(`Unsupported type: ${typeof value}`);\n }\n }\n\n try {\n // Parse input JSON if it's a string\n const jsonData = typeof input === 'string' ? \n JSON.parse(input) : \n JSON.parse(sdk.asString(input));\n\n // Encode to MessagePack\n encode(jsonData);\n\n // Return the MessagePack bytes\n return new Uint8Array(bytes);\n } catch (error) {\n return `Error encoding MessagePack: ${error.message}`;\n }\n}\n", + + "kind": "string" + + } + + } + + ], + + "name": "Javascript", + + "version": "0.1.0" + + } + + ] + + }, + + "id": "serialize-JSON-to-msgpack-workflow", + + "kind": "convert", + + "name": "JSON to MsgPack" + +} diff --git a/convert/JSON to MsgPack/README.md b/convert/JSON to MsgPack/README.md new file mode 100644 index 0000000..be4cde0 --- /dev/null +++ b/convert/JSON to MsgPack/README.md @@ -0,0 +1,8 @@ +# Serialize JSON to MessagePack data + +Author: craftysecurity + +Workflow to serialize JSON to MessagePack data. + +## IMPORTANT +The MessagePack binary format cannot be reliably copy and pasted as it contains non-printable characters and binary data that text editors and clipboards do not support properly. You should use 'replace' feature instead so the binary data is directly placed into caido intact. diff --git a/convert/MsgPack to JSON/MsgPack to JSON.json b/convert/MsgPack to JSON/MsgPack to JSON.json new file mode 100644 index 0000000..dce582f --- /dev/null +++ b/convert/MsgPack to JSON/MsgPack to JSON.json @@ -0,0 +1,183 @@ +{ + + "description": "Deserializes MessagePack data to JSON with support for extended types", + + "edition": 2, + + "graph": { + + "edges": [ + + { + + "source": { + + "exec_alias": "exec", + + "node_id": 0 + + }, + + "target": { + + "exec_alias": "exec", + + "node_id": 2 + + } + + }, + + { + + "source": { + + "exec_alias": "exec", + + "node_id": 2 + + }, + + "target": { + + "exec_alias": "exec", + + "node_id": 1 + + } + + } + + ], + + "nodes": [ + + { + + "alias": "convert_start", + + "definition_id": "caido/convert-start", + + "display": { + + "x": 0, + + "y": 0 + + }, + + "id": 0, + + "inputs": [], + + "name": "Convert Start", + + "version": "0.1.0" + + }, + + { + + "alias": "convert_end", + + "definition_id": "caido/convert-end", + + "display": { + + "x": -20, + + "y": 200 + + }, + + "id": 1, + + "inputs": [ + + { + + "alias": "data", + + "value": { + + "data": "$javascript.data", + + "kind": "ref" + + } + + } + + ], + + "name": "Convert End", + + "version": "0.1.0" + + }, + + { + + "alias": "javascript", + + "definition_id": "caido/code-js", + + "display": { + + "x": -10, + + "y": 100 + + }, + + "id": 2, + + "inputs": [ + + { + + "alias": "data", + + "value": { + + "data": "$convert_start.data", + + "kind": "ref" + + } + + }, + + { + + "alias": "code", + + "value": { + + "data": "export function run(input, sdk) {\n const data = new Uint8Array(input);\n let pos = 0;\n\n function readUInt8() {\n return data[pos++];\n }\n\n function readUInt16() {\n return (data[pos++] << 8) | data[pos++];\n }\n\n function readUInt32() {\n return (data[pos++] << 24) | (data[pos++] << 16) | \n (data[pos++] << 8) | data[pos++];\n }\n\n function readInt8() {\n const value = readUInt8();\n return value & 0x80 ? value - 0x100 : value;\n }\n\n function readInt16() {\n const value = readUInt16();\n return value & 0x8000 ? value - 0x10000 : value;\n }\n\n function readInt32() {\n const value = readUInt32();\n return value >>> 0;\n }\n\n function readStr(len) {\n const str = String.fromCharCode.apply(null, data.slice(pos, pos + len));\n pos += len;\n return str;\n }\n\n function readBin(len) {\n const bytes = data.slice(pos, pos + len);\n pos += len;\n return Array.from(bytes);\n }\n\n function readMap(len) {\n const result = {};\n for (let i = 0; i < len; i++) {\n const key = decode();\n result[key] = decode();\n }\n return result;\n }\n\n function readArray(len) {\n const result = new Array(len);\n for (let i = 0; i < len; i++) {\n result[i] = decode();\n }\n return result;\n }\n\n function decode() {\n const byte = readUInt8();\n \n // positive fixint (0xxxxxxx)\n if ((byte & 0x80) === 0) {\n return byte;\n }\n \n // fixmap (1000xxxx)\n if ((byte & 0xf0) === 0x80) {\n return readMap(byte & 0x0f);\n }\n \n // fixarray (1001xxxx)\n if ((byte & 0xf0) === 0x90) {\n return readArray(byte & 0x0f);\n }\n \n // fixstr (101xxxxx)\n if ((byte & 0xe0) === 0xa0) {\n return readStr(byte & 0x1f);\n }\n \n // negative fixint (111xxxxx)\n if ((byte & 0xe0) === 0xe0) {\n return byte - 0x100;\n }\n\n switch (byte) {\n case 0xc0: return null;\n case 0xc2: return false;\n case 0xc3: return true;\n \n case 0xcc: return readUInt8(); // uint 8\n case 0xcd: return readUInt16(); // uint 16\n case 0xce: return readUInt32(); // uint 32\n \n case 0xd0: return readInt8(); // int 8\n case 0xd1: return readInt16(); // int 16\n case 0xd2: return readInt32(); // int 32\n \n case 0xd9: return readStr(readUInt8()); // str 8\n case 0xda: return readStr(readUInt16()); // str 16\n case 0xdb: return readStr(readUInt32()); // str 32\n \n case 0xc4: return readBin(readUInt8()); // bin 8\n case 0xc5: return readBin(readUInt16()); // bin 16\n case 0xc6: return readBin(readUInt32()); // bin 32\n \n case 0xdc: return readArray(readUInt16()); // array 16\n case 0xdd: return readArray(readUInt32()); // array 32\n \n case 0xde: return readMap(readUInt16()); // map 16\n case 0xdf: return readMap(readUInt32()); // map 32\n }\n\n throw new Error(`Unknown type byte: 0x${byte.toString(16)} at position ${pos-1}`);\n }\n\n try {\n const result = decode();\n return JSON.stringify(result, null, 2);\n } catch (error) {\n return JSON.stringify({\n error: error.message,\n position: pos,\n bytesNearError: Array.from(data.slice(Math.max(0, pos - 8), pos + 8)).map(b => '0x' + b.toString(16)),\n totalLength: data.length\n }, null, 2);\n }\n}\n", + + "kind": "string" + + } + + } + + ], + + "name": "Javascript", + + "version": "0.1.0" + + } + + ] + + }, + + "id": "msgpack-deserialize-json-workflow", + + "kind": "convert", + + "name": "MsgPack to JSON" + +} diff --git a/convert/MsgPack to JSON/README.md b/convert/MsgPack to JSON/README.md new file mode 100644 index 0000000..25c823d --- /dev/null +++ b/convert/MsgPack to JSON/README.md @@ -0,0 +1,5 @@ +# Deserialize MessagePack to json + +Author: craftysecurity + +Workflow to deserialize MessagePack data to JSON.