diff --git a/README.md b/README.md index aa5ae5c2..1c905a8b 100755 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![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](http://img.shields.io/npm/v/cyberchef.svg)](https://www.npmjs.com/package/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) @@ -100,6 +100,6 @@ CyberChef is released under the [Apache 2.0 Licence](https://www.apache.org/lice [5]: https://gchq.github.io/CyberChef/#recipe=From_Hexdump()Gunzip()&input=MDAwMDAwMDAgIDFmIDhiIDA4IDAwIDEyIGJjIGYzIDU3IDAwIGZmIDBkIGM3IGMxIDA5IDAwIDIwICB8Li4uLi6881cu/y7HwS4uIHwKMDAwMDAwMTAgIDA4IDA1IGQwIDU1IGZlIDA0IDJkIGQzIDA0IDFmIGNhIDhjIDQ0IDIxIDViIGZmICB8Li7QVf4uLdMuLsouRCFb/3wKMDAwMDAwMjAgIDYwIGM3IGQ3IDAzIDE2IGJlIDQwIDFmIDc4IDRhIDNmIDA5IDg5IDBiIDlhIDdkICB8YMfXLi6%2BQC54Sj8uLi4ufXwKMDAwMDAwMzAgIDRlIGM4IDRlIDZkIDA1IDFlIDAxIDhiIDRjIDI0IDAwIDAwIDAwICAgICAgICAgICB8TshObS4uLi5MJC4uLnw [6]: https://gchq.github.io/CyberChef/#recipe=RC4(%7B'option':'UTF8','string':'secret'%7D,'Hex','Hex')Disassemble_x86('64','Full%20x86%20architecture',16,0,true,true)&input=MjFkZGQyNTQwMTYwZWU2NWZlMDc3NzEwM2YyYTM5ZmJlNWJjYjZhYTBhYWJkNDE0ZjkwYzZjYWY1MzEyNzU0YWY3NzRiNzZiM2JiY2QxOTNjYjNkZGZkYmM1YTI2NTMzYTY4NmI1OWI4ZmVkNGQzODBkNDc0NDIwMWFlYzIwNDA1MDcxMzhlMmZlMmIzOTUwNDQ2ZGIzMWQyYmM2MjliZTRkM2YyZWIwMDQzYzI5M2Q3YTVkMjk2MmMwMGZlNmRhMzAwNzJkOGM1YTZiNGZlN2Q4NTlhMDQwZWVhZjI5OTczMzYzMDJmNWEwZWMxOQ [7]: https://gchq.github.io/CyberChef/#recipe=Fork('%5C%5Cn','%5C%5Cn',false)From_UNIX_Timestamp('Seconds%20(s)')&input=OTc4MzQ2ODAwCjEwMTI2NTEyMDAKMTA0NjY5NjQwMAoxMDgxMDg3MjAwCjExMTUzMDUyMDAKMTE0OTYwOTYwMA - [8]: https://gchq.github.io/CyberChef/#recipe=Fork('%5C%5Cn','%5C%5Cn',false)Conditional_Jump('1',2,10)To_Hex('Space')Return()To_Base64('A-Za-z0-9%2B/%3D')&input=U29tZSBkYXRhIHdpdGggYSAxIGluIGl0ClNvbWUgZGF0YSB3aXRoIGEgMiBpbiBpdA + [8]: https://gchq.github.ioeCyberChef/#recipe=Fork('%5C%5Cn','%5C%5Cn',false)Conditional_Jump('1',false,'base64',10)To_Hex('Space')Return()Label('base64')To_Base64('A-Za-z0-9%2B/%3D')&input=U29tZSBkYXRhIHdpdGggYSAxIGluIGl0ClNvbWUgZGF0YSB3aXRoIGEgMiBpbiBpdA [9]: https://gchq.github.io/CyberChef/#recipe=Register('key%3D(%5B%5C%5Cda-f%5D*)',true,false)Find_/_Replace(%7B'option':'Regex','string':'.*data%3D(.*)'%7D,'$1',true,false,true)RC4(%7B'option':'Hex','string':'$R0'%7D,'Hex','Latin1')&input=aHR0cDovL21hbHdhcmV6LmJpei9iZWFjb24ucGhwP2tleT0wZTkzMmE1YyZkYXRhPThkYjdkNWViZTM4NjYzYTU0ZWNiYjMzNGUzZGIxMQ [10]: https://gchq.github.io/CyberChef/#recipe=XOR(%7B'option':'Hex','string':'3a'%7D,'',false)To_Hexdump(16,false,false)&input=VGhlIGFuc3dlciB0byB0aGUgdWx0aW1hdGUgcXVlc3Rpb24gb2YgbGlmZSwgdGhlIFVuaXZlcnNlLCBhbmQgZXZlcnl0aGluZyBpcyA0Mi4 diff --git a/package-lock.json b/package-lock.json index e4ba3947..8370224b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "6.5.0", + "version": "6.8.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -242,7 +242,7 @@ "dev": true, "requires": { "define-properties": "1.1.2", - "es-abstract": "1.9.0" + "es-abstract": "1.10.0" } }, "array-union": { @@ -286,9 +286,9 @@ "dev": true }, "asn1.js": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.9.1.tgz", - "integrity": "sha1-SLokC0WpKA6UdImQull9IWYX/UA=", + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.9.2.tgz", + "integrity": "sha512-b/OsSjvWEo8Pi8H0zsDd2P6Uqo2TK2pH8gNLSJtNLM2Db0v2QaAZ0pBQJXVjAn4gBuugeVDr7s63ZogpUIwWDg==", "dev": true, "requires": { "bn.js": "4.11.8", @@ -1054,9 +1054,9 @@ "dev": true }, "binary-extensions": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.10.0.tgz", - "integrity": "sha1-muuabF6IY4qtFx4Wf1kAq+JINdA=", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz", + "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=", "dev": true }, "bluebird": { @@ -1099,7 +1099,7 @@ "deep-equal": "1.0.1", "dns-equal": "1.0.0", "dns-txt": "2.0.2", - "multicast-dns": "6.2.0", + "multicast-dns": "6.2.1", "multicast-dns-service-types": "1.1.0" } }, @@ -1225,12 +1225,12 @@ } }, "browserify-zlib": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz", - "integrity": "sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0=", + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", "dev": true, "requires": { - "pako": "0.2.9" + "pako": "1.0.6" } }, "browserslist": { @@ -1799,9 +1799,9 @@ "integrity": "sha1-TCc3K8s85mnSKNV7NZG8YRjFKdU=" }, "crypto-browserify": { - "version": "3.11.1", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.11.1.tgz", - "integrity": "sha512-Na7ZlwCOqoaW5RwUK1WpXws2kv8mNhWdTlzob0UXulk6G9BDbyiJaGTYBIX61Ozn9l1EPPJpICZb4DaOpT9NlQ==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", "dev": true, "requires": { "browserify-cipher": "1.0.0", @@ -1813,7 +1813,8 @@ "inherits": "2.0.3", "pbkdf2": "3.0.14", "public-encrypt": "4.0.0", - "randombytes": "2.0.5" + "randombytes": "2.0.5", + "randomfill": "1.0.3" } }, "crypto-js": { @@ -1977,7 +1978,7 @@ "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", "dev": true, "requires": { - "es5-ext": "0.10.35" + "es5-ext": "0.10.37" } }, "dashdash": { @@ -2377,9 +2378,9 @@ } }, "es-abstract": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.9.0.tgz", - "integrity": "sha512-kk3IJoKo7A3pWJc0OV8yZ/VEX2oSUytfekrJiqoxBlKJMFAJVJVpGdHClCCTdv+Fn2zHfpDHHIelMFhZVfef3Q==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.10.0.tgz", + "integrity": "sha512-/uh/DhdqIOSkAWifU+8nG78vlQxdLckUdI/sPgy0VhuXi2qJ7T8czBmqIYtLQVpCIFYafChnsRsB5pyb1JdmCQ==", "dev": true, "requires": { "es-to-primitive": "1.1.1", @@ -2401,9 +2402,9 @@ } }, "es5-ext": { - "version": "0.10.35", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.35.tgz", - "integrity": "sha1-GO6FjOajxFx9eekcFfzKnsVoSU8=", + "version": "0.10.37", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.37.tgz", + "integrity": "sha1-DudB0Ui4AGm6J9AgOTdWryV978M=", "dev": true, "requires": { "es6-iterator": "2.0.3", @@ -2417,7 +2418,7 @@ "dev": true, "requires": { "d": "1.0.0", - "es5-ext": "0.10.35", + "es5-ext": "0.10.37", "es6-symbol": "3.1.1" } }, @@ -2428,7 +2429,7 @@ "dev": true, "requires": { "d": "1.0.0", - "es5-ext": "0.10.35", + "es5-ext": "0.10.37", "es6-iterator": "2.0.3", "es6-set": "0.1.5", "es6-symbol": "3.1.1", @@ -2448,7 +2449,7 @@ "dev": true, "requires": { "d": "1.0.0", - "es5-ext": "0.10.35", + "es5-ext": "0.10.37", "es6-iterator": "2.0.3", "es6-symbol": "3.1.1", "event-emitter": "0.3.5" @@ -2461,7 +2462,7 @@ "dev": true, "requires": { "d": "1.0.0", - "es5-ext": "0.10.35" + "es5-ext": "0.10.37" } }, "es6-weak-map": { @@ -2471,7 +2472,7 @@ "dev": true, "requires": { "d": "1.0.0", - "es5-ext": "0.10.35", + "es5-ext": "0.10.37", "es6-iterator": "2.0.3", "es6-symbol": "3.1.1" } @@ -2833,7 +2834,7 @@ "dev": true, "requires": { "d": "1.0.0", - "es5-ext": "0.10.35" + "es5-ext": "0.10.37" } }, "eventemitter2": { @@ -3110,9 +3111,9 @@ } }, "file-loader": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-1.1.5.tgz", - "integrity": "sha512-RzGHDatcVNpGISTvCpfUfOGpYuSR7HSsSg87ki+wF6rw1Hm0RALPTiAdsxAq1UwLf0RRhbe22/eHK6nhXspiOQ==", + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-1.1.6.tgz", + "integrity": "sha512-873ztuL+/hfvXbLDJ262PGO6XjERnybJu2gW1/5j8HUfxSiFJI9Hj/DhZ50ZGRUxBvuNiazb/cM2rh9pqrxP6Q==", "dev": true, "requires": { "loader-utils": "1.1.0", @@ -4966,9 +4967,9 @@ } }, "https-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-0.0.1.tgz", - "integrity": "sha1-P5E2XKvmC3ftDruiS0VOPgnZWoI=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", "dev": true }, "iconv-lite": { @@ -5134,7 +5135,7 @@ "integrity": "sha512-STx5orGQU1gfrkoI/fMU7lX6CSP7LBGO10gXNgOZhwKhUqbtNjCkYSewJtNnLmWP1tAGN6oyEpG1HFPw5vpa5Q==", "dev": true, "requires": { - "moment": "2.19.2", + "moment": "2.20.1", "sanitize-html": "1.15.0" } }, @@ -5222,9 +5223,9 @@ } }, "interpret": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.0.4.tgz", - "integrity": "sha1-ggzdWIuGj/sZGoCVBtbJyPISsbA=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", + "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", "dev": true }, "invariant": { @@ -5272,7 +5273,7 @@ "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", "dev": true, "requires": { - "binary-extensions": "1.10.0" + "binary-extensions": "1.11.0" } }, "is-buffer": { @@ -5569,9 +5570,9 @@ "integrity": "sha1-9yxcdhgXa/91zIEqHO2949jraDk=" }, "js-sha3": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.6.1.tgz", - "integrity": "sha1-W4n3enR3Z5h39YxKB1JAk0sflcA=" + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.7.0.tgz", + "integrity": "sha512-Wpks3yBDm0UcL5qlVhwW9Jr9n9i4FfeWBFOOXP5puDS/SiudJGhw7DPyBqn3487qD4F0lsC0q3zxink37f7zeA==" }, "js-tokens": { "version": "3.0.2", @@ -5684,7 +5685,7 @@ "cssstyle": "0.2.37", "escodegen": "1.9.0", "html-encoding-sniffer": "1.0.1", - "nwmatcher": "1.4.2", + "nwmatcher": "1.4.3", "parse5": "1.5.1", "request": "2.83.0", "sax": "1.2.4", @@ -6394,16 +6395,16 @@ } }, "moment": { - "version": "2.19.2", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.19.2.tgz", - "integrity": "sha512-Rf6jiHPEfxp9+dlzxPTmRHbvoFXsh2L/U8hOupUMpnuecHQmI6cF6lUbJl3QqKPko1u6ujO+FxtcajLVfLpAtA==" + "version": "2.20.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.20.1.tgz", + "integrity": "sha512-Yh9y73JRljxW5QxN08Fner68eFLxM5ynNOAw2LbIB1YAGeQzZT8QFSUvkAz609Zf+IHhhaUxqZK8dG3W/+HEvg==" }, "moment-timezone": { "version": "0.5.14", "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.14.tgz", "integrity": "sha1-TrOP+VOLgBCLpGekWPPtQmjM/LE=", "requires": { - "moment": "2.19.2" + "moment": "2.20.1" } }, "ms": { @@ -6413,9 +6414,9 @@ "dev": true }, "multicast-dns": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.0.tgz", - "integrity": "sha512-tnQqWkuWYHCOVRveiWQf+5KjHUnEmtxUycTy1esL4prQjXoT4qpndIS4fH63zObmHNxIHke3YHRnQrXYpXHf2A==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.1.tgz", + "integrity": "sha512-uV3/ckdsffHx9IrGQrx613mturMdMqQ06WTq+C09NsStJ9iNG6RcUWgPKs1Rfjy+idZT6tfQoXEusGNnEZhT3w==", "dev": true, "requires": { "dns-packet": "1.2.2", @@ -6478,21 +6479,21 @@ "dev": true }, "node-libs-browser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.0.0.tgz", - "integrity": "sha1-o6WeyXAkmFtG6Vg3lkb5bEthZkY=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.1.0.tgz", + "integrity": "sha512-5AzFzdoIMb89hBGMZglEegffzgRg+ZFoUmisQ8HI4j1KDdpx13J0taNp2y9xPbur6W61gepGDDotGBVQ7mfUCg==", "dev": true, "requires": { "assert": "1.4.1", - "browserify-zlib": "0.1.4", + "browserify-zlib": "0.2.0", "buffer": "4.9.1", "console-browserify": "1.1.0", "constants-browserify": "1.0.0", - "crypto-browserify": "3.11.1", + "crypto-browserify": "3.12.0", "domain-browser": "1.1.7", "events": "1.1.1", - "https-browserify": "0.0.1", - "os-browserify": "0.2.1", + "https-browserify": "1.0.0", + "os-browserify": "0.3.0", "path-browserify": "0.0.0", "process": "0.11.10", "punycode": "1.4.1", @@ -6500,20 +6501,12 @@ "readable-stream": "2.3.3", "stream-browserify": "2.0.1", "stream-http": "2.7.2", - "string_decoder": "0.10.31", + "string_decoder": "1.0.3", "timers-browserify": "2.0.4", "tty-browserify": "0.0.0", "url": "0.11.0", "util": "0.10.3", "vm-browserify": "0.0.4" - }, - "dependencies": { - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - } } }, "node-md6": { @@ -6616,10 +6609,9 @@ "dev": true }, "nwmatcher": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.2.tgz", - "integrity": "sha512-QMkCGQFYp5p+zwU3INntLmz1HMfSx9dMVJMYKmE1yuSf/22Wjo6VPFa405mCLUuQn9lbQvH2DZN9lt10ZNvtAg==", - "dev": true + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.3.tgz", + "integrity": "sha512-IKdSTiDWCarf2JTS5e9e2+5tPZGdkRJ79XjYV0pzK8Q9BpsFyBq1RGKxzs7Q8UBushGw7m6TzVKz6fcY99iSWw==" }, "oauth-sign": { "version": "0.8.2", @@ -6732,9 +6724,9 @@ } }, "os-browserify": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.2.1.tgz", - "integrity": "sha1-Y/xMzuXS13Y9Jrv4YBB45sLgBE8=", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", "dev": true }, "os-homedir": { @@ -6809,9 +6801,9 @@ } }, "pako": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", - "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz", + "integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg==", "dev": true }, "param-case": { @@ -6829,7 +6821,7 @@ "integrity": "sha1-N8T5t+06tlx0gXtfJICTf7+XxxI=", "dev": true, "requires": { - "asn1.js": "4.9.1", + "asn1.js": "4.9.2", "browserify-aes": "1.1.1", "create-hash": "1.1.3", "evp_bytestokey": "1.0.3", @@ -7425,13 +7417,13 @@ } }, "postcss-loader": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-2.0.8.tgz", - "integrity": "sha512-KtXBiQ/r/WYW8LxTSJK7h8wLqvCMSub/BqmRnud/Mu8RzwflW9cmXxwsMwbn15TNv287Hcufdb3ZSs7xHKnG8Q==", + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-2.0.9.tgz", + "integrity": "sha512-sgoXPtmgVT3aBAhU47Kig8oPF+mbXl8Unjvtz1Qj1q2D2EvSVJW2mKJNzxv5y/LvA9xWwuvdysvhc7Zn80UWWw==", "dev": true, "requires": { "loader-utils": "1.1.0", - "postcss": "6.0.13", + "postcss": "6.0.14", "postcss-load-config": "1.2.0", "schema-utils": "0.3.0" }, @@ -7463,9 +7455,9 @@ "dev": true }, "postcss": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz", - "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==", + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", "dev": true, "requires": { "chalk": "2.3.0", @@ -8142,6 +8134,16 @@ "safe-buffer": "5.1.1" } }, + "randomfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.3.tgz", + "integrity": "sha512-YL6GrhrWoic0Eq8rXVbMptH7dAxCs0J+mh5Y0euNekPPYaxEmdVGim6GdoxoRzKW2yJoU8tueifS7mYxvcFDEQ==", + "dev": true, + "requires": { + "randombytes": "2.0.5", + "safe-buffer": "5.1.1" + } + }, "range-parser": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", @@ -9137,9 +9139,9 @@ "dev": true }, "style-loader": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.19.0.tgz", - "integrity": "sha512-9mx9sC9nX1dgP96MZOODpGC6l1RzQBITI2D5WJhu+wnbrSYVKLGuy14XJSLVQih/0GFrPpjelt+s//VcZQ2Evw==", + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.19.1.tgz", + "integrity": "sha512-IRE+ijgojrygQi3rsqT0U4dd+UcPCqcVvauZpCnQrGAlEe+FUIyrK93bUDScamesjP08JlQNsFJU+KmPedP5Og==", "dev": true, "requires": { "loader-utils": "1.1.0", @@ -9762,26 +9764,26 @@ "dev": true }, "webpack": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-3.8.1.tgz", - "integrity": "sha512-5ZXLWWsMqHKFr5y0N3Eo5IIisxeEeRAajNq4mELb/WELOR7srdbQk2N5XiyNy2A/AgvlR3AmeBCZJW8lHrolbw==", + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-3.10.0.tgz", + "integrity": "sha512-fxxKXoicjdXNUMY7LIdY89tkJJJ0m1Oo8PQutZ5rLgWbV5QVKI15Cn7+/IHnRTd3vfKfiwBx6SBqlorAuNA8LA==", "dev": true, "requires": { - "acorn": "5.1.2", + "acorn": "5.2.1", "acorn-dynamic-import": "2.0.2", "ajv": "5.2.3", "ajv-keywords": "2.1.0", "async": "2.5.0", "enhanced-resolve": "3.4.1", "escope": "3.6.0", - "interpret": "1.0.4", + "interpret": "1.1.0", "json-loader": "0.5.7", "json5": "0.5.1", "loader-runner": "2.3.0", "loader-utils": "1.1.0", "memory-fs": "0.4.1", "mkdirp": "0.5.1", - "node-libs-browser": "2.0.0", + "node-libs-browser": "2.1.0", "source-map": "0.5.7", "supports-color": "4.5.0", "tapable": "0.2.8", @@ -9792,9 +9794,9 @@ }, "dependencies": { "acorn": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.1.2.tgz", - "integrity": "sha512-o96FZLJBPY1lvTuJylGA9Bk3t/GKPPJG8H0ydQQl01crzwJgspa4AEIq/pVTXigmK0PHVQhiAtn8WMBLL9D2WA==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.2.1.tgz", + "integrity": "sha512-jG0u7c4Ly+3QkkW18V+NRDN+4bWHdln30NL1ZL2AvFZZmQe/BfopYCtghCKKVBUSetZ4QKcyA0pY6/4Gw8Pv8w==", "dev": true }, "escope": { @@ -9827,22 +9829,30 @@ } }, "webpack-dev-middleware": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-1.12.0.tgz", - "integrity": "sha1-007++y7dp+HTtdvgcolRMhllFwk=", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-1.12.2.tgz", + "integrity": "sha512-FCrqPy1yy/sN6U/SaEZcHKRXGlqU0DUaEBL45jkUYoB8foVb6wCnbIJ1HKIx+qUFTW+3JpVcCJCxZ8VATL4e+A==", "dev": true, "requires": { "memory-fs": "0.4.1", - "mime": "1.4.1", + "mime": "1.6.0", "path-is-absolute": "1.0.1", "range-parser": "1.2.0", "time-stamp": "2.0.0" + }, + "dependencies": { + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + } } }, "webpack-dev-server": { - "version": "2.9.4", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-2.9.4.tgz", - "integrity": "sha512-thrqC0EQEoSjXeYgP6pUXcUCZ+LNrKsDPn+mItLnn5VyyNZOJKd06hUP5vqkYwL8nWWXsii0loSF9NHNccT6ow==", + "version": "2.9.7", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-2.9.7.tgz", + "integrity": "sha512-Pu7uoQFgQj5RE5wmlfkpYSzihMKxulwEuO2xCsaMnAnyRSApwoVi3B8WCm9XbigyWTHaIMzYGkB90Vr6leAeTQ==", "dev": true, "requires": { "ansi-html": "0.0.7", @@ -9870,7 +9880,7 @@ "spdy": "3.4.7", "strip-ansi": "3.0.1", "supports-color": "4.5.0", - "webpack-dev-middleware": "1.12.0", + "webpack-dev-middleware": "1.12.2", "yargs": "6.6.0" }, "dependencies": { @@ -10203,9 +10213,9 @@ "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=" }, "xpath": { - "version": "0.0.24", - "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.24.tgz", - "integrity": "sha1-Gt4WLhzFI8jTn8fQavwW6iFvKfs=" + "version": "0.0.27", + "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.27.tgz", + "integrity": "sha512-fg03WRxtkCV6ohClePNAECYsmpKKTv5L8y/X3Dn1hQrec3POx2jHZ/0P2qQ6HvsrU1BmeqXcof3NGGueG6LxwQ==" }, "xtend": { "version": "4.0.1", diff --git a/package.json b/package.json index 8c6fc2d8..3319e9fa 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "6.5.0", + "version": "6.8.0", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef", @@ -36,7 +36,7 @@ "css-loader": "^0.28.7", "exports-loader": "^0.6.4", "extract-text-webpack-plugin": "^3.0.2", - "file-loader": "^1.1.5", + "file-loader": "^1.1.6", "grunt": ">=1.0.1", "grunt-accessibility": "~5.0.0", "grunt-chmod": "~1.1.1", @@ -56,13 +56,13 @@ "less-loader": "^4.0.5", "postcss-css-variables": "^0.8.0", "postcss-import": "^11.0.0", - "postcss-loader": "^2.0.8", - "style-loader": "^0.19.0", + "postcss-loader": "^2.0.9", + "style-loader": "^0.19.1", "url-loader": "^0.6.2", "val-loader": "^1.1.0", "web-resource-inliner": "^4.2.0", - "webpack": "^3.8.1", - "webpack-dev-server": "^2.9.4", + "webpack": "^3.10.0", + "webpack-dev-server": "^2.9.7", "webpack-node-externals": "^1.6.0", "worker-loader": "^1.1.0" }, @@ -82,14 +82,15 @@ "google-code-prettify": "^1.0.5", "jquery": "^3.2.1", "js-crc": "^0.2.0", - "js-sha3": "^0.6.1", + "js-sha3": "^0.7.0", "jsbn": "^1.1.0", "jsonpath": "^1.0.0", "jsrsasign": "8.0.4", "lodash": "^4.17.4", - "moment": "^2.19.2", + "moment": "^2.20.1", "moment-timezone": "^0.5.14", "node-md6": "^0.1.0", + "nwmatcher": "^1.4.3", "otp": "^0.1.3", "sladex-blowfish": "^0.8.1", "sortablejs": "^1.7.0", @@ -97,7 +98,7 @@ "utf8": "^3.0.0", "vkbeautify": "^0.99.3", "xmldom": "^0.1.27", - "xpath": "0.0.24", + "xpath": "0.0.27", "zlibjs": "^0.3.1" }, "scripts": { diff --git a/src/core/Dish.js b/src/core/Dish.js index f1093966..4a16919a 100755 --- a/src/core/Dish.js +++ b/src/core/Dish.js @@ -13,7 +13,7 @@ import Utils from "./Utils.js"; */ const Dish = function(value, type) { this.value = value || typeof value === "string" ? value : null; - this.type = type || Dish.BYTE_ARRAY; + this.type = type || Dish.BYTE_ARRAY; }; @@ -112,7 +112,7 @@ Dish.enumLookup = function(typeEnum) { */ Dish.prototype.set = function(value, type) { this.value = value; - this.type = type; + this.type = type; if (!this.valid()) { const sample = Utils.truncate(JSON.stringify(this.value), 13); diff --git a/src/core/FlowControl.js b/src/core/FlowControl.js index 4a94ffdf..bba5eaf1 100755 --- a/src/core/FlowControl.js +++ b/src/core/FlowControl.js @@ -170,18 +170,14 @@ const FlowControl = { */ runJump: function(state) { let ings = state.opList[state.progress].getIngValues(), - jumpNum = ings[0], + jmpIndex = FlowControl._getLabelIndex(ings[0], state), maxJumps = ings[1]; - if (jumpNum < 0) { - jumpNum--; - } - - if (state.numJumps >= maxJumps) { + if (state.numJumps >= maxJumps || jmpIndex === -1) { return state; } - state.progress += jumpNum; + state.progress = jmpIndex; state.numJumps++; return state; }, @@ -201,20 +197,20 @@ const FlowControl = { let ings = state.opList[state.progress].getIngValues(), dish = state.dish, regexStr = ings[0], - jumpNum = ings[1], - maxJumps = ings[2]; + invert = ings[1], + jmpIndex = FlowControl._getLabelIndex(ings[2], state), + maxJumps = ings[3]; - if (jumpNum < 0) { - jumpNum--; - } - - if (state.numJumps >= maxJumps) { + if (state.numJumps >= maxJumps || jmpIndex === -1) { return state; } - if (regexStr !== "" && dish.get(Dish.STRING).search(regexStr) > -1) { - state.progress += jumpNum; - state.numJumps++; + if (regexStr !== "") { + let strMatch = dish.get(Dish.STRING).search(regexStr) > -1; + if (!invert && strMatch || invert && !strMatch) { + state.progress = jmpIndex; + state.numJumps++; + } } return state; @@ -249,6 +245,26 @@ const FlowControl = { return state; }, + + /** + * Returns the index of a label. + * + * @param {Object} state + * @param {string} name + * @returns {number} + */ + _getLabelIndex: function(name, state) { + for (let o = 0; o < state.opList.length; o++) { + let operation = state.opList[o]; + if (operation.name === "Label"){ + let ings = operation.getIngValues(); + if (name === ings[0]) { + return o; + } + } + } + return -1; + }, }; export default FlowControl; diff --git a/src/core/Utils.js b/src/core/Utils.js index 4ab365c8..766bc118 100755 --- a/src/core/Utils.js +++ b/src/core/Utils.js @@ -879,7 +879,7 @@ const Utils = { * * fragment = *( pchar / "/" / "?" ) * query = *( pchar / "/" / "?" ) - * pchar = unreserved / pct-encoded / sub-delims / ":" / "@" + * pchar = unreserved / pct-encoded / sub-delims / ":" / "@" * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" * pct-encoded = "%" HEXDIG HEXDIG * sub-delims = "!" / "$" / "&" / "'" / "(" / ")" diff --git a/src/core/config/Categories.js b/src/core/config/Categories.js index 3bc672b7..e2ee57cf 100755 --- a/src/core/config/Categories.js +++ b/src/core/config/Categories.js @@ -113,7 +113,7 @@ const Categories = [ ] }, { - name: "Logical operations", + name: "Arithmetic / Logic", ops: [ "XOR", "XOR Brute Force", @@ -122,6 +122,13 @@ const Categories = [ "AND", "ADD", "SUB", + "Sum", + "Subtract", + "Multiply", + "Divide", + "Mean", + "Median", + "Standard Deviation", "Bit shift left", "Bit shift right", "Rotate left", @@ -302,6 +309,7 @@ const Categories = [ ops: [ "Entropy", "Frequency distribution", + "Chi Square", "Detect File Type", "Scan for Embedded Files", "Disassemble x86", @@ -320,6 +328,7 @@ const Categories = [ "Fork", "Merge", "Register", + "Label", "Jump", "Conditional Jump", "Return", diff --git a/src/core/config/OperationConfig.js b/src/core/config/OperationConfig.js index d353328b..354ec12e 100755 --- a/src/core/config/OperationConfig.js +++ b/src/core/config/OperationConfig.js @@ -1,3 +1,4 @@ +import Arithmetic from "../operations/Arithmetic.js"; import Base from "../operations/Base.js"; import Base58 from "../operations/Base58.js"; import Base64 from "../operations/Base64.js"; @@ -137,15 +138,15 @@ const OperationConfig = { }, "Jump": { module: "Default", - description: "Jump forwards or backwards over the specified number of operations.", + description: "Jump forwards or backwards to the specified Label", inputType: "string", outputType: "string", flowControl: true, args: [ { - name: "Number of operations to jump over", - type: "number", - value: 0 + name: "Label name", + type: "string", + value: "" }, { name: "Maximum jumps (if jumping backwards)", @@ -156,7 +157,7 @@ const OperationConfig = { }, "Conditional Jump": { module: "Default", - description: "Conditionally jump forwards or backwards over the specified number of operations based on whether the data matches the specified regular expression.", + description: "Conditionally jump forwards or backwards to the specified Label based on whether the data matches the specified regular expression.", inputType: "string", outputType: "string", flowControl: true, @@ -167,9 +168,14 @@ const OperationConfig = { value: "" }, { - name: "Number of operations to jump over if match found", - type: "number", - value: 0 + name: "Invert match", + type: "boolean", + value: false + }, + { + name: "Label name", + type: "shortString", + value: "" }, { name: "Maximum jumps (if jumping backwards)", @@ -178,6 +184,20 @@ const OperationConfig = { } ] }, + "Label": { + module: "Default", + description: "Provides a location for conditional and fixed jumps to redirect execution to.", + inputType: "string", + outputType: "string", + flowControl: true, + args: [ + { + name: "Name", + type: "shortString", + value: "" + } + ] + }, "Return": { module: "Default", description: "End execution of operations at this point in the recipe.", @@ -500,6 +520,97 @@ const OperationConfig = { } ] }, + "Sum": { + module: "Default", + description: "Adds together a list of numbers. If an item in the string is not a number it is excluded from the list.

e.g. 0x0a 8 .5 becomes 18.5", + inputType: "string", + outputType: "number", + args: [ + { + name: "Delimiter", + type: "option", + value: Arithmetic.DELIM_OPTIONS + } + ] + }, + "Subtract": { + module: "Default", + description: "Subtracts a list of numbers. If an item in the string is not a number it is excluded from the list.

e.g. 0x0a 8 .5 becomes 1.5", + inputType: "string", + outputType: "number", + args: [ + { + name: "Delimiter", + type: "option", + value: Arithmetic.DELIM_OPTIONS + } + ] + }, + "Multiply": { + module: "Default", + description: "Multiplies a list of numbers. If an item in the string is not a number it is excluded from the list.

e.g. 0x0a 8 .5 becomes 40", + inputType: "string", + outputType: "number", + args: [ + { + name: "Delimiter", + type: "option", + value: Arithmetic.DELIM_OPTIONS + } + ] + }, + "Divide": { + module: "Default", + description: "Divides a list of numbers. If an item in the string is not a number it is excluded from the list.

e.g. 0x0a 8 .5 becomes 2.5", + inputType: "string", + outputType: "number", + args: [ + { + name: "Delimiter", + type: "option", + value: Arithmetic.DELIM_OPTIONS + } + ] + }, + "Mean": { + module: "Default", + description: "Computes the mean (average) of a number list. If an item in the string is not a number it is excluded from the list.

e.g. 0x0a 8 .5 .5 becomes 4.75", + inputType: "string", + outputType: "number", + args: [ + { + name: "Delimiter", + type: "option", + value: Arithmetic.DELIM_OPTIONS + } + ] + }, + "Median": { + module: "Default", + description: "Computes the median of a number list. If an item in the string is not a number it is excluded from the list.

e.g. 0x0a 8 1 .5 becomes 4.5", + inputType: "string", + outputType: "number", + args: [ + { + name: "Delimiter", + type: "option", + value: Arithmetic.DELIM_OPTIONS + } + ] + }, + "Standard Deviation": { + module: "Default", + description: "Computes the standard deviation of a number list. If an item in the string is not a number it is excluded from the list.

e.g. 0x0a 8 .5 becomes 4.089281382128433", + inputType: "string", + outputType: "number", + args: [ + { + name: "Delimiter", + type: "option", + value: Arithmetic.DELIM_OPTIONS + } + ] + }, "From Hex": { module: "Default", description: "Converts a hexadecimal byte string back into its raw value.

e.g. ce 93 ce b5 ce b9 ce ac 20 cf 83 ce bf cf 85 0a becomes the UTF-8 encoded string Γειά σου", @@ -3186,6 +3297,13 @@ const OperationConfig = { } ] }, + "Chi Square": { + module: "Default", + description: "Calculates the Chi Square distribution of values.", + inputType: "byteArray", + outputType: "number", + args: [] + }, "Numberwang": { module: "Default", description: "Based on the popular gameshow by Mitchell and Webb.", @@ -3821,7 +3939,7 @@ const OperationConfig = { "Generate HOTP": { module: "Default", description: "The HMAC-based One-Time Password algorithm (HOTP) is an algorithm that computes a one-time password from a shared secret key and an incrementing counter. It has been adopted as Internet Engineering Task Force standard RFC 4226, is the cornerstone of Initiative For Open Authentication (OATH), and is used in a number of two-factor authentication systems.

Enter the secret as the input or leave it blank for a random secret to be generated.", - inputType: "string", + inputType: "byteArray", outputType: "string", args: [ { diff --git a/src/core/config/modules/Default.js b/src/core/config/modules/Default.js index eea41164..b36e00aa 100644 --- a/src/core/config/modules/Default.js +++ b/src/core/config/modules/Default.js @@ -1,4 +1,5 @@ import FlowControl from "../../FlowControl.js"; +import Arithmetic from "../../operations/Arithmetic.js"; import Base from "../../operations/Base.js"; import Base58 from "../../operations/Base58.js"; import Base64 from "../../operations/Base64.js"; @@ -38,6 +39,7 @@ import UUID from "../../operations/UUID.js"; * Libraries: * - Utils.js * - otp + * - crypto * * @author n1474335 [n1474335@gmail.com] * @copyright Crown Copyright 2017 @@ -141,6 +143,7 @@ OpModules.Default = { "Microsoft Script Decoder": MS.runDecodeScript, "Entropy": Entropy.runEntropy, "Frequency distribution": Entropy.runFreqDistrib, + "Chi Square": Entropy.runChiSq, "Detect File Type": FileType.runDetect, "Scan for Embedded Files": FileType.runScanForEmbeddedFiles, "Generate UUID": UUID.runGenerateV4, @@ -150,11 +153,19 @@ OpModules.Default = { "Fork": FlowControl.runFork, "Merge": FlowControl.runMerge, "Register": FlowControl.runRegister, + "Label": FlowControl.runComment, "Jump": FlowControl.runJump, "Conditional Jump": FlowControl.runCondJump, "Return": FlowControl.runReturn, "Comment": FlowControl.runComment, "PHP Deserialize": PHP.runDeserialize, + "Sum": Arithmetic.runSum, + "Subtract": Arithmetic.runSub, + "Multiply": Arithmetic.runMulti, + "Divide": Arithmetic.runDiv, + "Mean": Arithmetic.runMean, + "Median": Arithmetic.runMedian, + "Standard Deviation": Arithmetic.runStdDev, /* diff --git a/src/core/operations/Arithmetic.js b/src/core/operations/Arithmetic.js new file mode 100644 index 00000000..1fe73ac1 --- /dev/null +++ b/src/core/operations/Arithmetic.js @@ -0,0 +1,252 @@ +import Utils from "../Utils.js"; + + +/** + * Math operations on numbers. + * + * @author bwhitn [brian.m.whitney@outlook.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + * + * @namespace + */ +const Arithmetic = { + + /** + * @constant + * @default + */ + DELIM_OPTIONS: ["Line feed", "Space", "Comma", "Semi-colon", "Colon", "CRLF"], + + + /** + * Splits a string based on a delimiter and calculates the sum of numbers. + * + * @param {string} input + * @param {Object[]} args + * @returns {number} + */ + runSum: function(input, args) { + const val = Arithmetic._sum(Arithmetic._createNumArray(input, args[0])); + return typeof(val) === "number" ? val : NaN; + }, + + + /** + * Splits a string based on a delimiter and subtracts all the numbers. + * + * @param {string} input + * @param {Object[]} args + * @returns {number} + */ + runSub: function(input, args) { + let val = Arithmetic._sub(Arithmetic._createNumArray(input, args[0])); + return typeof(val) === "number" ? val : NaN; + }, + + + /** + * Splits a string based on a delimiter and multiplies the numbers. + * + * @param {string} input + * @param {Object[]} args + * @returns {number} + */ + runMulti: function(input, args) { + let val = Arithmetic._multi(Arithmetic._createNumArray(input, args[0])); + return typeof(val) === "number" ? val : NaN; + }, + + + /** + * Splits a string based on a delimiter and divides the numbers. + * + * @param {string} input + * @param {Object[]} args + * @returns {number} + */ + runDiv: function(input, args) { + let val = Arithmetic._div(Arithmetic._createNumArray(input, args[0])); + return typeof(val) === "number" ? val : NaN; + }, + + + /** + * Splits a string based on a delimiter and computes the mean (average). + * + * @param {string} input + * @param {Object[]} args + * @returns {number} + */ + runMean: function(input, args) { + let val = Arithmetic._mean(Arithmetic._createNumArray(input, args[0])); + return typeof(val) === "number" ? val : NaN; + }, + + + /** + * Splits a string based on a delimiter and finds the median. + * + * @param {string} input + * @param {Object[]} args + * @returns {number} + */ + runMedian: function(input, args) { + let val = Arithmetic._median(Arithmetic._createNumArray(input, args[0])); + return typeof(val) === "number" ? val : NaN; + }, + + + /** + * splits a string based on a delimiter and computes the standard deviation. + * + * @param {string} input + * @param {Object[]} args + * @returns {number} + */ + runStdDev: function(input, args) { + let val = Arithmetic._stdDev(Arithmetic._createNumArray(input, args[0])); + return typeof(val) === "number" ? val : NaN; + }, + + + /** + * Converts a string array to a number array. + * + * @private + * @param {string[]} input + * @param {string} delim + * @returns {number[]} + */ + _createNumArray: function(input, delim) { + delim = Utils.charRep[delim || "Space"]; + let splitNumbers = input.split(delim), + numbers = [], + num; + + for (let i = 0; i < splitNumbers.length; i++) { + if (splitNumbers[i].indexOf(".") >= 0) { + num = parseFloat(splitNumbers[i].trim()); + } else { + num = parseInt(splitNumbers[i].trim(), 0); + } + if (!isNaN(num)) { + numbers.push(num); + } + } + return numbers; + }, + + + /** + * Adds an array of numbers and returns the value. + * + * @private + * @param {number[]} data + * @returns {number} + */ + _sum: function(data) { + if (data.length > 0) { + return data.reduce((acc, curr) => acc + curr); + } + }, + + + /** + * Subtracts an array of numbers and returns the value. + * + * @private + * @param {number[]} data + * @returns {number} + */ + _sub: function(data) { + if (data.length > 0) { + return data.reduce((acc, curr) => acc - curr); + } + }, + + + /** + * Multiplies an array of numbers and returns the value. + * + * @private + * @param {number[]} data + * @returns {number} + */ + _multi: function(data) { + if (data.length > 0) { + return data.reduce((acc, curr) => acc * curr); + } + }, + + + /** + * Divides an array of numbers and returns the value. + * + * @private + * @param {number[]} data + * @returns {number} + */ + _div: function(data) { + if (data.length > 0) { + return data.reduce((acc, curr) => acc / curr); + } + }, + + + /** + * Computes mean of a number array and returns the value. + * + * @private + * @param {number[]} data + * @returns {number} + */ + _mean: function(data) { + if (data.length > 0) { + return Arithmetic._sum(data) / data.length; + } + }, + + + /** + * Computes median of a number array and returns the value. + * + * @private + * @param {number[]} data + * @returns {number} + */ + _median: function (data) { + if ((data.length % 2) === 0) { + let first, second; + data.sort(function(a, b){ + return a - b; + }); + first = data[Math.floor(data.length / 2)]; + second = data[Math.floor(data.length / 2) - 1]; + return Arithmetic._mean([first, second]); + } else { + return data[Math.floor(data.length / 2)]; + } + }, + + + /** + * Computes standard deviation of a number array and returns the value. + * + * @private + * @param {number[]} data + * @returns {number} + */ + _stdDev: function (data) { + if (data.length > 0) { + let avg = Arithmetic._mean(data); + let devSum = 0; + for (let i = 0; i < data.length; i++) { + devSum += (data[i] - avg) ** 2; + } + return Math.sqrt(devSum / data.length); + } + }, +}; + +export default Arithmetic; diff --git a/src/core/operations/ByteRepr.js b/src/core/operations/ByteRepr.js index 5ba7f082..87a543ff 100755 --- a/src/core/operations/ByteRepr.js +++ b/src/core/operations/ByteRepr.js @@ -186,7 +186,7 @@ const ByteRepr = { // 0x and \x are added to the beginning if they are selected, so increment the positions accordingly if (delim === "0x" || delim === "\\x") { pos[0].start += 2; - pos[0].end += 2; + pos[0].end += 2; } return pos; }, diff --git a/src/core/operations/Code.js b/src/core/operations/Code.js index fb4a7e9d..d6904e09 100755 --- a/src/core/operations/Code.js +++ b/src/core/operations/Code.js @@ -2,9 +2,10 @@ import {camelCase, kebabCase, snakeCase} from "lodash"; import Utils from "../Utils.js"; import vkbeautify from "vkbeautify"; -import {DOMParser as dom} from "xmldom"; +import {DOMParser} from "xmldom"; import xpath from "xpath"; import jpath from "jsonpath"; +import nwmatcher from "nwmatcher"; import prettyPrintOne from "imports-loader?window=>global!exports-loader?prettyPrintOne!google-code-prettify/bin/prettify.min.js"; @@ -336,7 +337,7 @@ const Code = { let doc; try { - doc = new dom().parseFromString(input); + doc = new DOMParser().parseFromString(input, "application/xml"); } catch (err) { return "Invalid input XML."; } @@ -423,7 +424,7 @@ const Code = { let query = args[0], delimiter = args[1], parser = new DOMParser(), - html, + dom, result; if (!query.length || !input.length) { @@ -431,32 +432,32 @@ const Code = { } try { - html = parser.parseFromString(input, "text/html"); + dom = parser.parseFromString(input); } catch (err) { return "Invalid input HTML."; } try { - result = html.querySelectorAll(query); + const matcher = nwmatcher({document: dom}); + result = matcher.select(query, dom); } catch (err) { return "Invalid CSS Selector. Details:\n" + err.message; } const nodeToString = function(node) { + return node.toString(); + /* xmldom does not return the outerHTML value. switch (node.nodeType) { - case Node.ELEMENT_NODE: return node.outerHTML; - case Node.ATTRIBUTE_NODE: return node.value; - case Node.COMMENT_NODE: return node.data; - case Node.TEXT_NODE: return node.wholeText; - case Node.DOCUMENT_NODE: return node.outerHTML; + case node.ELEMENT_NODE: return node.outerHTML; + case node.ATTRIBUTE_NODE: return node.value; + case node.TEXT_NODE: return node.wholeText; + case node.COMMENT_NODE: return node.data; + case node.DOCUMENT_NODE: return node.outerHTML; default: throw new Error("Unknown Node Type: " + node.nodeType); - } + }*/ }; - return Array.apply(null, Array(result.length)) - .map(function(_, i) { - return result[i]; - }) + return result .map(nodeToString) .join(delimiter); }, diff --git a/src/core/operations/Entropy.js b/src/core/operations/Entropy.js index 3451914d..aa9ed0bc 100755 --- a/src/core/operations/Entropy.js +++ b/src/core/operations/Entropy.js @@ -135,6 +135,31 @@ const Entropy = { }, + /** + * Chi Square operation. + * + * @param {byteArray} data + * @param {Object[]} args + * @returns {number} + */ + runChiSq: function(input, args) { + let distArray = new Array(256).fill(0), + total = 0; + + for (let i = 0; i < input.length; i++) { + distArray[input[i]]++; + } + + for (let i = 0; i < distArray.length; i++) { + if (distArray[i] > 0) { + total += Math.pow(distArray[i] - input.length / 256, 2) / (input.length / 256); + } + } + + return total; + }, + + /** * Calculates the Shannon entropy for a given chunk of data. * diff --git a/src/core/operations/MS.js b/src/core/operations/MS.js index d0f6149a..a74dbe17 100644 --- a/src/core/operations/MS.js +++ b/src/core/operations/MS.js @@ -1,5 +1,5 @@ /** - * Microsoft operations. + * Microsoft operations. * * @author bmwhitn [brian.m.whitney@outlook.com] * @copyright Crown Copyright 2017 diff --git a/src/core/operations/NetBIOS.js b/src/core/operations/NetBIOS.js index 0927775a..60866b65 100644 --- a/src/core/operations/NetBIOS.js +++ b/src/core/operations/NetBIOS.js @@ -26,9 +26,14 @@ const NetBIOS = { let output = [], offset = args[0]; - for (let i = 0; i < input.length; i++) { - output.push((input[i] >> 4) + offset); - output.push((input[i] & 0xf) + offset); + if (input.length <= 16) { + let len = input.length; + input.length = 16; + input.fill(32, len, 16); + for (let i = 0; i < input.length; i++) { + output.push((input[i] >> 4) + offset); + output.push((input[i] & 0xf) + offset); + } } return output; @@ -46,9 +51,15 @@ const NetBIOS = { let output = [], offset = args[0]; - for (let i = 0; i < input.length; i += 2) { - output.push(((input[i] - offset) << 4) | - ((input[i + 1] - offset) & 0xf)); + if (input.length <= 32 && (input.length % 2) === 0) { + for (let i = 0; i < input.length; i += 2) { + output.push((((input[i] & 0xff) - offset) << 4) | + (((input[i + 1] & 0xff) - offset) & 0xf)); + } + for (let i = output.length - 1; i > 0; i--) { + if (output[i] === 32) output.splice(i, i); + else break; + } } return output; diff --git a/src/core/operations/Numberwang.js b/src/core/operations/Numberwang.js index 9d0fce68..e323f74c 100755 --- a/src/core/operations/Numberwang.js +++ b/src/core/operations/Numberwang.js @@ -14,16 +14,72 @@ const Numberwang = { * @returns {string} */ run: function(input, args) { - if (!input) return "Let's play Wangernumb!"; - const match = input.match(/\d+/); - if (match) { - return match[0] + "! That's Numberwang!"; + let output; + if (!input) { + output = "Let's play Wangernumb!"; } else { - // That's a bad miss! - return "Sorry, that's not Numberwang. Let's rotate the board!"; + const match = input.match(/(f0rty-s1x|shinty-six|filth-hundred and neeb|-?√?\d+(\.\d+)?i?([a-z]?)%?)/i); + if (match) { + if (match[3]) output = match[0] + "! That's AlphaNumericWang!"; + else output = match[0] + "! That's Numberwang!"; + } else { + // That's a bad miss! + output = "Sorry, that's not Numberwang. Let's rotate the board!"; + } } + + const rand = Math.floor(Math.random() * Numberwang._didYouKnow.length); + return output + "\n\nDid you know: " + Numberwang._didYouKnow[rand]; }, + + /** + * Taken from http://numberwang.wikia.com/wiki/Numberwang_Wikia + * + * @private + * @constant + */ + _didYouKnow: [ + "Numberwang, contrary to popular belief, is a fruit and not a vegetable.", + "Robert Webb once got WordWang while presenting an episode of Numberwang.", + "The 6705th digit of pi is Numberwang.", + "Numberwang was invented on a Sevenday.", + "Contrary to popular belief, Albert Einstein always got good grades in Numberwang at school. He once scored ^4$ on a test.", + "680 asteroids have been named after Numberwang.", + "Archimedes is most famous for proclaiming \"That's Numberwang!\" during an epiphany about water displacement he had while taking a bath.", + "Numberwang Day is celebrated in Japan on every day of the year apart from June 6.", + "Biologists recently discovered Numberwang within a strand of human DNA.", + "Numbernot is a special type of non-Numberwang number. It is divisible by 3 and the letter \"y\".", + "Julie once got 612.04 Numberwangs in a single episode of Emmerdale.", + "In India, it is traditional to shout out \"Numberwang!\" instead of checkmate during games of chess.", + "There is a rule on Countdown which states that if you get Numberwang in the numbers round, you automatically win. It has only ever been invoked twice.", + "\"Numberwang\" was the third-most common baby name for a brief period in 1722.", + "\"The Lion King\" was loosely based on Numberwang.", + "\"A Numberwang a day keeps the doctor away\" is how Donny Cosy, the oldest man in the world, explained how he was in such good health at the age of 136.", + "The \"number lock\" button on a keyboard is based on the popular round of the same name in \"Numberwang\".", + "Cambridge became the first university to offer a course in Numberwang in 1567.", + "Schrödinger's Numberwang is a number that has been confusing dentists for centuries.", + "\"Harry Potter and the Numberwang of Numberwang\" was rejected by publishers -41 times before it became a bestseller.", + "\"Numberwang\" is the longest-running British game show in history; it has aired 226 seasons, each containing 19 episodes, which makes a grand total of 132 episodes.", + "The triple Numberwang bonus was discovered by archaeologist Thomas Jefferson in Somerset.", + "Numberwang is illegal in parts of Czechoslovakia.", + "Numberwang was discovered in India in the 12th century.", + "Numberwang has the chemical formula Zn4SO2(HgEs)3.", + "The first pack of cards ever created featured two \"Numberwang\" cards instead of jokers.", + "Julius Caesar was killed by an overdose of Numberwang.", + "The most Numberwang musical note is G#.", + "In 1934, the forty-third Google Doodle promoted the upcoming television show \"Numberwang on Ice\".", + "A recent psychology study found that toddlers were 17% faster at identifying numbers which were Numberwang.", + "There are 700 ways to commit a foul in the television show \"Numberwang\". All 700 of these fouls were committed by Julie in one single episode in 1473.", + "Astronomers suspect God is Numberwang.", + "Numberwang is the official beverage of Canada.", + "In the pilot episode of \"The Price is Right\", if a contestant got the value of an item exactly right they were told \"That's Numberwang!\" and immediately won ₹5.7032.", + "The first person to get three Numberwangs in a row was Madonna.", + "\"Numberwang\" has the code U+46402 in Unicode.", + "The musical note \"Numberwang\" is between D# and E♮.", + "Numberwang was first played on the moon in 1834.", + ], + }; export default Numberwang; diff --git a/src/core/operations/OTP.js b/src/core/operations/OTP.js index ff67d1c8..f7862310 100755 --- a/src/core/operations/OTP.js +++ b/src/core/operations/OTP.js @@ -1,6 +1,7 @@ import otp from "otp"; import Base64 from "./Base64.js"; + /** * One-Time Password operations. * diff --git a/src/core/operations/UUID.js b/src/core/operations/UUID.js index 761f245a..7b485579 100755 --- a/src/core/operations/UUID.js +++ b/src/core/operations/UUID.js @@ -1,3 +1,6 @@ +import crypto from "crypto"; + + /** * UUID operations. * @@ -17,25 +20,17 @@ const UUID = { * @returns {string} */ runGenerateV4: function(input, args) { - if (window && typeof(window.crypto) !== "undefined" && typeof(window.crypto.getRandomValues) !== "undefined") { - let buf = new Uint32Array(4), - i = 0; - window.crypto.getRandomValues(buf); - return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) { - let r = (buf[i >> 3] >> ((i % 8) * 4)) & 0xf, - v = c === "x" ? r : (r & 0x3 | 0x8); - i++; - return v.toString(16); - }); - } else { - return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) { - let r = Math.random() * 16 | 0, - v = c === "x" ? r : (r & 0x3 | 0x8); - return v.toString(16); - }); - } - }, - + const buf = new Uint32Array(4).map(() => { + return crypto.randomBytes(4).readUInt32BE(0, true); + }); + let i = 0; + return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) { + let r = (buf[i >> 3] >> ((i % 8) * 4)) & 0xf, + v = c === "x" ? r : (r & 0x3 | 0x8); + i++; + return v.toString(16); + }); + } }; export default UUID; diff --git a/src/web/App.js b/src/web/App.js index 036a4fb9..d877791d 100755 --- a/src/web/App.js +++ b/src/web/App.js @@ -529,7 +529,7 @@ App.prototype.setCompileMessage = function() { /** * Determines whether the browser supports Local Storage and if it is accessible. - * + * * @returns {boolean} */ App.prototype.isLocalStorageAvailable = function() { diff --git a/src/web/html/index.html b/src/web/html/index.html index e6525b80..ea5fec36 100755 --- a/src/web/html/index.html +++ b/src/web/html/index.html @@ -466,7 +466,7 @@
  • Convert data from a hexdump, then decompress
  • Decrypt and disassemble shellcode
  • Display multiple timestamps as full dates
  • -
  • Carry out different operations on data of different types
  • +
  • Carry out different operations on data of different types
  • Use parts of the input as arguments to operations
  • diff --git a/test/index.js b/test/index.js index 748e1103..050acf0f 100644 --- a/test/index.js +++ b/test/index.js @@ -26,6 +26,8 @@ import "./tests/operations/Image.js"; import "./tests/operations/MorseCode.js"; import "./tests/operations/MS.js"; import "./tests/operations/PHP.js"; +import "./tests/operations/NetBIOS.js"; +import "./tests/operations/OTP.js"; import "./tests/operations/StrUtils.js"; import "./tests/operations/SeqUtils.js"; diff --git a/test/tests/operations/Code.js b/test/tests/operations/Code.js index fee0b5f4..b13dcfd9 100644 --- a/test/tests/operations/Code.js +++ b/test/tests/operations/Code.js @@ -310,4 +310,26 @@ TestRegister.addTests([ } ], }, + { + name: "CSS selector", + input: '
    \n

    hello

    \n

    world

    \n

    again

    \n
    ', + expectedOutput: '

    hello

    \n

    again

    ', + recipeConfig: [ + { + "op": "CSS selector", + "args": ["#test p.a", "\\n"] + } + ] + }, + { + name: "XPath expression", + input: '
    \n

    hello

    \n

    world

    \n

    again

    \n
    ', + expectedOutput: '

    hello

    \n

    again

    ', + recipeConfig: [ + { + "op": "XPath expression", + "args": ["/div/p[@class=\"a\"]", "\\n"] + } + ] + } ]); diff --git a/test/tests/operations/FlowControl.js b/test/tests/operations/FlowControl.js index 42a4bfd3..04ed93eb 100644 --- a/test/tests/operations/FlowControl.js +++ b/test/tests/operations/FlowControl.js @@ -60,14 +60,15 @@ TestRegister.addTests([ expectedOutput: "U29tZSBkYXRhIHdpdGggYSAxIGluIGl0\n53 6f 6d 65 20 64 61 74 61 20 77 69 74 68 20 61 20 32 20 69 6e 20 69 74\n", recipeConfig: [ {"op": "Fork", "args": ["\\n", "\\n", false]}, - {"op": "Conditional Jump", "args": ["1", "2", "10"]}, + {"op": "Conditional Jump", "args": ["1", false, "skipReturn", "10"]}, {"op": "To Hex", "args": ["Space"]}, {"op": "Return", "args": []}, + {"op": "Label", "args": ["skipReturn"]}, {"op": "To Base64", "args": ["A-Za-z0-9+/="]} ] }, { - name: "Jump: skips 0", + name: "Jump: Empty Label", input: [ "should be changed", ].join("\n"), @@ -77,7 +78,7 @@ TestRegister.addTests([ recipeConfig: [ { op: "Jump", - args: [0, 10], + args: ["", 10], }, { op: "Find / Replace", @@ -105,7 +106,7 @@ TestRegister.addTests([ recipeConfig: [ { op: "Jump", - args: [1, 10], + args: ["skipReplace", 10], }, { op: "Find / Replace", @@ -120,6 +121,10 @@ TestRegister.addTests([ true, ], }, + { + op: "Label", + args: ["skipReplace"] + }, ], }, { @@ -137,7 +142,7 @@ TestRegister.addTests([ recipeConfig: [ { op: "Conditional Jump", - args: ["match", 0, 0], + args: ["match", false, "", 0], }, { op: "Find / Replace", @@ -212,7 +217,7 @@ TestRegister.addTests([ recipeConfig: [ { op: "Conditional Jump", - args: ["match", 1, 10], + args: ["match", false, "skip match", 10], }, { op: "Find / Replace", @@ -227,6 +232,9 @@ TestRegister.addTests([ true, ], }, + { + op: "Label", args: ["skip match"], + }, { op: "Find / Replace", args: [ @@ -251,9 +259,13 @@ TestRegister.addTests([ "replaced", ].join("\n"), recipeConfig: [ + { + op: "Label", + args: ["back to the beginning"], + }, { op: "Jump", - args: [1], + args: ["skip replace"], }, { op: "Find / Replace", @@ -268,9 +280,13 @@ TestRegister.addTests([ true, ], }, + { + op: "Label", + args: ["skip replace"], + }, { op: "Conditional Jump", - args: ["match", -2, 10], + args: ["match", false, "back to the beginning", 10], }, ], }, diff --git a/test/tests/operations/NetBIOS.js b/test/tests/operations/NetBIOS.js new file mode 100644 index 00000000..2994b79e --- /dev/null +++ b/test/tests/operations/NetBIOS.js @@ -0,0 +1,34 @@ +/** + * NetBIOS tests. + * + * @author bwhitn [brian.m.whitney@outlook.com] + * + * @copyright Crown Copyright 2017 + * @license Apache-2.0 + */ +import TestRegister from "../../TestRegister.js"; + +TestRegister.addTests([ + { + name: "Encode NetBIOS name", + input: "The NetBIOS name", + expectedOutput: "FEGIGFCAEOGFHEECEJEPFDCAGOGBGNGF", + recipeConfig: [ + { + op: "Encode NetBIOS Name", + args: [65], + }, + ], + }, + { + name: "Decode NetBIOS Name", + input: "FEGIGFCAEOGFHEECEJEPFDCAGOGBGNGF", + expectedOutput: "The NetBIOS name", + recipeConfig: [ + { + op: "Decode NetBIOS Name", + args: [65], + }, + ], + }, +]); diff --git a/test/tests/operations/OTP.js b/test/tests/operations/OTP.js new file mode 100644 index 00000000..b321e7cf --- /dev/null +++ b/test/tests/operations/OTP.js @@ -0,0 +1,23 @@ +/** + * OTP HOTP tests. + * + * @author bwhitn [brian.m.whitney@outlook.com] + * + * @copyright Crown Copyright 2017 + * @license Apache-2.0 + */ +import TestRegister from "../../TestRegister.js"; + +TestRegister.addTests([ + { + name: "Generate HOTP", + input: "12345678901234567890", + expectedOutput: "URI: otpauth://hotp/OTPAuthentication?secret=GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ\n\nPassword: 755224", + recipeConfig: [ + { + op: "Generate HOTP", + args: ["", 32, 6, 0], + }, + ], + }, +]);