From e108a48ac415ab2b1fc212c63ad1a2e68efd5e4e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 21 Nov 2016 16:08:12 +0100 Subject: [PATCH] ADD: added the 'hf mf hardnested' to be called within LUA scripts. ADD: 'script run hard' - a first try for a lua script to run the hardnested attack on a complete tag. --- client/cmdhfmf.c | 3 +- client/cmdhfmfhard.c | 21 +++++--- client/cmdhfmfhard.h | 2 +- client/scripting.c | 75 ++++++++++++++++++++++++++- client/scripting.h | 1 + client/scripts/hard.lua | 109 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 202 insertions(+), 9 deletions(-) create mode 100644 client/scripts/hard.lua diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 6b4d3a73..0ea171af 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1057,7 +1057,8 @@ int CmdHF14AMfNestedHard(const char *Cmd) { slow ? "Yes" : "No", tests); - int16_t isOK = mfnestedhard(blockNo, keyType, key, trgBlockNo, trgKeyType, know_target_key ? trgkey : NULL, nonce_file_read, nonce_file_write, slow, tests); + uint64_t foundkey = 0; + int16_t isOK = mfnestedhard(blockNo, keyType, key, trgBlockNo, trgKeyType, know_target_key ? trgkey : NULL, nonce_file_read, nonce_file_write, slow, tests, &foundkey); if (isOK) { switch (isOK) { diff --git a/client/cmdhfmfhard.c b/client/cmdhfmfhard.c index a9dc8762..f9c1415c 100644 --- a/client/cmdhfmfhard.c +++ b/client/cmdhfmfhard.c @@ -777,6 +777,7 @@ static int acquire_nonces(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_ uint32_t next_fivehundred = 500; uint32_t total_added_nonces = 0; uint32_t idx = 1; + uint32_t timeout = 0; FILE *fnonces = NULL; field_off = false; UsbCommand resp; @@ -799,10 +800,15 @@ static int acquire_nonces(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_ if (field_off) break; - if (!WaitForResponseTimeout(CMD_ACK, &resp, 6000)) { - if (fnonces) fclose(fnonces); - return 1; - } + while(!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { + timeout++; + printf("."); + if (timeout > 7) { + PrintAndLog("\nNo response from Proxmark. Aborting..."); + if (fnonces) fclose(fnonces); + return 1; + } + } if (resp.arg[0]) { if (fnonces) fclose(fnonces); @@ -1723,12 +1729,14 @@ static bool brute_force(void) { return ret; } -int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t *trgkey, bool nonce_file_read, bool nonce_file_write, bool slow, int tests) +int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t *trgkey, bool nonce_file_read, bool nonce_file_write, bool slow, int tests, uint64_t *found_key) { // initialize Random number generator time_t t; srand((unsigned) time(&t)); + *found_key = 0; + if (trgkey != NULL) { known_target_key = bytes_to_num(trgkey, 6); } else { @@ -1790,5 +1798,6 @@ int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBloc free_candidates_memory(candidates); candidates = NULL; } + *found_key = foundkey; return 0; -} +} \ No newline at end of file diff --git a/client/cmdhfmfhard.h b/client/cmdhfmfhard.h index a12875ac..c6401cae 100644 --- a/client/cmdhfmfhard.h +++ b/client/cmdhfmfhard.h @@ -31,6 +31,6 @@ #endif #include -int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t *trgkey, bool nonce_file_read, bool nonce_file_write, bool slow, int tests); +int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t *trgkey, bool nonce_file_read, bool nonce_file_write, bool slow, int tests, uint64_t *foundkey); #endif diff --git a/client/scripting.c b/client/scripting.c index 64fb2a8f..752edba6 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -463,6 +463,79 @@ static int l_reveng_RunModel(lua_State *L){ return 1; } +static int l_hardnested(lua_State *L){ + + bool haveTarget = TRUE; + size_t size; + const char *p_blockno = luaL_checklstring(L, 1, &size); + if(size != 2) return returnToLuaWithError(L,"Wrong size of blockNo, got %d bytes, expected 2", (int) size); + + const char *p_keytype = luaL_checklstring(L, 2, &size); + if(size != 1) return returnToLuaWithError(L,"Wrong size of keyType, got %d bytes, expected 1", (int) size); + + const char *p_key = luaL_checklstring(L, 3, &size); + if(size != 12) return returnToLuaWithError(L,"Wrong size of key, got %d bytes, expected 12", (int) size); + + const char *p_trg_blockno = luaL_checklstring(L, 4, &size); + if(size != 2) return returnToLuaWithError(L,"Wrong size of trgBlockNo, got %d bytes, expected 2", (int) size); + + const char *p_trg_keytype = luaL_checklstring(L, 5, &size); + if(size != 1) return returnToLuaWithError(L,"Wrong size of trgKeyType, got %d bytes, expected 1", (int) size); + + const char *p_trgkey = luaL_checklstring(L, 6, &size); + if(size != 12) + haveTarget = FALSE; + + const char *p_nonce_file_read = luaL_checklstring(L, 7, &size); + if(size != 1) return returnToLuaWithError(L,"Wrong size of nonce_file_read, got %d bytes, expected 1", (int) size); + + const char *p_nonce_file_write = luaL_checklstring(L, 8, &size); + if(size != 1) return returnToLuaWithError(L,"Wrong size of nonce_file_write, got %d bytes, expected 1", (int) size); + + const char *p_slow = luaL_checklstring(L, 9, &size); + if(size != 1) return returnToLuaWithError(L,"Wrong size of slow, got %d bytes, expected 1", (int) size); + + const char *p_tests = luaL_checklstring(L, 10, &size); + if(size != 1) return returnToLuaWithError(L,"Wrong size of tests, got %d bytes, expected 1", (int) size); + + uint32_t blockNo = 0, keyType = 0; + uint32_t trgBlockNo = 0, trgKeyType = 0; + uint32_t slow = 0, tests = 0; + uint32_t nonce_file_read = 0, nonce_file_write = 0; + + sscanf(p_blockno, "%02x", &blockNo); + sscanf(p_keytype, "%x", &keyType); + sscanf(p_trg_blockno, "%02x", &trgBlockNo); + sscanf(p_trg_keytype, "%x", &trgKeyType); + sscanf(p_nonce_file_read, "%x", &nonce_file_read); + sscanf(p_nonce_file_write, "%x", &nonce_file_write); + + sscanf(p_slow, "%x", &slow); + sscanf(p_tests, "%x", &tests); + + uint8_t key[6] = {0,0,0,0,0,0}; + uint8_t trgkey[6] = {0,0,0,0,0,0}; + for (int i = 0; i < 32; i += 2) { + sscanf(&p_key[i], "%02x", (unsigned int *)&key[i / 2]); + if (haveTarget) + sscanf(&p_trgkey[i], "%02x", (unsigned int *)&trgkey[i / 2]); + } + + uint64_t foundkey = 0; + int retval = mfnestedhard(blockNo, keyType, key, trgBlockNo, trgKeyType, haveTarget ? trgkey : NULL, nonce_file_read, nonce_file_write, slow, tests, &foundkey); + + //Push the retval on the stack + lua_pushinteger(L,retval); + + //Push the key onto the stack + uint8_t dest_key[6]; + num_to_bytes(foundkey, sizeof(dest_key), dest_key); + + //printf("Pushing to lua stack: %012"llx"\n",key); + lua_pushlstring(L, (const char *) dest_key, sizeof(dest_key)); + return 2; //Two return values +} + /** * @brief Sets the lua path to include "./lualibs/?.lua", in order for a script to be * able to do "require('foobar')" if foobar.lua is within lualibs folder. @@ -489,7 +562,6 @@ int setLuaPath( lua_State* L, const char* path ) int set_pm3_libraries(lua_State *L) { - static const luaL_Reg libs[] = { {"SendCommand", l_SendCommand}, {"WaitForResponseTimeout", l_WaitForResponseTimeout}, @@ -511,6 +583,7 @@ int set_pm3_libraries(lua_State *L) {"sha1", l_sha1}, {"reveng_models", l_reveng_models}, {"reveng_runmodel", l_reveng_RunModel}, + {"hardnested", l_hardnested}, {NULL, NULL} }; diff --git a/client/scripting.h b/client/scripting.h index 3a3babe3..fadb81f5 100644 --- a/client/scripting.h +++ b/client/scripting.h @@ -26,6 +26,7 @@ #include "../common/sha1.h" #include "aes.h" #include "cmdcrc.h" +#include "cmdhfmfhard.h" /** * @brief set_libraries loads the core components of pm3 into the 'pm3' diff --git a/client/scripts/hard.lua b/client/scripts/hard.lua new file mode 100644 index 00000000..7671c9d6 --- /dev/null +++ b/client/scripts/hard.lua @@ -0,0 +1,109 @@ +local cmds = require('commands') +local getopt = require('getopt') +local utils = require('utils') +local lib14a = require('read14a') + +example = "script iterates over all possible sectors for a tag and runs hardnested attack against them to collect the keys." +author = "Iceman" +desc = +[[ +This script iterates over all possible sectors for a tag and runs hardnested attack against them to collect the keys. + +Arguments: + -k Known key, 6 bytes (12 hex digits) +Examples : + script hard -b 112233445566 +]] + +local numBlocks = 64 +local numSectors = 16 +local DEBUG = TRUE +--- +-- A debug printout-function +function dbg(args) + if not DEBUG then return end + + if type(args) == "table" then + local i = 1 + while result[i] do + dbg(result[i]) + i = i+1 + end + else + print("###", args) + end +end +--- +-- This is only meant to be used when errors occur +function oops(err) + print("ERROR: ",err) + return nil,err +end +--- +-- Usage help +function help() + print(desc) + print("Example usage") + print(example) +end +-- +-- Exit message +function ExitMsg(msg) + print( string.rep('--',20) ) + print( string.rep('--',20) ) + print(msg) + print() +end +--- +-- a simple selftest function, +local function selftest() + return nil +end + +--- +-- The main entry point +function main(args) + + local blockno = '00' + local keytype = 0 --A 01==B + local key = 'fc00018778f7' + local trgkey = '' + + local data + -- Read the parameters + for o, a in getopt.getopt(args, 'hk:t') do + if o == "h" then return help() end + if o == "k" then key = a end + if o == "t" then return selftest() end + end + + -- Turn off Debug + local cmdSetDbgOff = "hf mf dbg 0" + core.console( cmdSetDbgOff) + -- identify tag + result, err = lib14a.read1443a(false) + if not result then + return oops(err) + end + core.clearCommandBuffer() + + -- Show tag info + print((' Found tag %s'):format(result.name)) + + local keys = {} + -- loop + for i=4, 12 , 4 do + for trgkeytype=0,1 do + local trgblockno = ("%02d"):format(i) + local err, found_key = core.hardnested(blockno, keytype, key, trgblockno, trgkeytype, trgkey, 0,0,0,0) + + table.insert( keys , { ["success"] = err, ["sector"] = i, ["type"] = trgkeytype, ["key"] = utils.ConvertAsciiToHex(found_key) } ) + end + end + --print + for k,v in pairs(keys) do + for a,b in pairs(v) do print(a,b) end + end +end + +main(args) \ No newline at end of file -- 2.39.2