2
0
Fork 0
mirror of https://github.com/gchq/CyberChef synced 2025-03-14 05:46:56 +00:00

Add DNS message parsing operation

Example:

- Input: `q80BAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB`
- Operations: `From Base64` -> `Parse DNS Message`
- Output:
```
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 43981
;; flags: rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;www.example.com.		IN	A
```
This commit is contained in:
Minghang Chen 2024-06-07 10:52:09 -07:00
parent 4c5577ddeb
commit 462cda7f2e
6 changed files with 157 additions and 0 deletions

15
package-lock.json generated
View file

@ -13,6 +13,7 @@
"@astronautlabs/amf": "^0.0.6", "@astronautlabs/amf": "^0.0.6",
"@babel/polyfill": "^7.12.1", "@babel/polyfill": "^7.12.1",
"@blu3r4y/lzma": "^2.3.3", "@blu3r4y/lzma": "^2.3.3",
"@dnspect/dns-ts": "^0.3.0",
"@wavesenterprise/crypto-gost-js": "^2.1.0-RC1", "@wavesenterprise/crypto-gost-js": "^2.1.0-RC1",
"@xmldom/xmldom": "^0.8.10", "@xmldom/xmldom": "^0.8.10",
"argon2-browser": "^1.18.0", "argon2-browser": "^1.18.0",
@ -2079,6 +2080,20 @@
"node": ">=10.0.0" "node": ">=10.0.0"
} }
}, },
"node_modules/@dnspect/dns-ts": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/@dnspect/dns-ts/-/dns-ts-0.3.0.tgz",
"integrity": "sha512-XbzLcKSlsBRxg1U4xaKf0fGJS66hxu1LGPHs0UHWCI92BifTZsr2KaRouBcusil0VJ4ESgoR+HLU7tG4HrpFjA==",
"dependencies": {
"@dnspect/ip-address-ts": "0.2.1",
"base64-js": "1"
}
},
"node_modules/@dnspect/ip-address-ts": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/@dnspect/ip-address-ts/-/ip-address-ts-0.2.1.tgz",
"integrity": "sha512-iJsRv0nychs5GQM7K9woY5iZp4i8We3a7KG3t77QnV2DSvGiwERZQliR4oBqMb6RjHBPckX60p1ONCcXHVrXTw=="
},
"node_modules/@es-joy/jsdoccomment": { "node_modules/@es-joy/jsdoccomment": {
"version": "0.43.1", "version": "0.43.1",
"resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.43.1.tgz", "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.43.1.tgz",

View file

@ -97,6 +97,7 @@
"@astronautlabs/amf": "^0.0.6", "@astronautlabs/amf": "^0.0.6",
"@babel/polyfill": "^7.12.1", "@babel/polyfill": "^7.12.1",
"@blu3r4y/lzma": "^2.3.3", "@blu3r4y/lzma": "^2.3.3",
"@dnspect/dns-ts": "^0.3.0",
"@wavesenterprise/crypto-gost-js": "^2.1.0-RC1", "@wavesenterprise/crypto-gost-js": "^2.1.0-RC1",
"@xmldom/xmldom": "^0.8.10", "@xmldom/xmldom": "^0.8.10",
"argon2-browser": "^1.18.0", "argon2-browser": "^1.18.0",

View file

@ -238,6 +238,7 @@
"Parse UDP", "Parse UDP",
"Parse SSH Host Key", "Parse SSH Host Key",
"Parse URI", "Parse URI",
"Parse DNS Message",
"URL Encode", "URL Encode",
"URL Decode", "URL Decode",
"Protobuf Decode", "Protobuf Decode",

View file

@ -0,0 +1,55 @@
/**
* @author Minghang Chen [chen@minghang.dev]
* @copyright Crown Copyright 2024
* @license Apache-2.0
*/
import Operation from "../Operation.mjs";
import OperationError from "../errors/OperationError.mjs";
import { Message } from "@dnspect/dns-ts";
/**
* Parse DNS Message operation
*/
class ParseDNSMessage extends Operation {
/**
* ParseDNSMessage constructor
*/
constructor() {
super();
this.name = "Parse DNS Message";
this.module = "Default";
this.description = "Parse the DNS wireformat binary of a DNS message and return a text representation";
this.infoURL = "https://en.wikipedia.org/wiki/Domain_Name_System#DNS_message_format";
this.inputType = "ArrayBuffer";
this.outputType = "string";
this.args = [{
"name": "Output format",
"type": "option",
"value": ["dig-like", "dns-json"]
}];
}
/**
* @param {ArrayBuffer} input
* @param {Object[]} args
* @returns {string}
*/
run(input, args) {
const format = args[0];
let msg;
try {
msg = Message.unpack(input);
} catch (e) {
throw new OperationError(`Malformed DNS message: ${e}`);
}
switch (format) {
case "dig-like": return msg.toString();
case "dns-json": return JSON.stringify(msg.toJsonObject(), null, 2);
default: throw new OperationError(`Unsupported output format: ${format}`);
}
}
}
export default ParseDNSMessage;

View file

@ -117,6 +117,7 @@ import "./tests/ParseSSHHostKey.mjs";
import "./tests/ParseTCP.mjs"; import "./tests/ParseTCP.mjs";
import "./tests/ParseTLV.mjs"; import "./tests/ParseTLV.mjs";
import "./tests/ParseUDP.mjs"; import "./tests/ParseUDP.mjs";
import "./tests/ParseDNSMessage.mjs";
import "./tests/PEMtoHex.mjs"; import "./tests/PEMtoHex.mjs";
import "./tests/PGP.mjs"; import "./tests/PGP.mjs";
import "./tests/PHP.mjs"; import "./tests/PHP.mjs";

View file

@ -0,0 +1,84 @@
/**
* Parse DNS Message tests.
*
* @author Minghang Chen [chen@minghang.dev]
* @copyright Crown Copyright 2024
* @license Apache-2.0
*/
import TestRegister from "../../lib/TestRegister.mjs";
TestRegister.addTests([
{
name: "Parse DNS Message: No Data",
input: "",
expectedOutput: "Malformed DNS message: ParseError: insufficient bytes remaining for read: needs 12, have 0",
recipeConfig: [
{
op: "Parse DNS Message",
args: ["dig-like"],
},
],
},
{
name: "Parse DNS Message: Malformed",
input: "\xab\xcd\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x03\x77\x77\x77\x07\x65\x78\x61\x6d\x70\x6c\x65\x03\x63\x6f",
expectedOutput: "Malformed DNS message: RangeError: try to access beyond buffer length: read 3 start from 25",
recipeConfig: [
{
op: "Parse DNS Message",
args: ["dig-like"],
}
],
},
{
name: "Parse DNS Message: dig-like",
input: "\xab\xcd\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x03\x77\x77\x77\x07\x65\x78\x61\x6d\x70\x6c\x65\x03\x63\x6f\x6d\x00\x00\x01\x00\x01",
expectedOutput: `;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 43981
;; flags: rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;www.example.com. IN A`,
recipeConfig: [
{
op: "Parse DNS Message",
args: ["dig-like"],
}
],
},
{
name: "Parse DNS Message: dns-json",
input: "\xab\xcd\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x03\x77\x77\x77\x07\x65\x78\x61\x6d\x70\x6c\x65\x03\x63\x6f\x6d\x00\x00\x01\x00\x01",
expectedOutput: `{
"Status": 0,
"TC": false,
"RD": true,
"RA": false,
"AD": false,
"CD": false,
"Question": [
{
"name": "www.example.com.",
"type": 1
}
],
"Answer": []
}`,
recipeConfig: [
{
op: "Parse DNS Message",
args: ["dns-json"],
}
],
},
{
name: "Parse DNS Message: unsupported-output-format",
input: "\xab\xcd\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x03\x77\x77\x77\x07\x65\x78\x61\x6d\x70\x6c\x65\x03\x63\x6f\x6d\x00\x00\x01\x00\x01",
expectedOutput: "Unsupported output format: invalid",
recipeConfig: [
{
op: "Parse DNS Message",
args: ["invalid"],
}
],
}
]);