diff --git a/dist/dhcp/index.js b/dist/dhcp/index.js index a3295f2..fe17464 100644 --- a/dist/dhcp/index.js +++ b/dist/dhcp/index.js @@ -1,9 +1,11 @@ -var path, server, toHexArray; +var args, path, server, toHexArray; server = require('./server'); path = require('path'); +args = require('../args'); + toHexArray = function(str) { return str.split('').map(function(d, i) { return str.charCodeAt(i); @@ -11,7 +13,8 @@ toHexArray = function(str) { }; module.exports = function(ip, acsurl, acspass) { - var vendor; + var fullip, vendor; + fullip = ip; ip = ip.split('.'); ip.pop(); ip = ip.join('.'); @@ -24,6 +27,7 @@ module.exports = function(ip, acsurl, acspass) { randomIP: true, vendor: vendor, netmask: '255.255.255.0', + dns: args.dnsserver ? [fullip] : ['8.8.8.8', '8.8.4.4'], router: [ip + '.1'], hostname: 'second.gateway', broadcast: ip + '.255', diff --git a/dist/http/index.js b/dist/http/index.js index e2c7be7..34672a4 100644 --- a/dist/http/index.js +++ b/dist/http/index.js @@ -1,10 +1,12 @@ -var Duplex, args, createServer, cwmp, existsSync, file, path, readFileSync, ref, route, statSync; +var Duplex, args, createHttpsServer, createServer, cwmp, file, path, readFileSync, route; Duplex = require('stream').Duplex; createServer = require('http').createServer; -ref = require('fs'), readFileSync = ref.readFileSync, existsSync = ref.existsSync, statSync = ref.statSync; +createHttpsServer = require('https').createServer; + +readFileSync = require('fs').readFileSync; path = require('path'); @@ -17,7 +19,7 @@ args = require('../args'); cwmp = require('./cwmp'); module.exports = function(ip, port, url) { - var e, srv; + var e, httpsoptions, srv; if (args.file) { file.name = path.basename(args.file); try { @@ -43,21 +45,30 @@ module.exports = function(ip, port, url) { stream = new Duplex(); stream.push(file.data); stream.push(null); - return stream.pipe(res); - }).get('/done', function(req, res) { + stream.pipe(res).get('/done', function(req, res) {}); console.log('>>> WPS CALLBACK'); console.log("\n\nAll done,\n\n- change network card settings back to dhcp and move the cable back to a lan port\n- try ssh connection to the gateways ip (usually 192.168.0.1) with username root and password root (change password immediately with passwd!)\n\nssh root@192.168.0.1"); setTimeout(function() { return process.exit(1); }, 20000); res.writeHead(200); - return res.end(); - }).post('/', cwmp(url)); - srv = createServer(route); + return res.end().post('/', cwmp(url)); + }); + if (args.https) { + console.log("Starting HTTPS server..."); + httpsoptions = { + key: readFileSync('./key.key'), + cert: readFileSync('./cert.cert') + }; + srv = createHttpsServer(httpsoptions, route); + } else { + console.log("Starting HTTP server..."); + srv = createServer(route); + } srv.keepAliveTimeout = 30000; srv.on('error', function(e) { - var ref1; - if ((ref1 = e.code) === 'EADDRINUSE' || ref1 === 'EADDRNOTAVAIL') { + var ref; + if ((ref = e.code) === 'EADDRINUSE' || ref === 'EADDRNOTAVAIL') { console.log(e.code + ', retrying...'); return setTimeout(function() { srv.close(); diff --git a/dist/http/lecerts.js b/dist/http/lecerts.js new file mode 100644 index 0000000..6b4aa1a --- /dev/null +++ b/dist/http/lecerts.js @@ -0,0 +1,88 @@ +var ACME, args, duckdns, existsSync, ref, writeFileSync; + +ref = require('fs'), writeFileSync = ref.writeFileSync, existsSync = ref.existsSync; + +ACME = require('@root/acme'); + +duckdns = require('acme-dns-01-duckdns'); + +args = require('../args'); + +module.exports = function(domain) { + var acme, dns01; + if (existsSync('./key.key') && existsSync('./cert.cert')) { + console.log("key.key and key.key already exists!"); + return; + } + if (args.duckdnstoken) { + dns01 = duckdns.create({ + baseUrl: 'https://www.duckdns.org/update', + token: args.duckdnstoken + }); + console.log("Requesting HTTPS certificate to LE via duckdns..."); + } else { + console.log("No duckdns token!!"); + return; + } + acme = ACME.create({ + maintainerEmail: 'tch-exploit@github.com', + packageAgent: 'tch-exploit/v1.0' + }); + return acme.init('https://acme-v02.api.letsencrypt.org/directory').then(function(r) { + var Keypairs; + Keypairs = require('@root/keypairs'); + return Keypairs.generate({ + kty: 'EC', + format: 'jwk' + }).then(function(accountKeypair) { + return acme.accounts.create({ + subscriberEmail: 'tch-exploit@github.com', + agreeToTerm: true, + accountKey: accountKeypair["private"] + }).then(function(account) { + console.log("Starting LetsEncrypt DNS challenge via duckdns..."); + return Keypairs.generate({ + kty: 'RSA', + format: 'jwk' + }).then(function(serverKeypair) { + return Keypairs["export"]({ + jwk: serverKeypair["private"] + }).then(function(privateKey) { + var CSR, PEM, punycode; + CSR = require('@root/csr'); + PEM = require('@root/pem'); + punycode = require('punycode'); + return CSR.csr({ + jwk: serverKeypair["private"], + domains: [punycode.toASCII(domain)], + encoding: 'der' + }).then(function(csrDer) { + var csr; + csr = PEM.packBlock({ + type: 'CERTIFICATE REQUEST', + bytes: csrDer + }); + return acme.certificates.create({ + account: account, + accountKey: accountKeypair["private"], + csr: csr, + domains: [domain], + challenges: { + 'dns-01': dns01 + } + }).then(function(pems) { + console.log("Key:"); + console.log(privateKey); + console.log("Cert:"); + console.log(pems.cert); + console.log("Certificate received, saving to key.key and cert.cert!"); + writeFileSync('./key.key', privateKey); + return writeFileSync('./cert.cert', pems.cert); + }); + }); + }); + }); + }); + }); + }); +}; diff --git a/dist/index.js b/dist/index.js index e106a24..2095f7c 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1,4 +1,4 @@ -var args, ask, dhcpd, httpd, ip, pkg, port, rl, servers, tftp; +var args, ask, dhcpd, httpd, ip, lecerts, ndns, pkg, port, rl, servers, tftp; pkg = require('../package.json'); @@ -14,25 +14,45 @@ dhcpd = require('./dhcp'); httpd = require('./http'); +lecerts = require('./http/lecerts'); + port = require('./get-port'); tftp = require('./tftp'); +ndns = require('node-named-fixed'); + servers = []; if (args.tftp) { servers.push.apply(servers, tftp(args)); } else if (args.dhcponly) { servers.push(dhcpd(ip, args.acsurl, args.acspass)); +} else if (args.certonly) { + lecerts(new URL(args.acsurl).hostname); } else { ask(ip).then(port).then(function(p) { - var u, url; + var server, u, url; u = new URL(args.acsurl || ("http://" + ip)); u.port = p; url = u.toString(); console.log("listening for cwmp requests at " + url); servers.push(dhcpd(ip, url, args.acspass)); - return servers.push(httpd(ip, p, url)); + servers.push(httpd(ip, p, url)); + if (args.dnsserver) { + server = ndns.createServer(); + server.listen(53, ip, function() { + return console.log('DNS server started on port 53'); + }); + return server.on('query', function(query) { + var domain, target; + domain = query.name(); + console.log('DNS Query: %s', domain); + target = new ndns.ARecord(ip); + query.addAnswer(domain, target, 10); + return server.send(query); + }); + } }); } diff --git a/package-lock.json b/package-lock.json index fa3aa89..8840482 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,19 +1,594 @@ { "name": "tch-exploit", - "version": "2.0.0-rc3", - "lockfileVersion": 1, + "version": "2.0.1-rc8", + "lockfileVersion": 2, "requires": true, + "packages": { + "": { + "version": "2.0.1-rc8", + "license": "MIT", + "dependencies": { + "@root/acme": "^3.1.0", + "@root/greenlock": "^4.0.5", + "@root/keypairs": "^0.10.3", + "acme-dns-01-duckdns": "^3.0.1", + "http-request": "^0.7.0", + "node-named-fixed": "^0.0.1", + "punycode": "^2.1.1", + "tftp": "^0.1.2" + }, + "bin": { + "tch-exploit": "dist/index.js" + } + }, + "node_modules/@greenlock/manager": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@greenlock/manager/-/manager-3.1.0.tgz", + "integrity": "sha512-PBy5CMK+j4oD7sj7hF5qE+xKEOSiiuL2hHd5X5ttEbtnTSDKjNeqbrR5k2ZddwVNdjOVeBIeuqlm81IFZ+Ftew==", + "dependencies": { + "greenlock-manager-fs": "^3.1.0" + } + }, + "node_modules/@root/acme": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@root/acme/-/acme-3.1.0.tgz", + "integrity": "sha512-GAyaW63cpSYd2KvVp5lHLbCWeEhJPKZK9nsJvZJOKsD9Uv88KEttn4FpDZEJ+2q3Jsey0DWpuQ2I4ft0JV9p2w==", + "hasInstallScript": true, + "dependencies": { + "@root/csr": "^0.8.1", + "@root/encoding": "^1.0.1", + "@root/keypairs": "^0.10.0", + "@root/pem": "^1.0.4", + "@root/request": "^1.6.1", + "@root/x509": "^0.7.2" + } + }, + "node_modules/@root/asn1": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@root/asn1/-/asn1-1.0.0.tgz", + "integrity": "sha512-0lfZNuOULKJDJmdIkP8V9RnbV3XaK6PAHD3swnFy4tZwtlMDzLKoM/dfNad7ut8Hu3r91wy9uK0WA/9zym5mig==", + "dependencies": { + "@root/encoding": "^1.0.1" + } + }, + "node_modules/@root/csr": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@root/csr/-/csr-0.8.1.tgz", + "integrity": "sha512-hKl0VuE549TK6SnS2Yn9nRvKbFZXn/oAg+dZJU/tlKl/f/0yRXeuUzf8akg3JjtJq+9E592zDqeXZ7yyrg8fSQ==", + "dependencies": { + "@root/asn1": "^1.0.0", + "@root/pem": "^1.0.4", + "@root/x509": "^0.7.2" + } + }, + "node_modules/@root/encoding": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@root/encoding/-/encoding-1.0.1.tgz", + "integrity": "sha512-OaEub02ufoU038gy6bsNHQOjIn8nUjGiLcaRmJ40IUykneJkIW5fxDqKxQx48cszuNflYldsJLPPXCrGfHs8yQ==" + }, + "node_modules/@root/greenlock": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@root/greenlock/-/greenlock-4.0.5.tgz", + "integrity": "sha512-KR9w3mYE9aH33FCibI8oSYBQV+f7lc3MVPdZ9nxY2tqRLmJp05cMOMz340mtG14VnWDuznLj4TbBj3sHIuoQPQ==", + "dependencies": { + "@greenlock/manager": "^3.1.0", + "@root/acme": "^3.1.0", + "@root/csr": "^0.8.1", + "@root/keypairs": "^0.10.0", + "@root/mkdirp": "^1.0.0", + "@root/request": "^1.6.1", + "acme-http-01-standalone": "^3.0.5", + "cert-info": "^1.5.1", + "greenlock-store-fs": "^3.2.2", + "safe-replace": "^1.1.0" + }, + "bin": { + "greenlock": "bin/greenlock.js" + } + }, + "node_modules/@root/keypairs": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/@root/keypairs/-/keypairs-0.10.3.tgz", + "integrity": "sha512-hbmjVbk/G99Z1XlUzJM4VOAaR8jm4vMnfwpZL301FA24ubJ/bOjj6enCrz9gKsQvBO6RY4/R4MgUuWpXeqeZZQ==", + "dependencies": { + "@root/encoding": "^1.0.1", + "@root/pem": "^1.0.4", + "@root/x509": "^0.7.2" + } + }, + "node_modules/@root/mkdirp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@root/mkdirp/-/mkdirp-1.0.0.tgz", + "integrity": "sha512-hxGAYUx5029VggfG+U9naAhQkoMSXtOeXtbql97m3Hi6/sQSRL/4khKZPyOF6w11glyCOU38WCNLu9nUcSjOfA==" + }, + "node_modules/@root/pem": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@root/pem/-/pem-1.0.4.tgz", + "integrity": "sha512-rEUDiUsHtild8GfIjFE9wXtcVxeS+ehCJQBwbQQ3IVfORKHK93CFnRtkr69R75lZFjcmKYVc+AXDB+AeRFOULA==" + }, + "node_modules/@root/request": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@root/request/-/request-1.8.1.tgz", + "integrity": "sha512-Ib6jLQj4P4Dnx3LMqdV+TaSDlc7tWz25wKorklQ1rMHzHfc7LKELIuWl3XDQybimOPvIvlDuVX6/Mb10dEdQYg==" + }, + "node_modules/@root/x509": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@root/x509/-/x509-0.7.2.tgz", + "integrity": "sha512-ENq3LGYORK5NiMFHEVeNMt+fTXaC7DTS6sQXoqV+dFdfT0vmiL5cDLjaXQhaklJQq0NiwicZegzJRl1ZOTp3WQ==", + "dependencies": { + "@root/asn1": "^1.0.0", + "@root/encoding": "^1.0.1" + } + }, + "node_modules/acme-dns-01-duckdns": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/acme-dns-01-duckdns/-/acme-dns-01-duckdns-3.0.1.tgz", + "integrity": "sha512-s3BC1FFWUjTIoavRFP1mVc6YEqPazt8CVGPLGMV7r9Of70nvfYC8sWIOvol+PCrmTK7vUt8a9tS+P7qLoQE03A==", + "dependencies": { + "@root/request": "^1.3.11" + } + }, + "node_modules/acme-http-01-standalone": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/acme-http-01-standalone/-/acme-http-01-standalone-3.0.5.tgz", + "integrity": "sha512-W4GfK+39GZ+u0mvxRVUcVFCG6gposfzEnSBF20T/NUwWAKG59wQT1dUbS1NixRIAsRuhpGc4Jx659cErFQH0Pg==" + }, + "node_modules/argp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/argp/-/argp-1.0.4.tgz", + "integrity": "sha1-sxxzB1rW1syx2MhqzWn/MAMFsZQ=", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "node_modules/bunyan": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-0.7.0.tgz", + "integrity": "sha1-khBl5wyTb+MCp0DixWBXdb7qL0I=", + "engines": [ + "node >=0.4.0" + ], + "bin": { + "bunyan": "bin/bunyan" + } + }, + "node_modules/cert-info": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/cert-info/-/cert-info-1.5.1.tgz", + "integrity": "sha512-eoQC/yAgW3gKTKxjzyClvi+UzuY97YCjcl+lSqbsGIy7HeGaWxCPOQFivhUYm27hgsBMhsJJFya3kGvK6PMIcQ==", + "bin": { + "cert-info": "bin/cert-info.js" + } + }, + "node_modules/coffee-script": { + "version": "1.12.7", + "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.12.7.tgz", + "integrity": "sha512-fLeEhqwymYat/MpTPUjSKHVYYl0ec2mOyALEMLmzr5i1isuG+6jfI2j2d5oBO3VIzgUXgBVIcOT9uH1TFxBckw==", + "deprecated": "CoffeeScript on NPM has moved to \"coffeescript\" (no hyphen)", + "bin": { + "cake": "bin/cake", + "coffee": "bin/coffee" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/greenlock-manager-fs": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/greenlock-manager-fs/-/greenlock-manager-fs-3.1.1.tgz", + "integrity": "sha512-np6qdnPIOZx40PAcSQcqK1eMPWjTKxsxcgRd/OVg0ai49WC1Ds74CTrwmB84pq2n53ikbnDBQFmKEQ4AC0DK8w==", + "dependencies": { + "@root/mkdirp": "^1.0.0", + "safe-replace": "^1.1.0" + } + }, + "node_modules/greenlock-store-fs": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/greenlock-store-fs/-/greenlock-store-fs-3.2.2.tgz", + "integrity": "sha512-92ejLB4DyV4qv/2b6VLGF2nKfYQeIfg3o+e/1cIoYLjlIaUFdbBXkzLTRozFlHsQPZt2ALi5qYrpC9IwH7GK8A==", + "dependencies": { + "@root/mkdirp": "^1.0.0", + "safe-replace": "^1.1.0" + } + }, + "node_modules/http-request": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/http-request/-/http-request-0.7.0.tgz", + "integrity": "sha1-0DfisU1ozibsah3Tl60WDohxrMY=", + "dependencies": { + "form-data": ">= 0.1.2", + "mmmagic": ">= 0.3.4" + }, + "engines": { + "node": ">= 0.8.5" + } + }, + "node_modules/ipaddr.js": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-0.1.1.tgz", + "integrity": "sha1-KManwRagIcVVVE+QarGtVAsdY1o=", + "dependencies": { + "coffee-script": ">= 1.1.1" + }, + "engines": { + "node": ">= 0.2.5" + } + }, + "node_modules/mime-db": { + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.34", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", + "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", + "dependencies": { + "mime-db": "1.51.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mmmagic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mmmagic/-/mmmagic-0.5.3.tgz", + "integrity": "sha512-xLqCu7GJYTzJczg0jafXFuh+iPzQL/ru0YYf4GiTTz8Cehru/wiXtUS8Pp8Xi77zNaiVndJ0OO1yAFci6iHyFg==", + "hasInstallScript": true, + "dependencies": { + "nan": "^2.13.2" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/nan": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", + "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==" + }, + "node_modules/node-named-fixed": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/node-named-fixed/-/node-named-fixed-0.0.1.tgz", + "integrity": "sha512-dvmucpWOZHILXdDlBYefZ3Q62b2Z1zIuKJwgVDbJXDBTmszeJlwK2pDf5OaApqUHu2C4TYE5jBtNuGTXDq9MLQ==", + "dependencies": { + "bunyan": "0.7.0", + "ipaddr.js": "0.1.1" + }, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/progress-bar-formatter": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/progress-bar-formatter/-/progress-bar-formatter-2.0.1.tgz", + "integrity": "sha1-DZfrsWRn4sIwg3NXIXa3w1UeVW4=", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/safe-replace": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-replace/-/safe-replace-1.1.0.tgz", + "integrity": "sha512-9/V2E0CDsKs9DWOOwJH7jYpSl9S3N05uyevNjvsnDauBqRowBPOyot1fIvV5N2IuZAbYyvrTXrYFVG0RZInfFw==" + }, + "node_modules/status-bar": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/status-bar/-/status-bar-2.0.3.tgz", + "integrity": "sha1-DSaAIixFfhLeN86+FDjdScTgbhQ=", + "dependencies": { + "progress-bar-formatter": "^2.0.1" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/tftp": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/tftp/-/tftp-0.1.2.tgz", + "integrity": "sha1-lWdMCn/Ku1N1Wr7wutP55U/gt7U=", + "dependencies": { + "argp": "1.0.x", + "status-bar": "2.0.x" + }, + "bin": { + "ntftp": "bin/ntftp.js" + }, + "engines": { + "node": ">=0.10" + } + } + }, "dependencies": { + "@greenlock/manager": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@greenlock/manager/-/manager-3.1.0.tgz", + "integrity": "sha512-PBy5CMK+j4oD7sj7hF5qE+xKEOSiiuL2hHd5X5ttEbtnTSDKjNeqbrR5k2ZddwVNdjOVeBIeuqlm81IFZ+Ftew==", + "requires": { + "greenlock-manager-fs": "^3.1.0" + } + }, + "@root/acme": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@root/acme/-/acme-3.1.0.tgz", + "integrity": "sha512-GAyaW63cpSYd2KvVp5lHLbCWeEhJPKZK9nsJvZJOKsD9Uv88KEttn4FpDZEJ+2q3Jsey0DWpuQ2I4ft0JV9p2w==", + "requires": { + "@root/csr": "^0.8.1", + "@root/encoding": "^1.0.1", + "@root/keypairs": "^0.10.0", + "@root/pem": "^1.0.4", + "@root/request": "^1.6.1", + "@root/x509": "^0.7.2" + } + }, + "@root/asn1": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@root/asn1/-/asn1-1.0.0.tgz", + "integrity": "sha512-0lfZNuOULKJDJmdIkP8V9RnbV3XaK6PAHD3swnFy4tZwtlMDzLKoM/dfNad7ut8Hu3r91wy9uK0WA/9zym5mig==", + "requires": { + "@root/encoding": "^1.0.1" + } + }, + "@root/csr": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@root/csr/-/csr-0.8.1.tgz", + "integrity": "sha512-hKl0VuE549TK6SnS2Yn9nRvKbFZXn/oAg+dZJU/tlKl/f/0yRXeuUzf8akg3JjtJq+9E592zDqeXZ7yyrg8fSQ==", + "requires": { + "@root/asn1": "^1.0.0", + "@root/pem": "^1.0.4", + "@root/x509": "^0.7.2" + } + }, + "@root/encoding": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@root/encoding/-/encoding-1.0.1.tgz", + "integrity": "sha512-OaEub02ufoU038gy6bsNHQOjIn8nUjGiLcaRmJ40IUykneJkIW5fxDqKxQx48cszuNflYldsJLPPXCrGfHs8yQ==" + }, + "@root/greenlock": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@root/greenlock/-/greenlock-4.0.5.tgz", + "integrity": "sha512-KR9w3mYE9aH33FCibI8oSYBQV+f7lc3MVPdZ9nxY2tqRLmJp05cMOMz340mtG14VnWDuznLj4TbBj3sHIuoQPQ==", + "requires": { + "@greenlock/manager": "^3.1.0", + "@root/acme": "^3.1.0", + "@root/csr": "^0.8.1", + "@root/keypairs": "^0.10.0", + "@root/mkdirp": "^1.0.0", + "@root/request": "^1.6.1", + "acme-http-01-standalone": "^3.0.5", + "cert-info": "^1.5.1", + "greenlock-store-fs": "^3.2.2", + "safe-replace": "^1.1.0" + } + }, + "@root/keypairs": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/@root/keypairs/-/keypairs-0.10.3.tgz", + "integrity": "sha512-hbmjVbk/G99Z1XlUzJM4VOAaR8jm4vMnfwpZL301FA24ubJ/bOjj6enCrz9gKsQvBO6RY4/R4MgUuWpXeqeZZQ==", + "requires": { + "@root/encoding": "^1.0.1", + "@root/pem": "^1.0.4", + "@root/x509": "^0.7.2" + } + }, + "@root/mkdirp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@root/mkdirp/-/mkdirp-1.0.0.tgz", + "integrity": "sha512-hxGAYUx5029VggfG+U9naAhQkoMSXtOeXtbql97m3Hi6/sQSRL/4khKZPyOF6w11glyCOU38WCNLu9nUcSjOfA==" + }, + "@root/pem": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@root/pem/-/pem-1.0.4.tgz", + "integrity": "sha512-rEUDiUsHtild8GfIjFE9wXtcVxeS+ehCJQBwbQQ3IVfORKHK93CFnRtkr69R75lZFjcmKYVc+AXDB+AeRFOULA==" + }, + "@root/request": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@root/request/-/request-1.8.1.tgz", + "integrity": "sha512-Ib6jLQj4P4Dnx3LMqdV+TaSDlc7tWz25wKorklQ1rMHzHfc7LKELIuWl3XDQybimOPvIvlDuVX6/Mb10dEdQYg==" + }, + "@root/x509": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@root/x509/-/x509-0.7.2.tgz", + "integrity": "sha512-ENq3LGYORK5NiMFHEVeNMt+fTXaC7DTS6sQXoqV+dFdfT0vmiL5cDLjaXQhaklJQq0NiwicZegzJRl1ZOTp3WQ==", + "requires": { + "@root/asn1": "^1.0.0", + "@root/encoding": "^1.0.1" + } + }, + "acme-dns-01-duckdns": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/acme-dns-01-duckdns/-/acme-dns-01-duckdns-3.0.1.tgz", + "integrity": "sha512-s3BC1FFWUjTIoavRFP1mVc6YEqPazt8CVGPLGMV7r9Of70nvfYC8sWIOvol+PCrmTK7vUt8a9tS+P7qLoQE03A==", + "requires": { + "@root/request": "^1.3.11" + } + }, + "acme-http-01-standalone": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/acme-http-01-standalone/-/acme-http-01-standalone-3.0.5.tgz", + "integrity": "sha512-W4GfK+39GZ+u0mvxRVUcVFCG6gposfzEnSBF20T/NUwWAKG59wQT1dUbS1NixRIAsRuhpGc4Jx659cErFQH0Pg==" + }, "argp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/argp/-/argp-1.0.4.tgz", "integrity": "sha1-sxxzB1rW1syx2MhqzWn/MAMFsZQ=" }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "bunyan": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-0.7.0.tgz", + "integrity": "sha1-khBl5wyTb+MCp0DixWBXdb7qL0I=" + }, + "cert-info": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/cert-info/-/cert-info-1.5.1.tgz", + "integrity": "sha512-eoQC/yAgW3gKTKxjzyClvi+UzuY97YCjcl+lSqbsGIy7HeGaWxCPOQFivhUYm27hgsBMhsJJFya3kGvK6PMIcQ==" + }, + "coffee-script": { + "version": "1.12.7", + "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.12.7.tgz", + "integrity": "sha512-fLeEhqwymYat/MpTPUjSKHVYYl0ec2mOyALEMLmzr5i1isuG+6jfI2j2d5oBO3VIzgUXgBVIcOT9uH1TFxBckw==" + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "greenlock-manager-fs": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/greenlock-manager-fs/-/greenlock-manager-fs-3.1.1.tgz", + "integrity": "sha512-np6qdnPIOZx40PAcSQcqK1eMPWjTKxsxcgRd/OVg0ai49WC1Ds74CTrwmB84pq2n53ikbnDBQFmKEQ4AC0DK8w==", + "requires": { + "@root/mkdirp": "^1.0.0", + "safe-replace": "^1.1.0" + } + }, + "greenlock-store-fs": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/greenlock-store-fs/-/greenlock-store-fs-3.2.2.tgz", + "integrity": "sha512-92ejLB4DyV4qv/2b6VLGF2nKfYQeIfg3o+e/1cIoYLjlIaUFdbBXkzLTRozFlHsQPZt2ALi5qYrpC9IwH7GK8A==", + "requires": { + "@root/mkdirp": "^1.0.0", + "safe-replace": "^1.1.0" + } + }, + "http-request": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/http-request/-/http-request-0.7.0.tgz", + "integrity": "sha1-0DfisU1ozibsah3Tl60WDohxrMY=", + "requires": { + "form-data": ">= 0.1.2", + "mmmagic": ">= 0.3.4" + } + }, + "ipaddr.js": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-0.1.1.tgz", + "integrity": "sha1-KManwRagIcVVVE+QarGtVAsdY1o=", + "requires": { + "coffee-script": ">= 1.1.1" + } + }, + "mime-db": { + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==" + }, + "mime-types": { + "version": "2.1.34", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", + "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", + "requires": { + "mime-db": "1.51.0" + } + }, + "mmmagic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mmmagic/-/mmmagic-0.5.3.tgz", + "integrity": "sha512-xLqCu7GJYTzJczg0jafXFuh+iPzQL/ru0YYf4GiTTz8Cehru/wiXtUS8Pp8Xi77zNaiVndJ0OO1yAFci6iHyFg==", + "requires": { + "nan": "^2.13.2" + } + }, + "nan": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", + "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==" + }, + "node-named-fixed": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/node-named-fixed/-/node-named-fixed-0.0.1.tgz", + "integrity": "sha512-dvmucpWOZHILXdDlBYefZ3Q62b2Z1zIuKJwgVDbJXDBTmszeJlwK2pDf5OaApqUHu2C4TYE5jBtNuGTXDq9MLQ==", + "requires": { + "bunyan": "0.7.0", + "ipaddr.js": "0.1.1" + } + }, "progress-bar-formatter": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/progress-bar-formatter/-/progress-bar-formatter-2.0.1.tgz", "integrity": "sha1-DZfrsWRn4sIwg3NXIXa3w1UeVW4=" }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + }, + "safe-replace": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-replace/-/safe-replace-1.1.0.tgz", + "integrity": "sha512-9/V2E0CDsKs9DWOOwJH7jYpSl9S3N05uyevNjvsnDauBqRowBPOyot1fIvV5N2IuZAbYyvrTXrYFVG0RZInfFw==" + }, "status-bar": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/status-bar/-/status-bar-2.0.3.tgz", diff --git a/package.json b/package.json index f467b98..812c00b 100644 --- a/package.json +++ b/package.json @@ -10,12 +10,19 @@ "compress": "zip -r -X tch-exploit-win.zip release/tch-exploit-win.exe && zip -r -X tch-exploit-macos.zip release/tch-exploit-macos && zip -r -X tch-exploit-linux.zip release/tch-exploit-linux" }, "pkg": { - "scripts": "dist/*{,*/}*.js" + "scripts": ["dist/*{,*/}*.js", "./node_modules/node-named-fixed/lib/records/*"] }, "author": "BoLaMN", "license": "MIT", "description": "", "dependencies": { + "@root/acme": "^3.1.0", + "@root/greenlock": "^4.0.5", + "@root/keypairs": "^0.10.3", + "acme-dns-01-duckdns": "^3.0.1", + "http-request": "^0.7.0", + "node-named-fixed": "^0.0.1", + "punycode": "^2.1.1", "tftp": "^0.1.2" } } diff --git a/release/tch-exploit-linux b/release/tch-exploit-linux new file mode 100755 index 0000000..ba8a75e Binary files /dev/null and b/release/tch-exploit-linux differ diff --git a/release/tch-exploit-macos b/release/tch-exploit-macos new file mode 100755 index 0000000..e6cf08d Binary files /dev/null and b/release/tch-exploit-macos differ diff --git a/release/tch-exploit-win.exe b/release/tch-exploit-win.exe new file mode 100644 index 0000000..3f0997c Binary files /dev/null and b/release/tch-exploit-win.exe differ diff --git a/src/dhcp/index.coffee b/src/dhcp/index.coffee index fa55b88..223947e 100644 --- a/src/dhcp/index.coffee +++ b/src/dhcp/index.coffee @@ -1,6 +1,7 @@ server = require './server' path = require 'path' +args = require '../args' toHexArray = (str) -> str @@ -8,6 +9,7 @@ toHexArray = (str) -> .map (d, i) -> str.charCodeAt i module.exports = (ip, acsurl, acspass) -> + fullip = ip ip = ip.split '.' ip.pop() ip = ip.join '.' @@ -27,6 +29,7 @@ module.exports = (ip, acsurl, acspass) -> randomIP: true vendor: vendor netmask: '255.255.255.0' + dns: if args.dnsserver then [ fullip ] else [ '8.8.8.8', '8.8.4.4' ] router: [ ip + '.1' ] hostname: 'second.gateway' broadcast: ip + '.255' diff --git a/src/http/index.coffee b/src/http/index.coffee index ba0264d..1e1b4b6 100644 --- a/src/http/index.coffee +++ b/src/http/index.coffee @@ -1,6 +1,7 @@ -{ Duplex } = require 'stream' -{ createServer } = require 'http' -{ readFileSync, existsSync, statSync } = require 'fs' +{Duplex} = require 'stream' +{createServer} = require 'http' +createHttpsServer = require('https').createServer +{readFileSync} = require 'fs' path = require 'path' @@ -10,7 +11,6 @@ args = require '../args' cwmp = require './cwmp' module.exports = (ip, port, url) -> - if args.file file.name = path.basename args.file @@ -45,15 +45,15 @@ module.exports = (ip, port, url) -> stream.push file.data stream.push null stream.pipe res - .get '/done', (req, res) -> + .get '/done', (req, res) -> console.log '>>> WPS CALLBACK' console.log """\n - All done, + All done, - - change network card settings back to dhcp and move the cable back to a lan port - - try ssh connection to the gateways ip (usually 192.168.0.1) with username root and password root (change password immediately with passwd!) + - change network card settings back to dhcp and move the cable back to a lan port + - try ssh connection to the gateways ip (usually 192.168.0.1) with username root and password root (change password immediately with passwd!) - ssh root@192.168.0.1""" + ssh root@192.168.0.1""" setTimeout -> process.exit 1 @@ -62,13 +62,21 @@ module.exports = (ip, port, url) -> res.writeHead 200 res.end() - .post '/', cwmp(url) + .post '/', cwmp(url) + if(args.https) + console.log("Starting HTTPS server...") + httpsoptions = { + key: readFileSync('./key.key'), + cert: readFileSync('./cert.cert') + } + srv = createHttpsServer(httpsoptions,route) + else + console.log("Starting HTTP server...") + srv = createServer route - srv = createServer route srv.keepAliveTimeout = 30000 - srv.on 'error', (e) -> - if e.code in [ 'EADDRINUSE', 'EADDRNOTAVAIL' ] + if e.code in ['EADDRINUSE', 'EADDRNOTAVAIL'] console.log e.code + ', retrying...' setTimeout -> diff --git a/src/http/lecerts.coffee b/src/http/lecerts.coffee new file mode 100644 index 0000000..587e58c --- /dev/null +++ b/src/http/lecerts.coffee @@ -0,0 +1,57 @@ +{writeFileSync, existsSync} = require 'fs' +ACME = require '@root/acme' +duckdns = require 'acme-dns-01-duckdns' + +args = require '../args' + +module.exports = (domain) -> + if(existsSync('./key.key') && existsSync('./cert.cert')) + console.log("key.key and key.key already exists!") + return + if(args.duckdnstoken) + dns01 = duckdns.create({ + baseUrl: 'https://www.duckdns.org/update', + token: args.duckdnstoken + }); + console.log("Requesting HTTPS certificate to LE via duckdns...") + else + console.log("No duckdns token!!") + return + acme = ACME.create({ maintainerEmail:'tch-exploit@github.com', packageAgent:'tch-exploit/v1.0' }) + acme.init('https://acme-v02.api.letsencrypt.org/directory').then((r) -> + Keypairs = require('@root/keypairs'); + Keypairs.generate({ kty: 'EC', format: 'jwk' }).then((accountKeypair) -> + acme.accounts.create({ + subscriberEmail:'tch-exploit@github.com', + agreeToTerm:true, + accountKey:accountKeypair.private + }).then((account) -> + console.log("Starting LetsEncrypt DNS challenge via duckdns...") + Keypairs.generate({ kty: 'RSA', format: 'jwk' }).then((serverKeypair) -> + Keypairs.export({ jwk: serverKeypair.private }).then((privateKey) -> + CSR = require('@root/csr') + PEM = require('@root/pem') + punycode = require('punycode') + CSR.csr({ jwk: serverKeypair.private, domains: [punycode.toASCII(domain)], encoding:'der' }).then((csrDer) -> + csr = PEM.packBlock({ type: 'CERTIFICATE REQUEST', bytes: csrDer }); + acme.certificates.create({ + account: account, + accountKey: accountKeypair.private, + csr: csr, + domains: [domain], + challenges: { 'dns-01': dns01 } + }).then( (pems) -> + console.log("Key:") + console.log(privateKey) + console.log("Cert:") + console.log(pems.cert) + console.log("Certificate received, saving to key.key and cert.cert!") + writeFileSync('./key.key', privateKey) + writeFileSync('./cert.cert', pems.cert) + ) + ) + ) + ) + ) + ) + ) diff --git a/src/index.coffee b/src/index.coffee index 1b55e32..882853a 100644 --- a/src/index.coffee +++ b/src/index.coffee @@ -18,8 +18,10 @@ Technicolor OpenWRT Shell Unlocker v#{ pkg.version } By BoLaMN ask = require './ask' dhcpd = require './dhcp' httpd = require './http' +lecerts = require './http/lecerts' port = require './get-port' tftp = require './tftp' +ndns = require('node-named-fixed') servers = [] @@ -27,6 +29,8 @@ if args.tftp servers.push tftp(args)... else if args.dhcponly servers.push dhcpd ip, args.acsurl, args.acspass +else if args.certonly + lecerts new URL(args.acsurl).hostname else ask ip .then port @@ -41,6 +45,21 @@ else servers.push dhcpd ip, url, args.acspass servers.push httpd ip, p, url + if(args.dnsserver) + server = ndns.createServer(); + + server.listen(53, ip, -> + console.log('DNS server started on port 53') + ) + + server.on('query', (query) -> + domain = query.name(); + console.log('DNS Query: %s', domain) + target = new ndns.ARecord(ip); + query.addAnswer(domain, target, 10); + server.send(query); + ); + if process.platform is 'win32' rl = require('readline').createInterface input: process.stdin