From 1d32a5939c4cd822eb85683c9a180d090bd75923 Mon Sep 17 00:00:00 2001 From: h345983745 Date: Mon, 19 Aug 2019 20:14:22 +0100 Subject: [PATCH 1/4] Core UDP parsing functionality Added to categorie Description Added Tests Added tests --- src/core/config/Categories.json | 1 + src/core/operations/ParseUDP.mjs | 92 +++++++++++++++++++++++++++++ tests/operations/index.mjs | 1 + tests/operations/tests/ParseUDP.mjs | 68 +++++++++++++++++++++ 4 files changed, 162 insertions(+) create mode 100644 src/core/operations/ParseUDP.mjs create mode 100644 tests/operations/tests/ParseUDP.mjs diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index f1a7b815..89b93b87 100755 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -167,6 +167,7 @@ "Parse IP range", "Parse IPv6 address", "Parse IPv4 header", + "Parse UDP", "Parse SSH Host Key", "Parse URI", "URL Encode", diff --git a/src/core/operations/ParseUDP.mjs b/src/core/operations/ParseUDP.mjs new file mode 100644 index 00000000..14033143 --- /dev/null +++ b/src/core/operations/ParseUDP.mjs @@ -0,0 +1,92 @@ +/** + * @author h345983745 [] + * @copyright Crown Copyright 2019 + * @license Apache-2.0 + */ + +import Operation from "../Operation.mjs"; +import Stream from "../lib/Stream.mjs"; +import {toHex} from "../lib/Hex.mjs"; +import OperationError from "../errors/OperationError.mjs"; + +/** + * Parse UDP operation + */ +class ParseUDP extends Operation { + + /** + * ParseUDP constructor + */ + constructor() { + super(); + + this.name = "Parse UDP"; + this.module = "Default"; + this.description = "Parses a UDP header and payload if present."; + this.infoURL = "https://wikipedia.org/wiki/User_Datagram_Protocol"; + this.inputType = "byteArray"; + this.outputType = "json"; + this.presentType = "html"; + this.args = []; + } + + /** + * @param {Uint8Array} input + * @returns {Object} + */ + run(input, args) { + + if (input.length < "8"){ + throw new OperationError("Need 8 bytes for a UDP Header"); + } + + const s = new Stream(input); + //Parse Header + const UDPPacket = { + "Source port": s.readInt(2), + "Desination port": s.readInt(2), + "Length": s.readInt(2), + "Checksum": toHex(s.getBytes(2), "0x") + }; + //Parse data if present + if (s.hasMore()){ + UDPPacket.Data = toHex(s.getBytes(UDPPacket.Length - 8), "0x"); + } + + return UDPPacket; + + } + + /** + * Displays the UDP Packet in a table style + * @param {Object} data + * @returns {html} + */ + present(data) { + // const currentRecipeConfig = this.state.opList.map(op => op.config); + // console.log(currentRecipeConfig); + const html = []; + html.push(""); + html.push(""); + html.push(""); + html.push(""); + html.push(""); + + for (const key in data) { + switch (key){ + default: { + html.push(""); + html.push(""); + html.push(""); + html.push(""); + } + } + } + html.push("
FieldValue
" + key + "" + data[key] + "
"); + return html.join(""); + } + +} + + +export default ParseUDP; diff --git a/tests/operations/index.mjs b/tests/operations/index.mjs index eac6ab9a..1ad69228 100644 --- a/tests/operations/index.mjs +++ b/tests/operations/index.mjs @@ -88,6 +88,7 @@ import "./tests/BLAKE2s"; import "./tests/Protobuf"; import "./tests/ParseSSHHostKey"; import "./tests/DefangIP"; +import "./tests/ParseUDP"; // Cannot test operations that use the File type yet //import "./tests/SplitColourChannels"; diff --git a/tests/operations/tests/ParseUDP.mjs b/tests/operations/tests/ParseUDP.mjs new file mode 100644 index 00000000..1cd6482f --- /dev/null +++ b/tests/operations/tests/ParseUDP.mjs @@ -0,0 +1,68 @@ +/** + * Parse UDP tests. + * + * @author h345983745 + * + * @copyright Crown Copyright 2019 + * @license Apache-2.0 + */ +import TestRegister from "../../lib/TestRegister.mjs"; + +TestRegister.addTests([ + { + name: "Parse UDP: No Data - JSON", + input: "04 89 00 35 00 2c 01 01", + expectedOutput: "{\"Source port\":1161,\"Desination port\":53,\"Length\":44,\"Checksum\":\"0x010x01\"}", + recipeConfig: [ + { + op: "From Hex", + args: ["Auto"], + }, + { + op: "Parse UDP", + args: [], + }, + { + op: "JSON Minify", + args: [], + }, + ], + }, { + name: "Parse UDP: With Data - JSON", + input: "04 89 00 35 00 2c 01 01 02 02", + expectedOutput: "{\"Source port\":1161,\"Desination port\":53,\"Length\":44,\"Checksum\":\"0x010x01\",\"Data\":\"0x020x02\"}", + recipeConfig: [ + { + op: "From Hex", + args: ["Auto"], + }, + { + op: "Parse UDP", + args: [], + }, + { + op: "JSON Minify", + args: [], + }, + ], + }, + { + name: "Parse UDP: Not Enough Bytes", + input: "04 89 00", + expectedOutput: "Need 8 bytes for a UDP Header", + recipeConfig: [ + { + op: "From Hex", + args: ["Auto"], + }, + { + op: "Parse UDP", + args: [], + }, + { + op: "JSON Minify", + args: [], + }, + ], + } +]); From b14cb99587faa49da10237b49f4842527293995e Mon Sep 17 00:00:00 2001 From: h345983745 Date: Mon, 19 Aug 2019 20:55:04 +0100 Subject: [PATCH 2/4] Removed console.log --- src/core/operations/ParseUDP.mjs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/core/operations/ParseUDP.mjs b/src/core/operations/ParseUDP.mjs index 14033143..ec529d1b 100644 --- a/src/core/operations/ParseUDP.mjs +++ b/src/core/operations/ParseUDP.mjs @@ -63,8 +63,6 @@ class ParseUDP extends Operation { * @returns {html} */ present(data) { - // const currentRecipeConfig = this.state.opList.map(op => op.config); - // console.log(currentRecipeConfig); const html = []; html.push(""); html.push(""); From b8dbb111364346d027ce252f6bb2ec9f5c4b68e9 Mon Sep 17 00:00:00 2001 From: h345983745 Date: Mon, 19 Aug 2019 21:05:38 +0100 Subject: [PATCH 3/4] Spelling --- src/core/operations/ParseUDP.mjs | 4 ++-- tests/operations/tests/ParseUDP.mjs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/operations/ParseUDP.mjs b/src/core/operations/ParseUDP.mjs index ec529d1b..234a08f6 100644 --- a/src/core/operations/ParseUDP.mjs +++ b/src/core/operations/ParseUDP.mjs @@ -22,7 +22,7 @@ class ParseUDP extends Operation { this.name = "Parse UDP"; this.module = "Default"; - this.description = "Parses a UDP header and payload if present."; + this.description = "Parses a UDP header and payload (if present)."; this.infoURL = "https://wikipedia.org/wiki/User_Datagram_Protocol"; this.inputType = "byteArray"; this.outputType = "json"; @@ -44,7 +44,7 @@ class ParseUDP extends Operation { //Parse Header const UDPPacket = { "Source port": s.readInt(2), - "Desination port": s.readInt(2), + "Destination port": s.readInt(2), "Length": s.readInt(2), "Checksum": toHex(s.getBytes(2), "0x") }; diff --git a/tests/operations/tests/ParseUDP.mjs b/tests/operations/tests/ParseUDP.mjs index 1cd6482f..f6bf54d0 100644 --- a/tests/operations/tests/ParseUDP.mjs +++ b/tests/operations/tests/ParseUDP.mjs @@ -12,7 +12,7 @@ TestRegister.addTests([ { name: "Parse UDP: No Data - JSON", input: "04 89 00 35 00 2c 01 01", - expectedOutput: "{\"Source port\":1161,\"Desination port\":53,\"Length\":44,\"Checksum\":\"0x010x01\"}", + expectedOutput: "{\"Source port\":1161,\"Destination port\":53,\"Length\":44,\"Checksum\":\"0x010x01\"}", recipeConfig: [ { op: "From Hex", @@ -30,7 +30,7 @@ TestRegister.addTests([ }, { name: "Parse UDP: With Data - JSON", input: "04 89 00 35 00 2c 01 01 02 02", - expectedOutput: "{\"Source port\":1161,\"Desination port\":53,\"Length\":44,\"Checksum\":\"0x010x01\",\"Data\":\"0x020x02\"}", + expectedOutput: "{\"Source port\":1161,\"Destination port\":53,\"Length\":44,\"Checksum\":\"0x010x01\",\"Data\":\"0x020x02\"}", recipeConfig: [ { op: "From Hex", From 00313453837eb4b4ef19d366e22a149e1ff0b094 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Fri, 23 Aug 2019 10:56:13 +0100 Subject: [PATCH 4/4] Tidied up 'Parse UDP' operation --- README.md | 1 - src/core/operations/ParseUDP.mjs | 34 ++++++++++++----------------- tests/operations/tests/ParseUDP.mjs | 4 ++-- 3 files changed, 16 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 299b5d87..c0996378 100755 --- a/README.md +++ b/README.md @@ -3,7 +3,6 @@ [![Build Status](https://travis-ci.org/gchq/CyberChef.svg?branch=master)](https://travis-ci.org/gchq/CyberChef) [![dependencies Status](https://david-dm.org/gchq/CyberChef/status.svg)](https://david-dm.org/gchq/CyberChef) [![npm](https://img.shields.io/npm/v/cyberchef.svg)](https://www.npmjs.com/package/cyberchef) -![](https://reposs.herokuapp.com/?path=gchq/CyberChef&color=blue) [![](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](https://github.com/gchq/CyberChef/blob/master/LICENSE) [![Gitter](https://badges.gitter.im/gchq/CyberChef.svg)](https://gitter.im/gchq/CyberChef?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) diff --git a/src/core/operations/ParseUDP.mjs b/src/core/operations/ParseUDP.mjs index 234a08f6..0a88fd5d 100644 --- a/src/core/operations/ParseUDP.mjs +++ b/src/core/operations/ParseUDP.mjs @@ -24,37 +24,35 @@ class ParseUDP extends Operation { this.module = "Default"; this.description = "Parses a UDP header and payload (if present)."; this.infoURL = "https://wikipedia.org/wiki/User_Datagram_Protocol"; - this.inputType = "byteArray"; + this.inputType = "ArrayBuffer"; this.outputType = "json"; this.presentType = "html"; this.args = []; } /** - * @param {Uint8Array} input + * @param {ArrayBuffer} input * @returns {Object} */ run(input, args) { - - if (input.length < "8"){ + if (input.byteLength < 8) { throw new OperationError("Need 8 bytes for a UDP Header"); } - const s = new Stream(input); - //Parse Header + const s = new Stream(new Uint8Array(input)); + // Parse Header const UDPPacket = { "Source port": s.readInt(2), "Destination port": s.readInt(2), "Length": s.readInt(2), - "Checksum": toHex(s.getBytes(2), "0x") + "Checksum": toHex(s.getBytes(2), "") }; - //Parse data if present - if (s.hasMore()){ - UDPPacket.Data = toHex(s.getBytes(UDPPacket.Length - 8), "0x"); + // Parse data if present + if (s.hasMore()) { + UDPPacket.Data = toHex(s.getBytes(UDPPacket.Length - 8), ""); } return UDPPacket; - } /** @@ -64,21 +62,17 @@ class ParseUDP extends Operation { */ present(data) { const html = []; - html.push("
"); + html.push("
"); html.push(""); html.push(""); html.push(""); html.push(""); for (const key in data) { - switch (key){ - default: { - html.push(""); - html.push(""); - html.push(""); - html.push(""); - } - } + html.push(""); + html.push(""); + html.push(""); + html.push(""); } html.push("
FieldValue
" + key + "" + data[key] + "
" + key + "" + data[key] + "
"); return html.join(""); diff --git a/tests/operations/tests/ParseUDP.mjs b/tests/operations/tests/ParseUDP.mjs index f6bf54d0..2c519232 100644 --- a/tests/operations/tests/ParseUDP.mjs +++ b/tests/operations/tests/ParseUDP.mjs @@ -12,7 +12,7 @@ TestRegister.addTests([ { name: "Parse UDP: No Data - JSON", input: "04 89 00 35 00 2c 01 01", - expectedOutput: "{\"Source port\":1161,\"Destination port\":53,\"Length\":44,\"Checksum\":\"0x010x01\"}", + expectedOutput: "{\"Source port\":1161,\"Destination port\":53,\"Length\":44,\"Checksum\":\"0101\"}", recipeConfig: [ { op: "From Hex", @@ -30,7 +30,7 @@ TestRegister.addTests([ }, { name: "Parse UDP: With Data - JSON", input: "04 89 00 35 00 2c 01 01 02 02", - expectedOutput: "{\"Source port\":1161,\"Destination port\":53,\"Length\":44,\"Checksum\":\"0x010x01\",\"Data\":\"0x020x02\"}", + expectedOutput: "{\"Source port\":1161,\"Destination port\":53,\"Length\":44,\"Checksum\":\"0101\",\"Data\":\"0202\"}", recipeConfig: [ { op: "From Hex",