check dns0x20 support by default

This commit is contained in:
AJ ONeal 2017-10-02 16:43:58 -06:00
parent 7bb2e84486
commit 4e0a37c0f5
3 changed files with 58 additions and 3 deletions

View File

@ -4,7 +4,7 @@ dig.js
| [dns-suite](https://git.daplie.com/Daplie/dns-suite) | **dig.js** | [digd.js](https://git.daplie.com/Daplie/digd.js) | | [dns-suite](https://git.daplie.com/Daplie/dns-suite) | **dig.js** | [digd.js](https://git.daplie.com/Daplie/digd.js) |
Create and capture DNS and mDNS query and response packets to disk as binary and/or JSON. Create and capture DNS and mDNS query and response packets to disk as binary and/or JSON.
Options are similar to the Unix `dig` command. Options are similar to the Unix `dig` command. Supports dns0x20 security checking.
Install Install
------- -------
@ -85,5 +85,8 @@ Options
+norecurse Set `rd` flag to 0. Do not request recursion +norecurse Set `rd` flag to 0. Do not request recursion
+aaonly Set `aa` flag to 1. +aaonly Set `aa` flag to 1.
--norecase Disable dns0x20 security checking (mixed casing). See https://dyn.com/blog/use-of-bit-0x20-in-dns-labels/
--recase Print the dns0x20 casing as-is rather than converting it back to lowercase. This is the default when explicitly using mixed case.
--debug verbose output --debug verbose output
``` ```

View File

@ -22,6 +22,8 @@ cli.parse({
//, 'serve': [ 's', 'path to json file with array of responses to issue for given queries', 'string' ] //, 'serve': [ 's', 'path to json file with array of responses to issue for given queries', 'string' ]
, 'type': [ 't', 'type (defaults to ANY for dns and PTR for mdns)', 'string' ] , 'type': [ 't', 'type (defaults to ANY for dns and PTR for mdns)', 'string' ]
, 'query': [ 'q', 'a superfluous explicit option to set the query as a command line flag' ] , 'query': [ 'q', 'a superfluous explicit option to set the query as a command line flag' ]
, 'norecase': [ false, 'Disable dns0x20 security checking (mixed casing). See https://dyn.com/blog/use-of-bit-0x20-in-dns-labels/' ]
, 'recase': [ false, "Print the dns0x20 casing as-is rather than converting it back to lowercase. This is the default when explicitly using mixed case." ]
}); });
var common = require('../common.js'); var common = require('../common.js');
@ -109,6 +111,20 @@ cli.main(function (args, cli) {
} }
} }
if (cli.query !== cli.query.toLowerCase()) {
cli.norecase = true;
}
if (!cli.norecase) {
cli.casedQuery = cli.query.split('').map(function (ch) {
// dns0x20 takes advantage of the fact that the binary operation for toUpperCase is
// ch = ch | 0x20;
return Math.round(Math.random()) % 2 ? ch : ch.toUpperCase();
}).join('');
} else {
cli.casedQuery = cli.query;
}
if (!cli.type) { if (!cli.type) {
cli.type = cli.t = 'ANY'; cli.type = cli.t = 'ANY';
} }
@ -141,7 +157,7 @@ cli.main(function (args, cli) {
, rcode: 0 // NA , rcode: 0 // NA
} }
, question: [ , question: [
{ name: cli.query { name: cli.casedQuery
, typeName: cli.type , typeName: cli.type
, className: cli.class , className: cli.class
} }
@ -181,6 +197,40 @@ cli.main(function (args, cli) {
console.log(packet); console.log(packet);
} }
packet.question.forEach(function (q) {
// if (-1 === q.name.indexOf(cli.casedQuery))
if (q.name !== cli.casedQuery) {
console.log(";; Warning: DNS 0x20 security not implemented (or packet spoofed). Queried '" + cli.casedQuery + "' but got response for '" + q.name + "'.");
}
});
if (!cli.norecase && !cli.recase) {
[ 'question', 'answer', 'authority', 'additional' ].forEach(function (group) {
(packet[group]||[]).forEach(function (a) {
var an = a.name;
var i = cli.query.toLowerCase().indexOf(a.name.toLowerCase()); // answer is something like ExAMPle.cOM and query was wWw.ExAMPle.cOM
var j = a.name.toLowerCase().indexOf(cli.query.toLowerCase()); // answer is something like www.ExAMPle.cOM and query was ExAMPle.cOM
// it's important to note that these should only relpace changes in casing that we expected
// any abnormalities should be left intact to go "huh?" about
// TODO detect abnormalities?
if (-1 !== i) {
// "EXamPLE.cOm".replace("wWw.EXamPLE.cOm".substr(4), "www.example.com".substr(4))
a.name = a.name.replace(cli.casedQuery.substr(i), cli.query.substr(i));
} else {
// "www.example.com".replace("EXamPLE.cOm", "example.com")
a.name = a.name.substr(0, j) + a.name.substr(j).replace(cli.casedQuery, cli.query);
}
// NOTE: right now this assumes that anything matching the query matches all the way to the end
// it does not handle the case of a record for example.com.uk being returned in response to a query for www.example.com correctly
// (but I don't think it should need to)
if (a.name.length !== an.length) {
console.error("[ERROR] '" + an + "' != '" + a.length + "'");
}
});
});
}
console.log(';; Got answer:'); console.log(';; Got answer:');
dig.logQuestion(packet); dig.logQuestion(packet);
@ -236,7 +286,7 @@ cli.main(function (args, cli) {
console.log(''); console.log('');
if (!cli.nocmd) { if (!cli.nocmd) {
console.log('; <<>> dig.js ' + 'v0.0.0' + ' <<>> ' + process.argv.slice(2).join(' ')); console.log('; <<>> dig.js ' + 'v0.0.0' + ' <<>> ' + process.argv.slice(2).join(' ').replace(cli.query, cli.casedQuery));
console.log(';; global options: +cmd'); console.log(';; global options: +cmd');
} }

View File

@ -24,6 +24,8 @@
"dig", "dig",
"dns", "dns",
"mdns", "mdns",
"dns0x20",
"0x20",
"lint", "lint",
"capture", "capture",
"create", "create",